1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; @ -- print a segment register of thread base pointer load
65 (define_c_enum "unspec" [
66 ;; Relocation specifiers
77 UNSPEC_MACHOPIC_OFFSET
85 UNSPEC_MEMORY_BLOCKAGE
95 ;; Other random patterns
104 UNSPEC_LD_MPIC ; load_macho_picbase
106 UNSPEC_DIV_ALREADY_SPLIT
107 UNSPEC_MS_TO_SYSV_CALL
108 UNSPEC_CALL_NEEDS_VZEROUPPER
111 ;; For SSE/MMX support:
119 ;; Generic math support
121 UNSPEC_IEEE_MIN ; not commutative
122 UNSPEC_IEEE_MAX ; not commutative
124 ;; x87 Floating point
140 UNSPEC_FRNDINT_MASK_PM
144 ;; x87 Double output FP
179 (define_c_enum "unspecv" [
182 UNSPECV_PROBE_STACK_RANGE
185 UNSPECV_SPLIT_STACK_RETURN
191 UNSPECV_LLWP_INTRINSIC
192 UNSPECV_SLWP_INTRINSIC
193 UNSPECV_LWPVAL_INTRINSIC
194 UNSPECV_LWPINS_INTRINSIC
200 ;; For RDRAND support
204 ;; Constants to represent rounding modes in the ROUND instruction
213 ;; Constants to represent pcomtrue/pcomfalse variants
223 ;; Constants used in the XOP pperm instruction
225 [(PPERM_SRC 0x00) /* copy source */
226 (PPERM_INVERT 0x20) /* invert source */
227 (PPERM_REVERSE 0x40) /* bit reverse source */
228 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
229 (PPERM_ZERO 0x80) /* all 0's */
230 (PPERM_ONES 0xa0) /* all 1's */
231 (PPERM_SIGN 0xc0) /* propagate sign bit */
232 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
233 (PPERM_SRC1 0x00) /* use first source byte */
234 (PPERM_SRC2 0x10) /* use second source byte */
237 ;; Registers by name.
290 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
293 ;; In C guard expressions, put expressions which may be compile-time
294 ;; constants first. This allows for better optimization. For
295 ;; example, write "TARGET_64BIT && reload_completed", not
296 ;; "reload_completed && TARGET_64BIT".
300 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
301 atom,generic64,amdfam10,bdver1,bdver2,btver1"
302 (const (symbol_ref "ix86_schedule")))
304 ;; A basic instruction type. Refinements due to arguments to be
305 ;; provided in other attributes.
308 alu,alu1,negnot,imov,imovx,lea,
309 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
310 icmp,test,ibr,setcc,icmov,
311 push,pop,call,callv,leave,
313 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
314 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
315 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
316 ssemuladd,sse4arg,lwp,
317 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
318 (const_string "other"))
320 ;; Main data type used by the insn
322 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
323 (const_string "unknown"))
325 ;; The CPU unit operations uses.
326 (define_attr "unit" "integer,i387,sse,mmx,unknown"
327 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
328 (const_string "i387")
329 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
330 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
331 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
333 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
335 (eq_attr "type" "other")
336 (const_string "unknown")]
337 (const_string "integer")))
339 ;; The (bounding maximum) length of an instruction immediate.
340 (define_attr "length_immediate" ""
341 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
344 (eq_attr "unit" "i387,sse,mmx")
346 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
347 rotate,rotatex,rotate1,imul,icmp,push,pop")
348 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
349 (eq_attr "type" "imov,test")
350 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
351 (eq_attr "type" "call")
352 (if_then_else (match_operand 0 "constant_call_address_operand" "")
355 (eq_attr "type" "callv")
356 (if_then_else (match_operand 1 "constant_call_address_operand" "")
359 ;; We don't know the size before shorten_branches. Expect
360 ;; the instruction to fit for better scheduling.
361 (eq_attr "type" "ibr")
364 (symbol_ref "/* Update immediate_length and other attributes! */
365 gcc_unreachable (),1")))
367 ;; The (bounding maximum) length of an instruction address.
368 (define_attr "length_address" ""
369 (cond [(eq_attr "type" "str,other,multi,fxch")
371 (and (eq_attr "type" "call")
372 (match_operand 0 "constant_call_address_operand" ""))
374 (and (eq_attr "type" "callv")
375 (match_operand 1 "constant_call_address_operand" ""))
378 (symbol_ref "ix86_attr_length_address_default (insn)")))
380 ;; Set when length prefix is used.
381 (define_attr "prefix_data16" ""
382 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
384 (eq_attr "mode" "HI")
386 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
391 ;; Set when string REP prefix is used.
392 (define_attr "prefix_rep" ""
393 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
395 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
400 ;; Set when 0f opcode prefix is used.
401 (define_attr "prefix_0f" ""
403 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
404 (eq_attr "unit" "sse,mmx"))
408 ;; Set when REX opcode prefix is used.
409 (define_attr "prefix_rex" ""
410 (cond [(not (match_test "TARGET_64BIT"))
412 (and (eq_attr "mode" "DI")
413 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
414 (eq_attr "unit" "!mmx")))
416 (and (eq_attr "mode" "QI")
417 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
419 (match_test "x86_extended_reg_mentioned_p (insn)")
421 (and (eq_attr "type" "imovx")
422 (match_operand:QI 1 "ext_QIreg_operand" ""))
427 ;; There are also additional prefixes in 3DNOW, SSSE3.
428 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
429 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
430 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
431 (define_attr "prefix_extra" ""
432 (cond [(eq_attr "type" "ssemuladd,sse4arg")
434 (eq_attr "type" "sseiadd1,ssecvt1")
439 ;; Prefix used: original, VEX or maybe VEX.
440 (define_attr "prefix" "orig,vex,maybe_vex"
441 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
443 (const_string "orig")))
445 ;; VEX W bit is used.
446 (define_attr "prefix_vex_w" "" (const_int 0))
448 ;; The length of VEX prefix
449 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
450 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
451 ;; still prefix_0f 1, with prefix_extra 1.
452 (define_attr "length_vex" ""
453 (if_then_else (and (eq_attr "prefix_0f" "1")
454 (eq_attr "prefix_extra" "0"))
455 (if_then_else (eq_attr "prefix_vex_w" "1")
456 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
457 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
458 (if_then_else (eq_attr "prefix_vex_w" "1")
459 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
460 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
462 ;; Set when modrm byte is used.
463 (define_attr "modrm" ""
464 (cond [(eq_attr "type" "str,leave")
466 (eq_attr "unit" "i387")
468 (and (eq_attr "type" "incdec")
469 (and (not (match_test "TARGET_64BIT"))
470 (ior (match_operand:SI 1 "register_operand" "")
471 (match_operand:HI 1 "register_operand" ""))))
473 (and (eq_attr "type" "push")
474 (not (match_operand 1 "memory_operand" "")))
476 (and (eq_attr "type" "pop")
477 (not (match_operand 0 "memory_operand" "")))
479 (and (eq_attr "type" "imov")
480 (and (not (eq_attr "mode" "DI"))
481 (ior (and (match_operand 0 "register_operand" "")
482 (match_operand 1 "immediate_operand" ""))
483 (ior (and (match_operand 0 "ax_reg_operand" "")
484 (match_operand 1 "memory_displacement_only_operand" ""))
485 (and (match_operand 0 "memory_displacement_only_operand" "")
486 (match_operand 1 "ax_reg_operand" ""))))))
488 (and (eq_attr "type" "call")
489 (match_operand 0 "constant_call_address_operand" ""))
491 (and (eq_attr "type" "callv")
492 (match_operand 1 "constant_call_address_operand" ""))
494 (and (eq_attr "type" "alu,alu1,icmp,test")
495 (match_operand 0 "ax_reg_operand" ""))
496 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
500 ;; The (bounding maximum) length of an instruction in bytes.
501 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
502 ;; Later we may want to split them and compute proper length as for
504 (define_attr "length" ""
505 (cond [(eq_attr "type" "other,multi,fistp,frndint")
507 (eq_attr "type" "fcmp")
509 (eq_attr "unit" "i387")
511 (plus (attr "prefix_data16")
512 (attr "length_address")))
513 (ior (eq_attr "prefix" "vex")
514 (and (eq_attr "prefix" "maybe_vex")
515 (match_test "TARGET_AVX")))
516 (plus (attr "length_vex")
517 (plus (attr "length_immediate")
519 (attr "length_address"))))]
520 (plus (plus (attr "modrm")
521 (plus (attr "prefix_0f")
522 (plus (attr "prefix_rex")
523 (plus (attr "prefix_extra")
525 (plus (attr "prefix_rep")
526 (plus (attr "prefix_data16")
527 (plus (attr "length_immediate")
528 (attr "length_address")))))))
530 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
531 ;; `store' if there is a simple memory reference therein, or `unknown'
532 ;; if the instruction is complex.
534 (define_attr "memory" "none,load,store,both,unknown"
535 (cond [(eq_attr "type" "other,multi,str,lwp")
536 (const_string "unknown")
537 (eq_attr "type" "lea,fcmov,fpspc")
538 (const_string "none")
539 (eq_attr "type" "fistp,leave")
540 (const_string "both")
541 (eq_attr "type" "frndint")
542 (const_string "load")
543 (eq_attr "type" "push")
544 (if_then_else (match_operand 1 "memory_operand" "")
545 (const_string "both")
546 (const_string "store"))
547 (eq_attr "type" "pop")
548 (if_then_else (match_operand 0 "memory_operand" "")
549 (const_string "both")
550 (const_string "load"))
551 (eq_attr "type" "setcc")
552 (if_then_else (match_operand 0 "memory_operand" "")
553 (const_string "store")
554 (const_string "none"))
555 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
556 (if_then_else (ior (match_operand 0 "memory_operand" "")
557 (match_operand 1 "memory_operand" ""))
558 (const_string "load")
559 (const_string "none"))
560 (eq_attr "type" "ibr")
561 (if_then_else (match_operand 0 "memory_operand" "")
562 (const_string "load")
563 (const_string "none"))
564 (eq_attr "type" "call")
565 (if_then_else (match_operand 0 "constant_call_address_operand" "")
566 (const_string "none")
567 (const_string "load"))
568 (eq_attr "type" "callv")
569 (if_then_else (match_operand 1 "constant_call_address_operand" "")
570 (const_string "none")
571 (const_string "load"))
572 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
573 (match_operand 1 "memory_operand" ""))
574 (const_string "both")
575 (and (match_operand 0 "memory_operand" "")
576 (match_operand 1 "memory_operand" ""))
577 (const_string "both")
578 (match_operand 0 "memory_operand" "")
579 (const_string "store")
580 (match_operand 1 "memory_operand" "")
581 (const_string "load")
583 "!alu1,negnot,ishift1,
584 imov,imovx,icmp,test,bitmanip,
586 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
587 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
588 (match_operand 2 "memory_operand" ""))
589 (const_string "load")
590 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
591 (match_operand 3 "memory_operand" ""))
592 (const_string "load")
594 (const_string "none")))
596 ;; Indicates if an instruction has both an immediate and a displacement.
598 (define_attr "imm_disp" "false,true,unknown"
599 (cond [(eq_attr "type" "other,multi")
600 (const_string "unknown")
601 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
602 (and (match_operand 0 "memory_displacement_operand" "")
603 (match_operand 1 "immediate_operand" "")))
604 (const_string "true")
605 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
606 (and (match_operand 0 "memory_displacement_operand" "")
607 (match_operand 2 "immediate_operand" "")))
608 (const_string "true")
610 (const_string "false")))
612 ;; Indicates if an FP operation has an integer source.
614 (define_attr "fp_int_src" "false,true"
615 (const_string "false"))
617 ;; Defines rounding mode of an FP operation.
619 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
620 (const_string "any"))
622 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
623 (define_attr "use_carry" "0,1" (const_string "0"))
625 ;; Define attribute to indicate unaligned ssemov insns
626 (define_attr "movu" "0,1" (const_string "0"))
628 ;; Used to control the "enabled" attribute on a per-instruction basis.
629 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
630 (const_string "base"))
632 (define_attr "enabled" ""
633 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
634 (eq_attr "isa" "sse2_noavx")
635 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
636 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
637 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
638 (eq_attr "isa" "sse4_noavx")
639 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
640 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
641 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
642 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
646 ;; Describe a user's asm statement.
647 (define_asm_attributes
648 [(set_attr "length" "128")
649 (set_attr "type" "multi")])
651 (define_code_iterator plusminus [plus minus])
653 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
655 ;; Base name for define_insn
656 (define_code_attr plusminus_insn
657 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
658 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
660 ;; Base name for insn mnemonic.
661 (define_code_attr plusminus_mnemonic
662 [(plus "add") (ss_plus "adds") (us_plus "addus")
663 (minus "sub") (ss_minus "subs") (us_minus "subus")])
664 (define_code_attr plusminus_carry_mnemonic
665 [(plus "adc") (minus "sbb")])
667 ;; Mark commutative operators as such in constraints.
668 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
669 (minus "") (ss_minus "") (us_minus "")])
671 ;; Mapping of max and min
672 (define_code_iterator maxmin [smax smin umax umin])
674 ;; Mapping of signed max and min
675 (define_code_iterator smaxmin [smax smin])
677 ;; Mapping of unsigned max and min
678 (define_code_iterator umaxmin [umax umin])
680 ;; Base name for integer and FP insn mnemonic
681 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
682 (umax "maxu") (umin "minu")])
683 (define_code_attr maxmin_float [(smax "max") (smin "min")])
685 ;; Mapping of logic operators
686 (define_code_iterator any_logic [and ior xor])
687 (define_code_iterator any_or [ior xor])
689 ;; Base name for insn mnemonic.
690 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
692 ;; Mapping of logic-shift operators
693 (define_code_iterator any_lshift [ashift lshiftrt])
695 ;; Mapping of shift-right operators
696 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
698 ;; Base name for define_insn
699 (define_code_attr shift_insn
700 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
702 ;; Base name for insn mnemonic.
703 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
704 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
706 ;; Mapping of rotate operators
707 (define_code_iterator any_rotate [rotate rotatert])
709 ;; Base name for define_insn
710 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
712 ;; Base name for insn mnemonic.
713 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
715 ;; Mapping of abs neg operators
716 (define_code_iterator absneg [abs neg])
718 ;; Base name for x87 insn mnemonic.
719 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
721 ;; Used in signed and unsigned widening multiplications.
722 (define_code_iterator any_extend [sign_extend zero_extend])
724 ;; Prefix for insn menmonic.
725 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
727 ;; Prefix for define_insn
728 (define_code_attr u [(sign_extend "") (zero_extend "u")])
729 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
731 ;; All integer modes.
732 (define_mode_iterator SWI1248x [QI HI SI DI])
734 ;; All integer modes without QImode.
735 (define_mode_iterator SWI248x [HI SI DI])
737 ;; All integer modes without QImode and HImode.
738 (define_mode_iterator SWI48x [SI DI])
740 ;; All integer modes without SImode and DImode.
741 (define_mode_iterator SWI12 [QI HI])
743 ;; All integer modes without DImode.
744 (define_mode_iterator SWI124 [QI HI SI])
746 ;; All integer modes without QImode and DImode.
747 (define_mode_iterator SWI24 [HI SI])
749 ;; Single word integer modes.
750 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
752 ;; Single word integer modes without QImode.
753 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
755 ;; Single word integer modes without QImode and HImode.
756 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
758 ;; All math-dependant single and double word integer modes.
759 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
760 (HI "TARGET_HIMODE_MATH")
761 SI DI (TI "TARGET_64BIT")])
763 ;; Math-dependant single word integer modes.
764 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
765 (HI "TARGET_HIMODE_MATH")
766 SI (DI "TARGET_64BIT")])
768 ;; Math-dependant integer modes without DImode.
769 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
770 (HI "TARGET_HIMODE_MATH")
773 ;; Math-dependant single word integer modes without QImode.
774 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
775 SI (DI "TARGET_64BIT")])
777 ;; Double word integer modes.
778 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
779 (TI "TARGET_64BIT")])
781 ;; Double word integer modes as mode attribute.
782 (define_mode_attr DWI [(SI "DI") (DI "TI")])
783 (define_mode_attr dwi [(SI "di") (DI "ti")])
785 ;; Half mode for double word integer modes.
786 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
787 (DI "TARGET_64BIT")])
789 ;; Instruction suffix for integer modes.
790 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
792 ;; Pointer size prefix for integer modes (Intel asm dialect)
793 (define_mode_attr iptrsize [(QI "BYTE")
798 ;; Register class for integer modes.
799 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
801 ;; Immediate operand constraint for integer modes.
802 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
804 ;; General operand constraint for word modes.
805 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
807 ;; Immediate operand constraint for double integer modes.
808 (define_mode_attr di [(SI "nF") (DI "e")])
810 ;; Immediate operand constraint for shifts.
811 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
813 ;; General operand predicate for integer modes.
814 (define_mode_attr general_operand
815 [(QI "general_operand")
816 (HI "general_operand")
817 (SI "x86_64_general_operand")
818 (DI "x86_64_general_operand")
819 (TI "x86_64_general_operand")])
821 ;; General sign/zero extend operand predicate for integer modes.
822 (define_mode_attr general_szext_operand
823 [(QI "general_operand")
824 (HI "general_operand")
825 (SI "x86_64_szext_general_operand")
826 (DI "x86_64_szext_general_operand")])
828 ;; Immediate operand predicate for integer modes.
829 (define_mode_attr immediate_operand
830 [(QI "immediate_operand")
831 (HI "immediate_operand")
832 (SI "x86_64_immediate_operand")
833 (DI "x86_64_immediate_operand")])
835 ;; Nonmemory operand predicate for integer modes.
836 (define_mode_attr nonmemory_operand
837 [(QI "nonmemory_operand")
838 (HI "nonmemory_operand")
839 (SI "x86_64_nonmemory_operand")
840 (DI "x86_64_nonmemory_operand")])
842 ;; Operand predicate for shifts.
843 (define_mode_attr shift_operand
844 [(QI "nonimmediate_operand")
845 (HI "nonimmediate_operand")
846 (SI "nonimmediate_operand")
847 (DI "shiftdi_operand")
848 (TI "register_operand")])
850 ;; Operand predicate for shift argument.
851 (define_mode_attr shift_immediate_operand
852 [(QI "const_1_to_31_operand")
853 (HI "const_1_to_31_operand")
854 (SI "const_1_to_31_operand")
855 (DI "const_1_to_63_operand")])
857 ;; Input operand predicate for arithmetic left shifts.
858 (define_mode_attr ashl_input_operand
859 [(QI "nonimmediate_operand")
860 (HI "nonimmediate_operand")
861 (SI "nonimmediate_operand")
862 (DI "ashldi_input_operand")
863 (TI "reg_or_pm1_operand")])
865 ;; SSE and x87 SFmode and DFmode floating point modes
866 (define_mode_iterator MODEF [SF DF])
868 ;; All x87 floating point modes
869 (define_mode_iterator X87MODEF [SF DF XF])
871 ;; SSE instruction suffix for various modes
872 (define_mode_attr ssemodesuffix
874 (V8SF "ps") (V4DF "pd")
875 (V4SF "ps") (V2DF "pd")
876 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
877 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
879 ;; SSE vector suffix for floating point modes
880 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
882 ;; SSE vector mode corresponding to a scalar mode
883 (define_mode_attr ssevecmode
884 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
886 ;; Instruction suffix for REX 64bit operators.
887 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
889 ;; This mode iterator allows :P to be used for patterns that operate on
890 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
891 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
893 ;; This mode iterator allows :PTR to be used for patterns that operate on
894 ;; ptr_mode sized quantities.
895 (define_mode_iterator PTR
896 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
898 ;; Scheduling descriptions
900 (include "pentium.md")
903 (include "athlon.md")
904 (include "bdver1.md")
910 ;; Operand and operator predicates and constraints
912 (include "predicates.md")
913 (include "constraints.md")
916 ;; Compare and branch/compare and store instructions.
918 (define_expand "cbranch<mode>4"
919 [(set (reg:CC FLAGS_REG)
920 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
921 (match_operand:SDWIM 2 "<general_operand>" "")))
922 (set (pc) (if_then_else
923 (match_operator 0 "ordered_comparison_operator"
924 [(reg:CC FLAGS_REG) (const_int 0)])
925 (label_ref (match_operand 3 "" ""))
929 if (MEM_P (operands[1]) && MEM_P (operands[2]))
930 operands[1] = force_reg (<MODE>mode, operands[1]);
931 ix86_expand_branch (GET_CODE (operands[0]),
932 operands[1], operands[2], operands[3]);
936 (define_expand "cstore<mode>4"
937 [(set (reg:CC FLAGS_REG)
938 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
939 (match_operand:SWIM 3 "<general_operand>" "")))
940 (set (match_operand:QI 0 "register_operand" "")
941 (match_operator 1 "ordered_comparison_operator"
942 [(reg:CC FLAGS_REG) (const_int 0)]))]
945 if (MEM_P (operands[2]) && MEM_P (operands[3]))
946 operands[2] = force_reg (<MODE>mode, operands[2]);
947 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
948 operands[2], operands[3]);
952 (define_expand "cmp<mode>_1"
953 [(set (reg:CC FLAGS_REG)
954 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
955 (match_operand:SWI48 1 "<general_operand>" "")))])
957 (define_insn "*cmp<mode>_ccno_1"
958 [(set (reg FLAGS_REG)
959 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
960 (match_operand:SWI 1 "const0_operand" "")))]
961 "ix86_match_ccmode (insn, CCNOmode)"
963 test{<imodesuffix>}\t%0, %0
964 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
965 [(set_attr "type" "test,icmp")
966 (set_attr "length_immediate" "0,1")
967 (set_attr "mode" "<MODE>")])
969 (define_insn "*cmp<mode>_1"
970 [(set (reg FLAGS_REG)
971 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
972 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
973 "ix86_match_ccmode (insn, CCmode)"
974 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
975 [(set_attr "type" "icmp")
976 (set_attr "mode" "<MODE>")])
978 (define_insn "*cmp<mode>_minus_1"
979 [(set (reg FLAGS_REG)
981 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
982 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
984 "ix86_match_ccmode (insn, CCGOCmode)"
985 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
986 [(set_attr "type" "icmp")
987 (set_attr "mode" "<MODE>")])
989 (define_insn "*cmpqi_ext_1"
990 [(set (reg FLAGS_REG)
992 (match_operand:QI 0 "general_operand" "Qm")
995 (match_operand 1 "ext_register_operand" "Q")
998 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
999 "cmp{b}\t{%h1, %0|%0, %h1}"
1000 [(set_attr "type" "icmp")
1001 (set_attr "mode" "QI")])
1003 (define_insn "*cmpqi_ext_1_rex64"
1004 [(set (reg FLAGS_REG)
1006 (match_operand:QI 0 "register_operand" "Q")
1009 (match_operand 1 "ext_register_operand" "Q")
1011 (const_int 8)) 0)))]
1012 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1013 "cmp{b}\t{%h1, %0|%0, %h1}"
1014 [(set_attr "type" "icmp")
1015 (set_attr "mode" "QI")])
1017 (define_insn "*cmpqi_ext_2"
1018 [(set (reg FLAGS_REG)
1022 (match_operand 0 "ext_register_operand" "Q")
1025 (match_operand:QI 1 "const0_operand" "")))]
1026 "ix86_match_ccmode (insn, CCNOmode)"
1028 [(set_attr "type" "test")
1029 (set_attr "length_immediate" "0")
1030 (set_attr "mode" "QI")])
1032 (define_expand "cmpqi_ext_3"
1033 [(set (reg:CC FLAGS_REG)
1037 (match_operand 0 "ext_register_operand" "")
1040 (match_operand:QI 1 "immediate_operand" "")))])
1042 (define_insn "*cmpqi_ext_3_insn"
1043 [(set (reg FLAGS_REG)
1047 (match_operand 0 "ext_register_operand" "Q")
1050 (match_operand:QI 1 "general_operand" "Qmn")))]
1051 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1052 "cmp{b}\t{%1, %h0|%h0, %1}"
1053 [(set_attr "type" "icmp")
1054 (set_attr "modrm" "1")
1055 (set_attr "mode" "QI")])
1057 (define_insn "*cmpqi_ext_3_insn_rex64"
1058 [(set (reg FLAGS_REG)
1062 (match_operand 0 "ext_register_operand" "Q")
1065 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1066 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1067 "cmp{b}\t{%1, %h0|%h0, %1}"
1068 [(set_attr "type" "icmp")
1069 (set_attr "modrm" "1")
1070 (set_attr "mode" "QI")])
1072 (define_insn "*cmpqi_ext_4"
1073 [(set (reg FLAGS_REG)
1077 (match_operand 0 "ext_register_operand" "Q")
1082 (match_operand 1 "ext_register_operand" "Q")
1084 (const_int 8)) 0)))]
1085 "ix86_match_ccmode (insn, CCmode)"
1086 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1087 [(set_attr "type" "icmp")
1088 (set_attr "mode" "QI")])
1090 ;; These implement float point compares.
1091 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1092 ;; which would allow mix and match FP modes on the compares. Which is what
1093 ;; the old patterns did, but with many more of them.
1095 (define_expand "cbranchxf4"
1096 [(set (reg:CC FLAGS_REG)
1097 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1098 (match_operand:XF 2 "nonmemory_operand" "")))
1099 (set (pc) (if_then_else
1100 (match_operator 0 "ix86_fp_comparison_operator"
1103 (label_ref (match_operand 3 "" ""))
1107 ix86_expand_branch (GET_CODE (operands[0]),
1108 operands[1], operands[2], operands[3]);
1112 (define_expand "cstorexf4"
1113 [(set (reg:CC FLAGS_REG)
1114 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1115 (match_operand:XF 3 "nonmemory_operand" "")))
1116 (set (match_operand:QI 0 "register_operand" "")
1117 (match_operator 1 "ix86_fp_comparison_operator"
1122 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1123 operands[2], operands[3]);
1127 (define_expand "cbranch<mode>4"
1128 [(set (reg:CC FLAGS_REG)
1129 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1130 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1131 (set (pc) (if_then_else
1132 (match_operator 0 "ix86_fp_comparison_operator"
1135 (label_ref (match_operand 3 "" ""))
1137 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1139 ix86_expand_branch (GET_CODE (operands[0]),
1140 operands[1], operands[2], operands[3]);
1144 (define_expand "cstore<mode>4"
1145 [(set (reg:CC FLAGS_REG)
1146 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1147 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1148 (set (match_operand:QI 0 "register_operand" "")
1149 (match_operator 1 "ix86_fp_comparison_operator"
1152 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1154 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1155 operands[2], operands[3]);
1159 (define_expand "cbranchcc4"
1160 [(set (pc) (if_then_else
1161 (match_operator 0 "comparison_operator"
1162 [(match_operand 1 "flags_reg_operand" "")
1163 (match_operand 2 "const0_operand" "")])
1164 (label_ref (match_operand 3 "" ""))
1168 ix86_expand_branch (GET_CODE (operands[0]),
1169 operands[1], operands[2], operands[3]);
1173 (define_expand "cstorecc4"
1174 [(set (match_operand:QI 0 "register_operand" "")
1175 (match_operator 1 "comparison_operator"
1176 [(match_operand 2 "flags_reg_operand" "")
1177 (match_operand 3 "const0_operand" "")]))]
1180 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1181 operands[2], operands[3]);
1186 ;; FP compares, step 1:
1187 ;; Set the FP condition codes.
1189 ;; CCFPmode compare with exceptions
1190 ;; CCFPUmode compare with no exceptions
1192 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1193 ;; used to manage the reg stack popping would not be preserved.
1195 (define_insn "*cmpfp_0"
1196 [(set (match_operand:HI 0 "register_operand" "=a")
1199 (match_operand 1 "register_operand" "f")
1200 (match_operand 2 "const0_operand" ""))]
1202 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1203 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1204 "* return output_fp_compare (insn, operands, false, false);"
1205 [(set_attr "type" "multi")
1206 (set_attr "unit" "i387")
1208 (cond [(match_operand:SF 1 "" "")
1210 (match_operand:DF 1 "" "")
1213 (const_string "XF")))])
1215 (define_insn_and_split "*cmpfp_0_cc"
1216 [(set (reg:CCFP FLAGS_REG)
1218 (match_operand 1 "register_operand" "f")
1219 (match_operand 2 "const0_operand" "")))
1220 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1221 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1222 && TARGET_SAHF && !TARGET_CMOVE
1223 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1225 "&& reload_completed"
1228 [(compare:CCFP (match_dup 1)(match_dup 2))]
1230 (set (reg:CC FLAGS_REG)
1231 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1233 [(set_attr "type" "multi")
1234 (set_attr "unit" "i387")
1236 (cond [(match_operand:SF 1 "" "")
1238 (match_operand:DF 1 "" "")
1241 (const_string "XF")))])
1243 (define_insn "*cmpfp_xf"
1244 [(set (match_operand:HI 0 "register_operand" "=a")
1247 (match_operand:XF 1 "register_operand" "f")
1248 (match_operand:XF 2 "register_operand" "f"))]
1251 "* return output_fp_compare (insn, operands, false, false);"
1252 [(set_attr "type" "multi")
1253 (set_attr "unit" "i387")
1254 (set_attr "mode" "XF")])
1256 (define_insn_and_split "*cmpfp_xf_cc"
1257 [(set (reg:CCFP FLAGS_REG)
1259 (match_operand:XF 1 "register_operand" "f")
1260 (match_operand:XF 2 "register_operand" "f")))
1261 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1263 && TARGET_SAHF && !TARGET_CMOVE"
1265 "&& reload_completed"
1268 [(compare:CCFP (match_dup 1)(match_dup 2))]
1270 (set (reg:CC FLAGS_REG)
1271 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1273 [(set_attr "type" "multi")
1274 (set_attr "unit" "i387")
1275 (set_attr "mode" "XF")])
1277 (define_insn "*cmpfp_<mode>"
1278 [(set (match_operand:HI 0 "register_operand" "=a")
1281 (match_operand:MODEF 1 "register_operand" "f")
1282 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1285 "* return output_fp_compare (insn, operands, false, false);"
1286 [(set_attr "type" "multi")
1287 (set_attr "unit" "i387")
1288 (set_attr "mode" "<MODE>")])
1290 (define_insn_and_split "*cmpfp_<mode>_cc"
1291 [(set (reg:CCFP FLAGS_REG)
1293 (match_operand:MODEF 1 "register_operand" "f")
1294 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1295 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1297 && TARGET_SAHF && !TARGET_CMOVE"
1299 "&& reload_completed"
1302 [(compare:CCFP (match_dup 1)(match_dup 2))]
1304 (set (reg:CC FLAGS_REG)
1305 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1307 [(set_attr "type" "multi")
1308 (set_attr "unit" "i387")
1309 (set_attr "mode" "<MODE>")])
1311 (define_insn "*cmpfp_u"
1312 [(set (match_operand:HI 0 "register_operand" "=a")
1315 (match_operand 1 "register_operand" "f")
1316 (match_operand 2 "register_operand" "f"))]
1318 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1319 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1320 "* return output_fp_compare (insn, operands, false, true);"
1321 [(set_attr "type" "multi")
1322 (set_attr "unit" "i387")
1324 (cond [(match_operand:SF 1 "" "")
1326 (match_operand:DF 1 "" "")
1329 (const_string "XF")))])
1331 (define_insn_and_split "*cmpfp_u_cc"
1332 [(set (reg:CCFPU FLAGS_REG)
1334 (match_operand 1 "register_operand" "f")
1335 (match_operand 2 "register_operand" "f")))
1336 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1337 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1338 && TARGET_SAHF && !TARGET_CMOVE
1339 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1341 "&& reload_completed"
1344 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1346 (set (reg:CC FLAGS_REG)
1347 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1349 [(set_attr "type" "multi")
1350 (set_attr "unit" "i387")
1352 (cond [(match_operand:SF 1 "" "")
1354 (match_operand:DF 1 "" "")
1357 (const_string "XF")))])
1359 (define_insn "*cmpfp_<mode>"
1360 [(set (match_operand:HI 0 "register_operand" "=a")
1363 (match_operand 1 "register_operand" "f")
1364 (match_operator 3 "float_operator"
1365 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1367 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1368 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1369 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1370 "* return output_fp_compare (insn, operands, false, false);"
1371 [(set_attr "type" "multi")
1372 (set_attr "unit" "i387")
1373 (set_attr "fp_int_src" "true")
1374 (set_attr "mode" "<MODE>")])
1376 (define_insn_and_split "*cmpfp_<mode>_cc"
1377 [(set (reg:CCFP FLAGS_REG)
1379 (match_operand 1 "register_operand" "f")
1380 (match_operator 3 "float_operator"
1381 [(match_operand:SWI24 2 "memory_operand" "m")])))
1382 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1383 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1384 && TARGET_SAHF && !TARGET_CMOVE
1385 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1386 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1388 "&& reload_completed"
1393 (match_op_dup 3 [(match_dup 2)]))]
1395 (set (reg:CC FLAGS_REG)
1396 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1398 [(set_attr "type" "multi")
1399 (set_attr "unit" "i387")
1400 (set_attr "fp_int_src" "true")
1401 (set_attr "mode" "<MODE>")])
1403 ;; FP compares, step 2
1404 ;; Move the fpsw to ax.
1406 (define_insn "x86_fnstsw_1"
1407 [(set (match_operand:HI 0 "register_operand" "=a")
1408 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1411 [(set (attr "length")
1412 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1413 (set_attr "mode" "SI")
1414 (set_attr "unit" "i387")])
1416 ;; FP compares, step 3
1417 ;; Get ax into flags, general case.
1419 (define_insn "x86_sahf_1"
1420 [(set (reg:CC FLAGS_REG)
1421 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1425 #ifndef HAVE_AS_IX86_SAHF
1427 return ASM_BYTE "0x9e";
1432 [(set_attr "length" "1")
1433 (set_attr "athlon_decode" "vector")
1434 (set_attr "amdfam10_decode" "direct")
1435 (set_attr "bdver1_decode" "direct")
1436 (set_attr "mode" "SI")])
1438 ;; Pentium Pro can do steps 1 through 3 in one go.
1439 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1440 ;; (these i387 instructions set flags directly)
1441 (define_insn "*cmpfp_i_mixed"
1442 [(set (reg:CCFP FLAGS_REG)
1443 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1444 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1445 "TARGET_MIX_SSE_I387
1446 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1447 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1448 "* return output_fp_compare (insn, operands, true, false);"
1449 [(set_attr "type" "fcmp,ssecomi")
1450 (set_attr "prefix" "orig,maybe_vex")
1452 (if_then_else (match_operand:SF 1 "" "")
1454 (const_string "DF")))
1455 (set (attr "prefix_rep")
1456 (if_then_else (eq_attr "type" "ssecomi")
1458 (const_string "*")))
1459 (set (attr "prefix_data16")
1460 (cond [(eq_attr "type" "fcmp")
1462 (eq_attr "mode" "DF")
1465 (const_string "0")))
1466 (set_attr "athlon_decode" "vector")
1467 (set_attr "amdfam10_decode" "direct")
1468 (set_attr "bdver1_decode" "double")])
1470 (define_insn "*cmpfp_i_sse"
1471 [(set (reg:CCFP FLAGS_REG)
1472 (compare:CCFP (match_operand 0 "register_operand" "x")
1473 (match_operand 1 "nonimmediate_operand" "xm")))]
1475 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1476 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1477 "* return output_fp_compare (insn, operands, true, false);"
1478 [(set_attr "type" "ssecomi")
1479 (set_attr "prefix" "maybe_vex")
1481 (if_then_else (match_operand:SF 1 "" "")
1483 (const_string "DF")))
1484 (set_attr "prefix_rep" "0")
1485 (set (attr "prefix_data16")
1486 (if_then_else (eq_attr "mode" "DF")
1488 (const_string "0")))
1489 (set_attr "athlon_decode" "vector")
1490 (set_attr "amdfam10_decode" "direct")
1491 (set_attr "bdver1_decode" "double")])
1493 (define_insn "*cmpfp_i_i387"
1494 [(set (reg:CCFP FLAGS_REG)
1495 (compare:CCFP (match_operand 0 "register_operand" "f")
1496 (match_operand 1 "register_operand" "f")))]
1497 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1499 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1500 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1501 "* return output_fp_compare (insn, operands, true, false);"
1502 [(set_attr "type" "fcmp")
1504 (cond [(match_operand:SF 1 "" "")
1506 (match_operand:DF 1 "" "")
1509 (const_string "XF")))
1510 (set_attr "athlon_decode" "vector")
1511 (set_attr "amdfam10_decode" "direct")
1512 (set_attr "bdver1_decode" "double")])
1514 (define_insn "*cmpfp_iu_mixed"
1515 [(set (reg:CCFPU FLAGS_REG)
1516 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1517 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1518 "TARGET_MIX_SSE_I387
1519 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1520 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1521 "* return output_fp_compare (insn, operands, true, true);"
1522 [(set_attr "type" "fcmp,ssecomi")
1523 (set_attr "prefix" "orig,maybe_vex")
1525 (if_then_else (match_operand:SF 1 "" "")
1527 (const_string "DF")))
1528 (set (attr "prefix_rep")
1529 (if_then_else (eq_attr "type" "ssecomi")
1531 (const_string "*")))
1532 (set (attr "prefix_data16")
1533 (cond [(eq_attr "type" "fcmp")
1535 (eq_attr "mode" "DF")
1538 (const_string "0")))
1539 (set_attr "athlon_decode" "vector")
1540 (set_attr "amdfam10_decode" "direct")
1541 (set_attr "bdver1_decode" "double")])
1543 (define_insn "*cmpfp_iu_sse"
1544 [(set (reg:CCFPU FLAGS_REG)
1545 (compare:CCFPU (match_operand 0 "register_operand" "x")
1546 (match_operand 1 "nonimmediate_operand" "xm")))]
1548 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1549 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1550 "* return output_fp_compare (insn, operands, true, true);"
1551 [(set_attr "type" "ssecomi")
1552 (set_attr "prefix" "maybe_vex")
1554 (if_then_else (match_operand:SF 1 "" "")
1556 (const_string "DF")))
1557 (set_attr "prefix_rep" "0")
1558 (set (attr "prefix_data16")
1559 (if_then_else (eq_attr "mode" "DF")
1561 (const_string "0")))
1562 (set_attr "athlon_decode" "vector")
1563 (set_attr "amdfam10_decode" "direct")
1564 (set_attr "bdver1_decode" "double")])
1566 (define_insn "*cmpfp_iu_387"
1567 [(set (reg:CCFPU FLAGS_REG)
1568 (compare:CCFPU (match_operand 0 "register_operand" "f")
1569 (match_operand 1 "register_operand" "f")))]
1570 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1572 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1573 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1574 "* return output_fp_compare (insn, operands, true, true);"
1575 [(set_attr "type" "fcmp")
1577 (cond [(match_operand:SF 1 "" "")
1579 (match_operand:DF 1 "" "")
1582 (const_string "XF")))
1583 (set_attr "athlon_decode" "vector")
1584 (set_attr "amdfam10_decode" "direct")
1585 (set_attr "bdver1_decode" "direct")])
1587 ;; Push/pop instructions.
1589 (define_insn "*push<mode>2"
1590 [(set (match_operand:DWI 0 "push_operand" "=<")
1591 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1594 [(set_attr "type" "multi")
1595 (set_attr "mode" "<MODE>")])
1598 [(set (match_operand:TI 0 "push_operand" "")
1599 (match_operand:TI 1 "general_operand" ""))]
1600 "TARGET_64BIT && reload_completed
1601 && !SSE_REG_P (operands[1])"
1603 "ix86_split_long_move (operands); DONE;")
1605 (define_insn "*pushdi2_rex64"
1606 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1607 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1612 [(set_attr "type" "push,multi")
1613 (set_attr "mode" "DI")])
1615 ;; Convert impossible pushes of immediate to existing instructions.
1616 ;; First try to get scratch register and go through it. In case this
1617 ;; fails, push sign extended lower part first and then overwrite
1618 ;; upper part by 32bit move.
1620 [(match_scratch:DI 2 "r")
1621 (set (match_operand:DI 0 "push_operand" "")
1622 (match_operand:DI 1 "immediate_operand" ""))]
1623 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1624 && !x86_64_immediate_operand (operands[1], DImode)"
1625 [(set (match_dup 2) (match_dup 1))
1626 (set (match_dup 0) (match_dup 2))])
1628 ;; We need to define this as both peepholer and splitter for case
1629 ;; peephole2 pass is not run.
1630 ;; "&& 1" is needed to keep it from matching the previous pattern.
1632 [(set (match_operand:DI 0 "push_operand" "")
1633 (match_operand:DI 1 "immediate_operand" ""))]
1634 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1635 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1636 [(set (match_dup 0) (match_dup 1))
1637 (set (match_dup 2) (match_dup 3))]
1639 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1641 operands[1] = gen_lowpart (DImode, operands[2]);
1642 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1647 [(set (match_operand:DI 0 "push_operand" "")
1648 (match_operand:DI 1 "immediate_operand" ""))]
1649 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1650 ? epilogue_completed : reload_completed)
1651 && !symbolic_operand (operands[1], DImode)
1652 && !x86_64_immediate_operand (operands[1], DImode)"
1653 [(set (match_dup 0) (match_dup 1))
1654 (set (match_dup 2) (match_dup 3))]
1656 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1658 operands[1] = gen_lowpart (DImode, operands[2]);
1659 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1664 [(set (match_operand:DI 0 "push_operand" "")
1665 (match_operand:DI 1 "general_operand" ""))]
1666 "!TARGET_64BIT && reload_completed
1667 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1669 "ix86_split_long_move (operands); DONE;")
1671 (define_insn "*pushsi2"
1672 [(set (match_operand:SI 0 "push_operand" "=<")
1673 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1676 [(set_attr "type" "push")
1677 (set_attr "mode" "SI")])
1679 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1680 ;; "push a byte/word". But actually we use pushl, which has the effect
1681 ;; of rounding the amount pushed up to a word.
1683 ;; For TARGET_64BIT we always round up to 8 bytes.
1684 (define_insn "*push<mode>2_rex64"
1685 [(set (match_operand:SWI124 0 "push_operand" "=X")
1686 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1689 [(set_attr "type" "push")
1690 (set_attr "mode" "DI")])
1692 (define_insn "*push<mode>2"
1693 [(set (match_operand:SWI12 0 "push_operand" "=X")
1694 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1697 [(set_attr "type" "push")
1698 (set_attr "mode" "SI")])
1700 (define_insn "*push<mode>2_prologue"
1701 [(set (match_operand:P 0 "push_operand" "=<")
1702 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1703 (clobber (mem:BLK (scratch)))]
1705 "push{<imodesuffix>}\t%1"
1706 [(set_attr "type" "push")
1707 (set_attr "mode" "<MODE>")])
1709 (define_insn "*pop<mode>1"
1710 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1711 (match_operand:P 1 "pop_operand" ">"))]
1713 "pop{<imodesuffix>}\t%0"
1714 [(set_attr "type" "pop")
1715 (set_attr "mode" "<MODE>")])
1717 (define_insn "*pop<mode>1_epilogue"
1718 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1719 (match_operand:P 1 "pop_operand" ">"))
1720 (clobber (mem:BLK (scratch)))]
1722 "pop{<imodesuffix>}\t%0"
1723 [(set_attr "type" "pop")
1724 (set_attr "mode" "<MODE>")])
1726 ;; Move instructions.
1728 (define_expand "movoi"
1729 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1730 (match_operand:OI 1 "general_operand" ""))]
1732 "ix86_expand_move (OImode, operands); DONE;")
1734 (define_expand "movti"
1735 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1736 (match_operand:TI 1 "nonimmediate_operand" ""))]
1737 "TARGET_64BIT || TARGET_SSE"
1740 ix86_expand_move (TImode, operands);
1741 else if (push_operand (operands[0], TImode))
1742 ix86_expand_push (TImode, operands[1]);
1744 ix86_expand_vector_move (TImode, operands);
1748 ;; This expands to what emit_move_complex would generate if we didn't
1749 ;; have a movti pattern. Having this avoids problems with reload on
1750 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1751 ;; to have around all the time.
1752 (define_expand "movcdi"
1753 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1754 (match_operand:CDI 1 "general_operand" ""))]
1757 if (push_operand (operands[0], CDImode))
1758 emit_move_complex_push (CDImode, operands[0], operands[1]);
1760 emit_move_complex_parts (operands[0], operands[1]);
1764 (define_expand "mov<mode>"
1765 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1766 (match_operand:SWI1248x 1 "general_operand" ""))]
1768 "ix86_expand_move (<MODE>mode, operands); DONE;")
1770 (define_insn "*mov<mode>_xor"
1771 [(set (match_operand:SWI48 0 "register_operand" "=r")
1772 (match_operand:SWI48 1 "const0_operand" ""))
1773 (clobber (reg:CC FLAGS_REG))]
1776 [(set_attr "type" "alu1")
1777 (set_attr "mode" "SI")
1778 (set_attr "length_immediate" "0")])
1780 (define_insn "*mov<mode>_or"
1781 [(set (match_operand:SWI48 0 "register_operand" "=r")
1782 (match_operand:SWI48 1 "const_int_operand" ""))
1783 (clobber (reg:CC FLAGS_REG))]
1785 && operands[1] == constm1_rtx"
1786 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1787 [(set_attr "type" "alu1")
1788 (set_attr "mode" "<MODE>")
1789 (set_attr "length_immediate" "1")])
1791 (define_insn "*movoi_internal_avx"
1792 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1793 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1794 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1796 switch (which_alternative)
1799 return standard_sse_constant_opcode (insn, operands[1]);
1802 if (misaligned_operand (operands[0], OImode)
1803 || misaligned_operand (operands[1], OImode))
1804 return "vmovdqu\t{%1, %0|%0, %1}";
1806 return "vmovdqa\t{%1, %0|%0, %1}";
1811 [(set_attr "type" "sselog1,ssemov,ssemov")
1812 (set_attr "prefix" "vex")
1813 (set_attr "mode" "OI")])
1815 (define_insn "*movti_internal_rex64"
1816 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1817 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1818 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1820 switch (which_alternative)
1826 return standard_sse_constant_opcode (insn, operands[1]);
1829 /* TDmode values are passed as TImode on the stack. Moving them
1830 to stack may result in unaligned memory access. */
1831 if (misaligned_operand (operands[0], TImode)
1832 || misaligned_operand (operands[1], TImode))
1834 if (get_attr_mode (insn) == MODE_V4SF)
1835 return "%vmovups\t{%1, %0|%0, %1}";
1837 return "%vmovdqu\t{%1, %0|%0, %1}";
1841 if (get_attr_mode (insn) == MODE_V4SF)
1842 return "%vmovaps\t{%1, %0|%0, %1}";
1844 return "%vmovdqa\t{%1, %0|%0, %1}";
1850 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1851 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1853 (cond [(eq_attr "alternative" "2,3")
1855 (match_test "optimize_function_for_size_p (cfun)")
1856 (const_string "V4SF")
1857 (const_string "TI"))
1858 (eq_attr "alternative" "4")
1860 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1861 (match_test "optimize_function_for_size_p (cfun)"))
1862 (const_string "V4SF")
1863 (const_string "TI"))]
1864 (const_string "DI")))])
1867 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1868 (match_operand:TI 1 "general_operand" ""))]
1870 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1872 "ix86_split_long_move (operands); DONE;")
1874 (define_insn "*movti_internal_sse"
1875 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1876 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1877 "TARGET_SSE && !TARGET_64BIT
1878 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1880 switch (which_alternative)
1883 return standard_sse_constant_opcode (insn, operands[1]);
1886 /* TDmode values are passed as TImode on the stack. Moving them
1887 to stack may result in unaligned memory access. */
1888 if (misaligned_operand (operands[0], TImode)
1889 || misaligned_operand (operands[1], TImode))
1891 if (get_attr_mode (insn) == MODE_V4SF)
1892 return "%vmovups\t{%1, %0|%0, %1}";
1894 return "%vmovdqu\t{%1, %0|%0, %1}";
1898 if (get_attr_mode (insn) == MODE_V4SF)
1899 return "%vmovaps\t{%1, %0|%0, %1}";
1901 return "%vmovdqa\t{%1, %0|%0, %1}";
1907 [(set_attr "type" "sselog1,ssemov,ssemov")
1908 (set_attr "prefix" "maybe_vex")
1910 (cond [(ior (not (match_test "TARGET_SSE2"))
1911 (match_test "optimize_function_for_size_p (cfun)"))
1912 (const_string "V4SF")
1913 (and (eq_attr "alternative" "2")
1914 (match_test "TARGET_SSE_TYPELESS_STORES"))
1915 (const_string "V4SF")]
1916 (const_string "TI")))])
1918 (define_insn "*movdi_internal_rex64"
1919 [(set (match_operand:DI 0 "nonimmediate_operand"
1920 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1921 (match_operand:DI 1 "general_operand"
1922 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1923 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1925 switch (get_attr_type (insn))
1928 if (SSE_REG_P (operands[0]))
1929 return "movq2dq\t{%1, %0|%0, %1}";
1931 return "movdq2q\t{%1, %0|%0, %1}";
1934 if (get_attr_mode (insn) == MODE_TI)
1935 return "%vmovdqa\t{%1, %0|%0, %1}";
1936 /* Handle broken assemblers that require movd instead of movq. */
1937 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1938 return "%vmovd\t{%1, %0|%0, %1}";
1940 return "%vmovq\t{%1, %0|%0, %1}";
1943 /* Handle broken assemblers that require movd instead of movq. */
1944 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1945 return "movd\t{%1, %0|%0, %1}";
1947 return "movq\t{%1, %0|%0, %1}";
1950 return standard_sse_constant_opcode (insn, operands[1]);
1953 return "pxor\t%0, %0";
1959 return "lea{q}\t{%a1, %0|%0, %a1}";
1962 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1963 if (get_attr_mode (insn) == MODE_SI)
1964 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1965 else if (which_alternative == 2)
1966 return "movabs{q}\t{%1, %0|%0, %1}";
1967 else if (ix86_use_lea_for_mov (insn, operands))
1968 return "lea{q}\t{%a1, %0|%0, %a1}";
1970 return "mov{q}\t{%1, %0|%0, %1}";
1974 (cond [(eq_attr "alternative" "4")
1975 (const_string "multi")
1976 (eq_attr "alternative" "5")
1977 (const_string "mmx")
1978 (eq_attr "alternative" "6,7,8,9")
1979 (const_string "mmxmov")
1980 (eq_attr "alternative" "10")
1981 (const_string "sselog1")
1982 (eq_attr "alternative" "11,12,13,14,15")
1983 (const_string "ssemov")
1984 (eq_attr "alternative" "16,17")
1985 (const_string "ssecvt")
1986 (match_operand 1 "pic_32bit_operand" "")
1987 (const_string "lea")
1989 (const_string "imov")))
1992 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1994 (const_string "*")))
1995 (set (attr "length_immediate")
1997 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1999 (const_string "*")))
2000 (set (attr "prefix_rex")
2001 (if_then_else (eq_attr "alternative" "8,9")
2003 (const_string "*")))
2004 (set (attr "prefix_data16")
2005 (if_then_else (eq_attr "alternative" "11")
2007 (const_string "*")))
2008 (set (attr "prefix")
2009 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2010 (const_string "maybe_vex")
2011 (const_string "orig")))
2012 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2014 ;; Reload patterns to support multi-word load/store
2015 ;; with non-offsetable address.
2016 (define_expand "reload_noff_store"
2017 [(parallel [(match_operand 0 "memory_operand" "=m")
2018 (match_operand 1 "register_operand" "r")
2019 (match_operand:DI 2 "register_operand" "=&r")])]
2022 rtx mem = operands[0];
2023 rtx addr = XEXP (mem, 0);
2025 emit_move_insn (operands[2], addr);
2026 mem = replace_equiv_address_nv (mem, operands[2]);
2028 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2032 (define_expand "reload_noff_load"
2033 [(parallel [(match_operand 0 "register_operand" "=r")
2034 (match_operand 1 "memory_operand" "m")
2035 (match_operand:DI 2 "register_operand" "=r")])]
2038 rtx mem = operands[1];
2039 rtx addr = XEXP (mem, 0);
2041 emit_move_insn (operands[2], addr);
2042 mem = replace_equiv_address_nv (mem, operands[2]);
2044 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2048 ;; Convert impossible stores of immediate to existing instructions.
2049 ;; First try to get scratch register and go through it. In case this
2050 ;; fails, move by 32bit parts.
2052 [(match_scratch:DI 2 "r")
2053 (set (match_operand:DI 0 "memory_operand" "")
2054 (match_operand:DI 1 "immediate_operand" ""))]
2055 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2056 && !x86_64_immediate_operand (operands[1], DImode)"
2057 [(set (match_dup 2) (match_dup 1))
2058 (set (match_dup 0) (match_dup 2))])
2060 ;; We need to define this as both peepholer and splitter for case
2061 ;; peephole2 pass is not run.
2062 ;; "&& 1" is needed to keep it from matching the previous pattern.
2064 [(set (match_operand:DI 0 "memory_operand" "")
2065 (match_operand:DI 1 "immediate_operand" ""))]
2066 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2067 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2068 [(set (match_dup 2) (match_dup 3))
2069 (set (match_dup 4) (match_dup 5))]
2070 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2073 [(set (match_operand:DI 0 "memory_operand" "")
2074 (match_operand:DI 1 "immediate_operand" ""))]
2075 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2076 ? epilogue_completed : reload_completed)
2077 && !symbolic_operand (operands[1], DImode)
2078 && !x86_64_immediate_operand (operands[1], DImode)"
2079 [(set (match_dup 2) (match_dup 3))
2080 (set (match_dup 4) (match_dup 5))]
2081 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2083 (define_insn "*movdi_internal"
2084 [(set (match_operand:DI 0 "nonimmediate_operand"
2085 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2086 (match_operand:DI 1 "general_operand"
2087 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2088 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2090 switch (get_attr_type (insn))
2093 if (SSE_REG_P (operands[0]))
2094 return "movq2dq\t{%1, %0|%0, %1}";
2096 return "movdq2q\t{%1, %0|%0, %1}";
2099 switch (get_attr_mode (insn))
2102 return "%vmovdqa\t{%1, %0|%0, %1}";
2104 return "%vmovq\t{%1, %0|%0, %1}";
2106 return "movaps\t{%1, %0|%0, %1}";
2108 return "movlps\t{%1, %0|%0, %1}";
2114 return "movq\t{%1, %0|%0, %1}";
2117 return standard_sse_constant_opcode (insn, operands[1]);
2120 return "pxor\t%0, %0";
2130 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2131 (const_string "sse2")
2132 (eq_attr "alternative" "9,10,11,12")
2133 (const_string "noavx")
2135 (const_string "*")))
2137 (cond [(eq_attr "alternative" "0,1")
2138 (const_string "multi")
2139 (eq_attr "alternative" "2")
2140 (const_string "mmx")
2141 (eq_attr "alternative" "3,4")
2142 (const_string "mmxmov")
2143 (eq_attr "alternative" "5,9")
2144 (const_string "sselog1")
2145 (eq_attr "alternative" "13,14")
2146 (const_string "ssecvt")
2148 (const_string "ssemov")))
2149 (set (attr "prefix")
2150 (if_then_else (eq_attr "alternative" "5,6,7,8")
2151 (const_string "maybe_vex")
2152 (const_string "orig")))
2153 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2156 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2157 (match_operand:DI 1 "general_operand" ""))]
2158 "!TARGET_64BIT && reload_completed
2159 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2160 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2162 "ix86_split_long_move (operands); DONE;")
2164 (define_insn "*movsi_internal"
2165 [(set (match_operand:SI 0 "nonimmediate_operand"
2166 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2167 (match_operand:SI 1 "general_operand"
2168 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2169 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2171 switch (get_attr_type (insn))
2174 return standard_sse_constant_opcode (insn, operands[1]);
2177 switch (get_attr_mode (insn))
2180 return "%vmovdqa\t{%1, %0|%0, %1}";
2182 return "%vmovaps\t{%1, %0|%0, %1}";
2184 return "%vmovd\t{%1, %0|%0, %1}";
2186 return "%vmovss\t{%1, %0|%0, %1}";
2192 return "pxor\t%0, %0";
2195 if (get_attr_mode (insn) == MODE_DI)
2196 return "movq\t{%1, %0|%0, %1}";
2197 return "movd\t{%1, %0|%0, %1}";
2200 return "lea{l}\t{%a1, %0|%0, %a1}";
2203 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2204 if (ix86_use_lea_for_mov (insn, operands))
2205 return "lea{l}\t{%a1, %0|%0, %a1}";
2207 return "mov{l}\t{%1, %0|%0, %1}";
2211 (cond [(eq_attr "alternative" "2")
2212 (const_string "mmx")
2213 (eq_attr "alternative" "3,4,5")
2214 (const_string "mmxmov")
2215 (eq_attr "alternative" "6")
2216 (const_string "sselog1")
2217 (eq_attr "alternative" "7,8,9,10,11")
2218 (const_string "ssemov")
2219 (match_operand 1 "pic_32bit_operand" "")
2220 (const_string "lea")
2222 (const_string "imov")))
2223 (set (attr "prefix")
2224 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2225 (const_string "orig")
2226 (const_string "maybe_vex")))
2227 (set (attr "prefix_data16")
2228 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2230 (const_string "*")))
2232 (cond [(eq_attr "alternative" "2,3")
2234 (eq_attr "alternative" "6,7")
2236 (not (match_test "TARGET_SSE2"))
2237 (const_string "V4SF")
2238 (const_string "TI"))
2239 (and (eq_attr "alternative" "8,9,10,11")
2240 (not (match_test "TARGET_SSE2")))
2243 (const_string "SI")))])
2245 (define_insn "*movhi_internal"
2246 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2247 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2248 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2250 switch (get_attr_type (insn))
2253 /* movzwl is faster than movw on p2 due to partial word stalls,
2254 though not as fast as an aligned movl. */
2255 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2257 if (get_attr_mode (insn) == MODE_SI)
2258 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2260 return "mov{w}\t{%1, %0|%0, %1}";
2264 (cond [(match_test "optimize_function_for_size_p (cfun)")
2265 (const_string "imov")
2266 (and (eq_attr "alternative" "0")
2267 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2268 (not (match_test "TARGET_HIMODE_MATH"))))
2269 (const_string "imov")
2270 (and (eq_attr "alternative" "1,2")
2271 (match_operand:HI 1 "aligned_operand" ""))
2272 (const_string "imov")
2273 (and (match_test "TARGET_MOVX")
2274 (eq_attr "alternative" "0,2"))
2275 (const_string "imovx")
2277 (const_string "imov")))
2279 (cond [(eq_attr "type" "imovx")
2281 (and (eq_attr "alternative" "1,2")
2282 (match_operand:HI 1 "aligned_operand" ""))
2284 (and (eq_attr "alternative" "0")
2285 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2286 (not (match_test "TARGET_HIMODE_MATH"))))
2289 (const_string "HI")))])
2291 ;; Situation is quite tricky about when to choose full sized (SImode) move
2292 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2293 ;; partial register dependency machines (such as AMD Athlon), where QImode
2294 ;; moves issue extra dependency and for partial register stalls machines
2295 ;; that don't use QImode patterns (and QImode move cause stall on the next
2298 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2299 ;; register stall machines with, where we use QImode instructions, since
2300 ;; partial register stall can be caused there. Then we use movzx.
2301 (define_insn "*movqi_internal"
2302 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2303 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2304 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2306 switch (get_attr_type (insn))
2309 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2310 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2312 if (get_attr_mode (insn) == MODE_SI)
2313 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2315 return "mov{b}\t{%1, %0|%0, %1}";
2319 (cond [(and (eq_attr "alternative" "5")
2320 (not (match_operand:QI 1 "aligned_operand" "")))
2321 (const_string "imovx")
2322 (match_test "optimize_function_for_size_p (cfun)")
2323 (const_string "imov")
2324 (and (eq_attr "alternative" "3")
2325 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2326 (not (match_test "TARGET_QIMODE_MATH"))))
2327 (const_string "imov")
2328 (eq_attr "alternative" "3,5")
2329 (const_string "imovx")
2330 (and (match_test "TARGET_MOVX")
2331 (eq_attr "alternative" "2"))
2332 (const_string "imovx")
2334 (const_string "imov")))
2336 (cond [(eq_attr "alternative" "3,4,5")
2338 (eq_attr "alternative" "6")
2340 (eq_attr "type" "imovx")
2342 (and (eq_attr "type" "imov")
2343 (and (eq_attr "alternative" "0,1")
2344 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2345 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2346 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2348 ;; Avoid partial register stalls when not using QImode arithmetic
2349 (and (eq_attr "type" "imov")
2350 (and (eq_attr "alternative" "0,1")
2351 (and (match_test "TARGET_PARTIAL_REG_STALL")
2352 (not (match_test "TARGET_QIMODE_MATH")))))
2355 (const_string "QI")))])
2357 ;; Stores and loads of ax to arbitrary constant address.
2358 ;; We fake an second form of instruction to force reload to load address
2359 ;; into register when rax is not available
2360 (define_insn "*movabs<mode>_1"
2361 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2362 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2363 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2365 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2366 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2367 [(set_attr "type" "imov")
2368 (set_attr "modrm" "0,*")
2369 (set_attr "length_address" "8,0")
2370 (set_attr "length_immediate" "0,*")
2371 (set_attr "memory" "store")
2372 (set_attr "mode" "<MODE>")])
2374 (define_insn "*movabs<mode>_2"
2375 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2376 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2377 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2379 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2380 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2381 [(set_attr "type" "imov")
2382 (set_attr "modrm" "0,*")
2383 (set_attr "length_address" "8,0")
2384 (set_attr "length_immediate" "0")
2385 (set_attr "memory" "load")
2386 (set_attr "mode" "<MODE>")])
2388 (define_insn "*swap<mode>"
2389 [(set (match_operand:SWI48 0 "register_operand" "+r")
2390 (match_operand:SWI48 1 "register_operand" "+r"))
2394 "xchg{<imodesuffix>}\t%1, %0"
2395 [(set_attr "type" "imov")
2396 (set_attr "mode" "<MODE>")
2397 (set_attr "pent_pair" "np")
2398 (set_attr "athlon_decode" "vector")
2399 (set_attr "amdfam10_decode" "double")
2400 (set_attr "bdver1_decode" "double")])
2402 (define_insn "*swap<mode>_1"
2403 [(set (match_operand:SWI12 0 "register_operand" "+r")
2404 (match_operand:SWI12 1 "register_operand" "+r"))
2407 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2409 [(set_attr "type" "imov")
2410 (set_attr "mode" "SI")
2411 (set_attr "pent_pair" "np")
2412 (set_attr "athlon_decode" "vector")
2413 (set_attr "amdfam10_decode" "double")
2414 (set_attr "bdver1_decode" "double")])
2416 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2417 ;; is disabled for AMDFAM10
2418 (define_insn "*swap<mode>_2"
2419 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2420 (match_operand:SWI12 1 "register_operand" "+<r>"))
2423 "TARGET_PARTIAL_REG_STALL"
2424 "xchg{<imodesuffix>}\t%1, %0"
2425 [(set_attr "type" "imov")
2426 (set_attr "mode" "<MODE>")
2427 (set_attr "pent_pair" "np")
2428 (set_attr "athlon_decode" "vector")])
2430 (define_expand "movstrict<mode>"
2431 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2432 (match_operand:SWI12 1 "general_operand" ""))]
2435 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2437 if (GET_CODE (operands[0]) == SUBREG
2438 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2440 /* Don't generate memory->memory moves, go through a register */
2441 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2442 operands[1] = force_reg (<MODE>mode, operands[1]);
2445 (define_insn "*movstrict<mode>_1"
2446 [(set (strict_low_part
2447 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2448 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2449 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2450 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2451 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2452 [(set_attr "type" "imov")
2453 (set_attr "mode" "<MODE>")])
2455 (define_insn "*movstrict<mode>_xor"
2456 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2457 (match_operand:SWI12 1 "const0_operand" ""))
2458 (clobber (reg:CC FLAGS_REG))]
2460 "xor{<imodesuffix>}\t%0, %0"
2461 [(set_attr "type" "alu1")
2462 (set_attr "mode" "<MODE>")
2463 (set_attr "length_immediate" "0")])
2465 (define_insn "*mov<mode>_extv_1"
2466 [(set (match_operand:SWI24 0 "register_operand" "=R")
2467 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2471 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2472 [(set_attr "type" "imovx")
2473 (set_attr "mode" "SI")])
2475 (define_insn "*movqi_extv_1_rex64"
2476 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2477 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2482 switch (get_attr_type (insn))
2485 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2487 return "mov{b}\t{%h1, %0|%0, %h1}";
2491 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2492 (match_test "TARGET_MOVX"))
2493 (const_string "imovx")
2494 (const_string "imov")))
2496 (if_then_else (eq_attr "type" "imovx")
2498 (const_string "QI")))])
2500 (define_insn "*movqi_extv_1"
2501 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2502 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2507 switch (get_attr_type (insn))
2510 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2512 return "mov{b}\t{%h1, %0|%0, %h1}";
2516 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2517 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2518 (match_test "TARGET_MOVX")))
2519 (const_string "imovx")
2520 (const_string "imov")))
2522 (if_then_else (eq_attr "type" "imovx")
2524 (const_string "QI")))])
2526 (define_insn "*mov<mode>_extzv_1"
2527 [(set (match_operand:SWI48 0 "register_operand" "=R")
2528 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2532 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2533 [(set_attr "type" "imovx")
2534 (set_attr "mode" "SI")])
2536 (define_insn "*movqi_extzv_2_rex64"
2537 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2539 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2544 switch (get_attr_type (insn))
2547 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2549 return "mov{b}\t{%h1, %0|%0, %h1}";
2553 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2554 (match_test "TARGET_MOVX"))
2555 (const_string "imovx")
2556 (const_string "imov")))
2558 (if_then_else (eq_attr "type" "imovx")
2560 (const_string "QI")))])
2562 (define_insn "*movqi_extzv_2"
2563 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2565 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2570 switch (get_attr_type (insn))
2573 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2575 return "mov{b}\t{%h1, %0|%0, %h1}";
2579 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2580 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2581 (match_test "TARGET_MOVX")))
2582 (const_string "imovx")
2583 (const_string "imov")))
2585 (if_then_else (eq_attr "type" "imovx")
2587 (const_string "QI")))])
2589 (define_expand "mov<mode>_insv_1"
2590 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2593 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2595 (define_insn "*mov<mode>_insv_1_rex64"
2596 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2599 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2601 "mov{b}\t{%b1, %h0|%h0, %b1}"
2602 [(set_attr "type" "imov")
2603 (set_attr "mode" "QI")])
2605 (define_insn "*movsi_insv_1"
2606 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2609 (match_operand:SI 1 "general_operand" "Qmn"))]
2611 "mov{b}\t{%b1, %h0|%h0, %b1}"
2612 [(set_attr "type" "imov")
2613 (set_attr "mode" "QI")])
2615 (define_insn "*movqi_insv_2"
2616 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2619 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2622 "mov{b}\t{%h1, %h0|%h0, %h1}"
2623 [(set_attr "type" "imov")
2624 (set_attr "mode" "QI")])
2626 ;; Floating point push instructions.
2628 (define_insn "*pushtf"
2629 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2630 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2633 /* This insn should be already split before reg-stack. */
2636 [(set_attr "type" "multi")
2637 (set_attr "unit" "sse,*,*")
2638 (set_attr "mode" "TF,SI,SI")])
2640 ;; %%% Kill this when call knows how to work this out.
2642 [(set (match_operand:TF 0 "push_operand" "")
2643 (match_operand:TF 1 "sse_reg_operand" ""))]
2644 "TARGET_SSE2 && reload_completed"
2645 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2646 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2648 (define_insn "*pushxf"
2649 [(set (match_operand:XF 0 "push_operand" "=<,<")
2650 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2651 "optimize_function_for_speed_p (cfun)"
2653 /* This insn should be already split before reg-stack. */
2656 [(set_attr "type" "multi")
2657 (set_attr "unit" "i387,*")
2658 (set_attr "mode" "XF,SI")])
2660 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2661 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2662 ;; Pushing using integer instructions is longer except for constants
2663 ;; and direct memory references (assuming that any given constant is pushed
2664 ;; only once, but this ought to be handled elsewhere).
2666 (define_insn "*pushxf_nointeger"
2667 [(set (match_operand:XF 0 "push_operand" "=<,<")
2668 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2669 "optimize_function_for_size_p (cfun)"
2671 /* This insn should be already split before reg-stack. */
2674 [(set_attr "type" "multi")
2675 (set_attr "unit" "i387,*")
2676 (set_attr "mode" "XF,SI")])
2678 ;; %%% Kill this when call knows how to work this out.
2680 [(set (match_operand:XF 0 "push_operand" "")
2681 (match_operand:XF 1 "fp_register_operand" ""))]
2683 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2684 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2685 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2687 (define_insn "*pushdf_rex64"
2688 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2689 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2692 /* This insn should be already split before reg-stack. */
2695 [(set_attr "type" "multi")
2696 (set_attr "unit" "i387,*,*")
2697 (set_attr "mode" "DF,DI,DF")])
2699 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2700 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2701 ;; On the average, pushdf using integers can be still shorter.
2703 (define_insn "*pushdf"
2704 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2705 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2708 /* This insn should be already split before reg-stack. */
2711 [(set_attr "isa" "*,*,sse2")
2712 (set_attr "type" "multi")
2713 (set_attr "unit" "i387,*,*")
2714 (set_attr "mode" "DF,DI,DF")])
2716 ;; %%% Kill this when call knows how to work this out.
2718 [(set (match_operand:DF 0 "push_operand" "")
2719 (match_operand:DF 1 "any_fp_register_operand" ""))]
2721 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2722 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2724 (define_insn "*pushsf_rex64"
2725 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2726 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2729 /* Anything else should be already split before reg-stack. */
2730 gcc_assert (which_alternative == 1);
2731 return "push{q}\t%q1";
2733 [(set_attr "type" "multi,push,multi")
2734 (set_attr "unit" "i387,*,*")
2735 (set_attr "mode" "SF,DI,SF")])
2737 (define_insn "*pushsf"
2738 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2739 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2742 /* Anything else should be already split before reg-stack. */
2743 gcc_assert (which_alternative == 1);
2744 return "push{l}\t%1";
2746 [(set_attr "type" "multi,push,multi")
2747 (set_attr "unit" "i387,*,*")
2748 (set_attr "mode" "SF,SI,SF")])
2750 ;; %%% Kill this when call knows how to work this out.
2752 [(set (match_operand:SF 0 "push_operand" "")
2753 (match_operand:SF 1 "any_fp_register_operand" ""))]
2755 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2756 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2757 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2760 [(set (match_operand:SF 0 "push_operand" "")
2761 (match_operand:SF 1 "memory_operand" ""))]
2763 && (operands[2] = find_constant_src (insn))"
2764 [(set (match_dup 0) (match_dup 2))])
2767 [(set (match_operand 0 "push_operand" "")
2768 (match_operand 1 "general_operand" ""))]
2770 && (GET_MODE (operands[0]) == TFmode
2771 || GET_MODE (operands[0]) == XFmode
2772 || GET_MODE (operands[0]) == DFmode)
2773 && !ANY_FP_REG_P (operands[1])"
2775 "ix86_split_long_move (operands); DONE;")
2777 ;; Floating point move instructions.
2779 (define_expand "movtf"
2780 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2781 (match_operand:TF 1 "nonimmediate_operand" ""))]
2784 ix86_expand_move (TFmode, operands);
2788 (define_expand "mov<mode>"
2789 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2790 (match_operand:X87MODEF 1 "general_operand" ""))]
2792 "ix86_expand_move (<MODE>mode, operands); DONE;")
2794 (define_insn "*movtf_internal"
2795 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2796 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2798 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2799 && (!can_create_pseudo_p ()
2800 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2801 || GET_CODE (operands[1]) != CONST_DOUBLE
2802 || (optimize_function_for_size_p (cfun)
2803 && standard_sse_constant_p (operands[1])
2804 && !memory_operand (operands[0], TFmode))
2805 || (!TARGET_MEMORY_MISMATCH_STALL
2806 && memory_operand (operands[0], TFmode)))"
2808 switch (which_alternative)
2812 /* Handle misaligned load/store since we
2813 don't have movmisaligntf pattern. */
2814 if (misaligned_operand (operands[0], TFmode)
2815 || misaligned_operand (operands[1], TFmode))
2817 if (get_attr_mode (insn) == MODE_V4SF)
2818 return "%vmovups\t{%1, %0|%0, %1}";
2820 return "%vmovdqu\t{%1, %0|%0, %1}";
2824 if (get_attr_mode (insn) == MODE_V4SF)
2825 return "%vmovaps\t{%1, %0|%0, %1}";
2827 return "%vmovdqa\t{%1, %0|%0, %1}";
2831 return standard_sse_constant_opcode (insn, operands[1]);
2841 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2842 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2844 (cond [(eq_attr "alternative" "0,2")
2846 (match_test "optimize_function_for_size_p (cfun)")
2847 (const_string "V4SF")
2848 (const_string "TI"))
2849 (eq_attr "alternative" "1")
2851 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2852 (match_test "optimize_function_for_size_p (cfun)"))
2853 (const_string "V4SF")
2854 (const_string "TI"))]
2855 (const_string "DI")))])
2857 ;; Possible store forwarding (partial memory) stall in alternative 4.
2858 (define_insn "*movxf_internal"
2859 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2860 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2861 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2862 && (!can_create_pseudo_p ()
2863 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2864 || GET_CODE (operands[1]) != CONST_DOUBLE
2865 || (optimize_function_for_size_p (cfun)
2866 && standard_80387_constant_p (operands[1]) > 0
2867 && !memory_operand (operands[0], XFmode))
2868 || (!TARGET_MEMORY_MISMATCH_STALL
2869 && memory_operand (operands[0], XFmode)))"
2871 switch (which_alternative)
2875 return output_387_reg_move (insn, operands);
2878 return standard_80387_constant_opcode (operands[1]);
2888 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2889 (set_attr "mode" "XF,XF,XF,SI,SI")])
2891 (define_insn "*movdf_internal_rex64"
2892 [(set (match_operand:DF 0 "nonimmediate_operand"
2893 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2894 (match_operand:DF 1 "general_operand"
2895 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2896 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2897 && (!can_create_pseudo_p ()
2898 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2899 || GET_CODE (operands[1]) != CONST_DOUBLE
2900 || (optimize_function_for_size_p (cfun)
2901 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2902 && standard_80387_constant_p (operands[1]) > 0)
2903 || (TARGET_SSE2 && TARGET_SSE_MATH
2904 && standard_sse_constant_p (operands[1]))))
2905 || memory_operand (operands[0], DFmode))"
2907 switch (which_alternative)
2911 return output_387_reg_move (insn, operands);
2914 return standard_80387_constant_opcode (operands[1]);
2918 return "mov{q}\t{%1, %0|%0, %1}";
2921 return "movabs{q}\t{%1, %0|%0, %1}";
2927 return standard_sse_constant_opcode (insn, operands[1]);
2932 switch (get_attr_mode (insn))
2935 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2936 return "%vmovapd\t{%1, %0|%0, %1}";
2938 return "%vmovaps\t{%1, %0|%0, %1}";
2941 return "%vmovq\t{%1, %0|%0, %1}";
2943 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2944 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2945 return "%vmovsd\t{%1, %0|%0, %1}";
2947 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2949 return "%vmovlps\t{%1, %d0|%d0, %1}";
2956 /* Handle broken assemblers that require movd instead of movq. */
2957 return "%vmovd\t{%1, %0|%0, %1}";
2964 (cond [(eq_attr "alternative" "0,1,2")
2965 (const_string "fmov")
2966 (eq_attr "alternative" "3,4,5")
2967 (const_string "imov")
2968 (eq_attr "alternative" "6")
2969 (const_string "multi")
2970 (eq_attr "alternative" "7")
2971 (const_string "sselog1")
2973 (const_string "ssemov")))
2976 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2978 (const_string "*")))
2979 (set (attr "length_immediate")
2981 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2983 (const_string "*")))
2984 (set (attr "prefix")
2985 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2986 (const_string "orig")
2987 (const_string "maybe_vex")))
2988 (set (attr "prefix_data16")
2989 (if_then_else (eq_attr "mode" "V1DF")
2991 (const_string "*")))
2993 (cond [(eq_attr "alternative" "0,1,2")
2995 (eq_attr "alternative" "3,4,5,6,11,12")
2998 /* xorps is one byte shorter. */
2999 (eq_attr "alternative" "7")
3000 (cond [(match_test "optimize_function_for_size_p (cfun)")
3001 (const_string "V4SF")
3002 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3005 (const_string "V2DF"))
3007 /* For architectures resolving dependencies on
3008 whole SSE registers use APD move to break dependency
3009 chains, otherwise use short move to avoid extra work.
3011 movaps encodes one byte shorter. */
3012 (eq_attr "alternative" "8")
3014 [(match_test "optimize_function_for_size_p (cfun)")
3015 (const_string "V4SF")
3016 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3017 (const_string "V2DF")
3019 (const_string "DF"))
3020 /* For architectures resolving dependencies on register
3021 parts we may avoid extra work to zero out upper part
3023 (eq_attr "alternative" "9")
3025 (match_test "TARGET_SSE_SPLIT_REGS")
3026 (const_string "V1DF")
3027 (const_string "DF"))
3029 (const_string "DF")))])
3031 ;; Possible store forwarding (partial memory) stall in alternative 4.
3032 (define_insn "*movdf_internal"
3033 [(set (match_operand:DF 0 "nonimmediate_operand"
3034 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3035 (match_operand:DF 1 "general_operand"
3036 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3037 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3038 && (!can_create_pseudo_p ()
3039 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3040 || GET_CODE (operands[1]) != CONST_DOUBLE
3041 || (optimize_function_for_size_p (cfun)
3042 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3043 && standard_80387_constant_p (operands[1]) > 0)
3044 || (TARGET_SSE2 && TARGET_SSE_MATH
3045 && standard_sse_constant_p (operands[1])))
3046 && !memory_operand (operands[0], DFmode))
3047 || (!TARGET_MEMORY_MISMATCH_STALL
3048 && memory_operand (operands[0], DFmode)))"
3050 switch (which_alternative)
3054 return output_387_reg_move (insn, operands);
3057 return standard_80387_constant_opcode (operands[1]);
3065 return standard_sse_constant_opcode (insn, operands[1]);
3073 switch (get_attr_mode (insn))
3076 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3077 return "%vmovapd\t{%1, %0|%0, %1}";
3079 return "%vmovaps\t{%1, %0|%0, %1}";
3082 return "%vmovq\t{%1, %0|%0, %1}";
3084 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3085 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3086 return "%vmovsd\t{%1, %0|%0, %1}";
3088 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3090 return "%vmovlps\t{%1, %d0|%d0, %1}";
3100 (if_then_else (eq_attr "alternative" "5,6,7,8")
3101 (const_string "sse2")
3102 (const_string "*")))
3104 (cond [(eq_attr "alternative" "0,1,2")
3105 (const_string "fmov")
3106 (eq_attr "alternative" "3,4")
3107 (const_string "multi")
3108 (eq_attr "alternative" "5,9")
3109 (const_string "sselog1")
3111 (const_string "ssemov")))
3112 (set (attr "prefix")
3113 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3114 (const_string "orig")
3115 (const_string "maybe_vex")))
3116 (set (attr "prefix_data16")
3117 (if_then_else (eq_attr "mode" "V1DF")
3119 (const_string "*")))
3121 (cond [(eq_attr "alternative" "0,1,2")
3123 (eq_attr "alternative" "3,4")
3126 /* For SSE1, we have many fewer alternatives. */
3127 (not (match_test "TARGET_SSE2"))
3129 (eq_attr "alternative" "5,6,9,10")
3130 (const_string "V4SF")
3131 (const_string "V2SF"))
3133 /* xorps is one byte shorter. */
3134 (eq_attr "alternative" "5,9")
3135 (cond [(match_test "optimize_function_for_size_p (cfun)")
3136 (const_string "V4SF")
3137 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3140 (const_string "V2DF"))
3142 /* For architectures resolving dependencies on
3143 whole SSE registers use APD move to break dependency
3144 chains, otherwise use short move to avoid extra work.
3146 movaps encodes one byte shorter. */
3147 (eq_attr "alternative" "6,10")
3149 [(match_test "optimize_function_for_size_p (cfun)")
3150 (const_string "V4SF")
3151 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3152 (const_string "V2DF")
3154 (const_string "DF"))
3155 /* For architectures resolving dependencies on register
3156 parts we may avoid extra work to zero out upper part
3158 (eq_attr "alternative" "7,11")
3160 (match_test "TARGET_SSE_SPLIT_REGS")
3161 (const_string "V1DF")
3162 (const_string "DF"))
3164 (const_string "DF")))])
3166 (define_insn "*movsf_internal"
3167 [(set (match_operand:SF 0 "nonimmediate_operand"
3168 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3169 (match_operand:SF 1 "general_operand"
3170 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3171 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3172 && (!can_create_pseudo_p ()
3173 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3174 || GET_CODE (operands[1]) != CONST_DOUBLE
3175 || (optimize_function_for_size_p (cfun)
3176 && ((!TARGET_SSE_MATH
3177 && standard_80387_constant_p (operands[1]) > 0)
3179 && standard_sse_constant_p (operands[1]))))
3180 || memory_operand (operands[0], SFmode))"
3182 switch (which_alternative)
3186 return output_387_reg_move (insn, operands);
3189 return standard_80387_constant_opcode (operands[1]);
3193 return "mov{l}\t{%1, %0|%0, %1}";
3196 return standard_sse_constant_opcode (insn, operands[1]);
3199 if (get_attr_mode (insn) == MODE_V4SF)
3200 return "%vmovaps\t{%1, %0|%0, %1}";
3202 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3206 return "%vmovss\t{%1, %0|%0, %1}";
3212 return "movd\t{%1, %0|%0, %1}";
3215 return "movq\t{%1, %0|%0, %1}";
3219 return "%vmovd\t{%1, %0|%0, %1}";
3226 (cond [(eq_attr "alternative" "0,1,2")
3227 (const_string "fmov")
3228 (eq_attr "alternative" "3,4")
3229 (const_string "multi")
3230 (eq_attr "alternative" "5")
3231 (const_string "sselog1")
3232 (eq_attr "alternative" "9,10,11,14,15")
3233 (const_string "mmxmov")
3235 (const_string "ssemov")))
3236 (set (attr "prefix")
3237 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3238 (const_string "maybe_vex")
3239 (const_string "orig")))
3241 (cond [(eq_attr "alternative" "3,4,9,10")
3243 (eq_attr "alternative" "5")
3245 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3246 (match_test "TARGET_SSE2"))
3247 (not (match_test "optimize_function_for_size_p (cfun)")))
3249 (const_string "V4SF"))
3250 /* For architectures resolving dependencies on
3251 whole SSE registers use APS move to break dependency
3252 chains, otherwise use short move to avoid extra work.
3254 Do the same for architectures resolving dependencies on
3255 the parts. While in DF mode it is better to always handle
3256 just register parts, the SF mode is different due to lack
3257 of instructions to load just part of the register. It is
3258 better to maintain the whole registers in single format
3259 to avoid problems on using packed logical operations. */
3260 (eq_attr "alternative" "6")
3262 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3263 (match_test "TARGET_SSE_SPLIT_REGS"))
3264 (const_string "V4SF")
3265 (const_string "SF"))
3266 (eq_attr "alternative" "11")
3267 (const_string "DI")]
3268 (const_string "SF")))])
3271 [(set (match_operand 0 "any_fp_register_operand" "")
3272 (match_operand 1 "memory_operand" ""))]
3274 && (GET_MODE (operands[0]) == TFmode
3275 || GET_MODE (operands[0]) == XFmode
3276 || GET_MODE (operands[0]) == DFmode
3277 || GET_MODE (operands[0]) == SFmode)
3278 && (operands[2] = find_constant_src (insn))"
3279 [(set (match_dup 0) (match_dup 2))]
3281 rtx c = operands[2];
3282 int r = REGNO (operands[0]);
3284 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3285 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3290 [(set (match_operand 0 "any_fp_register_operand" "")
3291 (float_extend (match_operand 1 "memory_operand" "")))]
3293 && (GET_MODE (operands[0]) == TFmode
3294 || GET_MODE (operands[0]) == XFmode
3295 || GET_MODE (operands[0]) == DFmode)
3296 && (operands[2] = find_constant_src (insn))"
3297 [(set (match_dup 0) (match_dup 2))]
3299 rtx c = operands[2];
3300 int r = REGNO (operands[0]);
3302 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3303 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3307 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3309 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3310 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3312 && (standard_80387_constant_p (operands[1]) == 8
3313 || standard_80387_constant_p (operands[1]) == 9)"
3314 [(set (match_dup 0)(match_dup 1))
3316 (neg:X87MODEF (match_dup 0)))]
3320 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3321 if (real_isnegzero (&r))
3322 operands[1] = CONST0_RTX (<MODE>mode);
3324 operands[1] = CONST1_RTX (<MODE>mode);
3328 [(set (match_operand 0 "nonimmediate_operand" "")
3329 (match_operand 1 "general_operand" ""))]
3331 && (GET_MODE (operands[0]) == TFmode
3332 || GET_MODE (operands[0]) == XFmode
3333 || GET_MODE (operands[0]) == DFmode)
3334 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3336 "ix86_split_long_move (operands); DONE;")
3338 (define_insn "swapxf"
3339 [(set (match_operand:XF 0 "register_operand" "+f")
3340 (match_operand:XF 1 "register_operand" "+f"))
3345 if (STACK_TOP_P (operands[0]))
3350 [(set_attr "type" "fxch")
3351 (set_attr "mode" "XF")])
3353 (define_insn "*swap<mode>"
3354 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3355 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3358 "TARGET_80387 || reload_completed"
3360 if (STACK_TOP_P (operands[0]))
3365 [(set_attr "type" "fxch")
3366 (set_attr "mode" "<MODE>")])
3368 ;; Zero extension instructions
3370 (define_expand "zero_extendsidi2"
3371 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3372 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3377 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3382 (define_insn "*zero_extendsidi2_rex64"
3383 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3385 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3388 mov{l}\t{%1, %k0|%k0, %1}
3390 movd\t{%1, %0|%0, %1}
3391 movd\t{%1, %0|%0, %1}
3392 %vmovd\t{%1, %0|%0, %1}
3393 %vmovd\t{%1, %0|%0, %1}"
3394 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3395 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3396 (set_attr "prefix_0f" "0,*,*,*,*,*")
3397 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3400 [(set (match_operand:DI 0 "memory_operand" "")
3401 (zero_extend:DI (match_dup 0)))]
3403 [(set (match_dup 4) (const_int 0))]
3404 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3406 ;; %%% Kill me once multi-word ops are sane.
3407 (define_insn "zero_extendsidi2_1"
3408 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3410 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3411 (clobber (reg:CC FLAGS_REG))]
3417 movd\t{%1, %0|%0, %1}
3418 movd\t{%1, %0|%0, %1}
3419 %vmovd\t{%1, %0|%0, %1}
3420 %vmovd\t{%1, %0|%0, %1}"
3421 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3422 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3423 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3424 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3427 [(set (match_operand:DI 0 "register_operand" "")
3428 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3429 (clobber (reg:CC FLAGS_REG))]
3430 "!TARGET_64BIT && reload_completed
3431 && true_regnum (operands[0]) == true_regnum (operands[1])"
3432 [(set (match_dup 4) (const_int 0))]
3433 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3436 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3437 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3438 (clobber (reg:CC FLAGS_REG))]
3439 "!TARGET_64BIT && reload_completed
3440 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3441 [(set (match_dup 3) (match_dup 1))
3442 (set (match_dup 4) (const_int 0))]
3443 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3445 (define_insn "zero_extend<mode>di2"
3446 [(set (match_operand:DI 0 "register_operand" "=r")
3448 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3450 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3451 [(set_attr "type" "imovx")
3452 (set_attr "mode" "SI")])
3454 (define_expand "zero_extendhisi2"
3455 [(set (match_operand:SI 0 "register_operand" "")
3456 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3459 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3461 operands[1] = force_reg (HImode, operands[1]);
3462 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3467 (define_insn_and_split "zero_extendhisi2_and"
3468 [(set (match_operand:SI 0 "register_operand" "=r")
3469 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3470 (clobber (reg:CC FLAGS_REG))]
3471 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3473 "&& reload_completed"
3474 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3475 (clobber (reg:CC FLAGS_REG))])]
3477 [(set_attr "type" "alu1")
3478 (set_attr "mode" "SI")])
3480 (define_insn "*zero_extendhisi2_movzwl"
3481 [(set (match_operand:SI 0 "register_operand" "=r")
3482 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3483 "!TARGET_ZERO_EXTEND_WITH_AND
3484 || optimize_function_for_size_p (cfun)"
3485 "movz{wl|x}\t{%1, %0|%0, %1}"
3486 [(set_attr "type" "imovx")
3487 (set_attr "mode" "SI")])
3489 (define_expand "zero_extendqi<mode>2"
3491 [(set (match_operand:SWI24 0 "register_operand" "")
3492 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3493 (clobber (reg:CC FLAGS_REG))])])
3495 (define_insn "*zero_extendqi<mode>2_and"
3496 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3497 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3498 (clobber (reg:CC FLAGS_REG))]
3499 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3501 [(set_attr "type" "alu1")
3502 (set_attr "mode" "<MODE>")])
3504 ;; When source and destination does not overlap, clear destination
3505 ;; first and then do the movb
3507 [(set (match_operand:SWI24 0 "register_operand" "")
3508 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3509 (clobber (reg:CC FLAGS_REG))]
3511 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3512 && ANY_QI_REG_P (operands[0])
3513 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3514 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3515 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3517 operands[2] = gen_lowpart (QImode, operands[0]);
3518 ix86_expand_clear (operands[0]);
3521 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3522 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3523 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3524 (clobber (reg:CC FLAGS_REG))]
3525 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3527 [(set_attr "type" "imovx,alu1")
3528 (set_attr "mode" "<MODE>")])
3530 ;; For the movzbl case strip only the clobber
3532 [(set (match_operand:SWI24 0 "register_operand" "")
3533 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3534 (clobber (reg:CC FLAGS_REG))]
3536 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3537 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3539 (zero_extend:SWI24 (match_dup 1)))])
3541 ; zero extend to SImode to avoid partial register stalls
3542 (define_insn "*zero_extendqi<mode>2_movzbl"
3543 [(set (match_operand:SWI24 0 "register_operand" "=r")
3544 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3546 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3547 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3548 [(set_attr "type" "imovx")
3549 (set_attr "mode" "SI")])
3551 ;; Rest is handled by single and.
3553 [(set (match_operand:SWI24 0 "register_operand" "")
3554 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3555 (clobber (reg:CC FLAGS_REG))]
3557 && true_regnum (operands[0]) == true_regnum (operands[1])"
3558 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3559 (clobber (reg:CC FLAGS_REG))])])
3561 ;; Sign extension instructions
3563 (define_expand "extendsidi2"
3564 [(set (match_operand:DI 0 "register_operand" "")
3565 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3570 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3575 (define_insn "*extendsidi2_rex64"
3576 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3577 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3581 movs{lq|x}\t{%1, %0|%0, %1}"
3582 [(set_attr "type" "imovx")
3583 (set_attr "mode" "DI")
3584 (set_attr "prefix_0f" "0")
3585 (set_attr "modrm" "0,1")])
3587 (define_insn "extendsidi2_1"
3588 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3589 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3590 (clobber (reg:CC FLAGS_REG))
3591 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3595 ;; Extend to memory case when source register does die.
3597 [(set (match_operand:DI 0 "memory_operand" "")
3598 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3599 (clobber (reg:CC FLAGS_REG))
3600 (clobber (match_operand:SI 2 "register_operand" ""))]
3602 && dead_or_set_p (insn, operands[1])
3603 && !reg_mentioned_p (operands[1], operands[0]))"
3604 [(set (match_dup 3) (match_dup 1))
3605 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3606 (clobber (reg:CC FLAGS_REG))])
3607 (set (match_dup 4) (match_dup 1))]
3608 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3610 ;; Extend to memory case when source register does not die.
3612 [(set (match_operand:DI 0 "memory_operand" "")
3613 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3614 (clobber (reg:CC FLAGS_REG))
3615 (clobber (match_operand:SI 2 "register_operand" ""))]
3619 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3621 emit_move_insn (operands[3], operands[1]);
3623 /* Generate a cltd if possible and doing so it profitable. */
3624 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3625 && true_regnum (operands[1]) == AX_REG
3626 && true_regnum (operands[2]) == DX_REG)
3628 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3632 emit_move_insn (operands[2], operands[1]);
3633 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3635 emit_move_insn (operands[4], operands[2]);
3639 ;; Extend to register case. Optimize case where source and destination
3640 ;; registers match and cases where we can use cltd.
3642 [(set (match_operand:DI 0 "register_operand" "")
3643 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3644 (clobber (reg:CC FLAGS_REG))
3645 (clobber (match_scratch:SI 2 ""))]
3649 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3651 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3652 emit_move_insn (operands[3], operands[1]);
3654 /* Generate a cltd if possible and doing so it profitable. */
3655 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3656 && true_regnum (operands[3]) == AX_REG
3657 && true_regnum (operands[4]) == DX_REG)
3659 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3663 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3664 emit_move_insn (operands[4], operands[1]);
3666 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3670 (define_insn "extend<mode>di2"
3671 [(set (match_operand:DI 0 "register_operand" "=r")
3673 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3675 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3676 [(set_attr "type" "imovx")
3677 (set_attr "mode" "DI")])
3679 (define_insn "extendhisi2"
3680 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3681 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3684 switch (get_attr_prefix_0f (insn))
3687 return "{cwtl|cwde}";
3689 return "movs{wl|x}\t{%1, %0|%0, %1}";
3692 [(set_attr "type" "imovx")
3693 (set_attr "mode" "SI")
3694 (set (attr "prefix_0f")
3695 ;; movsx is short decodable while cwtl is vector decoded.
3696 (if_then_else (and (eq_attr "cpu" "!k6")
3697 (eq_attr "alternative" "0"))
3699 (const_string "1")))
3701 (if_then_else (eq_attr "prefix_0f" "0")
3703 (const_string "1")))])
3705 (define_insn "*extendhisi2_zext"
3706 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3709 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3712 switch (get_attr_prefix_0f (insn))
3715 return "{cwtl|cwde}";
3717 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3720 [(set_attr "type" "imovx")
3721 (set_attr "mode" "SI")
3722 (set (attr "prefix_0f")
3723 ;; movsx is short decodable while cwtl is vector decoded.
3724 (if_then_else (and (eq_attr "cpu" "!k6")
3725 (eq_attr "alternative" "0"))
3727 (const_string "1")))
3729 (if_then_else (eq_attr "prefix_0f" "0")
3731 (const_string "1")))])
3733 (define_insn "extendqisi2"
3734 [(set (match_operand:SI 0 "register_operand" "=r")
3735 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3737 "movs{bl|x}\t{%1, %0|%0, %1}"
3738 [(set_attr "type" "imovx")
3739 (set_attr "mode" "SI")])
3741 (define_insn "*extendqisi2_zext"
3742 [(set (match_operand:DI 0 "register_operand" "=r")
3744 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3746 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3747 [(set_attr "type" "imovx")
3748 (set_attr "mode" "SI")])
3750 (define_insn "extendqihi2"
3751 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3752 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3755 switch (get_attr_prefix_0f (insn))
3758 return "{cbtw|cbw}";
3760 return "movs{bw|x}\t{%1, %0|%0, %1}";
3763 [(set_attr "type" "imovx")
3764 (set_attr "mode" "HI")
3765 (set (attr "prefix_0f")
3766 ;; movsx is short decodable while cwtl is vector decoded.
3767 (if_then_else (and (eq_attr "cpu" "!k6")
3768 (eq_attr "alternative" "0"))
3770 (const_string "1")))
3772 (if_then_else (eq_attr "prefix_0f" "0")
3774 (const_string "1")))])
3776 ;; Conversions between float and double.
3778 ;; These are all no-ops in the model used for the 80387.
3779 ;; So just emit moves.
3781 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3783 [(set (match_operand:DF 0 "push_operand" "")
3784 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3786 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3787 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3790 [(set (match_operand:XF 0 "push_operand" "")
3791 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3793 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3794 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3795 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3797 (define_expand "extendsfdf2"
3798 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3799 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3800 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3802 /* ??? Needed for compress_float_constant since all fp constants
3803 are TARGET_LEGITIMATE_CONSTANT_P. */
3804 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3806 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3807 && standard_80387_constant_p (operands[1]) > 0)
3809 operands[1] = simplify_const_unary_operation
3810 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3811 emit_move_insn_1 (operands[0], operands[1]);
3814 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3818 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3820 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3822 We do the conversion post reload to avoid producing of 128bit spills
3823 that might lead to ICE on 32bit target. The sequence unlikely combine
3826 [(set (match_operand:DF 0 "register_operand" "")
3828 (match_operand:SF 1 "nonimmediate_operand" "")))]
3829 "TARGET_USE_VECTOR_FP_CONVERTS
3830 && optimize_insn_for_speed_p ()
3831 && reload_completed && SSE_REG_P (operands[0])"
3836 (parallel [(const_int 0) (const_int 1)]))))]
3838 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3839 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3840 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3841 Try to avoid move when unpacking can be done in source. */
3842 if (REG_P (operands[1]))
3844 /* If it is unsafe to overwrite upper half of source, we need
3845 to move to destination and unpack there. */
3846 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3847 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3848 && true_regnum (operands[0]) != true_regnum (operands[1]))
3850 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3851 emit_move_insn (tmp, operands[1]);
3854 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3855 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3859 emit_insn (gen_vec_setv4sf_0 (operands[3],
3860 CONST0_RTX (V4SFmode), operands[1]));
3863 (define_insn "*extendsfdf2_mixed"
3864 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3866 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3867 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3869 switch (which_alternative)
3873 return output_387_reg_move (insn, operands);
3876 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3882 [(set_attr "type" "fmov,fmov,ssecvt")
3883 (set_attr "prefix" "orig,orig,maybe_vex")
3884 (set_attr "mode" "SF,XF,DF")])
3886 (define_insn "*extendsfdf2_sse"
3887 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3888 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3889 "TARGET_SSE2 && TARGET_SSE_MATH"
3890 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3891 [(set_attr "type" "ssecvt")
3892 (set_attr "prefix" "maybe_vex")
3893 (set_attr "mode" "DF")])
3895 (define_insn "*extendsfdf2_i387"
3896 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3897 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3899 "* return output_387_reg_move (insn, operands);"
3900 [(set_attr "type" "fmov")
3901 (set_attr "mode" "SF,XF")])
3903 (define_expand "extend<mode>xf2"
3904 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3905 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3908 /* ??? Needed for compress_float_constant since all fp constants
3909 are TARGET_LEGITIMATE_CONSTANT_P. */
3910 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3912 if (standard_80387_constant_p (operands[1]) > 0)
3914 operands[1] = simplify_const_unary_operation
3915 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3916 emit_move_insn_1 (operands[0], operands[1]);
3919 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3923 (define_insn "*extend<mode>xf2_i387"
3924 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3926 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3928 "* return output_387_reg_move (insn, operands);"
3929 [(set_attr "type" "fmov")
3930 (set_attr "mode" "<MODE>,XF")])
3932 ;; %%% This seems bad bad news.
3933 ;; This cannot output into an f-reg because there is no way to be sure
3934 ;; of truncating in that case. Otherwise this is just like a simple move
3935 ;; insn. So we pretend we can output to a reg in order to get better
3936 ;; register preferencing, but we really use a stack slot.
3938 ;; Conversion from DFmode to SFmode.
3940 (define_expand "truncdfsf2"
3941 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3943 (match_operand:DF 1 "nonimmediate_operand" "")))]
3944 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3946 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3948 else if (flag_unsafe_math_optimizations)
3952 enum ix86_stack_slot slot = (virtuals_instantiated
3955 rtx temp = assign_386_stack_local (SFmode, slot);
3956 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3961 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3963 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3965 We do the conversion post reload to avoid producing of 128bit spills
3966 that might lead to ICE on 32bit target. The sequence unlikely combine
3969 [(set (match_operand:SF 0 "register_operand" "")
3971 (match_operand:DF 1 "nonimmediate_operand" "")))]
3972 "TARGET_USE_VECTOR_FP_CONVERTS
3973 && optimize_insn_for_speed_p ()
3974 && reload_completed && SSE_REG_P (operands[0])"
3977 (float_truncate:V2SF
3981 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3982 operands[3] = CONST0_RTX (V2SFmode);
3983 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3984 /* Use movsd for loading from memory, unpcklpd for registers.
3985 Try to avoid move when unpacking can be done in source, or SSE3
3986 movddup is available. */
3987 if (REG_P (operands[1]))
3990 && true_regnum (operands[0]) != true_regnum (operands[1])
3991 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3992 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3994 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3995 emit_move_insn (tmp, operands[1]);
3998 else if (!TARGET_SSE3)
3999 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4000 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4003 emit_insn (gen_sse2_loadlpd (operands[4],
4004 CONST0_RTX (V2DFmode), operands[1]));
4007 (define_expand "truncdfsf2_with_temp"
4008 [(parallel [(set (match_operand:SF 0 "" "")
4009 (float_truncate:SF (match_operand:DF 1 "" "")))
4010 (clobber (match_operand:SF 2 "" ""))])])
4012 (define_insn "*truncdfsf_fast_mixed"
4013 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4015 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4016 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4018 switch (which_alternative)
4021 return output_387_reg_move (insn, operands);
4023 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4028 [(set_attr "type" "fmov,ssecvt")
4029 (set_attr "prefix" "orig,maybe_vex")
4030 (set_attr "mode" "SF")])
4032 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4033 ;; because nothing we do here is unsafe.
4034 (define_insn "*truncdfsf_fast_sse"
4035 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4037 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4038 "TARGET_SSE2 && TARGET_SSE_MATH"
4039 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4040 [(set_attr "type" "ssecvt")
4041 (set_attr "prefix" "maybe_vex")
4042 (set_attr "mode" "SF")])
4044 (define_insn "*truncdfsf_fast_i387"
4045 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4047 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4048 "TARGET_80387 && flag_unsafe_math_optimizations"
4049 "* return output_387_reg_move (insn, operands);"
4050 [(set_attr "type" "fmov")
4051 (set_attr "mode" "SF")])
4053 (define_insn "*truncdfsf_mixed"
4054 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4056 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4057 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4058 "TARGET_MIX_SSE_I387"
4060 switch (which_alternative)
4063 return output_387_reg_move (insn, operands);
4065 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4071 [(set_attr "isa" "*,sse2,*,*,*")
4072 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4073 (set_attr "unit" "*,*,i387,i387,i387")
4074 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4075 (set_attr "mode" "SF")])
4077 (define_insn "*truncdfsf_i387"
4078 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4080 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4081 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4084 switch (which_alternative)
4087 return output_387_reg_move (insn, operands);
4093 [(set_attr "type" "fmov,multi,multi,multi")
4094 (set_attr "unit" "*,i387,i387,i387")
4095 (set_attr "mode" "SF")])
4097 (define_insn "*truncdfsf2_i387_1"
4098 [(set (match_operand:SF 0 "memory_operand" "=m")
4100 (match_operand:DF 1 "register_operand" "f")))]
4102 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4103 && !TARGET_MIX_SSE_I387"
4104 "* return output_387_reg_move (insn, operands);"
4105 [(set_attr "type" "fmov")
4106 (set_attr "mode" "SF")])
4109 [(set (match_operand:SF 0 "register_operand" "")
4111 (match_operand:DF 1 "fp_register_operand" "")))
4112 (clobber (match_operand 2 "" ""))]
4114 [(set (match_dup 2) (match_dup 1))
4115 (set (match_dup 0) (match_dup 2))]
4116 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4118 ;; Conversion from XFmode to {SF,DF}mode
4120 (define_expand "truncxf<mode>2"
4121 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4122 (float_truncate:MODEF
4123 (match_operand:XF 1 "register_operand" "")))
4124 (clobber (match_dup 2))])]
4127 if (flag_unsafe_math_optimizations)
4129 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4130 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4131 if (reg != operands[0])
4132 emit_move_insn (operands[0], reg);
4137 enum ix86_stack_slot slot = (virtuals_instantiated
4140 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4144 (define_insn "*truncxfsf2_mixed"
4145 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4147 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4148 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4151 gcc_assert (!which_alternative);
4152 return output_387_reg_move (insn, operands);
4154 [(set_attr "type" "fmov,multi,multi,multi")
4155 (set_attr "unit" "*,i387,i387,i387")
4156 (set_attr "mode" "SF")])
4158 (define_insn "*truncxfdf2_mixed"
4159 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4161 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4162 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4165 gcc_assert (!which_alternative);
4166 return output_387_reg_move (insn, operands);
4168 [(set_attr "isa" "*,*,sse2,*")
4169 (set_attr "type" "fmov,multi,multi,multi")
4170 (set_attr "unit" "*,i387,i387,i387")
4171 (set_attr "mode" "DF")])
4173 (define_insn "truncxf<mode>2_i387_noop"
4174 [(set (match_operand:MODEF 0 "register_operand" "=f")
4175 (float_truncate:MODEF
4176 (match_operand:XF 1 "register_operand" "f")))]
4177 "TARGET_80387 && flag_unsafe_math_optimizations"
4178 "* return output_387_reg_move (insn, operands);"
4179 [(set_attr "type" "fmov")
4180 (set_attr "mode" "<MODE>")])
4182 (define_insn "*truncxf<mode>2_i387"
4183 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4184 (float_truncate:MODEF
4185 (match_operand:XF 1 "register_operand" "f")))]
4187 "* return output_387_reg_move (insn, operands);"
4188 [(set_attr "type" "fmov")
4189 (set_attr "mode" "<MODE>")])
4192 [(set (match_operand:MODEF 0 "register_operand" "")
4193 (float_truncate:MODEF
4194 (match_operand:XF 1 "register_operand" "")))
4195 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4196 "TARGET_80387 && reload_completed"
4197 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4198 (set (match_dup 0) (match_dup 2))])
4201 [(set (match_operand:MODEF 0 "memory_operand" "")
4202 (float_truncate:MODEF
4203 (match_operand:XF 1 "register_operand" "")))
4204 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4206 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4208 ;; Signed conversion to DImode.
4210 (define_expand "fix_truncxfdi2"
4211 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4212 (fix:DI (match_operand:XF 1 "register_operand" "")))
4213 (clobber (reg:CC FLAGS_REG))])]
4218 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4223 (define_expand "fix_trunc<mode>di2"
4224 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4225 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4226 (clobber (reg:CC FLAGS_REG))])]
4227 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4230 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4232 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4235 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4237 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4238 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4239 if (out != operands[0])
4240 emit_move_insn (operands[0], out);
4245 ;; Signed conversion to SImode.
4247 (define_expand "fix_truncxfsi2"
4248 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4249 (fix:SI (match_operand:XF 1 "register_operand" "")))
4250 (clobber (reg:CC FLAGS_REG))])]
4255 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4260 (define_expand "fix_trunc<mode>si2"
4261 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4262 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4263 (clobber (reg:CC FLAGS_REG))])]
4264 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4267 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4269 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4272 if (SSE_FLOAT_MODE_P (<MODE>mode))
4274 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4275 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4276 if (out != operands[0])
4277 emit_move_insn (operands[0], out);
4282 ;; Signed conversion to HImode.
4284 (define_expand "fix_trunc<mode>hi2"
4285 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4286 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4287 (clobber (reg:CC FLAGS_REG))])]
4289 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4293 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4298 ;; Unsigned conversion to SImode.
4300 (define_expand "fixuns_trunc<mode>si2"
4302 [(set (match_operand:SI 0 "register_operand" "")
4304 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4306 (clobber (match_scratch:<ssevecmode> 3 ""))
4307 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4308 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4310 enum machine_mode mode = <MODE>mode;
4311 enum machine_mode vecmode = <ssevecmode>mode;
4312 REAL_VALUE_TYPE TWO31r;
4315 if (optimize_insn_for_size_p ())
4318 real_ldexp (&TWO31r, &dconst1, 31);
4319 two31 = const_double_from_real_value (TWO31r, mode);
4320 two31 = ix86_build_const_vector (vecmode, true, two31);
4321 operands[2] = force_reg (vecmode, two31);
4324 (define_insn_and_split "*fixuns_trunc<mode>_1"
4325 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4327 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4328 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4329 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4330 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4331 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4332 && optimize_function_for_speed_p (cfun)"
4334 "&& reload_completed"
4337 ix86_split_convert_uns_si_sse (operands);
4341 ;; Unsigned conversion to HImode.
4342 ;; Without these patterns, we'll try the unsigned SI conversion which
4343 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4345 (define_expand "fixuns_trunc<mode>hi2"
4347 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4348 (set (match_operand:HI 0 "nonimmediate_operand" "")
4349 (subreg:HI (match_dup 2) 0))]
4350 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4351 "operands[2] = gen_reg_rtx (SImode);")
4353 ;; When SSE is available, it is always faster to use it!
4354 (define_insn "fix_trunc<mode>di_sse"
4355 [(set (match_operand:DI 0 "register_operand" "=r,r")
4356 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4357 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4358 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4359 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4360 [(set_attr "type" "sseicvt")
4361 (set_attr "prefix" "maybe_vex")
4362 (set_attr "prefix_rex" "1")
4363 (set_attr "mode" "<MODE>")
4364 (set_attr "athlon_decode" "double,vector")
4365 (set_attr "amdfam10_decode" "double,double")
4366 (set_attr "bdver1_decode" "double,double")])
4368 (define_insn "fix_trunc<mode>si_sse"
4369 [(set (match_operand:SI 0 "register_operand" "=r,r")
4370 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4371 "SSE_FLOAT_MODE_P (<MODE>mode)
4372 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4373 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4374 [(set_attr "type" "sseicvt")
4375 (set_attr "prefix" "maybe_vex")
4376 (set_attr "mode" "<MODE>")
4377 (set_attr "athlon_decode" "double,vector")
4378 (set_attr "amdfam10_decode" "double,double")
4379 (set_attr "bdver1_decode" "double,double")])
4381 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4383 [(set (match_operand:MODEF 0 "register_operand" "")
4384 (match_operand:MODEF 1 "memory_operand" ""))
4385 (set (match_operand:SWI48x 2 "register_operand" "")
4386 (fix:SWI48x (match_dup 0)))]
4387 "TARGET_SHORTEN_X87_SSE
4388 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4389 && peep2_reg_dead_p (2, operands[0])"
4390 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4392 ;; Avoid vector decoded forms of the instruction.
4394 [(match_scratch:DF 2 "x")
4395 (set (match_operand:SWI48x 0 "register_operand" "")
4396 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4397 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4398 [(set (match_dup 2) (match_dup 1))
4399 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4402 [(match_scratch:SF 2 "x")
4403 (set (match_operand:SWI48x 0 "register_operand" "")
4404 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4405 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4406 [(set (match_dup 2) (match_dup 1))
4407 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4409 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4410 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4411 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4412 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4414 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4415 && (TARGET_64BIT || <MODE>mode != DImode))
4417 && can_create_pseudo_p ()"
4422 if (memory_operand (operands[0], VOIDmode))
4423 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4426 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4427 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4433 [(set_attr "type" "fisttp")
4434 (set_attr "mode" "<MODE>")])
4436 (define_insn "fix_trunc<mode>_i387_fisttp"
4437 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4438 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4439 (clobber (match_scratch:XF 2 "=&1f"))]
4440 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4442 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4443 && (TARGET_64BIT || <MODE>mode != DImode))
4444 && TARGET_SSE_MATH)"
4445 "* return output_fix_trunc (insn, operands, true);"
4446 [(set_attr "type" "fisttp")
4447 (set_attr "mode" "<MODE>")])
4449 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4450 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4451 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4452 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4453 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4454 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4456 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4457 && (TARGET_64BIT || <MODE>mode != DImode))
4458 && TARGET_SSE_MATH)"
4460 [(set_attr "type" "fisttp")
4461 (set_attr "mode" "<MODE>")])
4464 [(set (match_operand:SWI248x 0 "register_operand" "")
4465 (fix:SWI248x (match_operand 1 "register_operand" "")))
4466 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4467 (clobber (match_scratch 3 ""))]
4469 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4470 (clobber (match_dup 3))])
4471 (set (match_dup 0) (match_dup 2))])
4474 [(set (match_operand:SWI248x 0 "memory_operand" "")
4475 (fix:SWI248x (match_operand 1 "register_operand" "")))
4476 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4477 (clobber (match_scratch 3 ""))]
4479 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4480 (clobber (match_dup 3))])])
4482 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4483 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4484 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4485 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4486 ;; function in i386.c.
4487 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4488 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4489 (fix:SWI248x (match_operand 1 "register_operand" "")))
4490 (clobber (reg:CC FLAGS_REG))]
4491 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4493 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4494 && (TARGET_64BIT || <MODE>mode != DImode))
4495 && can_create_pseudo_p ()"
4500 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4502 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4503 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4504 if (memory_operand (operands[0], VOIDmode))
4505 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4506 operands[2], operands[3]));
4509 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4510 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4511 operands[2], operands[3],
4516 [(set_attr "type" "fistp")
4517 (set_attr "i387_cw" "trunc")
4518 (set_attr "mode" "<MODE>")])
4520 (define_insn "fix_truncdi_i387"
4521 [(set (match_operand:DI 0 "memory_operand" "=m")
4522 (fix:DI (match_operand 1 "register_operand" "f")))
4523 (use (match_operand:HI 2 "memory_operand" "m"))
4524 (use (match_operand:HI 3 "memory_operand" "m"))
4525 (clobber (match_scratch:XF 4 "=&1f"))]
4526 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4528 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4529 "* return output_fix_trunc (insn, operands, false);"
4530 [(set_attr "type" "fistp")
4531 (set_attr "i387_cw" "trunc")
4532 (set_attr "mode" "DI")])
4534 (define_insn "fix_truncdi_i387_with_temp"
4535 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4536 (fix:DI (match_operand 1 "register_operand" "f,f")))
4537 (use (match_operand:HI 2 "memory_operand" "m,m"))
4538 (use (match_operand:HI 3 "memory_operand" "m,m"))
4539 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4540 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4541 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4543 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4545 [(set_attr "type" "fistp")
4546 (set_attr "i387_cw" "trunc")
4547 (set_attr "mode" "DI")])
4550 [(set (match_operand:DI 0 "register_operand" "")
4551 (fix:DI (match_operand 1 "register_operand" "")))
4552 (use (match_operand:HI 2 "memory_operand" ""))
4553 (use (match_operand:HI 3 "memory_operand" ""))
4554 (clobber (match_operand:DI 4 "memory_operand" ""))
4555 (clobber (match_scratch 5 ""))]
4557 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4560 (clobber (match_dup 5))])
4561 (set (match_dup 0) (match_dup 4))])
4564 [(set (match_operand:DI 0 "memory_operand" "")
4565 (fix:DI (match_operand 1 "register_operand" "")))
4566 (use (match_operand:HI 2 "memory_operand" ""))
4567 (use (match_operand:HI 3 "memory_operand" ""))
4568 (clobber (match_operand:DI 4 "memory_operand" ""))
4569 (clobber (match_scratch 5 ""))]
4571 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4574 (clobber (match_dup 5))])])
4576 (define_insn "fix_trunc<mode>_i387"
4577 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4578 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4579 (use (match_operand:HI 2 "memory_operand" "m"))
4580 (use (match_operand:HI 3 "memory_operand" "m"))]
4581 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4583 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4584 "* return output_fix_trunc (insn, operands, false);"
4585 [(set_attr "type" "fistp")
4586 (set_attr "i387_cw" "trunc")
4587 (set_attr "mode" "<MODE>")])
4589 (define_insn "fix_trunc<mode>_i387_with_temp"
4590 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4591 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4592 (use (match_operand:HI 2 "memory_operand" "m,m"))
4593 (use (match_operand:HI 3 "memory_operand" "m,m"))
4594 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4595 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4597 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4599 [(set_attr "type" "fistp")
4600 (set_attr "i387_cw" "trunc")
4601 (set_attr "mode" "<MODE>")])
4604 [(set (match_operand:SWI24 0 "register_operand" "")
4605 (fix:SWI24 (match_operand 1 "register_operand" "")))
4606 (use (match_operand:HI 2 "memory_operand" ""))
4607 (use (match_operand:HI 3 "memory_operand" ""))
4608 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4610 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4612 (use (match_dup 3))])
4613 (set (match_dup 0) (match_dup 4))])
4616 [(set (match_operand:SWI24 0 "memory_operand" "")
4617 (fix:SWI24 (match_operand 1 "register_operand" "")))
4618 (use (match_operand:HI 2 "memory_operand" ""))
4619 (use (match_operand:HI 3 "memory_operand" ""))
4620 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4622 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4624 (use (match_dup 3))])])
4626 (define_insn "x86_fnstcw_1"
4627 [(set (match_operand:HI 0 "memory_operand" "=m")
4628 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4631 [(set (attr "length")
4632 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4633 (set_attr "mode" "HI")
4634 (set_attr "unit" "i387")
4635 (set_attr "bdver1_decode" "vector")])
4637 (define_insn "x86_fldcw_1"
4638 [(set (reg:HI FPCR_REG)
4639 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4642 [(set (attr "length")
4643 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4644 (set_attr "mode" "HI")
4645 (set_attr "unit" "i387")
4646 (set_attr "athlon_decode" "vector")
4647 (set_attr "amdfam10_decode" "vector")
4648 (set_attr "bdver1_decode" "vector")])
4650 ;; Conversion between fixed point and floating point.
4652 ;; Even though we only accept memory inputs, the backend _really_
4653 ;; wants to be able to do this between registers.
4655 (define_expand "floathi<mode>2"
4656 [(set (match_operand:X87MODEF 0 "register_operand" "")
4657 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4659 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4660 || TARGET_MIX_SSE_I387)")
4662 ;; Pre-reload splitter to add memory clobber to the pattern.
4663 (define_insn_and_split "*floathi<mode>2_1"
4664 [(set (match_operand:X87MODEF 0 "register_operand" "")
4665 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4667 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4668 || TARGET_MIX_SSE_I387)
4669 && can_create_pseudo_p ()"
4672 [(parallel [(set (match_dup 0)
4673 (float:X87MODEF (match_dup 1)))
4674 (clobber (match_dup 2))])]
4675 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4677 (define_insn "*floathi<mode>2_i387_with_temp"
4678 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4679 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4680 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4682 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4683 || TARGET_MIX_SSE_I387)"
4685 [(set_attr "type" "fmov,multi")
4686 (set_attr "mode" "<MODE>")
4687 (set_attr "unit" "*,i387")
4688 (set_attr "fp_int_src" "true")])
4690 (define_insn "*floathi<mode>2_i387"
4691 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4692 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4694 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4695 || TARGET_MIX_SSE_I387)"
4697 [(set_attr "type" "fmov")
4698 (set_attr "mode" "<MODE>")
4699 (set_attr "fp_int_src" "true")])
4702 [(set (match_operand:X87MODEF 0 "register_operand" "")
4703 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4704 (clobber (match_operand:HI 2 "memory_operand" ""))]
4706 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4707 || TARGET_MIX_SSE_I387)
4708 && reload_completed"
4709 [(set (match_dup 2) (match_dup 1))
4710 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4713 [(set (match_operand:X87MODEF 0 "register_operand" "")
4714 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4715 (clobber (match_operand:HI 2 "memory_operand" ""))]
4717 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4718 || TARGET_MIX_SSE_I387)
4719 && reload_completed"
4720 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4722 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4723 [(set (match_operand:X87MODEF 0 "register_operand" "")
4725 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4727 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4728 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4730 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4731 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4732 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4734 rtx reg = gen_reg_rtx (XFmode);
4735 rtx (*insn)(rtx, rtx);
4737 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4739 if (<X87MODEF:MODE>mode == SFmode)
4740 insn = gen_truncxfsf2;
4741 else if (<X87MODEF:MODE>mode == DFmode)
4742 insn = gen_truncxfdf2;
4746 emit_insn (insn (operands[0], reg));
4751 ;; Pre-reload splitter to add memory clobber to the pattern.
4752 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4753 [(set (match_operand:X87MODEF 0 "register_operand" "")
4754 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4756 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4757 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4758 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4759 || TARGET_MIX_SSE_I387))
4760 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4761 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4762 && ((<SWI48x:MODE>mode == SImode
4763 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4764 && optimize_function_for_speed_p (cfun)
4765 && flag_trapping_math)
4766 || !(TARGET_INTER_UNIT_CONVERSIONS
4767 || optimize_function_for_size_p (cfun)))))
4768 && can_create_pseudo_p ()"
4771 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4772 (clobber (match_dup 2))])]
4774 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4776 /* Avoid store forwarding (partial memory) stall penalty
4777 by passing DImode value through XMM registers. */
4778 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4779 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4780 && optimize_function_for_speed_p (cfun))
4782 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4789 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4790 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4792 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4793 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4794 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4795 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4797 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4798 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4799 (set_attr "unit" "*,i387,*,*,*")
4800 (set_attr "athlon_decode" "*,*,double,direct,double")
4801 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4802 (set_attr "bdver1_decode" "*,*,double,direct,double")
4803 (set_attr "fp_int_src" "true")])
4805 (define_insn "*floatsi<mode>2_vector_mixed"
4806 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4807 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4808 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4809 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4813 [(set_attr "type" "fmov,sseicvt")
4814 (set_attr "mode" "<MODE>,<ssevecmode>")
4815 (set_attr "unit" "i387,*")
4816 (set_attr "athlon_decode" "*,direct")
4817 (set_attr "amdfam10_decode" "*,double")
4818 (set_attr "bdver1_decode" "*,direct")
4819 (set_attr "fp_int_src" "true")])
4821 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4822 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4824 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4825 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4826 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4827 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4829 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4830 (set_attr "mode" "<MODEF:MODE>")
4831 (set_attr "unit" "*,i387,*,*")
4832 (set_attr "athlon_decode" "*,*,double,direct")
4833 (set_attr "amdfam10_decode" "*,*,vector,double")
4834 (set_attr "bdver1_decode" "*,*,double,direct")
4835 (set_attr "fp_int_src" "true")])
4838 [(set (match_operand:MODEF 0 "register_operand" "")
4839 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4840 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4841 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4842 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4843 && TARGET_INTER_UNIT_CONVERSIONS
4845 && (SSE_REG_P (operands[0])
4846 || (GET_CODE (operands[0]) == SUBREG
4847 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4848 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4851 [(set (match_operand:MODEF 0 "register_operand" "")
4852 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4853 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4854 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4855 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4856 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4858 && (SSE_REG_P (operands[0])
4859 || (GET_CODE (operands[0]) == SUBREG
4860 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4861 [(set (match_dup 2) (match_dup 1))
4862 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4864 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4865 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4867 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4868 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4869 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4870 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4873 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4874 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4875 [(set_attr "type" "fmov,sseicvt,sseicvt")
4876 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4877 (set_attr "mode" "<MODEF:MODE>")
4878 (set (attr "prefix_rex")
4880 (and (eq_attr "prefix" "maybe_vex")
4881 (match_test "<SWI48x:MODE>mode == DImode"))
4883 (const_string "*")))
4884 (set_attr "unit" "i387,*,*")
4885 (set_attr "athlon_decode" "*,double,direct")
4886 (set_attr "amdfam10_decode" "*,vector,double")
4887 (set_attr "bdver1_decode" "*,double,direct")
4888 (set_attr "fp_int_src" "true")])
4890 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4891 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4893 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4894 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4895 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4896 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4899 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4900 [(set_attr "type" "fmov,sseicvt")
4901 (set_attr "prefix" "orig,maybe_vex")
4902 (set_attr "mode" "<MODEF:MODE>")
4903 (set (attr "prefix_rex")
4905 (and (eq_attr "prefix" "maybe_vex")
4906 (match_test "<SWI48x:MODE>mode == DImode"))
4908 (const_string "*")))
4909 (set_attr "athlon_decode" "*,direct")
4910 (set_attr "amdfam10_decode" "*,double")
4911 (set_attr "bdver1_decode" "*,direct")
4912 (set_attr "fp_int_src" "true")])
4914 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4915 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4917 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4918 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4919 "TARGET_SSE2 && TARGET_SSE_MATH
4920 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4922 [(set_attr "type" "sseicvt")
4923 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4924 (set_attr "athlon_decode" "double,direct,double")
4925 (set_attr "amdfam10_decode" "vector,double,double")
4926 (set_attr "bdver1_decode" "double,direct,double")
4927 (set_attr "fp_int_src" "true")])
4929 (define_insn "*floatsi<mode>2_vector_sse"
4930 [(set (match_operand:MODEF 0 "register_operand" "=x")
4931 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4932 "TARGET_SSE2 && TARGET_SSE_MATH
4933 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4935 [(set_attr "type" "sseicvt")
4936 (set_attr "mode" "<MODE>")
4937 (set_attr "athlon_decode" "direct")
4938 (set_attr "amdfam10_decode" "double")
4939 (set_attr "bdver1_decode" "direct")
4940 (set_attr "fp_int_src" "true")])
4943 [(set (match_operand:MODEF 0 "register_operand" "")
4944 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4945 (clobber (match_operand:SI 2 "memory_operand" ""))]
4946 "TARGET_SSE2 && TARGET_SSE_MATH
4947 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4949 && (SSE_REG_P (operands[0])
4950 || (GET_CODE (operands[0]) == SUBREG
4951 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4954 rtx op1 = operands[1];
4956 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4958 if (GET_CODE (op1) == SUBREG)
4959 op1 = SUBREG_REG (op1);
4961 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4963 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4964 emit_insn (gen_sse2_loadld (operands[4],
4965 CONST0_RTX (V4SImode), operands[1]));
4967 /* We can ignore possible trapping value in the
4968 high part of SSE register for non-trapping math. */
4969 else if (SSE_REG_P (op1) && !flag_trapping_math)
4970 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4973 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4974 emit_move_insn (operands[2], operands[1]);
4975 emit_insn (gen_sse2_loadld (operands[4],
4976 CONST0_RTX (V4SImode), operands[2]));
4978 if (<ssevecmode>mode == V4SFmode)
4979 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4981 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4986 [(set (match_operand:MODEF 0 "register_operand" "")
4987 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4988 (clobber (match_operand:SI 2 "memory_operand" ""))]
4989 "TARGET_SSE2 && TARGET_SSE_MATH
4990 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4992 && (SSE_REG_P (operands[0])
4993 || (GET_CODE (operands[0]) == SUBREG
4994 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4997 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4999 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5001 emit_insn (gen_sse2_loadld (operands[4],
5002 CONST0_RTX (V4SImode), operands[1]));
5003 if (<ssevecmode>mode == V4SFmode)
5004 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5006 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5011 [(set (match_operand:MODEF 0 "register_operand" "")
5012 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5013 "TARGET_SSE2 && TARGET_SSE_MATH
5014 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5016 && (SSE_REG_P (operands[0])
5017 || (GET_CODE (operands[0]) == SUBREG
5018 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5021 rtx op1 = operands[1];
5023 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5025 if (GET_CODE (op1) == SUBREG)
5026 op1 = SUBREG_REG (op1);
5028 if (GENERAL_REG_P (op1))
5030 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5031 if (TARGET_INTER_UNIT_MOVES)
5032 emit_insn (gen_sse2_loadld (operands[4],
5033 CONST0_RTX (V4SImode), operands[1]));
5036 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5038 emit_insn (gen_sse2_loadld (operands[4],
5039 CONST0_RTX (V4SImode), operands[5]));
5040 ix86_free_from_memory (GET_MODE (operands[1]));
5043 /* We can ignore possible trapping value in the
5044 high part of SSE register for non-trapping math. */
5045 else if (SSE_REG_P (op1) && !flag_trapping_math)
5046 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5049 if (<ssevecmode>mode == V4SFmode)
5050 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5052 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5057 [(set (match_operand:MODEF 0 "register_operand" "")
5058 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5059 "TARGET_SSE2 && TARGET_SSE_MATH
5060 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5062 && (SSE_REG_P (operands[0])
5063 || (GET_CODE (operands[0]) == SUBREG
5064 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5067 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5069 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5071 emit_insn (gen_sse2_loadld (operands[4],
5072 CONST0_RTX (V4SImode), operands[1]));
5073 if (<ssevecmode>mode == V4SFmode)
5074 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5076 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5080 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5081 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5083 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5084 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5085 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5086 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5088 [(set_attr "type" "sseicvt")
5089 (set_attr "mode" "<MODEF:MODE>")
5090 (set_attr "athlon_decode" "double,direct")
5091 (set_attr "amdfam10_decode" "vector,double")
5092 (set_attr "bdver1_decode" "double,direct")
5093 (set_attr "fp_int_src" "true")])
5095 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5096 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5098 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5099 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5100 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5101 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5102 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5103 [(set_attr "type" "sseicvt")
5104 (set_attr "prefix" "maybe_vex")
5105 (set_attr "mode" "<MODEF:MODE>")
5106 (set (attr "prefix_rex")
5108 (and (eq_attr "prefix" "maybe_vex")
5109 (match_test "<SWI48x:MODE>mode == DImode"))
5111 (const_string "*")))
5112 (set_attr "athlon_decode" "double,direct")
5113 (set_attr "amdfam10_decode" "vector,double")
5114 (set_attr "bdver1_decode" "double,direct")
5115 (set_attr "fp_int_src" "true")])
5118 [(set (match_operand:MODEF 0 "register_operand" "")
5119 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5120 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5121 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5122 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5123 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5125 && (SSE_REG_P (operands[0])
5126 || (GET_CODE (operands[0]) == SUBREG
5127 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5128 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5130 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5131 [(set (match_operand:MODEF 0 "register_operand" "=x")
5133 (match_operand:SWI48x 1 "memory_operand" "m")))]
5134 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5135 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5136 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5137 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5138 [(set_attr "type" "sseicvt")
5139 (set_attr "prefix" "maybe_vex")
5140 (set_attr "mode" "<MODEF:MODE>")
5141 (set (attr "prefix_rex")
5143 (and (eq_attr "prefix" "maybe_vex")
5144 (match_test "<SWI48x:MODE>mode == DImode"))
5146 (const_string "*")))
5147 (set_attr "athlon_decode" "direct")
5148 (set_attr "amdfam10_decode" "double")
5149 (set_attr "bdver1_decode" "direct")
5150 (set_attr "fp_int_src" "true")])
5153 [(set (match_operand:MODEF 0 "register_operand" "")
5154 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5155 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
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))
5160 && (SSE_REG_P (operands[0])
5161 || (GET_CODE (operands[0]) == SUBREG
5162 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5163 [(set (match_dup 2) (match_dup 1))
5164 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5167 [(set (match_operand:MODEF 0 "register_operand" "")
5168 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5169 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5170 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5171 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5173 && (SSE_REG_P (operands[0])
5174 || (GET_CODE (operands[0]) == SUBREG
5175 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5176 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5178 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5179 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5181 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5182 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5184 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5188 [(set_attr "type" "fmov,multi")
5189 (set_attr "mode" "<X87MODEF:MODE>")
5190 (set_attr "unit" "*,i387")
5191 (set_attr "fp_int_src" "true")])
5193 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5194 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5196 (match_operand:SWI48x 1 "memory_operand" "m")))]
5198 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5200 [(set_attr "type" "fmov")
5201 (set_attr "mode" "<X87MODEF:MODE>")
5202 (set_attr "fp_int_src" "true")])
5205 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5206 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5207 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5209 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5210 && reload_completed"
5211 [(set (match_dup 2) (match_dup 1))
5212 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5215 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5216 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5217 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5219 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5220 && reload_completed"
5221 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5223 ;; Avoid store forwarding (partial memory) stall penalty
5224 ;; by passing DImode value through XMM registers. */
5226 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5227 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5229 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5230 (clobber (match_scratch:V4SI 3 "=X,x"))
5231 (clobber (match_scratch:V4SI 4 "=X,x"))
5232 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5233 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5234 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5235 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5237 [(set_attr "type" "multi")
5238 (set_attr "mode" "<X87MODEF:MODE>")
5239 (set_attr "unit" "i387")
5240 (set_attr "fp_int_src" "true")])
5243 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5244 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5245 (clobber (match_scratch:V4SI 3 ""))
5246 (clobber (match_scratch:V4SI 4 ""))
5247 (clobber (match_operand:DI 2 "memory_operand" ""))]
5248 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5249 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5250 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5251 && reload_completed"
5252 [(set (match_dup 2) (match_dup 3))
5253 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5255 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5256 Assemble the 64-bit DImode value in an xmm register. */
5257 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5258 gen_rtx_SUBREG (SImode, operands[1], 0)));
5259 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5260 gen_rtx_SUBREG (SImode, operands[1], 4)));
5261 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5264 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5268 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5269 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5270 (clobber (match_scratch:V4SI 3 ""))
5271 (clobber (match_scratch:V4SI 4 ""))
5272 (clobber (match_operand:DI 2 "memory_operand" ""))]
5273 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5274 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5275 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5276 && reload_completed"
5277 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5279 ;; Avoid store forwarding (partial memory) stall penalty by extending
5280 ;; SImode value to DImode through XMM register instead of pushing two
5281 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5282 ;; targets benefit from this optimization. Also note that fild
5283 ;; loads from memory only.
5285 (define_insn "*floatunssi<mode>2_1"
5286 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5287 (unsigned_float:X87MODEF
5288 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5289 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5290 (clobber (match_scratch:SI 3 "=X,x"))]
5292 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5295 [(set_attr "type" "multi")
5296 (set_attr "mode" "<MODE>")])
5299 [(set (match_operand:X87MODEF 0 "register_operand" "")
5300 (unsigned_float:X87MODEF
5301 (match_operand:SI 1 "register_operand" "")))
5302 (clobber (match_operand:DI 2 "memory_operand" ""))
5303 (clobber (match_scratch:SI 3 ""))]
5305 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5307 && reload_completed"
5308 [(set (match_dup 2) (match_dup 1))
5310 (float:X87MODEF (match_dup 2)))]
5311 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5314 [(set (match_operand:X87MODEF 0 "register_operand" "")
5315 (unsigned_float:X87MODEF
5316 (match_operand:SI 1 "memory_operand" "")))
5317 (clobber (match_operand:DI 2 "memory_operand" ""))
5318 (clobber (match_scratch:SI 3 ""))]
5320 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5322 && reload_completed"
5323 [(set (match_dup 2) (match_dup 3))
5325 (float:X87MODEF (match_dup 2)))]
5327 emit_move_insn (operands[3], operands[1]);
5328 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5331 (define_expand "floatunssi<mode>2"
5333 [(set (match_operand:X87MODEF 0 "register_operand" "")
5334 (unsigned_float:X87MODEF
5335 (match_operand:SI 1 "nonimmediate_operand" "")))
5336 (clobber (match_dup 2))
5337 (clobber (match_scratch:SI 3 ""))])]
5339 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5341 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5343 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5345 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5350 enum ix86_stack_slot slot = (virtuals_instantiated
5353 operands[2] = assign_386_stack_local (DImode, slot);
5357 (define_expand "floatunsdisf2"
5358 [(use (match_operand:SF 0 "register_operand" ""))
5359 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5360 "TARGET_64BIT && TARGET_SSE_MATH"
5361 "x86_emit_floatuns (operands); DONE;")
5363 (define_expand "floatunsdidf2"
5364 [(use (match_operand:DF 0 "register_operand" ""))
5365 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5366 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5367 && TARGET_SSE2 && TARGET_SSE_MATH"
5370 x86_emit_floatuns (operands);
5372 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5378 (define_expand "add<mode>3"
5379 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5380 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5381 (match_operand:SDWIM 2 "<general_operand>" "")))]
5383 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5385 (define_insn_and_split "*add<dwi>3_doubleword"
5386 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5388 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5389 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5390 (clobber (reg:CC FLAGS_REG))]
5391 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5394 [(parallel [(set (reg:CC FLAGS_REG)
5395 (unspec:CC [(match_dup 1) (match_dup 2)]
5398 (plus:DWIH (match_dup 1) (match_dup 2)))])
5399 (parallel [(set (match_dup 3)
5403 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5405 (clobber (reg:CC FLAGS_REG))])]
5406 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5408 (define_insn "*add<mode>3_cc"
5409 [(set (reg:CC FLAGS_REG)
5411 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5412 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5414 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5415 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5416 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5417 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5418 [(set_attr "type" "alu")
5419 (set_attr "mode" "<MODE>")])
5421 (define_insn "addqi3_cc"
5422 [(set (reg:CC FLAGS_REG)
5424 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5425 (match_operand:QI 2 "general_operand" "qn,qm")]
5427 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5428 (plus:QI (match_dup 1) (match_dup 2)))]
5429 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5430 "add{b}\t{%2, %0|%0, %2}"
5431 [(set_attr "type" "alu")
5432 (set_attr "mode" "QI")])
5434 (define_insn_and_split "*lea_1"
5435 [(set (match_operand:SI 0 "register_operand" "=r")
5436 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5438 "lea{l}\t{%a1, %0|%0, %a1}"
5439 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5442 ix86_split_lea_for_addr (operands, SImode);
5445 [(set_attr "type" "lea")
5446 (set_attr "mode" "SI")])
5448 (define_insn_and_split "*lea<mode>_2"
5449 [(set (match_operand:SWI48 0 "register_operand" "=r")
5450 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5452 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5453 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5456 ix86_split_lea_for_addr (operands, <MODE>mode);
5459 [(set_attr "type" "lea")
5460 (set_attr "mode" "<MODE>")])
5462 (define_insn "*lea_3_zext"
5463 [(set (match_operand:DI 0 "register_operand" "=r")
5465 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5467 "lea{l}\t{%a1, %k0|%k0, %a1}"
5468 [(set_attr "type" "lea")
5469 (set_attr "mode" "SI")])
5471 (define_insn "*lea_4_zext"
5472 [(set (match_operand:DI 0 "register_operand" "=r")
5474 (match_operand:SI 1 "lea_address_operand" "j")))]
5476 "lea{l}\t{%a1, %k0|%k0, %a1}"
5477 [(set_attr "type" "lea")
5478 (set_attr "mode" "SI")])
5480 (define_insn "*lea_5_zext"
5481 [(set (match_operand:DI 0 "register_operand" "=r")
5483 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5484 (match_operand:DI 2 "const_32bit_mask" "n")))]
5486 "lea{l}\t{%a1, %k0|%k0, %a1}"
5487 [(set_attr "type" "lea")
5488 (set_attr "mode" "SI")])
5490 (define_insn "*lea_6_zext"
5491 [(set (match_operand:DI 0 "register_operand" "=r")
5493 (match_operand:DI 1 "lea_address_operand" "p")
5494 (match_operand:DI 2 "const_32bit_mask" "n")))]
5496 "lea{l}\t{%a1, %k0|%k0, %a1}"
5497 [(set_attr "type" "lea")
5498 (set_attr "mode" "SI")])
5500 (define_insn "*add<mode>_1"
5501 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5503 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5504 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5505 (clobber (reg:CC FLAGS_REG))]
5506 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5508 switch (get_attr_type (insn))
5514 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5515 if (operands[2] == const1_rtx)
5516 return "inc{<imodesuffix>}\t%0";
5519 gcc_assert (operands[2] == constm1_rtx);
5520 return "dec{<imodesuffix>}\t%0";
5524 /* For most processors, ADD is faster than LEA. This alternative
5525 was added to use ADD as much as possible. */
5526 if (which_alternative == 2)
5529 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5532 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5533 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5534 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5536 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5540 (cond [(eq_attr "alternative" "3")
5541 (const_string "lea")
5542 (match_operand:SWI48 2 "incdec_operand" "")
5543 (const_string "incdec")
5545 (const_string "alu")))
5546 (set (attr "length_immediate")
5548 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5550 (const_string "*")))
5551 (set_attr "mode" "<MODE>")])
5553 ;; It may seem that nonimmediate operand is proper one for operand 1.
5554 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5555 ;; we take care in ix86_binary_operator_ok to not allow two memory
5556 ;; operands so proper swapping will be done in reload. This allow
5557 ;; patterns constructed from addsi_1 to match.
5559 (define_insn "addsi_1_zext"
5560 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5562 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5563 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5564 (clobber (reg:CC FLAGS_REG))]
5565 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5567 switch (get_attr_type (insn))
5573 if (operands[2] == const1_rtx)
5574 return "inc{l}\t%k0";
5577 gcc_assert (operands[2] == constm1_rtx);
5578 return "dec{l}\t%k0";
5582 /* For most processors, ADD is faster than LEA. This alternative
5583 was added to use ADD as much as possible. */
5584 if (which_alternative == 1)
5587 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5590 if (x86_maybe_negate_const_int (&operands[2], SImode))
5591 return "sub{l}\t{%2, %k0|%k0, %2}";
5593 return "add{l}\t{%2, %k0|%k0, %2}";
5597 (cond [(eq_attr "alternative" "2")
5598 (const_string "lea")
5599 (match_operand:SI 2 "incdec_operand" "")
5600 (const_string "incdec")
5602 (const_string "alu")))
5603 (set (attr "length_immediate")
5605 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5607 (const_string "*")))
5608 (set_attr "mode" "SI")])
5610 (define_insn "*addhi_1"
5611 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5612 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5613 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5614 (clobber (reg:CC FLAGS_REG))]
5615 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5617 switch (get_attr_type (insn))
5623 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5624 if (operands[2] == const1_rtx)
5625 return "inc{w}\t%0";
5628 gcc_assert (operands[2] == constm1_rtx);
5629 return "dec{w}\t%0";
5633 /* For most processors, ADD is faster than LEA. This alternative
5634 was added to use ADD as much as possible. */
5635 if (which_alternative == 2)
5638 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5641 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5642 if (x86_maybe_negate_const_int (&operands[2], HImode))
5643 return "sub{w}\t{%2, %0|%0, %2}";
5645 return "add{w}\t{%2, %0|%0, %2}";
5649 (cond [(eq_attr "alternative" "3")
5650 (const_string "lea")
5651 (match_operand:HI 2 "incdec_operand" "")
5652 (const_string "incdec")
5654 (const_string "alu")))
5655 (set (attr "length_immediate")
5657 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5659 (const_string "*")))
5660 (set_attr "mode" "HI,HI,HI,SI")])
5662 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5663 (define_insn "*addqi_1"
5664 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5665 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5666 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5667 (clobber (reg:CC FLAGS_REG))]
5668 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5670 bool widen = (which_alternative == 3 || which_alternative == 4);
5672 switch (get_attr_type (insn))
5678 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5679 if (operands[2] == const1_rtx)
5680 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5683 gcc_assert (operands[2] == constm1_rtx);
5684 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5688 /* For most processors, ADD is faster than LEA. These alternatives
5689 were added to use ADD as much as possible. */
5690 if (which_alternative == 2 || which_alternative == 4)
5693 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5696 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5697 if (x86_maybe_negate_const_int (&operands[2], QImode))
5700 return "sub{l}\t{%2, %k0|%k0, %2}";
5702 return "sub{b}\t{%2, %0|%0, %2}";
5705 return "add{l}\t{%k2, %k0|%k0, %k2}";
5707 return "add{b}\t{%2, %0|%0, %2}";
5711 (cond [(eq_attr "alternative" "5")
5712 (const_string "lea")
5713 (match_operand:QI 2 "incdec_operand" "")
5714 (const_string "incdec")
5716 (const_string "alu")))
5717 (set (attr "length_immediate")
5719 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5721 (const_string "*")))
5722 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5724 (define_insn "*addqi_1_slp"
5725 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5726 (plus:QI (match_dup 0)
5727 (match_operand:QI 1 "general_operand" "qn,qm")))
5728 (clobber (reg:CC FLAGS_REG))]
5729 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5730 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5732 switch (get_attr_type (insn))
5735 if (operands[1] == const1_rtx)
5736 return "inc{b}\t%0";
5739 gcc_assert (operands[1] == constm1_rtx);
5740 return "dec{b}\t%0";
5744 if (x86_maybe_negate_const_int (&operands[1], QImode))
5745 return "sub{b}\t{%1, %0|%0, %1}";
5747 return "add{b}\t{%1, %0|%0, %1}";
5751 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5752 (const_string "incdec")
5753 (const_string "alu1")))
5754 (set (attr "memory")
5755 (if_then_else (match_operand 1 "memory_operand" "")
5756 (const_string "load")
5757 (const_string "none")))
5758 (set_attr "mode" "QI")])
5760 ;; Split non destructive adds if we cannot use lea.
5762 [(set (match_operand:SWI48 0 "register_operand" "")
5763 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5764 (match_operand:SWI48 2 "nonmemory_operand" "")))
5765 (clobber (reg:CC FLAGS_REG))]
5766 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5767 [(set (match_dup 0) (match_dup 1))
5768 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5769 (clobber (reg:CC FLAGS_REG))])])
5771 ;; Convert add to the lea pattern to avoid flags dependency.
5773 [(set (match_operand:SWI 0 "register_operand" "")
5774 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5775 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5776 (clobber (reg:CC FLAGS_REG))]
5777 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5780 enum machine_mode mode = <MODE>mode;
5783 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5786 operands[0] = gen_lowpart (mode, operands[0]);
5787 operands[1] = gen_lowpart (mode, operands[1]);
5788 operands[2] = gen_lowpart (mode, operands[2]);
5791 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5793 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5797 ;; Convert add to the lea pattern to avoid flags dependency.
5799 [(set (match_operand:DI 0 "register_operand" "")
5801 (plus:SI (match_operand:SI 1 "register_operand" "")
5802 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5803 (clobber (reg:CC FLAGS_REG))]
5804 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5806 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5808 (define_insn "*add<mode>_2"
5809 [(set (reg FLAGS_REG)
5812 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5813 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5815 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5816 (plus:SWI (match_dup 1) (match_dup 2)))]
5817 "ix86_match_ccmode (insn, CCGOCmode)
5818 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5820 switch (get_attr_type (insn))
5823 if (operands[2] == const1_rtx)
5824 return "inc{<imodesuffix>}\t%0";
5827 gcc_assert (operands[2] == constm1_rtx);
5828 return "dec{<imodesuffix>}\t%0";
5832 if (which_alternative == 2)
5835 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5838 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5839 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5840 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5842 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5846 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5847 (const_string "incdec")
5848 (const_string "alu")))
5849 (set (attr "length_immediate")
5851 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5853 (const_string "*")))
5854 (set_attr "mode" "<MODE>")])
5856 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5857 (define_insn "*addsi_2_zext"
5858 [(set (reg FLAGS_REG)
5860 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5861 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5863 (set (match_operand:DI 0 "register_operand" "=r,r")
5864 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5865 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5866 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5868 switch (get_attr_type (insn))
5871 if (operands[2] == const1_rtx)
5872 return "inc{l}\t%k0";
5875 gcc_assert (operands[2] == constm1_rtx);
5876 return "dec{l}\t%k0";
5880 if (which_alternative == 1)
5883 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5886 if (x86_maybe_negate_const_int (&operands[2], SImode))
5887 return "sub{l}\t{%2, %k0|%k0, %2}";
5889 return "add{l}\t{%2, %k0|%k0, %2}";
5893 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5894 (const_string "incdec")
5895 (const_string "alu")))
5896 (set (attr "length_immediate")
5898 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5900 (const_string "*")))
5901 (set_attr "mode" "SI")])
5903 (define_insn "*add<mode>_3"
5904 [(set (reg FLAGS_REG)
5906 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5907 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5908 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5909 "ix86_match_ccmode (insn, CCZmode)
5910 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5912 switch (get_attr_type (insn))
5915 if (operands[2] == const1_rtx)
5916 return "inc{<imodesuffix>}\t%0";
5919 gcc_assert (operands[2] == constm1_rtx);
5920 return "dec{<imodesuffix>}\t%0";
5924 if (which_alternative == 1)
5927 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5930 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5931 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5932 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5934 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5938 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5939 (const_string "incdec")
5940 (const_string "alu")))
5941 (set (attr "length_immediate")
5943 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5945 (const_string "*")))
5946 (set_attr "mode" "<MODE>")])
5948 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5949 (define_insn "*addsi_3_zext"
5950 [(set (reg FLAGS_REG)
5952 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5953 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5954 (set (match_operand:DI 0 "register_operand" "=r,r")
5955 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5956 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5957 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5959 switch (get_attr_type (insn))
5962 if (operands[2] == const1_rtx)
5963 return "inc{l}\t%k0";
5966 gcc_assert (operands[2] == constm1_rtx);
5967 return "dec{l}\t%k0";
5971 if (which_alternative == 1)
5974 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5977 if (x86_maybe_negate_const_int (&operands[2], SImode))
5978 return "sub{l}\t{%2, %k0|%k0, %2}";
5980 return "add{l}\t{%2, %k0|%k0, %2}";
5984 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5985 (const_string "incdec")
5986 (const_string "alu")))
5987 (set (attr "length_immediate")
5989 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5991 (const_string "*")))
5992 (set_attr "mode" "SI")])
5994 ; For comparisons against 1, -1 and 128, we may generate better code
5995 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5996 ; is matched then. We can't accept general immediate, because for
5997 ; case of overflows, the result is messed up.
5998 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5999 ; only for comparisons not depending on it.
6001 (define_insn "*adddi_4"
6002 [(set (reg FLAGS_REG)
6004 (match_operand:DI 1 "nonimmediate_operand" "0")
6005 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6006 (clobber (match_scratch:DI 0 "=rm"))]
6008 && ix86_match_ccmode (insn, CCGCmode)"
6010 switch (get_attr_type (insn))
6013 if (operands[2] == constm1_rtx)
6014 return "inc{q}\t%0";
6017 gcc_assert (operands[2] == const1_rtx);
6018 return "dec{q}\t%0";
6022 if (x86_maybe_negate_const_int (&operands[2], DImode))
6023 return "add{q}\t{%2, %0|%0, %2}";
6025 return "sub{q}\t{%2, %0|%0, %2}";
6029 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6030 (const_string "incdec")
6031 (const_string "alu")))
6032 (set (attr "length_immediate")
6034 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6036 (const_string "*")))
6037 (set_attr "mode" "DI")])
6039 ; For comparisons against 1, -1 and 128, we may generate better code
6040 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6041 ; is matched then. We can't accept general immediate, because for
6042 ; case of overflows, the result is messed up.
6043 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6044 ; only for comparisons not depending on it.
6046 (define_insn "*add<mode>_4"
6047 [(set (reg FLAGS_REG)
6049 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6050 (match_operand:SWI124 2 "const_int_operand" "n")))
6051 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6052 "ix86_match_ccmode (insn, CCGCmode)"
6054 switch (get_attr_type (insn))
6057 if (operands[2] == constm1_rtx)
6058 return "inc{<imodesuffix>}\t%0";
6061 gcc_assert (operands[2] == const1_rtx);
6062 return "dec{<imodesuffix>}\t%0";
6066 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6067 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6069 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6073 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6074 (const_string "incdec")
6075 (const_string "alu")))
6076 (set (attr "length_immediate")
6078 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6080 (const_string "*")))
6081 (set_attr "mode" "<MODE>")])
6083 (define_insn "*add<mode>_5"
6084 [(set (reg FLAGS_REG)
6087 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6088 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6090 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6091 "ix86_match_ccmode (insn, CCGOCmode)
6092 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6094 switch (get_attr_type (insn))
6097 if (operands[2] == const1_rtx)
6098 return "inc{<imodesuffix>}\t%0";
6101 gcc_assert (operands[2] == constm1_rtx);
6102 return "dec{<imodesuffix>}\t%0";
6106 if (which_alternative == 1)
6109 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6112 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6113 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6114 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6116 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6120 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6121 (const_string "incdec")
6122 (const_string "alu")))
6123 (set (attr "length_immediate")
6125 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6127 (const_string "*")))
6128 (set_attr "mode" "<MODE>")])
6130 (define_insn "*addqi_ext_1_rex64"
6131 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6136 (match_operand 1 "ext_register_operand" "0")
6139 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6140 (clobber (reg:CC FLAGS_REG))]
6143 switch (get_attr_type (insn))
6146 if (operands[2] == const1_rtx)
6147 return "inc{b}\t%h0";
6150 gcc_assert (operands[2] == constm1_rtx);
6151 return "dec{b}\t%h0";
6155 return "add{b}\t{%2, %h0|%h0, %2}";
6159 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6160 (const_string "incdec")
6161 (const_string "alu")))
6162 (set_attr "modrm" "1")
6163 (set_attr "mode" "QI")])
6165 (define_insn "addqi_ext_1"
6166 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6171 (match_operand 1 "ext_register_operand" "0")
6174 (match_operand:QI 2 "general_operand" "Qmn")))
6175 (clobber (reg:CC FLAGS_REG))]
6178 switch (get_attr_type (insn))
6181 if (operands[2] == const1_rtx)
6182 return "inc{b}\t%h0";
6185 gcc_assert (operands[2] == constm1_rtx);
6186 return "dec{b}\t%h0";
6190 return "add{b}\t{%2, %h0|%h0, %2}";
6194 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6195 (const_string "incdec")
6196 (const_string "alu")))
6197 (set_attr "modrm" "1")
6198 (set_attr "mode" "QI")])
6200 (define_insn "*addqi_ext_2"
6201 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6206 (match_operand 1 "ext_register_operand" "%0")
6210 (match_operand 2 "ext_register_operand" "Q")
6213 (clobber (reg:CC FLAGS_REG))]
6215 "add{b}\t{%h2, %h0|%h0, %h2}"
6216 [(set_attr "type" "alu")
6217 (set_attr "mode" "QI")])
6219 ;; The lea patterns for modes less than 32 bits need to be matched by
6220 ;; several insns converted to real lea by splitters.
6222 (define_insn_and_split "*lea_general_1"
6223 [(set (match_operand 0 "register_operand" "=r")
6224 (plus (plus (match_operand 1 "index_register_operand" "l")
6225 (match_operand 2 "register_operand" "r"))
6226 (match_operand 3 "immediate_operand" "i")))]
6227 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6228 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6229 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6230 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6231 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6232 || GET_MODE (operands[3]) == VOIDmode)"
6234 "&& reload_completed"
6237 enum machine_mode mode = SImode;
6240 operands[0] = gen_lowpart (mode, operands[0]);
6241 operands[1] = gen_lowpart (mode, operands[1]);
6242 operands[2] = gen_lowpart (mode, operands[2]);
6243 operands[3] = gen_lowpart (mode, operands[3]);
6245 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6248 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6251 [(set_attr "type" "lea")
6252 (set_attr "mode" "SI")])
6254 (define_insn_and_split "*lea_general_2"
6255 [(set (match_operand 0 "register_operand" "=r")
6256 (plus (mult (match_operand 1 "index_register_operand" "l")
6257 (match_operand 2 "const248_operand" "n"))
6258 (match_operand 3 "nonmemory_operand" "ri")))]
6259 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6260 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6261 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6262 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6263 || GET_MODE (operands[3]) == VOIDmode)"
6265 "&& reload_completed"
6268 enum machine_mode mode = SImode;
6271 operands[0] = gen_lowpart (mode, operands[0]);
6272 operands[1] = gen_lowpart (mode, operands[1]);
6273 operands[3] = gen_lowpart (mode, operands[3]);
6275 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6278 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6281 [(set_attr "type" "lea")
6282 (set_attr "mode" "SI")])
6284 (define_insn_and_split "*lea_general_3"
6285 [(set (match_operand 0 "register_operand" "=r")
6286 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6287 (match_operand 2 "const248_operand" "n"))
6288 (match_operand 3 "register_operand" "r"))
6289 (match_operand 4 "immediate_operand" "i")))]
6290 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6291 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6292 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6293 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6295 "&& reload_completed"
6298 enum machine_mode mode = SImode;
6301 operands[0] = gen_lowpart (mode, operands[0]);
6302 operands[1] = gen_lowpart (mode, operands[1]);
6303 operands[3] = gen_lowpart (mode, operands[3]);
6304 operands[4] = gen_lowpart (mode, operands[4]);
6306 pat = gen_rtx_PLUS (mode,
6308 gen_rtx_MULT (mode, operands[1],
6313 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6316 [(set_attr "type" "lea")
6317 (set_attr "mode" "SI")])
6319 (define_insn_and_split "*lea_general_4"
6320 [(set (match_operand 0 "register_operand" "=r")
6322 (match_operand 1 "index_register_operand" "l")
6323 (match_operand 2 "const_int_operand" "n"))
6324 (match_operand 3 "const_int_operand" "n")))]
6325 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6326 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6327 || GET_MODE (operands[0]) == SImode
6328 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6329 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6330 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6331 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6332 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6334 "&& reload_completed"
6337 enum machine_mode mode = GET_MODE (operands[0]);
6340 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6343 operands[0] = gen_lowpart (mode, operands[0]);
6344 operands[1] = gen_lowpart (mode, operands[1]);
6347 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6349 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6350 INTVAL (operands[3]));
6352 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6355 [(set_attr "type" "lea")
6357 (if_then_else (match_operand:DI 0 "" "")
6359 (const_string "SI")))])
6361 ;; Subtract instructions
6363 (define_expand "sub<mode>3"
6364 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6365 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6366 (match_operand:SDWIM 2 "<general_operand>" "")))]
6368 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6370 (define_insn_and_split "*sub<dwi>3_doubleword"
6371 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6373 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6374 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6375 (clobber (reg:CC FLAGS_REG))]
6376 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6379 [(parallel [(set (reg:CC FLAGS_REG)
6380 (compare:CC (match_dup 1) (match_dup 2)))
6382 (minus:DWIH (match_dup 1) (match_dup 2)))])
6383 (parallel [(set (match_dup 3)
6387 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6389 (clobber (reg:CC FLAGS_REG))])]
6390 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6392 (define_insn "*sub<mode>_1"
6393 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6395 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6396 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6397 (clobber (reg:CC FLAGS_REG))]
6398 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6399 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6400 [(set_attr "type" "alu")
6401 (set_attr "mode" "<MODE>")])
6403 (define_insn "*subsi_1_zext"
6404 [(set (match_operand:DI 0 "register_operand" "=r")
6406 (minus:SI (match_operand:SI 1 "register_operand" "0")
6407 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6408 (clobber (reg:CC FLAGS_REG))]
6409 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6410 "sub{l}\t{%2, %k0|%k0, %2}"
6411 [(set_attr "type" "alu")
6412 (set_attr "mode" "SI")])
6414 (define_insn "*subqi_1_slp"
6415 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6416 (minus:QI (match_dup 0)
6417 (match_operand:QI 1 "general_operand" "qn,qm")))
6418 (clobber (reg:CC FLAGS_REG))]
6419 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6420 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6421 "sub{b}\t{%1, %0|%0, %1}"
6422 [(set_attr "type" "alu1")
6423 (set_attr "mode" "QI")])
6425 (define_insn "*sub<mode>_2"
6426 [(set (reg FLAGS_REG)
6429 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6430 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6432 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6433 (minus:SWI (match_dup 1) (match_dup 2)))]
6434 "ix86_match_ccmode (insn, CCGOCmode)
6435 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6436 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6437 [(set_attr "type" "alu")
6438 (set_attr "mode" "<MODE>")])
6440 (define_insn "*subsi_2_zext"
6441 [(set (reg FLAGS_REG)
6443 (minus:SI (match_operand:SI 1 "register_operand" "0")
6444 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6446 (set (match_operand:DI 0 "register_operand" "=r")
6448 (minus:SI (match_dup 1)
6450 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6451 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6452 "sub{l}\t{%2, %k0|%k0, %2}"
6453 [(set_attr "type" "alu")
6454 (set_attr "mode" "SI")])
6456 (define_insn "*sub<mode>_3"
6457 [(set (reg FLAGS_REG)
6458 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6459 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6460 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6461 (minus:SWI (match_dup 1) (match_dup 2)))]
6462 "ix86_match_ccmode (insn, CCmode)
6463 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6464 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6465 [(set_attr "type" "alu")
6466 (set_attr "mode" "<MODE>")])
6468 (define_insn "*subsi_3_zext"
6469 [(set (reg FLAGS_REG)
6470 (compare (match_operand:SI 1 "register_operand" "0")
6471 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6472 (set (match_operand:DI 0 "register_operand" "=r")
6474 (minus:SI (match_dup 1)
6476 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6477 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6478 "sub{l}\t{%2, %1|%1, %2}"
6479 [(set_attr "type" "alu")
6480 (set_attr "mode" "SI")])
6482 ;; Add with carry and subtract with borrow
6484 (define_expand "<plusminus_insn><mode>3_carry"
6486 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6488 (match_operand:SWI 1 "nonimmediate_operand" "")
6489 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6490 [(match_operand 3 "flags_reg_operand" "")
6492 (match_operand:SWI 2 "<general_operand>" ""))))
6493 (clobber (reg:CC FLAGS_REG))])]
6494 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6496 (define_insn "*<plusminus_insn><mode>3_carry"
6497 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6499 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6501 (match_operator 3 "ix86_carry_flag_operator"
6502 [(reg FLAGS_REG) (const_int 0)])
6503 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6504 (clobber (reg:CC FLAGS_REG))]
6505 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6506 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6507 [(set_attr "type" "alu")
6508 (set_attr "use_carry" "1")
6509 (set_attr "pent_pair" "pu")
6510 (set_attr "mode" "<MODE>")])
6512 (define_insn "*addsi3_carry_zext"
6513 [(set (match_operand:DI 0 "register_operand" "=r")
6515 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6516 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6517 [(reg FLAGS_REG) (const_int 0)])
6518 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6519 (clobber (reg:CC FLAGS_REG))]
6520 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6521 "adc{l}\t{%2, %k0|%k0, %2}"
6522 [(set_attr "type" "alu")
6523 (set_attr "use_carry" "1")
6524 (set_attr "pent_pair" "pu")
6525 (set_attr "mode" "SI")])
6527 (define_insn "*subsi3_carry_zext"
6528 [(set (match_operand:DI 0 "register_operand" "=r")
6530 (minus:SI (match_operand:SI 1 "register_operand" "0")
6531 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6532 [(reg FLAGS_REG) (const_int 0)])
6533 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6534 (clobber (reg:CC FLAGS_REG))]
6535 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6536 "sbb{l}\t{%2, %k0|%k0, %2}"
6537 [(set_attr "type" "alu")
6538 (set_attr "pent_pair" "pu")
6539 (set_attr "mode" "SI")])
6541 ;; Overflow setting add and subtract instructions
6543 (define_insn "*add<mode>3_cconly_overflow"
6544 [(set (reg:CCC FLAGS_REG)
6547 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6548 (match_operand:SWI 2 "<general_operand>" "<g>"))
6550 (clobber (match_scratch:SWI 0 "=<r>"))]
6551 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6552 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6553 [(set_attr "type" "alu")
6554 (set_attr "mode" "<MODE>")])
6556 (define_insn "*sub<mode>3_cconly_overflow"
6557 [(set (reg:CCC FLAGS_REG)
6560 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6561 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6564 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6565 [(set_attr "type" "icmp")
6566 (set_attr "mode" "<MODE>")])
6568 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6569 [(set (reg:CCC FLAGS_REG)
6572 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6573 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6575 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6576 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6577 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6578 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6579 [(set_attr "type" "alu")
6580 (set_attr "mode" "<MODE>")])
6582 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6583 [(set (reg:CCC FLAGS_REG)
6586 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6587 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6589 (set (match_operand:DI 0 "register_operand" "=r")
6590 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6591 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6592 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6593 [(set_attr "type" "alu")
6594 (set_attr "mode" "SI")])
6596 ;; The patterns that match these are at the end of this file.
6598 (define_expand "<plusminus_insn>xf3"
6599 [(set (match_operand:XF 0 "register_operand" "")
6601 (match_operand:XF 1 "register_operand" "")
6602 (match_operand:XF 2 "register_operand" "")))]
6605 (define_expand "<plusminus_insn><mode>3"
6606 [(set (match_operand:MODEF 0 "register_operand" "")
6608 (match_operand:MODEF 1 "register_operand" "")
6609 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6610 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6611 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6613 ;; Multiply instructions
6615 (define_expand "mul<mode>3"
6616 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6618 (match_operand:SWIM248 1 "register_operand" "")
6619 (match_operand:SWIM248 2 "<general_operand>" "")))
6620 (clobber (reg:CC FLAGS_REG))])])
6622 (define_expand "mulqi3"
6623 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6625 (match_operand:QI 1 "register_operand" "")
6626 (match_operand:QI 2 "nonimmediate_operand" "")))
6627 (clobber (reg:CC FLAGS_REG))])]
6628 "TARGET_QIMODE_MATH")
6631 ;; IMUL reg32/64, reg32/64, imm8 Direct
6632 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6633 ;; IMUL reg32/64, reg32/64, imm32 Direct
6634 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6635 ;; IMUL reg32/64, reg32/64 Direct
6636 ;; IMUL reg32/64, mem32/64 Direct
6638 ;; On BDVER1, all above IMULs use DirectPath
6640 (define_insn "*mul<mode>3_1"
6641 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6643 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6644 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6645 (clobber (reg:CC FLAGS_REG))]
6646 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6648 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6649 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6650 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "imul")
6652 (set_attr "prefix_0f" "0,0,1")
6653 (set (attr "athlon_decode")
6654 (cond [(eq_attr "cpu" "athlon")
6655 (const_string "vector")
6656 (eq_attr "alternative" "1")
6657 (const_string "vector")
6658 (and (eq_attr "alternative" "2")
6659 (match_operand 1 "memory_operand" ""))
6660 (const_string "vector")]
6661 (const_string "direct")))
6662 (set (attr "amdfam10_decode")
6663 (cond [(and (eq_attr "alternative" "0,1")
6664 (match_operand 1 "memory_operand" ""))
6665 (const_string "vector")]
6666 (const_string "direct")))
6667 (set_attr "bdver1_decode" "direct")
6668 (set_attr "mode" "<MODE>")])
6670 (define_insn "*mulsi3_1_zext"
6671 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6673 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6674 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6675 (clobber (reg:CC FLAGS_REG))]
6677 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6679 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6680 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6681 imul{l}\t{%2, %k0|%k0, %2}"
6682 [(set_attr "type" "imul")
6683 (set_attr "prefix_0f" "0,0,1")
6684 (set (attr "athlon_decode")
6685 (cond [(eq_attr "cpu" "athlon")
6686 (const_string "vector")
6687 (eq_attr "alternative" "1")
6688 (const_string "vector")
6689 (and (eq_attr "alternative" "2")
6690 (match_operand 1 "memory_operand" ""))
6691 (const_string "vector")]
6692 (const_string "direct")))
6693 (set (attr "amdfam10_decode")
6694 (cond [(and (eq_attr "alternative" "0,1")
6695 (match_operand 1 "memory_operand" ""))
6696 (const_string "vector")]
6697 (const_string "direct")))
6698 (set_attr "bdver1_decode" "direct")
6699 (set_attr "mode" "SI")])
6702 ;; IMUL reg16, reg16, imm8 VectorPath
6703 ;; IMUL reg16, mem16, imm8 VectorPath
6704 ;; IMUL reg16, reg16, imm16 VectorPath
6705 ;; IMUL reg16, mem16, imm16 VectorPath
6706 ;; IMUL reg16, reg16 Direct
6707 ;; IMUL reg16, mem16 Direct
6709 ;; On BDVER1, all HI MULs use DoublePath
6711 (define_insn "*mulhi3_1"
6712 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6713 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6714 (match_operand:HI 2 "general_operand" "K,n,mr")))
6715 (clobber (reg:CC FLAGS_REG))]
6717 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6719 imul{w}\t{%2, %1, %0|%0, %1, %2}
6720 imul{w}\t{%2, %1, %0|%0, %1, %2}
6721 imul{w}\t{%2, %0|%0, %2}"
6722 [(set_attr "type" "imul")
6723 (set_attr "prefix_0f" "0,0,1")
6724 (set (attr "athlon_decode")
6725 (cond [(eq_attr "cpu" "athlon")
6726 (const_string "vector")
6727 (eq_attr "alternative" "1,2")
6728 (const_string "vector")]
6729 (const_string "direct")))
6730 (set (attr "amdfam10_decode")
6731 (cond [(eq_attr "alternative" "0,1")
6732 (const_string "vector")]
6733 (const_string "direct")))
6734 (set_attr "bdver1_decode" "double")
6735 (set_attr "mode" "HI")])
6737 ;;On AMDFAM10 and BDVER1
6741 (define_insn "*mulqi3_1"
6742 [(set (match_operand:QI 0 "register_operand" "=a")
6743 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6744 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6745 (clobber (reg:CC FLAGS_REG))]
6747 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6749 [(set_attr "type" "imul")
6750 (set_attr "length_immediate" "0")
6751 (set (attr "athlon_decode")
6752 (if_then_else (eq_attr "cpu" "athlon")
6753 (const_string "vector")
6754 (const_string "direct")))
6755 (set_attr "amdfam10_decode" "direct")
6756 (set_attr "bdver1_decode" "direct")
6757 (set_attr "mode" "QI")])
6759 (define_expand "<u>mul<mode><dwi>3"
6760 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6763 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6765 (match_operand:DWIH 2 "register_operand" ""))))
6766 (clobber (reg:CC FLAGS_REG))])])
6768 (define_expand "<u>mulqihi3"
6769 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6772 (match_operand:QI 1 "nonimmediate_operand" ""))
6774 (match_operand:QI 2 "register_operand" ""))))
6775 (clobber (reg:CC FLAGS_REG))])]
6776 "TARGET_QIMODE_MATH")
6778 (define_insn "*bmi2_umulditi3_1"
6779 [(set (match_operand:DI 0 "register_operand" "=r")
6781 (match_operand:DI 2 "nonimmediate_operand" "%d")
6782 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6783 (set (match_operand:DI 1 "register_operand" "=r")
6786 (mult:TI (zero_extend:TI (match_dup 2))
6787 (zero_extend:TI (match_dup 3)))
6789 "TARGET_64BIT && TARGET_BMI2
6790 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6791 "mulx\t{%3, %0, %1|%1, %0, %3}"
6792 [(set_attr "type" "imulx")
6793 (set_attr "prefix" "vex")
6794 (set_attr "mode" "DI")])
6796 (define_insn "*bmi2_umulsidi3_1"
6797 [(set (match_operand:SI 0 "register_operand" "=r")
6799 (match_operand:SI 2 "nonimmediate_operand" "%d")
6800 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6801 (set (match_operand:SI 1 "register_operand" "=r")
6804 (mult:DI (zero_extend:DI (match_dup 2))
6805 (zero_extend:DI (match_dup 3)))
6807 "!TARGET_64BIT && TARGET_BMI2
6808 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6809 "mulx\t{%3, %0, %1|%1, %0, %3}"
6810 [(set_attr "type" "imulx")
6811 (set_attr "prefix" "vex")
6812 (set_attr "mode" "SI")])
6814 (define_insn "*umul<mode><dwi>3_1"
6815 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6818 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6820 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6821 (clobber (reg:CC FLAGS_REG))]
6822 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6824 mul{<imodesuffix>}\t%2
6826 [(set_attr "isa" "*,bmi2")
6827 (set_attr "type" "imul,imulx")
6828 (set_attr "length_immediate" "0,*")
6829 (set (attr "athlon_decode")
6830 (cond [(eq_attr "alternative" "0")
6831 (if_then_else (eq_attr "cpu" "athlon")
6832 (const_string "vector")
6833 (const_string "double"))]
6834 (const_string "*")))
6835 (set_attr "amdfam10_decode" "double,*")
6836 (set_attr "bdver1_decode" "direct,*")
6837 (set_attr "prefix" "orig,vex")
6838 (set_attr "mode" "<MODE>")])
6840 ;; Convert mul to the mulx pattern to avoid flags dependency.
6842 [(set (match_operand:<DWI> 0 "register_operand" "")
6845 (match_operand:DWIH 1 "register_operand" ""))
6847 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6848 (clobber (reg:CC FLAGS_REG))]
6849 "TARGET_BMI2 && reload_completed
6850 && true_regnum (operands[1]) == DX_REG"
6851 [(parallel [(set (match_dup 3)
6852 (mult:DWIH (match_dup 1) (match_dup 2)))
6856 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6857 (zero_extend:<DWI> (match_dup 2)))
6860 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6862 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6865 (define_insn "*mul<mode><dwi>3_1"
6866 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6869 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6871 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6872 (clobber (reg:CC FLAGS_REG))]
6873 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6874 "imul{<imodesuffix>}\t%2"
6875 [(set_attr "type" "imul")
6876 (set_attr "length_immediate" "0")
6877 (set (attr "athlon_decode")
6878 (if_then_else (eq_attr "cpu" "athlon")
6879 (const_string "vector")
6880 (const_string "double")))
6881 (set_attr "amdfam10_decode" "double")
6882 (set_attr "bdver1_decode" "direct")
6883 (set_attr "mode" "<MODE>")])
6885 (define_insn "*<u>mulqihi3_1"
6886 [(set (match_operand:HI 0 "register_operand" "=a")
6889 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6891 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6892 (clobber (reg:CC FLAGS_REG))]
6894 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6895 "<sgnprefix>mul{b}\t%2"
6896 [(set_attr "type" "imul")
6897 (set_attr "length_immediate" "0")
6898 (set (attr "athlon_decode")
6899 (if_then_else (eq_attr "cpu" "athlon")
6900 (const_string "vector")
6901 (const_string "direct")))
6902 (set_attr "amdfam10_decode" "direct")
6903 (set_attr "bdver1_decode" "direct")
6904 (set_attr "mode" "QI")])
6906 (define_expand "<s>mul<mode>3_highpart"
6907 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6912 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6914 (match_operand:SWI48 2 "register_operand" "")))
6916 (clobber (match_scratch:SWI48 3 ""))
6917 (clobber (reg:CC FLAGS_REG))])]
6919 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6921 (define_insn "*<s>muldi3_highpart_1"
6922 [(set (match_operand:DI 0 "register_operand" "=d")
6927 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6929 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6931 (clobber (match_scratch:DI 3 "=1"))
6932 (clobber (reg:CC FLAGS_REG))]
6934 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6935 "<sgnprefix>mul{q}\t%2"
6936 [(set_attr "type" "imul")
6937 (set_attr "length_immediate" "0")
6938 (set (attr "athlon_decode")
6939 (if_then_else (eq_attr "cpu" "athlon")
6940 (const_string "vector")
6941 (const_string "double")))
6942 (set_attr "amdfam10_decode" "double")
6943 (set_attr "bdver1_decode" "direct")
6944 (set_attr "mode" "DI")])
6946 (define_insn "*<s>mulsi3_highpart_1"
6947 [(set (match_operand:SI 0 "register_operand" "=d")
6952 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6954 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6956 (clobber (match_scratch:SI 3 "=1"))
6957 (clobber (reg:CC FLAGS_REG))]
6958 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6959 "<sgnprefix>mul{l}\t%2"
6960 [(set_attr "type" "imul")
6961 (set_attr "length_immediate" "0")
6962 (set (attr "athlon_decode")
6963 (if_then_else (eq_attr "cpu" "athlon")
6964 (const_string "vector")
6965 (const_string "double")))
6966 (set_attr "amdfam10_decode" "double")
6967 (set_attr "bdver1_decode" "direct")
6968 (set_attr "mode" "SI")])
6970 (define_insn "*<s>mulsi3_highpart_zext"
6971 [(set (match_operand:DI 0 "register_operand" "=d")
6972 (zero_extend:DI (truncate:SI
6974 (mult:DI (any_extend:DI
6975 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6977 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6979 (clobber (match_scratch:SI 3 "=1"))
6980 (clobber (reg:CC FLAGS_REG))]
6982 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6983 "<sgnprefix>mul{l}\t%2"
6984 [(set_attr "type" "imul")
6985 (set_attr "length_immediate" "0")
6986 (set (attr "athlon_decode")
6987 (if_then_else (eq_attr "cpu" "athlon")
6988 (const_string "vector")
6989 (const_string "double")))
6990 (set_attr "amdfam10_decode" "double")
6991 (set_attr "bdver1_decode" "direct")
6992 (set_attr "mode" "SI")])
6994 ;; The patterns that match these are at the end of this file.
6996 (define_expand "mulxf3"
6997 [(set (match_operand:XF 0 "register_operand" "")
6998 (mult:XF (match_operand:XF 1 "register_operand" "")
6999 (match_operand:XF 2 "register_operand" "")))]
7002 (define_expand "mul<mode>3"
7003 [(set (match_operand:MODEF 0 "register_operand" "")
7004 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7005 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7006 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7007 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7009 ;; Divide instructions
7011 ;; The patterns that match these are at the end of this file.
7013 (define_expand "divxf3"
7014 [(set (match_operand:XF 0 "register_operand" "")
7015 (div:XF (match_operand:XF 1 "register_operand" "")
7016 (match_operand:XF 2 "register_operand" "")))]
7019 (define_expand "divdf3"
7020 [(set (match_operand:DF 0 "register_operand" "")
7021 (div:DF (match_operand:DF 1 "register_operand" "")
7022 (match_operand:DF 2 "nonimmediate_operand" "")))]
7023 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7024 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7026 (define_expand "divsf3"
7027 [(set (match_operand:SF 0 "register_operand" "")
7028 (div:SF (match_operand:SF 1 "register_operand" "")
7029 (match_operand:SF 2 "nonimmediate_operand" "")))]
7030 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7035 && optimize_insn_for_speed_p ()
7036 && flag_finite_math_only && !flag_trapping_math
7037 && flag_unsafe_math_optimizations)
7039 ix86_emit_swdivsf (operands[0], operands[1],
7040 operands[2], SFmode);
7045 ;; Divmod instructions.
7047 (define_expand "divmod<mode>4"
7048 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7050 (match_operand:SWIM248 1 "register_operand" "")
7051 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7052 (set (match_operand:SWIM248 3 "register_operand" "")
7053 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7054 (clobber (reg:CC FLAGS_REG))])])
7056 ;; Split with 8bit unsigned divide:
7057 ;; if (dividend an divisor are in [0-255])
7058 ;; use 8bit unsigned integer divide
7060 ;; use original integer divide
7062 [(set (match_operand:SWI48 0 "register_operand" "")
7063 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7064 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7065 (set (match_operand:SWI48 1 "register_operand" "")
7066 (mod:SWI48 (match_dup 2) (match_dup 3)))
7067 (clobber (reg:CC FLAGS_REG))]
7068 "TARGET_USE_8BIT_IDIV
7069 && TARGET_QIMODE_MATH
7070 && can_create_pseudo_p ()
7071 && !optimize_insn_for_size_p ()"
7073 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7075 (define_insn_and_split "divmod<mode>4_1"
7076 [(set (match_operand:SWI48 0 "register_operand" "=a")
7077 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7078 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7079 (set (match_operand:SWI48 1 "register_operand" "=&d")
7080 (mod:SWI48 (match_dup 2) (match_dup 3)))
7081 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7082 (clobber (reg:CC FLAGS_REG))]
7086 [(parallel [(set (match_dup 1)
7087 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7088 (clobber (reg:CC FLAGS_REG))])
7089 (parallel [(set (match_dup 0)
7090 (div:SWI48 (match_dup 2) (match_dup 3)))
7092 (mod:SWI48 (match_dup 2) (match_dup 3)))
7094 (clobber (reg:CC FLAGS_REG))])]
7096 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7098 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7099 operands[4] = operands[2];
7102 /* Avoid use of cltd in favor of a mov+shift. */
7103 emit_move_insn (operands[1], operands[2]);
7104 operands[4] = operands[1];
7107 [(set_attr "type" "multi")
7108 (set_attr "mode" "<MODE>")])
7110 (define_insn_and_split "*divmod<mode>4"
7111 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7112 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7113 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7114 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7115 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7116 (clobber (reg:CC FLAGS_REG))]
7120 [(parallel [(set (match_dup 1)
7121 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7122 (clobber (reg:CC FLAGS_REG))])
7123 (parallel [(set (match_dup 0)
7124 (div:SWIM248 (match_dup 2) (match_dup 3)))
7126 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7128 (clobber (reg:CC FLAGS_REG))])]
7130 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7132 if (<MODE>mode != HImode
7133 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7134 operands[4] = operands[2];
7137 /* Avoid use of cltd in favor of a mov+shift. */
7138 emit_move_insn (operands[1], operands[2]);
7139 operands[4] = operands[1];
7142 [(set_attr "type" "multi")
7143 (set_attr "mode" "<MODE>")])
7145 (define_insn "*divmod<mode>4_noext"
7146 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7147 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7148 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7149 (set (match_operand:SWIM248 1 "register_operand" "=d")
7150 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7151 (use (match_operand:SWIM248 4 "register_operand" "1"))
7152 (clobber (reg:CC FLAGS_REG))]
7154 "idiv{<imodesuffix>}\t%3"
7155 [(set_attr "type" "idiv")
7156 (set_attr "mode" "<MODE>")])
7158 (define_expand "divmodqi4"
7159 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7161 (match_operand:QI 1 "register_operand" "")
7162 (match_operand:QI 2 "nonimmediate_operand" "")))
7163 (set (match_operand:QI 3 "register_operand" "")
7164 (mod:QI (match_dup 1) (match_dup 2)))
7165 (clobber (reg:CC FLAGS_REG))])]
7166 "TARGET_QIMODE_MATH"
7171 tmp0 = gen_reg_rtx (HImode);
7172 tmp1 = gen_reg_rtx (HImode);
7174 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7176 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7177 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7179 /* Extract remainder from AH. */
7180 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7181 insn = emit_move_insn (operands[3], tmp1);
7183 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7184 set_unique_reg_note (insn, REG_EQUAL, mod);
7186 /* Extract quotient from AL. */
7187 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7189 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7190 set_unique_reg_note (insn, REG_EQUAL, div);
7195 ;; Divide AX by r/m8, with result stored in
7198 ;; Change div/mod to HImode and extend the second argument to HImode
7199 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7200 ;; combine may fail.
7201 (define_insn "divmodhiqi3"
7202 [(set (match_operand:HI 0 "register_operand" "=a")
7207 (mod:HI (match_operand:HI 1 "register_operand" "0")
7209 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7213 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7214 (clobber (reg:CC FLAGS_REG))]
7215 "TARGET_QIMODE_MATH"
7217 [(set_attr "type" "idiv")
7218 (set_attr "mode" "QI")])
7220 (define_expand "udivmod<mode>4"
7221 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7223 (match_operand:SWIM248 1 "register_operand" "")
7224 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7225 (set (match_operand:SWIM248 3 "register_operand" "")
7226 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7227 (clobber (reg:CC FLAGS_REG))])])
7229 ;; Split with 8bit unsigned divide:
7230 ;; if (dividend an divisor are in [0-255])
7231 ;; use 8bit unsigned integer divide
7233 ;; use original integer divide
7235 [(set (match_operand:SWI48 0 "register_operand" "")
7236 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7237 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7238 (set (match_operand:SWI48 1 "register_operand" "")
7239 (umod:SWI48 (match_dup 2) (match_dup 3)))
7240 (clobber (reg:CC FLAGS_REG))]
7241 "TARGET_USE_8BIT_IDIV
7242 && TARGET_QIMODE_MATH
7243 && can_create_pseudo_p ()
7244 && !optimize_insn_for_size_p ()"
7246 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7248 (define_insn_and_split "udivmod<mode>4_1"
7249 [(set (match_operand:SWI48 0 "register_operand" "=a")
7250 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7251 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7252 (set (match_operand:SWI48 1 "register_operand" "=&d")
7253 (umod:SWI48 (match_dup 2) (match_dup 3)))
7254 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7255 (clobber (reg:CC FLAGS_REG))]
7259 [(set (match_dup 1) (const_int 0))
7260 (parallel [(set (match_dup 0)
7261 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7263 (umod:SWI48 (match_dup 2) (match_dup 3)))
7265 (clobber (reg:CC FLAGS_REG))])]
7267 [(set_attr "type" "multi")
7268 (set_attr "mode" "<MODE>")])
7270 (define_insn_and_split "*udivmod<mode>4"
7271 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7272 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7273 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7274 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7275 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7276 (clobber (reg:CC FLAGS_REG))]
7280 [(set (match_dup 1) (const_int 0))
7281 (parallel [(set (match_dup 0)
7282 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7284 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7286 (clobber (reg:CC FLAGS_REG))])]
7288 [(set_attr "type" "multi")
7289 (set_attr "mode" "<MODE>")])
7291 (define_insn "*udivmod<mode>4_noext"
7292 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7293 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7294 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7295 (set (match_operand:SWIM248 1 "register_operand" "=d")
7296 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7297 (use (match_operand:SWIM248 4 "register_operand" "1"))
7298 (clobber (reg:CC FLAGS_REG))]
7300 "div{<imodesuffix>}\t%3"
7301 [(set_attr "type" "idiv")
7302 (set_attr "mode" "<MODE>")])
7304 (define_expand "udivmodqi4"
7305 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7307 (match_operand:QI 1 "register_operand" "")
7308 (match_operand:QI 2 "nonimmediate_operand" "")))
7309 (set (match_operand:QI 3 "register_operand" "")
7310 (umod:QI (match_dup 1) (match_dup 2)))
7311 (clobber (reg:CC FLAGS_REG))])]
7312 "TARGET_QIMODE_MATH"
7317 tmp0 = gen_reg_rtx (HImode);
7318 tmp1 = gen_reg_rtx (HImode);
7320 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7322 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7323 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7325 /* Extract remainder from AH. */
7326 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7327 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7328 insn = emit_move_insn (operands[3], tmp1);
7330 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7331 set_unique_reg_note (insn, REG_EQUAL, mod);
7333 /* Extract quotient from AL. */
7334 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7336 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7337 set_unique_reg_note (insn, REG_EQUAL, div);
7342 (define_insn "udivmodhiqi3"
7343 [(set (match_operand:HI 0 "register_operand" "=a")
7348 (mod:HI (match_operand:HI 1 "register_operand" "0")
7350 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7354 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7355 (clobber (reg:CC FLAGS_REG))]
7356 "TARGET_QIMODE_MATH"
7358 [(set_attr "type" "idiv")
7359 (set_attr "mode" "QI")])
7361 ;; We cannot use div/idiv for double division, because it causes
7362 ;; "division by zero" on the overflow and that's not what we expect
7363 ;; from truncate. Because true (non truncating) double division is
7364 ;; never generated, we can't create this insn anyway.
7367 ; [(set (match_operand:SI 0 "register_operand" "=a")
7369 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7371 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7372 ; (set (match_operand:SI 3 "register_operand" "=d")
7374 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7375 ; (clobber (reg:CC FLAGS_REG))]
7377 ; "div{l}\t{%2, %0|%0, %2}"
7378 ; [(set_attr "type" "idiv")])
7380 ;;- Logical AND instructions
7382 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7383 ;; Note that this excludes ah.
7385 (define_expand "testsi_ccno_1"
7386 [(set (reg:CCNO FLAGS_REG)
7388 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7389 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7392 (define_expand "testqi_ccz_1"
7393 [(set (reg:CCZ FLAGS_REG)
7394 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7395 (match_operand:QI 1 "nonmemory_operand" ""))
7398 (define_expand "testdi_ccno_1"
7399 [(set (reg:CCNO FLAGS_REG)
7401 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7402 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7404 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7406 (define_insn "*testdi_1"
7407 [(set (reg FLAGS_REG)
7410 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7411 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7413 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7414 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7416 test{l}\t{%k1, %k0|%k0, %k1}
7417 test{l}\t{%k1, %k0|%k0, %k1}
7418 test{q}\t{%1, %0|%0, %1}
7419 test{q}\t{%1, %0|%0, %1}
7420 test{q}\t{%1, %0|%0, %1}"
7421 [(set_attr "type" "test")
7422 (set_attr "modrm" "0,1,0,1,1")
7423 (set_attr "mode" "SI,SI,DI,DI,DI")])
7425 (define_insn "*testqi_1_maybe_si"
7426 [(set (reg FLAGS_REG)
7429 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7430 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7432 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7433 && ix86_match_ccmode (insn,
7434 CONST_INT_P (operands[1])
7435 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7437 if (which_alternative == 3)
7439 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7440 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7441 return "test{l}\t{%1, %k0|%k0, %1}";
7443 return "test{b}\t{%1, %0|%0, %1}";
7445 [(set_attr "type" "test")
7446 (set_attr "modrm" "0,1,1,1")
7447 (set_attr "mode" "QI,QI,QI,SI")
7448 (set_attr "pent_pair" "uv,np,uv,np")])
7450 (define_insn "*test<mode>_1"
7451 [(set (reg FLAGS_REG)
7454 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7455 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7457 "ix86_match_ccmode (insn, CCNOmode)
7458 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7459 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7460 [(set_attr "type" "test")
7461 (set_attr "modrm" "0,1,1")
7462 (set_attr "mode" "<MODE>")
7463 (set_attr "pent_pair" "uv,np,uv")])
7465 (define_expand "testqi_ext_ccno_0"
7466 [(set (reg:CCNO FLAGS_REG)
7470 (match_operand 0 "ext_register_operand" "")
7473 (match_operand 1 "const_int_operand" ""))
7476 (define_insn "*testqi_ext_0"
7477 [(set (reg FLAGS_REG)
7481 (match_operand 0 "ext_register_operand" "Q")
7484 (match_operand 1 "const_int_operand" "n"))
7486 "ix86_match_ccmode (insn, CCNOmode)"
7487 "test{b}\t{%1, %h0|%h0, %1}"
7488 [(set_attr "type" "test")
7489 (set_attr "mode" "QI")
7490 (set_attr "length_immediate" "1")
7491 (set_attr "modrm" "1")
7492 (set_attr "pent_pair" "np")])
7494 (define_insn "*testqi_ext_1_rex64"
7495 [(set (reg FLAGS_REG)
7499 (match_operand 0 "ext_register_operand" "Q")
7503 (match_operand:QI 1 "register_operand" "Q")))
7505 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7506 "test{b}\t{%1, %h0|%h0, %1}"
7507 [(set_attr "type" "test")
7508 (set_attr "mode" "QI")])
7510 (define_insn "*testqi_ext_1"
7511 [(set (reg FLAGS_REG)
7515 (match_operand 0 "ext_register_operand" "Q")
7519 (match_operand:QI 1 "general_operand" "Qm")))
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_2"
7527 [(set (reg FLAGS_REG)
7531 (match_operand 0 "ext_register_operand" "Q")
7535 (match_operand 1 "ext_register_operand" "Q")
7539 "ix86_match_ccmode (insn, CCNOmode)"
7540 "test{b}\t{%h1, %h0|%h0, %h1}"
7541 [(set_attr "type" "test")
7542 (set_attr "mode" "QI")])
7544 (define_insn "*testqi_ext_3_rex64"
7545 [(set (reg FLAGS_REG)
7546 (compare (zero_extract:DI
7547 (match_operand 0 "nonimmediate_operand" "rm")
7548 (match_operand:DI 1 "const_int_operand" "")
7549 (match_operand:DI 2 "const_int_operand" ""))
7552 && ix86_match_ccmode (insn, CCNOmode)
7553 && INTVAL (operands[1]) > 0
7554 && INTVAL (operands[2]) >= 0
7555 /* Ensure that resulting mask is zero or sign extended operand. */
7556 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7557 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7558 && INTVAL (operands[1]) > 32))
7559 && (GET_MODE (operands[0]) == SImode
7560 || GET_MODE (operands[0]) == DImode
7561 || GET_MODE (operands[0]) == HImode
7562 || GET_MODE (operands[0]) == QImode)"
7565 ;; Combine likes to form bit extractions for some tests. Humor it.
7566 (define_insn "*testqi_ext_3"
7567 [(set (reg FLAGS_REG)
7568 (compare (zero_extract:SI
7569 (match_operand 0 "nonimmediate_operand" "rm")
7570 (match_operand:SI 1 "const_int_operand" "")
7571 (match_operand:SI 2 "const_int_operand" ""))
7573 "ix86_match_ccmode (insn, CCNOmode)
7574 && INTVAL (operands[1]) > 0
7575 && INTVAL (operands[2]) >= 0
7576 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7577 && (GET_MODE (operands[0]) == SImode
7578 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7579 || GET_MODE (operands[0]) == HImode
7580 || GET_MODE (operands[0]) == QImode)"
7584 [(set (match_operand 0 "flags_reg_operand" "")
7585 (match_operator 1 "compare_operator"
7587 (match_operand 2 "nonimmediate_operand" "")
7588 (match_operand 3 "const_int_operand" "")
7589 (match_operand 4 "const_int_operand" ""))
7591 "ix86_match_ccmode (insn, CCNOmode)"
7592 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7594 rtx val = operands[2];
7595 HOST_WIDE_INT len = INTVAL (operands[3]);
7596 HOST_WIDE_INT pos = INTVAL (operands[4]);
7598 enum machine_mode mode, submode;
7600 mode = GET_MODE (val);
7603 /* ??? Combine likes to put non-volatile mem extractions in QImode
7604 no matter the size of the test. So find a mode that works. */
7605 if (! MEM_VOLATILE_P (val))
7607 mode = smallest_mode_for_size (pos + len, MODE_INT);
7608 val = adjust_address (val, mode, 0);
7611 else if (GET_CODE (val) == SUBREG
7612 && (submode = GET_MODE (SUBREG_REG (val)),
7613 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7614 && pos + len <= GET_MODE_BITSIZE (submode)
7615 && GET_MODE_CLASS (submode) == MODE_INT)
7617 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7619 val = SUBREG_REG (val);
7621 else if (mode == HImode && pos + len <= 8)
7623 /* Small HImode tests can be converted to QImode. */
7625 val = gen_lowpart (QImode, val);
7628 if (len == HOST_BITS_PER_WIDE_INT)
7631 mask = ((HOST_WIDE_INT)1 << len) - 1;
7634 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7637 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7638 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7639 ;; this is relatively important trick.
7640 ;; Do the conversion only post-reload to avoid limiting of the register class
7643 [(set (match_operand 0 "flags_reg_operand" "")
7644 (match_operator 1 "compare_operator"
7645 [(and (match_operand 2 "register_operand" "")
7646 (match_operand 3 "const_int_operand" ""))
7649 && QI_REG_P (operands[2])
7650 && GET_MODE (operands[2]) != QImode
7651 && ((ix86_match_ccmode (insn, CCZmode)
7652 && !(INTVAL (operands[3]) & ~(255 << 8)))
7653 || (ix86_match_ccmode (insn, CCNOmode)
7654 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7657 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7661 operands[2] = gen_lowpart (SImode, operands[2]);
7662 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7666 [(set (match_operand 0 "flags_reg_operand" "")
7667 (match_operator 1 "compare_operator"
7668 [(and (match_operand 2 "nonimmediate_operand" "")
7669 (match_operand 3 "const_int_operand" ""))
7672 && GET_MODE (operands[2]) != QImode
7673 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7674 && ((ix86_match_ccmode (insn, CCZmode)
7675 && !(INTVAL (operands[3]) & ~255))
7676 || (ix86_match_ccmode (insn, CCNOmode)
7677 && !(INTVAL (operands[3]) & ~127)))"
7679 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7682 operands[2] = gen_lowpart (QImode, operands[2]);
7683 operands[3] = gen_lowpart (QImode, operands[3]);
7686 ;; %%% This used to optimize known byte-wide and operations to memory,
7687 ;; and sometimes to QImode registers. If this is considered useful,
7688 ;; it should be done with splitters.
7690 (define_expand "and<mode>3"
7691 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7692 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7693 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7696 if (<MODE>mode == DImode
7697 && GET_CODE (operands[2]) == CONST_INT
7698 && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7699 && REG_P (operands[1]))
7700 emit_insn (gen_zero_extendsidi2 (operands[0],
7701 gen_lowpart (SImode, operands[1])));
7703 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7707 (define_insn "*anddi_1"
7708 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7710 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7711 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7712 (clobber (reg:CC FLAGS_REG))]
7713 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7715 switch (get_attr_type (insn))
7719 enum machine_mode mode;
7721 gcc_assert (CONST_INT_P (operands[2]));
7722 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7724 else if (INTVAL (operands[2]) == 0xffff)
7728 gcc_assert (INTVAL (operands[2]) == 0xff);
7732 operands[1] = gen_lowpart (mode, operands[1]);
7734 return "mov{l}\t{%1, %k0|%k0, %1}";
7735 else if (mode == HImode)
7736 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7738 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7742 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7743 if (get_attr_mode (insn) == MODE_SI)
7744 return "and{l}\t{%k2, %k0|%k0, %k2}";
7746 return "and{q}\t{%2, %0|%0, %2}";
7749 [(set_attr "type" "alu,alu,alu,imovx")
7750 (set_attr "length_immediate" "*,*,*,0")
7751 (set (attr "prefix_rex")
7753 (and (eq_attr "type" "imovx")
7754 (and (match_test "INTVAL (operands[2]) == 0xff")
7755 (match_operand 1 "ext_QIreg_operand" "")))
7757 (const_string "*")))
7758 (set_attr "mode" "SI,DI,DI,SI")])
7760 (define_insn "*andsi_1"
7761 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7762 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7763 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7764 (clobber (reg:CC FLAGS_REG))]
7765 "ix86_binary_operator_ok (AND, SImode, operands)"
7767 switch (get_attr_type (insn))
7771 enum machine_mode mode;
7773 gcc_assert (CONST_INT_P (operands[2]));
7774 if (INTVAL (operands[2]) == 0xffff)
7778 gcc_assert (INTVAL (operands[2]) == 0xff);
7782 operands[1] = gen_lowpart (mode, operands[1]);
7784 return "movz{wl|x}\t{%1, %0|%0, %1}";
7786 return "movz{bl|x}\t{%1, %0|%0, %1}";
7790 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7791 return "and{l}\t{%2, %0|%0, %2}";
7794 [(set_attr "type" "alu,alu,imovx")
7795 (set (attr "prefix_rex")
7797 (and (eq_attr "type" "imovx")
7798 (and (match_test "INTVAL (operands[2]) == 0xff")
7799 (match_operand 1 "ext_QIreg_operand" "")))
7801 (const_string "*")))
7802 (set_attr "length_immediate" "*,*,0")
7803 (set_attr "mode" "SI")])
7805 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7806 (define_insn "*andsi_1_zext"
7807 [(set (match_operand:DI 0 "register_operand" "=r")
7809 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7810 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7811 (clobber (reg:CC FLAGS_REG))]
7812 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7813 "and{l}\t{%2, %k0|%k0, %2}"
7814 [(set_attr "type" "alu")
7815 (set_attr "mode" "SI")])
7817 (define_insn "*andhi_1"
7818 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7819 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7820 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7821 (clobber (reg:CC FLAGS_REG))]
7822 "ix86_binary_operator_ok (AND, HImode, operands)"
7824 switch (get_attr_type (insn))
7827 gcc_assert (CONST_INT_P (operands[2]));
7828 gcc_assert (INTVAL (operands[2]) == 0xff);
7829 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7832 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7834 return "and{w}\t{%2, %0|%0, %2}";
7837 [(set_attr "type" "alu,alu,imovx")
7838 (set_attr "length_immediate" "*,*,0")
7839 (set (attr "prefix_rex")
7841 (and (eq_attr "type" "imovx")
7842 (match_operand 1 "ext_QIreg_operand" ""))
7844 (const_string "*")))
7845 (set_attr "mode" "HI,HI,SI")])
7847 ;; %%% Potential partial reg stall on alternative 2. What to do?
7848 (define_insn "*andqi_1"
7849 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7850 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7851 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7852 (clobber (reg:CC FLAGS_REG))]
7853 "ix86_binary_operator_ok (AND, QImode, operands)"
7855 and{b}\t{%2, %0|%0, %2}
7856 and{b}\t{%2, %0|%0, %2}
7857 and{l}\t{%k2, %k0|%k0, %k2}"
7858 [(set_attr "type" "alu")
7859 (set_attr "mode" "QI,QI,SI")])
7861 (define_insn "*andqi_1_slp"
7862 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7863 (and:QI (match_dup 0)
7864 (match_operand:QI 1 "general_operand" "qn,qmn")))
7865 (clobber (reg:CC FLAGS_REG))]
7866 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7867 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7868 "and{b}\t{%1, %0|%0, %1}"
7869 [(set_attr "type" "alu1")
7870 (set_attr "mode" "QI")])
7873 [(set (match_operand 0 "register_operand" "")
7875 (const_int -65536)))
7876 (clobber (reg:CC FLAGS_REG))]
7877 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7878 || optimize_function_for_size_p (cfun)"
7879 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7880 "operands[1] = gen_lowpart (HImode, operands[0]);")
7883 [(set (match_operand 0 "ext_register_operand" "")
7886 (clobber (reg:CC FLAGS_REG))]
7887 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7888 && reload_completed"
7889 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7890 "operands[1] = gen_lowpart (QImode, operands[0]);")
7893 [(set (match_operand 0 "ext_register_operand" "")
7895 (const_int -65281)))
7896 (clobber (reg:CC FLAGS_REG))]
7897 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7898 && reload_completed"
7899 [(parallel [(set (zero_extract:SI (match_dup 0)
7903 (zero_extract:SI (match_dup 0)
7906 (zero_extract:SI (match_dup 0)
7909 (clobber (reg:CC FLAGS_REG))])]
7910 "operands[0] = gen_lowpart (SImode, operands[0]);")
7912 (define_insn "*anddi_2"
7913 [(set (reg FLAGS_REG)
7916 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7917 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7919 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7920 (and:DI (match_dup 1) (match_dup 2)))]
7921 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7922 && ix86_binary_operator_ok (AND, DImode, operands)"
7924 and{l}\t{%k2, %k0|%k0, %k2}
7925 and{q}\t{%2, %0|%0, %2}
7926 and{q}\t{%2, %0|%0, %2}"
7927 [(set_attr "type" "alu")
7928 (set_attr "mode" "SI,DI,DI")])
7930 (define_insn "*andqi_2_maybe_si"
7931 [(set (reg FLAGS_REG)
7933 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7934 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7936 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7937 (and:QI (match_dup 1) (match_dup 2)))]
7938 "ix86_binary_operator_ok (AND, QImode, operands)
7939 && ix86_match_ccmode (insn,
7940 CONST_INT_P (operands[2])
7941 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7943 if (which_alternative == 2)
7945 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7946 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7947 return "and{l}\t{%2, %k0|%k0, %2}";
7949 return "and{b}\t{%2, %0|%0, %2}";
7951 [(set_attr "type" "alu")
7952 (set_attr "mode" "QI,QI,SI")])
7954 (define_insn "*and<mode>_2"
7955 [(set (reg FLAGS_REG)
7956 (compare (and:SWI124
7957 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7958 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7960 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7961 (and:SWI124 (match_dup 1) (match_dup 2)))]
7962 "ix86_match_ccmode (insn, CCNOmode)
7963 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7964 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7965 [(set_attr "type" "alu")
7966 (set_attr "mode" "<MODE>")])
7968 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7969 (define_insn "*andsi_2_zext"
7970 [(set (reg FLAGS_REG)
7972 (match_operand:SI 1 "nonimmediate_operand" "%0")
7973 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7975 (set (match_operand:DI 0 "register_operand" "=r")
7976 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7977 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7978 && ix86_binary_operator_ok (AND, SImode, operands)"
7979 "and{l}\t{%2, %k0|%k0, %2}"
7980 [(set_attr "type" "alu")
7981 (set_attr "mode" "SI")])
7983 (define_insn "*andqi_2_slp"
7984 [(set (reg FLAGS_REG)
7986 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7987 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7989 (set (strict_low_part (match_dup 0))
7990 (and:QI (match_dup 0) (match_dup 1)))]
7991 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7992 && ix86_match_ccmode (insn, CCNOmode)
7993 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7994 "and{b}\t{%1, %0|%0, %1}"
7995 [(set_attr "type" "alu1")
7996 (set_attr "mode" "QI")])
7998 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7999 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8000 ;; for a QImode operand, which of course failed.
8001 (define_insn "andqi_ext_0"
8002 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8007 (match_operand 1 "ext_register_operand" "0")
8010 (match_operand 2 "const_int_operand" "n")))
8011 (clobber (reg:CC FLAGS_REG))]
8013 "and{b}\t{%2, %h0|%h0, %2}"
8014 [(set_attr "type" "alu")
8015 (set_attr "length_immediate" "1")
8016 (set_attr "modrm" "1")
8017 (set_attr "mode" "QI")])
8019 ;; Generated by peephole translating test to and. This shows up
8020 ;; often in fp comparisons.
8021 (define_insn "*andqi_ext_0_cc"
8022 [(set (reg FLAGS_REG)
8026 (match_operand 1 "ext_register_operand" "0")
8029 (match_operand 2 "const_int_operand" "n"))
8031 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8040 "ix86_match_ccmode (insn, CCNOmode)"
8041 "and{b}\t{%2, %h0|%h0, %2}"
8042 [(set_attr "type" "alu")
8043 (set_attr "length_immediate" "1")
8044 (set_attr "modrm" "1")
8045 (set_attr "mode" "QI")])
8047 (define_insn "*andqi_ext_1_rex64"
8048 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8053 (match_operand 1 "ext_register_operand" "0")
8057 (match_operand 2 "ext_register_operand" "Q"))))
8058 (clobber (reg:CC FLAGS_REG))]
8060 "and{b}\t{%2, %h0|%h0, %2}"
8061 [(set_attr "type" "alu")
8062 (set_attr "length_immediate" "0")
8063 (set_attr "mode" "QI")])
8065 (define_insn "*andqi_ext_1"
8066 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8071 (match_operand 1 "ext_register_operand" "0")
8075 (match_operand:QI 2 "general_operand" "Qm"))))
8076 (clobber (reg:CC FLAGS_REG))]
8078 "and{b}\t{%2, %h0|%h0, %2}"
8079 [(set_attr "type" "alu")
8080 (set_attr "length_immediate" "0")
8081 (set_attr "mode" "QI")])
8083 (define_insn "*andqi_ext_2"
8084 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8089 (match_operand 1 "ext_register_operand" "%0")
8093 (match_operand 2 "ext_register_operand" "Q")
8096 (clobber (reg:CC FLAGS_REG))]
8098 "and{b}\t{%h2, %h0|%h0, %h2}"
8099 [(set_attr "type" "alu")
8100 (set_attr "length_immediate" "0")
8101 (set_attr "mode" "QI")])
8103 ;; Convert wide AND instructions with immediate operand to shorter QImode
8104 ;; equivalents when possible.
8105 ;; Don't do the splitting with memory operands, since it introduces risk
8106 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8107 ;; for size, but that can (should?) be handled by generic code instead.
8109 [(set (match_operand 0 "register_operand" "")
8110 (and (match_operand 1 "register_operand" "")
8111 (match_operand 2 "const_int_operand" "")))
8112 (clobber (reg:CC FLAGS_REG))]
8114 && QI_REG_P (operands[0])
8115 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8116 && !(~INTVAL (operands[2]) & ~(255 << 8))
8117 && GET_MODE (operands[0]) != QImode"
8118 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8119 (and:SI (zero_extract:SI (match_dup 1)
8120 (const_int 8) (const_int 8))
8122 (clobber (reg:CC FLAGS_REG))])]
8124 operands[0] = gen_lowpart (SImode, operands[0]);
8125 operands[1] = gen_lowpart (SImode, operands[1]);
8126 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8129 ;; Since AND can be encoded with sign extended immediate, this is only
8130 ;; profitable when 7th bit is not set.
8132 [(set (match_operand 0 "register_operand" "")
8133 (and (match_operand 1 "general_operand" "")
8134 (match_operand 2 "const_int_operand" "")))
8135 (clobber (reg:CC FLAGS_REG))]
8137 && ANY_QI_REG_P (operands[0])
8138 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8139 && !(~INTVAL (operands[2]) & ~255)
8140 && !(INTVAL (operands[2]) & 128)
8141 && GET_MODE (operands[0]) != QImode"
8142 [(parallel [(set (strict_low_part (match_dup 0))
8143 (and:QI (match_dup 1)
8145 (clobber (reg:CC FLAGS_REG))])]
8147 operands[0] = gen_lowpart (QImode, operands[0]);
8148 operands[1] = gen_lowpart (QImode, operands[1]);
8149 operands[2] = gen_lowpart (QImode, operands[2]);
8152 ;; Logical inclusive and exclusive OR instructions
8154 ;; %%% This used to optimize known byte-wide and operations to memory.
8155 ;; If this is considered useful, it should be done with splitters.
8157 (define_expand "<code><mode>3"
8158 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8159 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8160 (match_operand:SWIM 2 "<general_operand>" "")))]
8162 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8164 (define_insn "*<code><mode>_1"
8165 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8167 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8168 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8169 (clobber (reg:CC FLAGS_REG))]
8170 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8171 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8172 [(set_attr "type" "alu")
8173 (set_attr "mode" "<MODE>")])
8175 ;; %%% Potential partial reg stall on alternative 2. What to do?
8176 (define_insn "*<code>qi_1"
8177 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8178 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8179 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8180 (clobber (reg:CC FLAGS_REG))]
8181 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8183 <logic>{b}\t{%2, %0|%0, %2}
8184 <logic>{b}\t{%2, %0|%0, %2}
8185 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8186 [(set_attr "type" "alu")
8187 (set_attr "mode" "QI,QI,SI")])
8189 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8190 (define_insn "*<code>si_1_zext"
8191 [(set (match_operand:DI 0 "register_operand" "=r")
8193 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8194 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8195 (clobber (reg:CC FLAGS_REG))]
8196 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8197 "<logic>{l}\t{%2, %k0|%k0, %2}"
8198 [(set_attr "type" "alu")
8199 (set_attr "mode" "SI")])
8201 (define_insn "*<code>si_1_zext_imm"
8202 [(set (match_operand:DI 0 "register_operand" "=r")
8204 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8205 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8206 (clobber (reg:CC FLAGS_REG))]
8207 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8208 "<logic>{l}\t{%2, %k0|%k0, %2}"
8209 [(set_attr "type" "alu")
8210 (set_attr "mode" "SI")])
8212 (define_insn "*<code>qi_1_slp"
8213 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8214 (any_or:QI (match_dup 0)
8215 (match_operand:QI 1 "general_operand" "qmn,qn")))
8216 (clobber (reg:CC FLAGS_REG))]
8217 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8218 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8219 "<logic>{b}\t{%1, %0|%0, %1}"
8220 [(set_attr "type" "alu1")
8221 (set_attr "mode" "QI")])
8223 (define_insn "*<code><mode>_2"
8224 [(set (reg FLAGS_REG)
8225 (compare (any_or:SWI
8226 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8227 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8229 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8230 (any_or:SWI (match_dup 1) (match_dup 2)))]
8231 "ix86_match_ccmode (insn, CCNOmode)
8232 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8233 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8234 [(set_attr "type" "alu")
8235 (set_attr "mode" "<MODE>")])
8237 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8238 ;; ??? Special case for immediate operand is missing - it is tricky.
8239 (define_insn "*<code>si_2_zext"
8240 [(set (reg FLAGS_REG)
8241 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8242 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8244 (set (match_operand:DI 0 "register_operand" "=r")
8245 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8246 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8247 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8248 "<logic>{l}\t{%2, %k0|%k0, %2}"
8249 [(set_attr "type" "alu")
8250 (set_attr "mode" "SI")])
8252 (define_insn "*<code>si_2_zext_imm"
8253 [(set (reg FLAGS_REG)
8255 (match_operand:SI 1 "nonimmediate_operand" "%0")
8256 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8258 (set (match_operand:DI 0 "register_operand" "=r")
8259 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8260 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8261 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8262 "<logic>{l}\t{%2, %k0|%k0, %2}"
8263 [(set_attr "type" "alu")
8264 (set_attr "mode" "SI")])
8266 (define_insn "*<code>qi_2_slp"
8267 [(set (reg FLAGS_REG)
8268 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8269 (match_operand:QI 1 "general_operand" "qmn,qn"))
8271 (set (strict_low_part (match_dup 0))
8272 (any_or:QI (match_dup 0) (match_dup 1)))]
8273 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8274 && ix86_match_ccmode (insn, CCNOmode)
8275 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8276 "<logic>{b}\t{%1, %0|%0, %1}"
8277 [(set_attr "type" "alu1")
8278 (set_attr "mode" "QI")])
8280 (define_insn "*<code><mode>_3"
8281 [(set (reg FLAGS_REG)
8282 (compare (any_or:SWI
8283 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8284 (match_operand:SWI 2 "<general_operand>" "<g>"))
8286 (clobber (match_scratch:SWI 0 "=<r>"))]
8287 "ix86_match_ccmode (insn, CCNOmode)
8288 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8289 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8290 [(set_attr "type" "alu")
8291 (set_attr "mode" "<MODE>")])
8293 (define_insn "*<code>qi_ext_0"
8294 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8299 (match_operand 1 "ext_register_operand" "0")
8302 (match_operand 2 "const_int_operand" "n")))
8303 (clobber (reg:CC FLAGS_REG))]
8304 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8305 "<logic>{b}\t{%2, %h0|%h0, %2}"
8306 [(set_attr "type" "alu")
8307 (set_attr "length_immediate" "1")
8308 (set_attr "modrm" "1")
8309 (set_attr "mode" "QI")])
8311 (define_insn "*<code>qi_ext_1_rex64"
8312 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8317 (match_operand 1 "ext_register_operand" "0")
8321 (match_operand 2 "ext_register_operand" "Q"))))
8322 (clobber (reg:CC FLAGS_REG))]
8324 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8325 "<logic>{b}\t{%2, %h0|%h0, %2}"
8326 [(set_attr "type" "alu")
8327 (set_attr "length_immediate" "0")
8328 (set_attr "mode" "QI")])
8330 (define_insn "*<code>qi_ext_1"
8331 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8336 (match_operand 1 "ext_register_operand" "0")
8340 (match_operand:QI 2 "general_operand" "Qm"))))
8341 (clobber (reg:CC FLAGS_REG))]
8343 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8344 "<logic>{b}\t{%2, %h0|%h0, %2}"
8345 [(set_attr "type" "alu")
8346 (set_attr "length_immediate" "0")
8347 (set_attr "mode" "QI")])
8349 (define_insn "*<code>qi_ext_2"
8350 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8354 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8357 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8360 (clobber (reg:CC FLAGS_REG))]
8361 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8362 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8363 [(set_attr "type" "alu")
8364 (set_attr "length_immediate" "0")
8365 (set_attr "mode" "QI")])
8368 [(set (match_operand 0 "register_operand" "")
8369 (any_or (match_operand 1 "register_operand" "")
8370 (match_operand 2 "const_int_operand" "")))
8371 (clobber (reg:CC FLAGS_REG))]
8373 && QI_REG_P (operands[0])
8374 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8375 && !(INTVAL (operands[2]) & ~(255 << 8))
8376 && GET_MODE (operands[0]) != QImode"
8377 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8378 (any_or:SI (zero_extract:SI (match_dup 1)
8379 (const_int 8) (const_int 8))
8381 (clobber (reg:CC FLAGS_REG))])]
8383 operands[0] = gen_lowpart (SImode, operands[0]);
8384 operands[1] = gen_lowpart (SImode, operands[1]);
8385 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8388 ;; Since OR can be encoded with sign extended immediate, this is only
8389 ;; profitable when 7th bit is set.
8391 [(set (match_operand 0 "register_operand" "")
8392 (any_or (match_operand 1 "general_operand" "")
8393 (match_operand 2 "const_int_operand" "")))
8394 (clobber (reg:CC FLAGS_REG))]
8396 && ANY_QI_REG_P (operands[0])
8397 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8398 && !(INTVAL (operands[2]) & ~255)
8399 && (INTVAL (operands[2]) & 128)
8400 && GET_MODE (operands[0]) != QImode"
8401 [(parallel [(set (strict_low_part (match_dup 0))
8402 (any_or:QI (match_dup 1)
8404 (clobber (reg:CC FLAGS_REG))])]
8406 operands[0] = gen_lowpart (QImode, operands[0]);
8407 operands[1] = gen_lowpart (QImode, operands[1]);
8408 operands[2] = gen_lowpart (QImode, operands[2]);
8411 (define_expand "xorqi_cc_ext_1"
8413 (set (reg:CCNO FLAGS_REG)
8417 (match_operand 1 "ext_register_operand" "")
8420 (match_operand:QI 2 "general_operand" ""))
8422 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8432 (define_insn "*xorqi_cc_ext_1_rex64"
8433 [(set (reg FLAGS_REG)
8437 (match_operand 1 "ext_register_operand" "0")
8440 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8442 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8451 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8452 "xor{b}\t{%2, %h0|%h0, %2}"
8453 [(set_attr "type" "alu")
8454 (set_attr "modrm" "1")
8455 (set_attr "mode" "QI")])
8457 (define_insn "*xorqi_cc_ext_1"
8458 [(set (reg FLAGS_REG)
8462 (match_operand 1 "ext_register_operand" "0")
8465 (match_operand:QI 2 "general_operand" "qmn"))
8467 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8476 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8477 "xor{b}\t{%2, %h0|%h0, %2}"
8478 [(set_attr "type" "alu")
8479 (set_attr "modrm" "1")
8480 (set_attr "mode" "QI")])
8482 ;; Negation instructions
8484 (define_expand "neg<mode>2"
8485 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8486 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8488 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8490 (define_insn_and_split "*neg<dwi>2_doubleword"
8491 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8492 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8493 (clobber (reg:CC FLAGS_REG))]
8494 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8498 [(set (reg:CCZ FLAGS_REG)
8499 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8500 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8503 (plus:DWIH (match_dup 3)
8504 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8506 (clobber (reg:CC FLAGS_REG))])
8509 (neg:DWIH (match_dup 2)))
8510 (clobber (reg:CC FLAGS_REG))])]
8511 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8513 (define_insn "*neg<mode>2_1"
8514 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8515 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8516 (clobber (reg:CC FLAGS_REG))]
8517 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8518 "neg{<imodesuffix>}\t%0"
8519 [(set_attr "type" "negnot")
8520 (set_attr "mode" "<MODE>")])
8522 ;; Combine is quite creative about this pattern.
8523 (define_insn "*negsi2_1_zext"
8524 [(set (match_operand:DI 0 "register_operand" "=r")
8526 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8529 (clobber (reg:CC FLAGS_REG))]
8530 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8532 [(set_attr "type" "negnot")
8533 (set_attr "mode" "SI")])
8535 ;; The problem with neg is that it does not perform (compare x 0),
8536 ;; it really performs (compare 0 x), which leaves us with the zero
8537 ;; flag being the only useful item.
8539 (define_insn "*neg<mode>2_cmpz"
8540 [(set (reg:CCZ FLAGS_REG)
8542 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8544 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8545 (neg:SWI (match_dup 1)))]
8546 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8547 "neg{<imodesuffix>}\t%0"
8548 [(set_attr "type" "negnot")
8549 (set_attr "mode" "<MODE>")])
8551 (define_insn "*negsi2_cmpz_zext"
8552 [(set (reg:CCZ FLAGS_REG)
8556 (match_operand:DI 1 "register_operand" "0")
8560 (set (match_operand:DI 0 "register_operand" "=r")
8561 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8564 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8566 [(set_attr "type" "negnot")
8567 (set_attr "mode" "SI")])
8569 ;; Changing of sign for FP values is doable using integer unit too.
8571 (define_expand "<code><mode>2"
8572 [(set (match_operand:X87MODEF 0 "register_operand" "")
8573 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8574 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8575 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8577 (define_insn "*absneg<mode>2_mixed"
8578 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8579 (match_operator:MODEF 3 "absneg_operator"
8580 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8581 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8582 (clobber (reg:CC FLAGS_REG))]
8583 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8586 (define_insn "*absneg<mode>2_sse"
8587 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8588 (match_operator:MODEF 3 "absneg_operator"
8589 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8590 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8591 (clobber (reg:CC FLAGS_REG))]
8592 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8595 (define_insn "*absneg<mode>2_i387"
8596 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8597 (match_operator:X87MODEF 3 "absneg_operator"
8598 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8599 (use (match_operand 2 "" ""))
8600 (clobber (reg:CC FLAGS_REG))]
8601 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8604 (define_expand "<code>tf2"
8605 [(set (match_operand:TF 0 "register_operand" "")
8606 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8608 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8610 (define_insn "*absnegtf2_sse"
8611 [(set (match_operand:TF 0 "register_operand" "=x,x")
8612 (match_operator:TF 3 "absneg_operator"
8613 [(match_operand:TF 1 "register_operand" "0,x")]))
8614 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8615 (clobber (reg:CC FLAGS_REG))]
8619 ;; Splitters for fp abs and neg.
8622 [(set (match_operand 0 "fp_register_operand" "")
8623 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8624 (use (match_operand 2 "" ""))
8625 (clobber (reg:CC FLAGS_REG))]
8627 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8630 [(set (match_operand 0 "register_operand" "")
8631 (match_operator 3 "absneg_operator"
8632 [(match_operand 1 "register_operand" "")]))
8633 (use (match_operand 2 "nonimmediate_operand" ""))
8634 (clobber (reg:CC FLAGS_REG))]
8635 "reload_completed && SSE_REG_P (operands[0])"
8636 [(set (match_dup 0) (match_dup 3))]
8638 enum machine_mode mode = GET_MODE (operands[0]);
8639 enum machine_mode vmode = GET_MODE (operands[2]);
8642 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8643 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8644 if (operands_match_p (operands[0], operands[2]))
8647 operands[1] = operands[2];
8650 if (GET_CODE (operands[3]) == ABS)
8651 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8653 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8658 [(set (match_operand:SF 0 "register_operand" "")
8659 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8660 (use (match_operand:V4SF 2 "" ""))
8661 (clobber (reg:CC FLAGS_REG))]
8663 [(parallel [(set (match_dup 0) (match_dup 1))
8664 (clobber (reg:CC FLAGS_REG))])]
8667 operands[0] = gen_lowpart (SImode, operands[0]);
8668 if (GET_CODE (operands[1]) == ABS)
8670 tmp = gen_int_mode (0x7fffffff, SImode);
8671 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8675 tmp = gen_int_mode (0x80000000, SImode);
8676 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8682 [(set (match_operand:DF 0 "register_operand" "")
8683 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8684 (use (match_operand 2 "" ""))
8685 (clobber (reg:CC FLAGS_REG))]
8687 [(parallel [(set (match_dup 0) (match_dup 1))
8688 (clobber (reg:CC FLAGS_REG))])]
8693 tmp = gen_lowpart (DImode, operands[0]);
8694 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8697 if (GET_CODE (operands[1]) == ABS)
8700 tmp = gen_rtx_NOT (DImode, tmp);
8704 operands[0] = gen_highpart (SImode, operands[0]);
8705 if (GET_CODE (operands[1]) == ABS)
8707 tmp = gen_int_mode (0x7fffffff, SImode);
8708 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8712 tmp = gen_int_mode (0x80000000, SImode);
8713 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8720 [(set (match_operand:XF 0 "register_operand" "")
8721 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8722 (use (match_operand 2 "" ""))
8723 (clobber (reg:CC FLAGS_REG))]
8725 [(parallel [(set (match_dup 0) (match_dup 1))
8726 (clobber (reg:CC FLAGS_REG))])]
8729 operands[0] = gen_rtx_REG (SImode,
8730 true_regnum (operands[0])
8731 + (TARGET_64BIT ? 1 : 2));
8732 if (GET_CODE (operands[1]) == ABS)
8734 tmp = GEN_INT (0x7fff);
8735 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8739 tmp = GEN_INT (0x8000);
8740 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8745 ;; Conditionalize these after reload. If they match before reload, we
8746 ;; lose the clobber and ability to use integer instructions.
8748 (define_insn "*<code><mode>2_1"
8749 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8750 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8752 && (reload_completed
8753 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8754 "f<absneg_mnemonic>"
8755 [(set_attr "type" "fsgn")
8756 (set_attr "mode" "<MODE>")])
8758 (define_insn "*<code>extendsfdf2"
8759 [(set (match_operand:DF 0 "register_operand" "=f")
8760 (absneg:DF (float_extend:DF
8761 (match_operand:SF 1 "register_operand" "0"))))]
8762 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8763 "f<absneg_mnemonic>"
8764 [(set_attr "type" "fsgn")
8765 (set_attr "mode" "DF")])
8767 (define_insn "*<code>extendsfxf2"
8768 [(set (match_operand:XF 0 "register_operand" "=f")
8769 (absneg:XF (float_extend:XF
8770 (match_operand:SF 1 "register_operand" "0"))))]
8772 "f<absneg_mnemonic>"
8773 [(set_attr "type" "fsgn")
8774 (set_attr "mode" "XF")])
8776 (define_insn "*<code>extenddfxf2"
8777 [(set (match_operand:XF 0 "register_operand" "=f")
8778 (absneg:XF (float_extend:XF
8779 (match_operand:DF 1 "register_operand" "0"))))]
8781 "f<absneg_mnemonic>"
8782 [(set_attr "type" "fsgn")
8783 (set_attr "mode" "XF")])
8785 ;; Copysign instructions
8787 (define_mode_iterator CSGNMODE [SF DF TF])
8788 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8790 (define_expand "copysign<mode>3"
8791 [(match_operand:CSGNMODE 0 "register_operand" "")
8792 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8793 (match_operand:CSGNMODE 2 "register_operand" "")]
8794 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8795 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8796 "ix86_expand_copysign (operands); DONE;")
8798 (define_insn_and_split "copysign<mode>3_const"
8799 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8801 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8802 (match_operand:CSGNMODE 2 "register_operand" "0")
8803 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8805 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8806 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8808 "&& reload_completed"
8810 "ix86_split_copysign_const (operands); DONE;")
8812 (define_insn "copysign<mode>3_var"
8813 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8815 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8816 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8817 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8818 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8820 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8821 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8822 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8826 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8828 [(match_operand:CSGNMODE 2 "register_operand" "")
8829 (match_operand:CSGNMODE 3 "register_operand" "")
8830 (match_operand:<CSGNVMODE> 4 "" "")
8831 (match_operand:<CSGNVMODE> 5 "" "")]
8833 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8834 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8835 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8836 && reload_completed"
8838 "ix86_split_copysign_var (operands); DONE;")
8840 ;; One complement instructions
8842 (define_expand "one_cmpl<mode>2"
8843 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8844 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8846 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8848 (define_insn "*one_cmpl<mode>2_1"
8849 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8850 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8851 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8852 "not{<imodesuffix>}\t%0"
8853 [(set_attr "type" "negnot")
8854 (set_attr "mode" "<MODE>")])
8856 ;; %%% Potential partial reg stall on alternative 1. What to do?
8857 (define_insn "*one_cmplqi2_1"
8858 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8859 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8860 "ix86_unary_operator_ok (NOT, QImode, operands)"
8864 [(set_attr "type" "negnot")
8865 (set_attr "mode" "QI,SI")])
8867 ;; ??? Currently never generated - xor is used instead.
8868 (define_insn "*one_cmplsi2_1_zext"
8869 [(set (match_operand:DI 0 "register_operand" "=r")
8871 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8872 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8874 [(set_attr "type" "negnot")
8875 (set_attr "mode" "SI")])
8877 (define_insn "*one_cmpl<mode>2_2"
8878 [(set (reg FLAGS_REG)
8879 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8881 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8882 (not:SWI (match_dup 1)))]
8883 "ix86_match_ccmode (insn, CCNOmode)
8884 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8886 [(set_attr "type" "alu1")
8887 (set_attr "mode" "<MODE>")])
8890 [(set (match_operand 0 "flags_reg_operand" "")
8891 (match_operator 2 "compare_operator"
8892 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8894 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8895 (not:SWI (match_dup 3)))]
8896 "ix86_match_ccmode (insn, CCNOmode)"
8897 [(parallel [(set (match_dup 0)
8898 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8901 (xor:SWI (match_dup 3) (const_int -1)))])])
8903 ;; ??? Currently never generated - xor is used instead.
8904 (define_insn "*one_cmplsi2_2_zext"
8905 [(set (reg FLAGS_REG)
8906 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8908 (set (match_operand:DI 0 "register_operand" "=r")
8909 (zero_extend:DI (not:SI (match_dup 1))))]
8910 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8911 && ix86_unary_operator_ok (NOT, SImode, operands)"
8913 [(set_attr "type" "alu1")
8914 (set_attr "mode" "SI")])
8917 [(set (match_operand 0 "flags_reg_operand" "")
8918 (match_operator 2 "compare_operator"
8919 [(not:SI (match_operand:SI 3 "register_operand" ""))
8921 (set (match_operand:DI 1 "register_operand" "")
8922 (zero_extend:DI (not:SI (match_dup 3))))]
8923 "ix86_match_ccmode (insn, CCNOmode)"
8924 [(parallel [(set (match_dup 0)
8925 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8928 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8930 ;; Shift instructions
8932 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8933 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8934 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8935 ;; from the assembler input.
8937 ;; This instruction shifts the target reg/mem as usual, but instead of
8938 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8939 ;; is a left shift double, bits are taken from the high order bits of
8940 ;; reg, else if the insn is a shift right double, bits are taken from the
8941 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8942 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8944 ;; Since sh[lr]d does not change the `reg' operand, that is done
8945 ;; separately, making all shifts emit pairs of shift double and normal
8946 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8947 ;; support a 63 bit shift, each shift where the count is in a reg expands
8948 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8950 ;; If the shift count is a constant, we need never emit more than one
8951 ;; shift pair, instead using moves and sign extension for counts greater
8954 (define_expand "ashl<mode>3"
8955 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8956 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8957 (match_operand:QI 2 "nonmemory_operand" "")))]
8959 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8961 (define_insn "*ashl<mode>3_doubleword"
8962 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8963 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8964 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8965 (clobber (reg:CC FLAGS_REG))]
8968 [(set_attr "type" "multi")])
8971 [(set (match_operand:DWI 0 "register_operand" "")
8972 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8973 (match_operand:QI 2 "nonmemory_operand" "")))
8974 (clobber (reg:CC FLAGS_REG))]
8975 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8977 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8979 ;; By default we don't ask for a scratch register, because when DWImode
8980 ;; values are manipulated, registers are already at a premium. But if
8981 ;; we have one handy, we won't turn it away.
8984 [(match_scratch:DWIH 3 "r")
8985 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8987 (match_operand:<DWI> 1 "nonmemory_operand" "")
8988 (match_operand:QI 2 "nonmemory_operand" "")))
8989 (clobber (reg:CC FLAGS_REG))])
8993 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8995 (define_insn "x86_64_shld"
8996 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8997 (ior:DI (ashift:DI (match_dup 0)
8998 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8999 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9000 (minus:QI (const_int 64) (match_dup 2)))))
9001 (clobber (reg:CC FLAGS_REG))]
9003 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9004 [(set_attr "type" "ishift")
9005 (set_attr "prefix_0f" "1")
9006 (set_attr "mode" "DI")
9007 (set_attr "athlon_decode" "vector")
9008 (set_attr "amdfam10_decode" "vector")
9009 (set_attr "bdver1_decode" "vector")])
9011 (define_insn "x86_shld"
9012 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9013 (ior:SI (ashift:SI (match_dup 0)
9014 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9015 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9016 (minus:QI (const_int 32) (match_dup 2)))))
9017 (clobber (reg:CC FLAGS_REG))]
9019 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9020 [(set_attr "type" "ishift")
9021 (set_attr "prefix_0f" "1")
9022 (set_attr "mode" "SI")
9023 (set_attr "pent_pair" "np")
9024 (set_attr "athlon_decode" "vector")
9025 (set_attr "amdfam10_decode" "vector")
9026 (set_attr "bdver1_decode" "vector")])
9028 (define_expand "x86_shift<mode>_adj_1"
9029 [(set (reg:CCZ FLAGS_REG)
9030 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9033 (set (match_operand:SWI48 0 "register_operand" "")
9034 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9035 (match_operand:SWI48 1 "register_operand" "")
9038 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9039 (match_operand:SWI48 3 "register_operand" "")
9042 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9044 (define_expand "x86_shift<mode>_adj_2"
9045 [(use (match_operand:SWI48 0 "register_operand" ""))
9046 (use (match_operand:SWI48 1 "register_operand" ""))
9047 (use (match_operand:QI 2 "register_operand" ""))]
9050 rtx label = gen_label_rtx ();
9053 emit_insn (gen_testqi_ccz_1 (operands[2],
9054 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9056 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9057 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9058 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9059 gen_rtx_LABEL_REF (VOIDmode, label),
9061 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9062 JUMP_LABEL (tmp) = label;
9064 emit_move_insn (operands[0], operands[1]);
9065 ix86_expand_clear (operands[1]);
9068 LABEL_NUSES (label) = 1;
9073 ;; Avoid useless masking of count operand.
9074 (define_insn_and_split "*ashl<mode>3_mask"
9075 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9077 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9080 (match_operand:SI 2 "nonimmediate_operand" "c")
9081 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9082 (clobber (reg:CC FLAGS_REG))]
9083 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9084 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9085 == GET_MODE_BITSIZE (<MODE>mode)-1"
9088 [(parallel [(set (match_dup 0)
9089 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9090 (clobber (reg:CC FLAGS_REG))])]
9092 if (can_create_pseudo_p ())
9093 operands [2] = force_reg (SImode, operands[2]);
9095 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9097 [(set_attr "type" "ishift")
9098 (set_attr "mode" "<MODE>")])
9100 (define_insn "*bmi2_ashl<mode>3_1"
9101 [(set (match_operand:SWI48 0 "register_operand" "=r")
9102 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9103 (match_operand:SWI48 2 "register_operand" "r")))]
9105 "shlx\t{%2, %1, %0|%0, %1, %2}"
9106 [(set_attr "type" "ishiftx")
9107 (set_attr "mode" "<MODE>")])
9109 (define_insn "*ashl<mode>3_1"
9110 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9111 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9112 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9113 (clobber (reg:CC FLAGS_REG))]
9114 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9116 switch (get_attr_type (insn))
9123 gcc_assert (operands[2] == const1_rtx);
9124 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9125 return "add{<imodesuffix>}\t%0, %0";
9128 if (operands[2] == const1_rtx
9129 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9130 return "sal{<imodesuffix>}\t%0";
9132 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9135 [(set_attr "isa" "*,*,bmi2")
9137 (cond [(eq_attr "alternative" "1")
9138 (const_string "lea")
9139 (eq_attr "alternative" "2")
9140 (const_string "ishiftx")
9141 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9142 (match_operand 0 "register_operand" ""))
9143 (match_operand 2 "const1_operand" ""))
9144 (const_string "alu")
9146 (const_string "ishift")))
9147 (set (attr "length_immediate")
9149 (ior (eq_attr "type" "alu")
9150 (and (eq_attr "type" "ishift")
9151 (and (match_operand 2 "const1_operand" "")
9152 (ior (match_test "TARGET_SHIFT1")
9153 (match_test "optimize_function_for_size_p (cfun)")))))
9155 (const_string "*")))
9156 (set_attr "mode" "<MODE>")])
9158 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9160 [(set (match_operand:SWI48 0 "register_operand" "")
9161 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9162 (match_operand:QI 2 "register_operand" "")))
9163 (clobber (reg:CC FLAGS_REG))]
9164 "TARGET_BMI2 && reload_completed"
9166 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9167 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9169 (define_insn "*bmi2_ashlsi3_1_zext"
9170 [(set (match_operand:DI 0 "register_operand" "=r")
9172 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9173 (match_operand:SI 2 "register_operand" "r"))))]
9174 "TARGET_64BIT && TARGET_BMI2"
9175 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9176 [(set_attr "type" "ishiftx")
9177 (set_attr "mode" "SI")])
9179 (define_insn "*ashlsi3_1_zext"
9180 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9182 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9183 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9184 (clobber (reg:CC FLAGS_REG))]
9185 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9187 switch (get_attr_type (insn))
9194 gcc_assert (operands[2] == const1_rtx);
9195 return "add{l}\t%k0, %k0";
9198 if (operands[2] == const1_rtx
9199 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9200 return "sal{l}\t%k0";
9202 return "sal{l}\t{%2, %k0|%k0, %2}";
9205 [(set_attr "isa" "*,*,bmi2")
9207 (cond [(eq_attr "alternative" "1")
9208 (const_string "lea")
9209 (eq_attr "alternative" "2")
9210 (const_string "ishiftx")
9211 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9212 (match_operand 2 "const1_operand" ""))
9213 (const_string "alu")
9215 (const_string "ishift")))
9216 (set (attr "length_immediate")
9218 (ior (eq_attr "type" "alu")
9219 (and (eq_attr "type" "ishift")
9220 (and (match_operand 2 "const1_operand" "")
9221 (ior (match_test "TARGET_SHIFT1")
9222 (match_test "optimize_function_for_size_p (cfun)")))))
9224 (const_string "*")))
9225 (set_attr "mode" "SI")])
9227 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9229 [(set (match_operand:DI 0 "register_operand" "")
9231 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9232 (match_operand:QI 2 "register_operand" ""))))
9233 (clobber (reg:CC FLAGS_REG))]
9234 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9236 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9237 "operands[2] = gen_lowpart (SImode, operands[2]);")
9239 (define_insn "*ashlhi3_1"
9240 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9241 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9242 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9243 (clobber (reg:CC FLAGS_REG))]
9244 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9246 switch (get_attr_type (insn))
9252 gcc_assert (operands[2] == const1_rtx);
9253 return "add{w}\t%0, %0";
9256 if (operands[2] == const1_rtx
9257 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9258 return "sal{w}\t%0";
9260 return "sal{w}\t{%2, %0|%0, %2}";
9264 (cond [(eq_attr "alternative" "1")
9265 (const_string "lea")
9266 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9267 (match_operand 0 "register_operand" ""))
9268 (match_operand 2 "const1_operand" ""))
9269 (const_string "alu")
9271 (const_string "ishift")))
9272 (set (attr "length_immediate")
9274 (ior (eq_attr "type" "alu")
9275 (and (eq_attr "type" "ishift")
9276 (and (match_operand 2 "const1_operand" "")
9277 (ior (match_test "TARGET_SHIFT1")
9278 (match_test "optimize_function_for_size_p (cfun)")))))
9280 (const_string "*")))
9281 (set_attr "mode" "HI,SI")])
9283 ;; %%% Potential partial reg stall on alternative 1. What to do?
9284 (define_insn "*ashlqi3_1"
9285 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9286 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9287 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9288 (clobber (reg:CC FLAGS_REG))]
9289 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9291 switch (get_attr_type (insn))
9297 gcc_assert (operands[2] == const1_rtx);
9298 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9299 return "add{l}\t%k0, %k0";
9301 return "add{b}\t%0, %0";
9304 if (operands[2] == const1_rtx
9305 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9307 if (get_attr_mode (insn) == MODE_SI)
9308 return "sal{l}\t%k0";
9310 return "sal{b}\t%0";
9314 if (get_attr_mode (insn) == MODE_SI)
9315 return "sal{l}\t{%2, %k0|%k0, %2}";
9317 return "sal{b}\t{%2, %0|%0, %2}";
9322 (cond [(eq_attr "alternative" "2")
9323 (const_string "lea")
9324 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9325 (match_operand 0 "register_operand" ""))
9326 (match_operand 2 "const1_operand" ""))
9327 (const_string "alu")
9329 (const_string "ishift")))
9330 (set (attr "length_immediate")
9332 (ior (eq_attr "type" "alu")
9333 (and (eq_attr "type" "ishift")
9334 (and (match_operand 2 "const1_operand" "")
9335 (ior (match_test "TARGET_SHIFT1")
9336 (match_test "optimize_function_for_size_p (cfun)")))))
9338 (const_string "*")))
9339 (set_attr "mode" "QI,SI,SI")])
9341 (define_insn "*ashlqi3_1_slp"
9342 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9343 (ashift:QI (match_dup 0)
9344 (match_operand:QI 1 "nonmemory_operand" "cI")))
9345 (clobber (reg:CC FLAGS_REG))]
9346 "(optimize_function_for_size_p (cfun)
9347 || !TARGET_PARTIAL_FLAG_REG_STALL
9348 || (operands[1] == const1_rtx
9350 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9352 switch (get_attr_type (insn))
9355 gcc_assert (operands[1] == const1_rtx);
9356 return "add{b}\t%0, %0";
9359 if (operands[1] == const1_rtx
9360 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9361 return "sal{b}\t%0";
9363 return "sal{b}\t{%1, %0|%0, %1}";
9367 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9368 (match_operand 0 "register_operand" ""))
9369 (match_operand 1 "const1_operand" ""))
9370 (const_string "alu")
9372 (const_string "ishift1")))
9373 (set (attr "length_immediate")
9375 (ior (eq_attr "type" "alu")
9376 (and (eq_attr "type" "ishift1")
9377 (and (match_operand 1 "const1_operand" "")
9378 (ior (match_test "TARGET_SHIFT1")
9379 (match_test "optimize_function_for_size_p (cfun)")))))
9381 (const_string "*")))
9382 (set_attr "mode" "QI")])
9384 ;; Convert ashift to the lea pattern to avoid flags dependency.
9386 [(set (match_operand 0 "register_operand" "")
9387 (ashift (match_operand 1 "index_register_operand" "")
9388 (match_operand:QI 2 "const_int_operand" "")))
9389 (clobber (reg:CC FLAGS_REG))]
9390 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9392 && true_regnum (operands[0]) != true_regnum (operands[1])"
9395 enum machine_mode mode = GET_MODE (operands[0]);
9398 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9401 operands[0] = gen_lowpart (mode, operands[0]);
9402 operands[1] = gen_lowpart (mode, operands[1]);
9405 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9407 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9409 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9413 ;; Convert ashift to the lea pattern to avoid flags dependency.
9415 [(set (match_operand:DI 0 "register_operand" "")
9417 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9418 (match_operand:QI 2 "const_int_operand" ""))))
9419 (clobber (reg:CC FLAGS_REG))]
9420 "TARGET_64BIT && reload_completed
9421 && true_regnum (operands[0]) != true_regnum (operands[1])"
9423 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9425 operands[1] = gen_lowpart (DImode, operands[1]);
9426 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9429 ;; This pattern can't accept a variable shift count, since shifts by
9430 ;; zero don't affect the flags. We assume that shifts by constant
9431 ;; zero are optimized away.
9432 (define_insn "*ashl<mode>3_cmp"
9433 [(set (reg FLAGS_REG)
9435 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9436 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9438 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9439 (ashift:SWI (match_dup 1) (match_dup 2)))]
9440 "(optimize_function_for_size_p (cfun)
9441 || !TARGET_PARTIAL_FLAG_REG_STALL
9442 || (operands[2] == const1_rtx
9444 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9445 && ix86_match_ccmode (insn, CCGOCmode)
9446 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9448 switch (get_attr_type (insn))
9451 gcc_assert (operands[2] == const1_rtx);
9452 return "add{<imodesuffix>}\t%0, %0";
9455 if (operands[2] == const1_rtx
9456 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9457 return "sal{<imodesuffix>}\t%0";
9459 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9463 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9464 (match_operand 0 "register_operand" ""))
9465 (match_operand 2 "const1_operand" ""))
9466 (const_string "alu")
9468 (const_string "ishift")))
9469 (set (attr "length_immediate")
9471 (ior (eq_attr "type" "alu")
9472 (and (eq_attr "type" "ishift")
9473 (and (match_operand 2 "const1_operand" "")
9474 (ior (match_test "TARGET_SHIFT1")
9475 (match_test "optimize_function_for_size_p (cfun)")))))
9477 (const_string "*")))
9478 (set_attr "mode" "<MODE>")])
9480 (define_insn "*ashlsi3_cmp_zext"
9481 [(set (reg FLAGS_REG)
9483 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9484 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9486 (set (match_operand:DI 0 "register_operand" "=r")
9487 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9489 && (optimize_function_for_size_p (cfun)
9490 || !TARGET_PARTIAL_FLAG_REG_STALL
9491 || (operands[2] == const1_rtx
9493 || TARGET_DOUBLE_WITH_ADD)))
9494 && ix86_match_ccmode (insn, CCGOCmode)
9495 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9497 switch (get_attr_type (insn))
9500 gcc_assert (operands[2] == const1_rtx);
9501 return "add{l}\t%k0, %k0";
9504 if (operands[2] == const1_rtx
9505 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9506 return "sal{l}\t%k0";
9508 return "sal{l}\t{%2, %k0|%k0, %2}";
9512 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9513 (match_operand 2 "const1_operand" ""))
9514 (const_string "alu")
9516 (const_string "ishift")))
9517 (set (attr "length_immediate")
9519 (ior (eq_attr "type" "alu")
9520 (and (eq_attr "type" "ishift")
9521 (and (match_operand 2 "const1_operand" "")
9522 (ior (match_test "TARGET_SHIFT1")
9523 (match_test "optimize_function_for_size_p (cfun)")))))
9525 (const_string "*")))
9526 (set_attr "mode" "SI")])
9528 (define_insn "*ashl<mode>3_cconly"
9529 [(set (reg FLAGS_REG)
9531 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9532 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9534 (clobber (match_scratch:SWI 0 "=<r>"))]
9535 "(optimize_function_for_size_p (cfun)
9536 || !TARGET_PARTIAL_FLAG_REG_STALL
9537 || (operands[2] == const1_rtx
9539 || TARGET_DOUBLE_WITH_ADD)))
9540 && ix86_match_ccmode (insn, CCGOCmode)"
9542 switch (get_attr_type (insn))
9545 gcc_assert (operands[2] == const1_rtx);
9546 return "add{<imodesuffix>}\t%0, %0";
9549 if (operands[2] == const1_rtx
9550 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9551 return "sal{<imodesuffix>}\t%0";
9553 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9557 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9558 (match_operand 0 "register_operand" ""))
9559 (match_operand 2 "const1_operand" ""))
9560 (const_string "alu")
9562 (const_string "ishift")))
9563 (set (attr "length_immediate")
9565 (ior (eq_attr "type" "alu")
9566 (and (eq_attr "type" "ishift")
9567 (and (match_operand 2 "const1_operand" "")
9568 (ior (match_test "TARGET_SHIFT1")
9569 (match_test "optimize_function_for_size_p (cfun)")))))
9571 (const_string "*")))
9572 (set_attr "mode" "<MODE>")])
9574 ;; See comment above `ashl<mode>3' about how this works.
9576 (define_expand "<shift_insn><mode>3"
9577 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9578 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9579 (match_operand:QI 2 "nonmemory_operand" "")))]
9581 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9583 ;; Avoid useless masking of count operand.
9584 (define_insn_and_split "*<shift_insn><mode>3_mask"
9585 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9587 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9590 (match_operand:SI 2 "nonimmediate_operand" "c")
9591 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9592 (clobber (reg:CC FLAGS_REG))]
9593 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9594 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9595 == GET_MODE_BITSIZE (<MODE>mode)-1"
9598 [(parallel [(set (match_dup 0)
9599 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9600 (clobber (reg:CC FLAGS_REG))])]
9602 if (can_create_pseudo_p ())
9603 operands [2] = force_reg (SImode, operands[2]);
9605 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
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_and_split "*<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 "nonimmediate_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"
10061 [(parallel [(set (match_dup 0)
10062 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10063 (clobber (reg:CC FLAGS_REG))])]
10065 if (can_create_pseudo_p ())
10066 operands [2] = force_reg (SImode, operands[2]);
10068 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10070 [(set_attr "type" "rotate")
10071 (set_attr "mode" "<MODE>")])
10073 ;; Implement rotation using two double-precision
10074 ;; shift instructions and a scratch register.
10076 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10077 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10078 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10079 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10080 (clobber (reg:CC FLAGS_REG))
10081 (clobber (match_scratch:DWIH 3 "=&r"))]
10085 [(set (match_dup 3) (match_dup 4))
10087 [(set (match_dup 4)
10088 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10089 (lshiftrt:DWIH (match_dup 5)
10090 (minus:QI (match_dup 6) (match_dup 2)))))
10091 (clobber (reg:CC FLAGS_REG))])
10093 [(set (match_dup 5)
10094 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10095 (lshiftrt:DWIH (match_dup 3)
10096 (minus:QI (match_dup 6) (match_dup 2)))))
10097 (clobber (reg:CC FLAGS_REG))])]
10099 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10101 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10104 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10105 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10106 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10107 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10108 (clobber (reg:CC FLAGS_REG))
10109 (clobber (match_scratch:DWIH 3 "=&r"))]
10113 [(set (match_dup 3) (match_dup 4))
10115 [(set (match_dup 4)
10116 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10117 (ashift:DWIH (match_dup 5)
10118 (minus:QI (match_dup 6) (match_dup 2)))))
10119 (clobber (reg:CC FLAGS_REG))])
10121 [(set (match_dup 5)
10122 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10123 (ashift:DWIH (match_dup 3)
10124 (minus:QI (match_dup 6) (match_dup 2)))))
10125 (clobber (reg:CC FLAGS_REG))])]
10127 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10129 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10132 (define_insn "*bmi2_rorx<mode>3_1"
10133 [(set (match_operand:SWI48 0 "register_operand" "=r")
10134 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10135 (match_operand:QI 2 "immediate_operand" "<S>")))]
10137 "rorx\t{%2, %1, %0|%0, %1, %2}"
10138 [(set_attr "type" "rotatex")
10139 (set_attr "mode" "<MODE>")])
10141 (define_insn "*<rotate_insn><mode>3_1"
10142 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10144 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10145 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10146 (clobber (reg:CC FLAGS_REG))]
10147 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10149 switch (get_attr_type (insn))
10155 if (operands[2] == const1_rtx
10156 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10157 return "<rotate>{<imodesuffix>}\t%0";
10159 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10162 [(set_attr "isa" "*,bmi2")
10163 (set_attr "type" "rotate,rotatex")
10164 (set (attr "length_immediate")
10166 (and (eq_attr "type" "rotate")
10167 (and (match_operand 2 "const1_operand" "")
10168 (ior (match_test "TARGET_SHIFT1")
10169 (match_test "optimize_function_for_size_p (cfun)"))))
10171 (const_string "*")))
10172 (set_attr "mode" "<MODE>")])
10174 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10176 [(set (match_operand:SWI48 0 "register_operand" "")
10177 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10178 (match_operand:QI 2 "immediate_operand" "")))
10179 (clobber (reg:CC FLAGS_REG))]
10180 "TARGET_BMI2 && reload_completed"
10181 [(set (match_dup 0)
10182 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10185 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10189 [(set (match_operand:SWI48 0 "register_operand" "")
10190 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10191 (match_operand:QI 2 "immediate_operand" "")))
10192 (clobber (reg:CC FLAGS_REG))]
10193 "TARGET_BMI2 && reload_completed"
10194 [(set (match_dup 0)
10195 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10197 (define_insn "*bmi2_rorxsi3_1_zext"
10198 [(set (match_operand:DI 0 "register_operand" "=r")
10200 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10201 (match_operand:QI 2 "immediate_operand" "I"))))]
10202 "TARGET_64BIT && TARGET_BMI2"
10203 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10204 [(set_attr "type" "rotatex")
10205 (set_attr "mode" "SI")])
10207 (define_insn "*<rotate_insn>si3_1_zext"
10208 [(set (match_operand:DI 0 "register_operand" "=r,r")
10210 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10211 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10212 (clobber (reg:CC FLAGS_REG))]
10213 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10215 switch (get_attr_type (insn))
10221 if (operands[2] == const1_rtx
10222 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10223 return "<rotate>{l}\t%k0";
10225 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10228 [(set_attr "isa" "*,bmi2")
10229 (set_attr "type" "rotate,rotatex")
10230 (set (attr "length_immediate")
10232 (and (eq_attr "type" "rotate")
10233 (and (match_operand 2 "const1_operand" "")
10234 (ior (match_test "TARGET_SHIFT1")
10235 (match_test "optimize_function_for_size_p (cfun)"))))
10237 (const_string "*")))
10238 (set_attr "mode" "SI")])
10240 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10242 [(set (match_operand:DI 0 "register_operand" "")
10244 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10245 (match_operand:QI 2 "immediate_operand" ""))))
10246 (clobber (reg:CC FLAGS_REG))]
10247 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10248 [(set (match_dup 0)
10249 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10252 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10256 [(set (match_operand:DI 0 "register_operand" "")
10258 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10259 (match_operand:QI 2 "immediate_operand" ""))))
10260 (clobber (reg:CC FLAGS_REG))]
10261 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10262 [(set (match_dup 0)
10263 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10265 (define_insn "*<rotate_insn><mode>3_1"
10266 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10267 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10268 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10269 (clobber (reg:CC FLAGS_REG))]
10270 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10272 if (operands[2] == const1_rtx
10273 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10274 return "<rotate>{<imodesuffix>}\t%0";
10276 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10278 [(set_attr "type" "rotate")
10279 (set (attr "length_immediate")
10281 (and (match_operand 2 "const1_operand" "")
10282 (ior (match_test "TARGET_SHIFT1")
10283 (match_test "optimize_function_for_size_p (cfun)")))
10285 (const_string "*")))
10286 (set_attr "mode" "<MODE>")])
10288 (define_insn "*<rotate_insn>qi3_1_slp"
10289 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10290 (any_rotate:QI (match_dup 0)
10291 (match_operand:QI 1 "nonmemory_operand" "cI")))
10292 (clobber (reg:CC FLAGS_REG))]
10293 "(optimize_function_for_size_p (cfun)
10294 || !TARGET_PARTIAL_REG_STALL
10295 || (operands[1] == const1_rtx
10296 && TARGET_SHIFT1))"
10298 if (operands[1] == const1_rtx
10299 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10300 return "<rotate>{b}\t%0";
10302 return "<rotate>{b}\t{%1, %0|%0, %1}";
10304 [(set_attr "type" "rotate1")
10305 (set (attr "length_immediate")
10307 (and (match_operand 1 "const1_operand" "")
10308 (ior (match_test "TARGET_SHIFT1")
10309 (match_test "optimize_function_for_size_p (cfun)")))
10311 (const_string "*")))
10312 (set_attr "mode" "QI")])
10315 [(set (match_operand:HI 0 "register_operand" "")
10316 (any_rotate:HI (match_dup 0) (const_int 8)))
10317 (clobber (reg:CC FLAGS_REG))]
10319 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10320 [(parallel [(set (strict_low_part (match_dup 0))
10321 (bswap:HI (match_dup 0)))
10322 (clobber (reg:CC FLAGS_REG))])])
10324 ;; Bit set / bit test instructions
10326 (define_expand "extv"
10327 [(set (match_operand:SI 0 "register_operand" "")
10328 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10329 (match_operand:SI 2 "const8_operand" "")
10330 (match_operand:SI 3 "const8_operand" "")))]
10333 /* Handle extractions from %ah et al. */
10334 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10337 /* From mips.md: extract_bit_field doesn't verify that our source
10338 matches the predicate, so check it again here. */
10339 if (! ext_register_operand (operands[1], VOIDmode))
10343 (define_expand "extzv"
10344 [(set (match_operand:SI 0 "register_operand" "")
10345 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10346 (match_operand:SI 2 "const8_operand" "")
10347 (match_operand:SI 3 "const8_operand" "")))]
10350 /* Handle extractions from %ah et al. */
10351 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10354 /* From mips.md: extract_bit_field doesn't verify that our source
10355 matches the predicate, so check it again here. */
10356 if (! ext_register_operand (operands[1], VOIDmode))
10360 (define_expand "insv"
10361 [(set (zero_extract (match_operand 0 "register_operand" "")
10362 (match_operand 1 "const_int_operand" "")
10363 (match_operand 2 "const_int_operand" ""))
10364 (match_operand 3 "register_operand" ""))]
10367 rtx (*gen_mov_insv_1) (rtx, rtx);
10369 if (ix86_expand_pinsr (operands))
10372 /* Handle insertions to %ah et al. */
10373 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10376 /* From mips.md: insert_bit_field doesn't verify that our source
10377 matches the predicate, so check it again here. */
10378 if (! ext_register_operand (operands[0], VOIDmode))
10381 gen_mov_insv_1 = (TARGET_64BIT
10382 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10384 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10388 ;; %%% bts, btr, btc, bt.
10389 ;; In general these instructions are *slow* when applied to memory,
10390 ;; since they enforce atomic operation. When applied to registers,
10391 ;; it depends on the cpu implementation. They're never faster than
10392 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10393 ;; no point. But in 64-bit, we can't hold the relevant immediates
10394 ;; within the instruction itself, so operating on bits in the high
10395 ;; 32-bits of a register becomes easier.
10397 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10398 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10399 ;; negdf respectively, so they can never be disabled entirely.
10401 (define_insn "*btsq"
10402 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10404 (match_operand:DI 1 "const_0_to_63_operand" ""))
10406 (clobber (reg:CC FLAGS_REG))]
10407 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10408 "bts{q}\t{%1, %0|%0, %1}"
10409 [(set_attr "type" "alu1")
10410 (set_attr "prefix_0f" "1")
10411 (set_attr "mode" "DI")])
10413 (define_insn "*btrq"
10414 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10416 (match_operand:DI 1 "const_0_to_63_operand" ""))
10418 (clobber (reg:CC FLAGS_REG))]
10419 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10420 "btr{q}\t{%1, %0|%0, %1}"
10421 [(set_attr "type" "alu1")
10422 (set_attr "prefix_0f" "1")
10423 (set_attr "mode" "DI")])
10425 (define_insn "*btcq"
10426 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10428 (match_operand:DI 1 "const_0_to_63_operand" ""))
10429 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10430 (clobber (reg:CC FLAGS_REG))]
10431 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10432 "btc{q}\t{%1, %0|%0, %1}"
10433 [(set_attr "type" "alu1")
10434 (set_attr "prefix_0f" "1")
10435 (set_attr "mode" "DI")])
10437 ;; Allow Nocona to avoid these instructions if a register is available.
10440 [(match_scratch:DI 2 "r")
10441 (parallel [(set (zero_extract:DI
10442 (match_operand:DI 0 "register_operand" "")
10444 (match_operand:DI 1 "const_0_to_63_operand" ""))
10446 (clobber (reg:CC FLAGS_REG))])]
10447 "TARGET_64BIT && !TARGET_USE_BT"
10450 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10453 if (HOST_BITS_PER_WIDE_INT >= 64)
10454 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10455 else if (i < HOST_BITS_PER_WIDE_INT)
10456 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10458 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10460 op1 = immed_double_const (lo, hi, DImode);
10463 emit_move_insn (operands[2], op1);
10467 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10472 [(match_scratch:DI 2 "r")
10473 (parallel [(set (zero_extract:DI
10474 (match_operand:DI 0 "register_operand" "")
10476 (match_operand:DI 1 "const_0_to_63_operand" ""))
10478 (clobber (reg:CC FLAGS_REG))])]
10479 "TARGET_64BIT && !TARGET_USE_BT"
10482 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10485 if (HOST_BITS_PER_WIDE_INT >= 64)
10486 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10487 else if (i < HOST_BITS_PER_WIDE_INT)
10488 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10490 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10492 op1 = immed_double_const (~lo, ~hi, DImode);
10495 emit_move_insn (operands[2], op1);
10499 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10504 [(match_scratch:DI 2 "r")
10505 (parallel [(set (zero_extract:DI
10506 (match_operand:DI 0 "register_operand" "")
10508 (match_operand:DI 1 "const_0_to_63_operand" ""))
10509 (not:DI (zero_extract:DI
10510 (match_dup 0) (const_int 1) (match_dup 1))))
10511 (clobber (reg:CC FLAGS_REG))])]
10512 "TARGET_64BIT && !TARGET_USE_BT"
10515 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10518 if (HOST_BITS_PER_WIDE_INT >= 64)
10519 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10520 else if (i < HOST_BITS_PER_WIDE_INT)
10521 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10523 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10525 op1 = immed_double_const (lo, hi, DImode);
10528 emit_move_insn (operands[2], op1);
10532 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10536 (define_insn "*bt<mode>"
10537 [(set (reg:CCC FLAGS_REG)
10539 (zero_extract:SWI48
10540 (match_operand:SWI48 0 "register_operand" "r")
10542 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10544 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10545 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10546 [(set_attr "type" "alu1")
10547 (set_attr "prefix_0f" "1")
10548 (set_attr "mode" "<MODE>")])
10550 ;; Store-flag instructions.
10552 ;; For all sCOND expanders, also expand the compare or test insn that
10553 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10555 (define_insn_and_split "*setcc_di_1"
10556 [(set (match_operand:DI 0 "register_operand" "=q")
10557 (match_operator:DI 1 "ix86_comparison_operator"
10558 [(reg FLAGS_REG) (const_int 0)]))]
10559 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10561 "&& reload_completed"
10562 [(set (match_dup 2) (match_dup 1))
10563 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10565 PUT_MODE (operands[1], QImode);
10566 operands[2] = gen_lowpart (QImode, operands[0]);
10569 (define_insn_and_split "*setcc_si_1_and"
10570 [(set (match_operand:SI 0 "register_operand" "=q")
10571 (match_operator:SI 1 "ix86_comparison_operator"
10572 [(reg FLAGS_REG) (const_int 0)]))
10573 (clobber (reg:CC FLAGS_REG))]
10574 "!TARGET_PARTIAL_REG_STALL
10575 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10577 "&& reload_completed"
10578 [(set (match_dup 2) (match_dup 1))
10579 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10580 (clobber (reg:CC FLAGS_REG))])]
10582 PUT_MODE (operands[1], QImode);
10583 operands[2] = gen_lowpart (QImode, operands[0]);
10586 (define_insn_and_split "*setcc_si_1_movzbl"
10587 [(set (match_operand:SI 0 "register_operand" "=q")
10588 (match_operator:SI 1 "ix86_comparison_operator"
10589 [(reg FLAGS_REG) (const_int 0)]))]
10590 "!TARGET_PARTIAL_REG_STALL
10591 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10593 "&& reload_completed"
10594 [(set (match_dup 2) (match_dup 1))
10595 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10597 PUT_MODE (operands[1], QImode);
10598 operands[2] = gen_lowpart (QImode, operands[0]);
10601 (define_insn "*setcc_qi"
10602 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10603 (match_operator:QI 1 "ix86_comparison_operator"
10604 [(reg FLAGS_REG) (const_int 0)]))]
10607 [(set_attr "type" "setcc")
10608 (set_attr "mode" "QI")])
10610 (define_insn "*setcc_qi_slp"
10611 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10612 (match_operator:QI 1 "ix86_comparison_operator"
10613 [(reg FLAGS_REG) (const_int 0)]))]
10616 [(set_attr "type" "setcc")
10617 (set_attr "mode" "QI")])
10619 ;; In general it is not safe to assume too much about CCmode registers,
10620 ;; so simplify-rtx stops when it sees a second one. Under certain
10621 ;; conditions this is safe on x86, so help combine not create
10628 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10629 (ne:QI (match_operator 1 "ix86_comparison_operator"
10630 [(reg FLAGS_REG) (const_int 0)])
10633 [(set (match_dup 0) (match_dup 1))]
10634 "PUT_MODE (operands[1], QImode);")
10637 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10638 (ne:QI (match_operator 1 "ix86_comparison_operator"
10639 [(reg FLAGS_REG) (const_int 0)])
10642 [(set (match_dup 0) (match_dup 1))]
10643 "PUT_MODE (operands[1], QImode);")
10646 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10647 (eq:QI (match_operator 1 "ix86_comparison_operator"
10648 [(reg FLAGS_REG) (const_int 0)])
10651 [(set (match_dup 0) (match_dup 1))]
10653 rtx new_op1 = copy_rtx (operands[1]);
10654 operands[1] = new_op1;
10655 PUT_MODE (new_op1, QImode);
10656 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10657 GET_MODE (XEXP (new_op1, 0))));
10659 /* Make sure that (a) the CCmode we have for the flags is strong
10660 enough for the reversed compare or (b) we have a valid FP compare. */
10661 if (! ix86_comparison_operator (new_op1, VOIDmode))
10666 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10667 (eq:QI (match_operator 1 "ix86_comparison_operator"
10668 [(reg FLAGS_REG) (const_int 0)])
10671 [(set (match_dup 0) (match_dup 1))]
10673 rtx new_op1 = copy_rtx (operands[1]);
10674 operands[1] = new_op1;
10675 PUT_MODE (new_op1, QImode);
10676 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10677 GET_MODE (XEXP (new_op1, 0))));
10679 /* Make sure that (a) the CCmode we have for the flags is strong
10680 enough for the reversed compare or (b) we have a valid FP compare. */
10681 if (! ix86_comparison_operator (new_op1, VOIDmode))
10685 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10686 ;; subsequent logical operations are used to imitate conditional moves.
10687 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10690 (define_insn "setcc_<mode>_sse"
10691 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10692 (match_operator:MODEF 3 "sse_comparison_operator"
10693 [(match_operand:MODEF 1 "register_operand" "0,x")
10694 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10695 "SSE_FLOAT_MODE_P (<MODE>mode)"
10697 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10698 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10699 [(set_attr "isa" "noavx,avx")
10700 (set_attr "type" "ssecmp")
10701 (set_attr "length_immediate" "1")
10702 (set_attr "prefix" "orig,vex")
10703 (set_attr "mode" "<MODE>")])
10705 ;; Basic conditional jump instructions.
10706 ;; We ignore the overflow flag for signed branch instructions.
10708 (define_insn "*jcc_1"
10710 (if_then_else (match_operator 1 "ix86_comparison_operator"
10711 [(reg FLAGS_REG) (const_int 0)])
10712 (label_ref (match_operand 0 "" ""))
10716 [(set_attr "type" "ibr")
10717 (set_attr "modrm" "0")
10718 (set (attr "length")
10719 (if_then_else (and (ge (minus (match_dup 0) (pc))
10721 (lt (minus (match_dup 0) (pc))
10726 (define_insn "*jcc_2"
10728 (if_then_else (match_operator 1 "ix86_comparison_operator"
10729 [(reg FLAGS_REG) (const_int 0)])
10731 (label_ref (match_operand 0 "" ""))))]
10734 [(set_attr "type" "ibr")
10735 (set_attr "modrm" "0")
10736 (set (attr "length")
10737 (if_then_else (and (ge (minus (match_dup 0) (pc))
10739 (lt (minus (match_dup 0) (pc))
10744 ;; In general it is not safe to assume too much about CCmode registers,
10745 ;; so simplify-rtx stops when it sees a second one. Under certain
10746 ;; conditions this is safe on x86, so help combine not create
10754 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10755 [(reg FLAGS_REG) (const_int 0)])
10757 (label_ref (match_operand 1 "" ""))
10761 (if_then_else (match_dup 0)
10762 (label_ref (match_dup 1))
10764 "PUT_MODE (operands[0], VOIDmode);")
10768 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10769 [(reg FLAGS_REG) (const_int 0)])
10771 (label_ref (match_operand 1 "" ""))
10775 (if_then_else (match_dup 0)
10776 (label_ref (match_dup 1))
10779 rtx new_op0 = copy_rtx (operands[0]);
10780 operands[0] = new_op0;
10781 PUT_MODE (new_op0, VOIDmode);
10782 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10783 GET_MODE (XEXP (new_op0, 0))));
10785 /* Make sure that (a) the CCmode we have for the flags is strong
10786 enough for the reversed compare or (b) we have a valid FP compare. */
10787 if (! ix86_comparison_operator (new_op0, VOIDmode))
10791 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10792 ;; pass generates from shift insn with QImode operand. Actually, the mode
10793 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10794 ;; appropriate modulo of the bit offset value.
10796 (define_insn_and_split "*jcc_bt<mode>"
10798 (if_then_else (match_operator 0 "bt_comparison_operator"
10799 [(zero_extract:SWI48
10800 (match_operand:SWI48 1 "register_operand" "r")
10803 (match_operand:QI 2 "register_operand" "r")))
10805 (label_ref (match_operand 3 "" ""))
10807 (clobber (reg:CC FLAGS_REG))]
10808 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10811 [(set (reg:CCC FLAGS_REG)
10813 (zero_extract:SWI48
10819 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10820 (label_ref (match_dup 3))
10823 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10825 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10828 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10829 ;; also for DImode, this is what combine produces.
10830 (define_insn_and_split "*jcc_bt<mode>_mask"
10832 (if_then_else (match_operator 0 "bt_comparison_operator"
10833 [(zero_extract:SWI48
10834 (match_operand:SWI48 1 "register_operand" "r")
10837 (match_operand:SI 2 "register_operand" "r")
10838 (match_operand:SI 3 "const_int_operand" "n")))])
10839 (label_ref (match_operand 4 "" ""))
10841 (clobber (reg:CC FLAGS_REG))]
10842 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10843 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10844 == GET_MODE_BITSIZE (<MODE>mode)-1"
10847 [(set (reg:CCC FLAGS_REG)
10849 (zero_extract:SWI48
10855 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10856 (label_ref (match_dup 4))
10859 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10861 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10864 (define_insn_and_split "*jcc_btsi_1"
10866 (if_then_else (match_operator 0 "bt_comparison_operator"
10869 (match_operand:SI 1 "register_operand" "r")
10870 (match_operand:QI 2 "register_operand" "r"))
10873 (label_ref (match_operand 3 "" ""))
10875 (clobber (reg:CC FLAGS_REG))]
10876 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10879 [(set (reg:CCC FLAGS_REG)
10887 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10888 (label_ref (match_dup 3))
10891 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10893 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10896 ;; avoid useless masking of bit offset operand
10897 (define_insn_and_split "*jcc_btsi_mask_1"
10900 (match_operator 0 "bt_comparison_operator"
10903 (match_operand:SI 1 "register_operand" "r")
10906 (match_operand:SI 2 "register_operand" "r")
10907 (match_operand:SI 3 "const_int_operand" "n")) 0))
10910 (label_ref (match_operand 4 "" ""))
10912 (clobber (reg:CC FLAGS_REG))]
10913 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10914 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10917 [(set (reg:CCC FLAGS_REG)
10925 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10926 (label_ref (match_dup 4))
10928 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10930 ;; Define combination compare-and-branch fp compare instructions to help
10933 (define_insn "*fp_jcc_1_387"
10935 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10936 [(match_operand 1 "register_operand" "f")
10937 (match_operand 2 "nonimmediate_operand" "fm")])
10938 (label_ref (match_operand 3 "" ""))
10940 (clobber (reg:CCFP FPSR_REG))
10941 (clobber (reg:CCFP FLAGS_REG))
10942 (clobber (match_scratch:HI 4 "=a"))]
10944 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10945 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10946 && SELECT_CC_MODE (GET_CODE (operands[0]),
10947 operands[1], operands[2]) == CCFPmode
10951 (define_insn "*fp_jcc_1r_387"
10953 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10954 [(match_operand 1 "register_operand" "f")
10955 (match_operand 2 "nonimmediate_operand" "fm")])
10957 (label_ref (match_operand 3 "" ""))))
10958 (clobber (reg:CCFP FPSR_REG))
10959 (clobber (reg:CCFP FLAGS_REG))
10960 (clobber (match_scratch:HI 4 "=a"))]
10962 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10963 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10964 && SELECT_CC_MODE (GET_CODE (operands[0]),
10965 operands[1], operands[2]) == CCFPmode
10969 (define_insn "*fp_jcc_2_387"
10971 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10972 [(match_operand 1 "register_operand" "f")
10973 (match_operand 2 "register_operand" "f")])
10974 (label_ref (match_operand 3 "" ""))
10976 (clobber (reg:CCFP FPSR_REG))
10977 (clobber (reg:CCFP FLAGS_REG))
10978 (clobber (match_scratch:HI 4 "=a"))]
10979 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10980 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10984 (define_insn "*fp_jcc_2r_387"
10986 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10987 [(match_operand 1 "register_operand" "f")
10988 (match_operand 2 "register_operand" "f")])
10990 (label_ref (match_operand 3 "" ""))))
10991 (clobber (reg:CCFP FPSR_REG))
10992 (clobber (reg:CCFP FLAGS_REG))
10993 (clobber (match_scratch:HI 4 "=a"))]
10994 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10995 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10999 (define_insn "*fp_jcc_3_387"
11001 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11002 [(match_operand 1 "register_operand" "f")
11003 (match_operand 2 "const0_operand" "")])
11004 (label_ref (match_operand 3 "" ""))
11006 (clobber (reg:CCFP FPSR_REG))
11007 (clobber (reg:CCFP FLAGS_REG))
11008 (clobber (match_scratch:HI 4 "=a"))]
11009 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11010 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11011 && SELECT_CC_MODE (GET_CODE (operands[0]),
11012 operands[1], operands[2]) == CCFPmode
11018 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11019 [(match_operand 1 "register_operand" "")
11020 (match_operand 2 "nonimmediate_operand" "")])
11021 (match_operand 3 "" "")
11022 (match_operand 4 "" "")))
11023 (clobber (reg:CCFP FPSR_REG))
11024 (clobber (reg:CCFP FLAGS_REG))]
11028 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11029 operands[3], operands[4], NULL_RTX, NULL_RTX);
11035 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11036 [(match_operand 1 "register_operand" "")
11037 (match_operand 2 "general_operand" "")])
11038 (match_operand 3 "" "")
11039 (match_operand 4 "" "")))
11040 (clobber (reg:CCFP FPSR_REG))
11041 (clobber (reg:CCFP FLAGS_REG))
11042 (clobber (match_scratch:HI 5 "=a"))]
11046 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11047 operands[3], operands[4], operands[5], NULL_RTX);
11051 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11052 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11053 ;; with a precedence over other operators and is always put in the first
11054 ;; place. Swap condition and operands to match ficom instruction.
11056 (define_insn "*fp_jcc_4_<mode>_387"
11059 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11060 [(match_operator 1 "float_operator"
11061 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11062 (match_operand 3 "register_operand" "f,f")])
11063 (label_ref (match_operand 4 "" ""))
11065 (clobber (reg:CCFP FPSR_REG))
11066 (clobber (reg:CCFP FLAGS_REG))
11067 (clobber (match_scratch:HI 5 "=a,a"))]
11068 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11069 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11070 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11071 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11078 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11079 [(match_operator 1 "float_operator"
11080 [(match_operand:SWI24 2 "memory_operand" "")])
11081 (match_operand 3 "register_operand" "")])
11082 (match_operand 4 "" "")
11083 (match_operand 5 "" "")))
11084 (clobber (reg:CCFP FPSR_REG))
11085 (clobber (reg:CCFP FLAGS_REG))
11086 (clobber (match_scratch:HI 6 "=a"))]
11090 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11092 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11093 operands[3], operands[7],
11094 operands[4], operands[5], operands[6], NULL_RTX);
11098 ;; %%% Kill this when reload knows how to do it.
11102 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11103 [(match_operator 1 "float_operator"
11104 [(match_operand:SWI24 2 "register_operand" "")])
11105 (match_operand 3 "register_operand" "")])
11106 (match_operand 4 "" "")
11107 (match_operand 5 "" "")))
11108 (clobber (reg:CCFP FPSR_REG))
11109 (clobber (reg:CCFP FLAGS_REG))
11110 (clobber (match_scratch:HI 6 "=a"))]
11114 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11115 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11117 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11118 operands[3], operands[7],
11119 operands[4], operands[5], operands[6], operands[2]);
11123 ;; Unconditional and other jump instructions
11125 (define_insn "jump"
11127 (label_ref (match_operand 0 "" "")))]
11130 [(set_attr "type" "ibr")
11131 (set (attr "length")
11132 (if_then_else (and (ge (minus (match_dup 0) (pc))
11134 (lt (minus (match_dup 0) (pc))
11138 (set_attr "modrm" "0")])
11140 (define_expand "indirect_jump"
11141 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11143 (define_insn "*indirect_jump"
11144 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11147 [(set_attr "type" "ibr")
11148 (set_attr "length_immediate" "0")])
11150 (define_expand "tablejump"
11151 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11152 (use (label_ref (match_operand 1 "" "")))])]
11155 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11156 relative. Convert the relative address to an absolute address. */
11160 enum rtx_code code;
11162 /* We can't use @GOTOFF for text labels on VxWorks;
11163 see gotoff_operand. */
11164 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11168 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11170 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11174 op1 = pic_offset_table_rtx;
11179 op0 = pic_offset_table_rtx;
11183 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11186 else if (TARGET_X32)
11187 operands[0] = convert_memory_address (Pmode, operands[0]);
11190 (define_insn "*tablejump_1"
11191 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11192 (use (label_ref (match_operand 1 "" "")))]
11195 [(set_attr "type" "ibr")
11196 (set_attr "length_immediate" "0")])
11198 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11201 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11202 (set (match_operand:QI 1 "register_operand" "")
11203 (match_operator:QI 2 "ix86_comparison_operator"
11204 [(reg FLAGS_REG) (const_int 0)]))
11205 (set (match_operand 3 "q_regs_operand" "")
11206 (zero_extend (match_dup 1)))]
11207 "(peep2_reg_dead_p (3, operands[1])
11208 || operands_match_p (operands[1], operands[3]))
11209 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11210 [(set (match_dup 4) (match_dup 0))
11211 (set (strict_low_part (match_dup 5))
11214 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11215 operands[5] = gen_lowpart (QImode, operands[3]);
11216 ix86_expand_clear (operands[3]);
11219 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11222 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11223 (set (match_operand:QI 1 "register_operand" "")
11224 (match_operator:QI 2 "ix86_comparison_operator"
11225 [(reg FLAGS_REG) (const_int 0)]))
11226 (parallel [(set (match_operand 3 "q_regs_operand" "")
11227 (zero_extend (match_dup 1)))
11228 (clobber (reg:CC FLAGS_REG))])]
11229 "(peep2_reg_dead_p (3, operands[1])
11230 || operands_match_p (operands[1], operands[3]))
11231 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11232 [(set (match_dup 4) (match_dup 0))
11233 (set (strict_low_part (match_dup 5))
11236 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11237 operands[5] = gen_lowpart (QImode, operands[3]);
11238 ix86_expand_clear (operands[3]);
11241 ;; Call instructions.
11243 ;; The predicates normally associated with named expanders are not properly
11244 ;; checked for calls. This is a bug in the generic code, but it isn't that
11245 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11247 ;; P6 processors will jump to the address after the decrement when %esp
11248 ;; is used as a call operand, so they will execute return address as a code.
11249 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11251 ;; Register constraint for call instruction.
11252 (define_mode_attr c [(SI "l") (DI "r")])
11254 ;; Call subroutine returning no value.
11256 (define_expand "call"
11257 [(call (match_operand:QI 0 "" "")
11258 (match_operand 1 "" ""))
11259 (use (match_operand 2 "" ""))]
11262 ix86_expand_call (NULL, operands[0], operands[1],
11263 operands[2], NULL, false);
11267 (define_expand "sibcall"
11268 [(call (match_operand:QI 0 "" "")
11269 (match_operand 1 "" ""))
11270 (use (match_operand 2 "" ""))]
11273 ix86_expand_call (NULL, operands[0], operands[1],
11274 operands[2], NULL, true);
11278 (define_insn_and_split "*call_vzeroupper"
11279 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11280 (match_operand 1 "" ""))
11281 (unspec [(match_operand 2 "const_int_operand" "")]
11282 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11283 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11285 "&& reload_completed"
11287 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11288 [(set_attr "type" "call")])
11290 (define_insn "*call"
11291 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11292 (match_operand 1 "" ""))]
11293 "!SIBLING_CALL_P (insn)"
11294 "* return ix86_output_call_insn (insn, operands[0]);"
11295 [(set_attr "type" "call")])
11297 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11298 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11299 (match_operand 1 "" ""))
11300 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11301 (clobber (reg:TI XMM6_REG))
11302 (clobber (reg:TI XMM7_REG))
11303 (clobber (reg:TI XMM8_REG))
11304 (clobber (reg:TI XMM9_REG))
11305 (clobber (reg:TI XMM10_REG))
11306 (clobber (reg:TI XMM11_REG))
11307 (clobber (reg:TI XMM12_REG))
11308 (clobber (reg:TI XMM13_REG))
11309 (clobber (reg:TI XMM14_REG))
11310 (clobber (reg:TI XMM15_REG))
11311 (clobber (reg:DI SI_REG))
11312 (clobber (reg:DI DI_REG))
11313 (unspec [(match_operand 2 "const_int_operand" "")]
11314 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11315 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11317 "&& reload_completed"
11319 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11320 [(set_attr "type" "call")])
11322 (define_insn "*call_rex64_ms_sysv"
11323 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11324 (match_operand 1 "" ""))
11325 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11326 (clobber (reg:TI XMM6_REG))
11327 (clobber (reg:TI XMM7_REG))
11328 (clobber (reg:TI XMM8_REG))
11329 (clobber (reg:TI XMM9_REG))
11330 (clobber (reg:TI XMM10_REG))
11331 (clobber (reg:TI XMM11_REG))
11332 (clobber (reg:TI XMM12_REG))
11333 (clobber (reg:TI XMM13_REG))
11334 (clobber (reg:TI XMM14_REG))
11335 (clobber (reg:TI XMM15_REG))
11336 (clobber (reg:DI SI_REG))
11337 (clobber (reg:DI DI_REG))]
11338 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11339 "* return ix86_output_call_insn (insn, operands[0]);"
11340 [(set_attr "type" "call")])
11342 (define_insn_and_split "*sibcall_vzeroupper"
11343 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11344 (match_operand 1 "" ""))
11345 (unspec [(match_operand 2 "const_int_operand" "")]
11346 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11347 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11349 "&& reload_completed"
11351 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11352 [(set_attr "type" "call")])
11354 (define_insn "*sibcall"
11355 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11356 (match_operand 1 "" ""))]
11357 "SIBLING_CALL_P (insn)"
11358 "* return ix86_output_call_insn (insn, operands[0]);"
11359 [(set_attr "type" "call")])
11361 (define_expand "call_pop"
11362 [(parallel [(call (match_operand:QI 0 "" "")
11363 (match_operand:SI 1 "" ""))
11364 (set (reg:SI SP_REG)
11365 (plus:SI (reg:SI SP_REG)
11366 (match_operand:SI 3 "" "")))])]
11369 ix86_expand_call (NULL, operands[0], operands[1],
11370 operands[2], operands[3], false);
11374 (define_insn_and_split "*call_pop_vzeroupper"
11375 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11376 (match_operand:SI 1 "" ""))
11377 (set (reg:SI SP_REG)
11378 (plus:SI (reg:SI SP_REG)
11379 (match_operand:SI 2 "immediate_operand" "i")))
11380 (unspec [(match_operand 3 "const_int_operand" "")]
11381 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11382 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11384 "&& reload_completed"
11386 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11387 [(set_attr "type" "call")])
11389 (define_insn "*call_pop"
11390 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11391 (match_operand 1 "" ""))
11392 (set (reg:SI SP_REG)
11393 (plus:SI (reg:SI SP_REG)
11394 (match_operand:SI 2 "immediate_operand" "i")))]
11395 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11396 "* return ix86_output_call_insn (insn, operands[0]);"
11397 [(set_attr "type" "call")])
11399 (define_insn_and_split "*sibcall_pop_vzeroupper"
11400 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11401 (match_operand 1 "" ""))
11402 (set (reg:SI SP_REG)
11403 (plus:SI (reg:SI SP_REG)
11404 (match_operand:SI 2 "immediate_operand" "i")))
11405 (unspec [(match_operand 3 "const_int_operand" "")]
11406 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11407 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11409 "&& reload_completed"
11411 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11412 [(set_attr "type" "call")])
11414 (define_insn "*sibcall_pop"
11415 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11416 (match_operand 1 "" ""))
11417 (set (reg:SI SP_REG)
11418 (plus:SI (reg:SI SP_REG)
11419 (match_operand:SI 2 "immediate_operand" "i")))]
11420 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11421 "* return ix86_output_call_insn (insn, operands[0]);"
11422 [(set_attr "type" "call")])
11424 ;; Call subroutine, returning value in operand 0
11426 (define_expand "call_value"
11427 [(set (match_operand 0 "" "")
11428 (call (match_operand:QI 1 "" "")
11429 (match_operand 2 "" "")))
11430 (use (match_operand 3 "" ""))]
11433 ix86_expand_call (operands[0], operands[1], operands[2],
11434 operands[3], NULL, false);
11438 (define_expand "sibcall_value"
11439 [(set (match_operand 0 "" "")
11440 (call (match_operand:QI 1 "" "")
11441 (match_operand 2 "" "")))
11442 (use (match_operand 3 "" ""))]
11445 ix86_expand_call (operands[0], operands[1], operands[2],
11446 operands[3], NULL, true);
11450 (define_insn_and_split "*call_value_vzeroupper"
11451 [(set (match_operand 0 "" "")
11452 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11453 (match_operand 2 "" "")))
11454 (unspec [(match_operand 3 "const_int_operand" "")]
11455 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11456 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11458 "&& reload_completed"
11460 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11461 [(set_attr "type" "callv")])
11463 (define_insn "*call_value"
11464 [(set (match_operand 0 "" "")
11465 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11466 (match_operand 2 "" "")))]
11467 "!SIBLING_CALL_P (insn)"
11468 "* return ix86_output_call_insn (insn, operands[1]);"
11469 [(set_attr "type" "callv")])
11471 (define_insn_and_split "*sibcall_value_vzeroupper"
11472 [(set (match_operand 0 "" "")
11473 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11474 (match_operand 2 "" "")))
11475 (unspec [(match_operand 3 "const_int_operand" "")]
11476 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11477 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11479 "&& reload_completed"
11481 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11482 [(set_attr "type" "callv")])
11484 (define_insn "*sibcall_value"
11485 [(set (match_operand 0 "" "")
11486 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11487 (match_operand 2 "" "")))]
11488 "SIBLING_CALL_P (insn)"
11489 "* return ix86_output_call_insn (insn, operands[1]);"
11490 [(set_attr "type" "callv")])
11492 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11493 [(set (match_operand 0 "" "")
11494 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11495 (match_operand 2 "" "")))
11496 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11497 (clobber (reg:TI XMM6_REG))
11498 (clobber (reg:TI XMM7_REG))
11499 (clobber (reg:TI XMM8_REG))
11500 (clobber (reg:TI XMM9_REG))
11501 (clobber (reg:TI XMM10_REG))
11502 (clobber (reg:TI XMM11_REG))
11503 (clobber (reg:TI XMM12_REG))
11504 (clobber (reg:TI XMM13_REG))
11505 (clobber (reg:TI XMM14_REG))
11506 (clobber (reg:TI XMM15_REG))
11507 (clobber (reg:DI SI_REG))
11508 (clobber (reg:DI DI_REG))
11509 (unspec [(match_operand 3 "const_int_operand" "")]
11510 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11511 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11513 "&& reload_completed"
11515 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11516 [(set_attr "type" "callv")])
11518 (define_insn "*call_value_rex64_ms_sysv"
11519 [(set (match_operand 0 "" "")
11520 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11521 (match_operand 2 "" "")))
11522 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11523 (clobber (reg:TI XMM6_REG))
11524 (clobber (reg:TI XMM7_REG))
11525 (clobber (reg:TI XMM8_REG))
11526 (clobber (reg:TI XMM9_REG))
11527 (clobber (reg:TI XMM10_REG))
11528 (clobber (reg:TI XMM11_REG))
11529 (clobber (reg:TI XMM12_REG))
11530 (clobber (reg:TI XMM13_REG))
11531 (clobber (reg:TI XMM14_REG))
11532 (clobber (reg:TI XMM15_REG))
11533 (clobber (reg:DI SI_REG))
11534 (clobber (reg:DI DI_REG))]
11535 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11536 "* return ix86_output_call_insn (insn, operands[1]);"
11537 [(set_attr "type" "callv")])
11539 (define_expand "call_value_pop"
11540 [(parallel [(set (match_operand 0 "" "")
11541 (call (match_operand:QI 1 "" "")
11542 (match_operand:SI 2 "" "")))
11543 (set (reg:SI SP_REG)
11544 (plus:SI (reg:SI SP_REG)
11545 (match_operand:SI 4 "" "")))])]
11548 ix86_expand_call (operands[0], operands[1], operands[2],
11549 operands[3], operands[4], false);
11553 (define_insn_and_split "*call_value_pop_vzeroupper"
11554 [(set (match_operand 0 "" "")
11555 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11556 (match_operand 2 "" "")))
11557 (set (reg:SI SP_REG)
11558 (plus:SI (reg:SI SP_REG)
11559 (match_operand:SI 3 "immediate_operand" "i")))
11560 (unspec [(match_operand 4 "const_int_operand" "")]
11561 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11562 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11564 "&& reload_completed"
11566 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11567 [(set_attr "type" "callv")])
11569 (define_insn "*call_value_pop"
11570 [(set (match_operand 0 "" "")
11571 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11572 (match_operand 2 "" "")))
11573 (set (reg:SI SP_REG)
11574 (plus:SI (reg:SI SP_REG)
11575 (match_operand:SI 3 "immediate_operand" "i")))]
11576 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11577 "* return ix86_output_call_insn (insn, operands[1]);"
11578 [(set_attr "type" "callv")])
11580 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11581 [(set (match_operand 0 "" "")
11582 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11583 (match_operand 2 "" "")))
11584 (set (reg:SI SP_REG)
11585 (plus:SI (reg:SI SP_REG)
11586 (match_operand:SI 3 "immediate_operand" "i")))
11587 (unspec [(match_operand 4 "const_int_operand" "")]
11588 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11589 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11591 "&& reload_completed"
11593 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11594 [(set_attr "type" "callv")])
11596 (define_insn "*sibcall_value_pop"
11597 [(set (match_operand 0 "" "")
11598 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11599 (match_operand 2 "" "")))
11600 (set (reg:SI SP_REG)
11601 (plus:SI (reg:SI SP_REG)
11602 (match_operand:SI 3 "immediate_operand" "i")))]
11603 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11604 "* return ix86_output_call_insn (insn, operands[1]);"
11605 [(set_attr "type" "callv")])
11607 ;; Call subroutine returning any type.
11609 (define_expand "untyped_call"
11610 [(parallel [(call (match_operand 0 "" "")
11612 (match_operand 1 "" "")
11613 (match_operand 2 "" "")])]
11618 /* In order to give reg-stack an easier job in validating two
11619 coprocessor registers as containing a possible return value,
11620 simply pretend the untyped call returns a complex long double
11623 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11624 and should have the default ABI. */
11626 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11627 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11628 operands[0], const0_rtx,
11629 GEN_INT ((TARGET_64BIT
11630 ? (ix86_abi == SYSV_ABI
11631 ? X86_64_SSE_REGPARM_MAX
11632 : X86_64_MS_SSE_REGPARM_MAX)
11633 : X86_32_SSE_REGPARM_MAX)
11637 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11639 rtx set = XVECEXP (operands[2], 0, i);
11640 emit_move_insn (SET_DEST (set), SET_SRC (set));
11643 /* The optimizer does not know that the call sets the function value
11644 registers we stored in the result block. We avoid problems by
11645 claiming that all hard registers are used and clobbered at this
11647 emit_insn (gen_blockage ());
11652 ;; Prologue and epilogue instructions
11654 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11655 ;; all of memory. This blocks insns from being moved across this point.
11657 (define_insn "blockage"
11658 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11661 [(set_attr "length" "0")])
11663 ;; Do not schedule instructions accessing memory across this point.
11665 (define_expand "memory_blockage"
11666 [(set (match_dup 0)
11667 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11670 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11671 MEM_VOLATILE_P (operands[0]) = 1;
11674 (define_insn "*memory_blockage"
11675 [(set (match_operand:BLK 0 "" "")
11676 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11679 [(set_attr "length" "0")])
11681 ;; As USE insns aren't meaningful after reload, this is used instead
11682 ;; to prevent deleting instructions setting registers for PIC code
11683 (define_insn "prologue_use"
11684 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11687 [(set_attr "length" "0")])
11689 ;; Insn emitted into the body of a function to return from a function.
11690 ;; This is only done if the function's epilogue is known to be simple.
11691 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11693 (define_expand "return"
11695 "ix86_can_use_return_insn_p ()"
11697 ix86_maybe_emit_epilogue_vzeroupper ();
11698 if (crtl->args.pops_args)
11700 rtx popc = GEN_INT (crtl->args.pops_args);
11701 emit_jump_insn (gen_simple_return_pop_internal (popc));
11706 ;; We need to disable this for TARGET_SEH, as otherwise
11707 ;; shrink-wrapped prologue gets enabled too. This might exceed
11708 ;; the maximum size of prologue in unwind information.
11710 (define_expand "simple_return"
11714 ix86_maybe_emit_epilogue_vzeroupper ();
11715 if (crtl->args.pops_args)
11717 rtx popc = GEN_INT (crtl->args.pops_args);
11718 emit_jump_insn (gen_simple_return_pop_internal (popc));
11723 (define_insn "simple_return_internal"
11727 [(set_attr "length" "1")
11728 (set_attr "atom_unit" "jeu")
11729 (set_attr "length_immediate" "0")
11730 (set_attr "modrm" "0")])
11732 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11733 ;; instruction Athlon and K8 have.
11735 (define_insn "simple_return_internal_long"
11737 (unspec [(const_int 0)] UNSPEC_REP)]
11740 [(set_attr "length" "2")
11741 (set_attr "atom_unit" "jeu")
11742 (set_attr "length_immediate" "0")
11743 (set_attr "prefix_rep" "1")
11744 (set_attr "modrm" "0")])
11746 (define_insn "simple_return_pop_internal"
11748 (use (match_operand:SI 0 "const_int_operand" ""))]
11751 [(set_attr "length" "3")
11752 (set_attr "atom_unit" "jeu")
11753 (set_attr "length_immediate" "2")
11754 (set_attr "modrm" "0")])
11756 (define_insn "simple_return_indirect_internal"
11758 (use (match_operand:SI 0 "register_operand" "r"))]
11761 [(set_attr "type" "ibr")
11762 (set_attr "length_immediate" "0")])
11768 [(set_attr "length" "1")
11769 (set_attr "length_immediate" "0")
11770 (set_attr "modrm" "0")])
11772 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11773 (define_insn "nops"
11774 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11778 int num = INTVAL (operands[0]);
11780 gcc_assert (num >= 1 && num <= 8);
11783 fputs ("\tnop\n", asm_out_file);
11787 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11788 (set_attr "length_immediate" "0")
11789 (set_attr "modrm" "0")])
11791 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11792 ;; branch prediction penalty for the third jump in a 16-byte
11796 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11799 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11800 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11802 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11803 The align insn is used to avoid 3 jump instructions in the row to improve
11804 branch prediction and the benefits hardly outweigh the cost of extra 8
11805 nops on the average inserted by full alignment pseudo operation. */
11809 [(set_attr "length" "16")])
11811 (define_expand "prologue"
11814 "ix86_expand_prologue (); DONE;")
11816 (define_insn "set_got"
11817 [(set (match_operand:SI 0 "register_operand" "=r")
11818 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11819 (clobber (reg:CC FLAGS_REG))]
11821 "* return output_set_got (operands[0], NULL_RTX);"
11822 [(set_attr "type" "multi")
11823 (set_attr "length" "12")])
11825 (define_insn "set_got_labelled"
11826 [(set (match_operand:SI 0 "register_operand" "=r")
11827 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11829 (clobber (reg:CC FLAGS_REG))]
11831 "* return output_set_got (operands[0], operands[1]);"
11832 [(set_attr "type" "multi")
11833 (set_attr "length" "12")])
11835 (define_insn "set_got_rex64"
11836 [(set (match_operand:DI 0 "register_operand" "=r")
11837 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11839 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11840 [(set_attr "type" "lea")
11841 (set_attr "length_address" "4")
11842 (set_attr "mode" "DI")])
11844 (define_insn "set_rip_rex64"
11845 [(set (match_operand:DI 0 "register_operand" "=r")
11846 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11848 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11849 [(set_attr "type" "lea")
11850 (set_attr "length_address" "4")
11851 (set_attr "mode" "DI")])
11853 (define_insn "set_got_offset_rex64"
11854 [(set (match_operand:DI 0 "register_operand" "=r")
11856 [(label_ref (match_operand 1 "" ""))]
11857 UNSPEC_SET_GOT_OFFSET))]
11859 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11860 [(set_attr "type" "imov")
11861 (set_attr "length_immediate" "0")
11862 (set_attr "length_address" "8")
11863 (set_attr "mode" "DI")])
11865 (define_expand "epilogue"
11868 "ix86_expand_epilogue (1); DONE;")
11870 (define_expand "sibcall_epilogue"
11873 "ix86_expand_epilogue (0); DONE;")
11875 (define_expand "eh_return"
11876 [(use (match_operand 0 "register_operand" ""))]
11879 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11881 /* Tricky bit: we write the address of the handler to which we will
11882 be returning into someone else's stack frame, one word below the
11883 stack address we wish to restore. */
11884 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11885 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11886 tmp = gen_rtx_MEM (Pmode, tmp);
11887 emit_move_insn (tmp, ra);
11889 emit_jump_insn (gen_eh_return_internal ());
11894 (define_insn_and_split "eh_return_internal"
11898 "epilogue_completed"
11900 "ix86_expand_epilogue (2); DONE;")
11902 (define_insn "leave"
11903 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11904 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11905 (clobber (mem:BLK (scratch)))]
11908 [(set_attr "type" "leave")])
11910 (define_insn "leave_rex64"
11911 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11912 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11913 (clobber (mem:BLK (scratch)))]
11916 [(set_attr "type" "leave")])
11918 ;; Handle -fsplit-stack.
11920 (define_expand "split_stack_prologue"
11924 ix86_expand_split_stack_prologue ();
11928 ;; In order to support the call/return predictor, we use a return
11929 ;; instruction which the middle-end doesn't see.
11930 (define_insn "split_stack_return"
11931 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11932 UNSPECV_SPLIT_STACK_RETURN)]
11935 if (operands[0] == const0_rtx)
11940 [(set_attr "atom_unit" "jeu")
11941 (set_attr "modrm" "0")
11942 (set (attr "length")
11943 (if_then_else (match_operand:SI 0 "const0_operand" "")
11946 (set (attr "length_immediate")
11947 (if_then_else (match_operand:SI 0 "const0_operand" "")
11951 ;; If there are operand 0 bytes available on the stack, jump to
11954 (define_expand "split_stack_space_check"
11955 [(set (pc) (if_then_else
11956 (ltu (minus (reg SP_REG)
11957 (match_operand 0 "register_operand" ""))
11958 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11959 (label_ref (match_operand 1 "" ""))
11963 rtx reg, size, limit;
11965 reg = gen_reg_rtx (Pmode);
11966 size = force_reg (Pmode, operands[0]);
11967 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11968 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11969 UNSPEC_STACK_CHECK);
11970 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11971 ix86_expand_branch (GEU, reg, limit, operands[1]);
11976 ;; Bit manipulation instructions.
11978 (define_expand "ffs<mode>2"
11979 [(set (match_dup 2) (const_int -1))
11980 (parallel [(set (reg:CCZ FLAGS_REG)
11982 (match_operand:SWI48 1 "nonimmediate_operand" "")
11984 (set (match_operand:SWI48 0 "register_operand" "")
11985 (ctz:SWI48 (match_dup 1)))])
11986 (set (match_dup 0) (if_then_else:SWI48
11987 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11990 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11991 (clobber (reg:CC FLAGS_REG))])]
11994 if (<MODE>mode == SImode && !TARGET_CMOVE)
11996 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11999 operands[2] = gen_reg_rtx (<MODE>mode);
12002 (define_insn_and_split "ffssi2_no_cmove"
12003 [(set (match_operand:SI 0 "register_operand" "=r")
12004 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12005 (clobber (match_scratch:SI 2 "=&q"))
12006 (clobber (reg:CC FLAGS_REG))]
12009 "&& reload_completed"
12010 [(parallel [(set (reg:CCZ FLAGS_REG)
12011 (compare:CCZ (match_dup 1) (const_int 0)))
12012 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12013 (set (strict_low_part (match_dup 3))
12014 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12015 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12016 (clobber (reg:CC FLAGS_REG))])
12017 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12018 (clobber (reg:CC FLAGS_REG))])
12019 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12020 (clobber (reg:CC FLAGS_REG))])]
12022 operands[3] = gen_lowpart (QImode, operands[2]);
12023 ix86_expand_clear (operands[2]);
12026 (define_insn "*ffs<mode>_1"
12027 [(set (reg:CCZ FLAGS_REG)
12028 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12030 (set (match_operand:SWI48 0 "register_operand" "=r")
12031 (ctz:SWI48 (match_dup 1)))]
12033 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12034 [(set_attr "type" "alu1")
12035 (set_attr "prefix_0f" "1")
12036 (set_attr "mode" "<MODE>")])
12038 (define_insn "ctz<mode>2"
12039 [(set (match_operand:SWI248 0 "register_operand" "=r")
12040 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12041 (clobber (reg:CC FLAGS_REG))]
12045 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12047 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12049 [(set_attr "type" "alu1")
12050 (set_attr "prefix_0f" "1")
12051 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12052 (set_attr "mode" "<MODE>")])
12054 (define_expand "clz<mode>2"
12056 [(set (match_operand:SWI248 0 "register_operand" "")
12059 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12060 (clobber (reg:CC FLAGS_REG))])
12062 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12063 (clobber (reg:CC FLAGS_REG))])]
12068 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12071 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12074 (define_insn "clz<mode>2_lzcnt"
12075 [(set (match_operand:SWI248 0 "register_operand" "=r")
12076 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12077 (clobber (reg:CC FLAGS_REG))]
12079 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12080 [(set_attr "prefix_rep" "1")
12081 (set_attr "type" "bitmanip")
12082 (set_attr "mode" "<MODE>")])
12084 ;; BMI instructions.
12085 (define_insn "*bmi_andn_<mode>"
12086 [(set (match_operand:SWI48 0 "register_operand" "=r")
12089 (match_operand:SWI48 1 "register_operand" "r"))
12090 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12091 (clobber (reg:CC FLAGS_REG))]
12093 "andn\t{%2, %1, %0|%0, %1, %2}"
12094 [(set_attr "type" "bitmanip")
12095 (set_attr "mode" "<MODE>")])
12097 (define_insn "bmi_bextr_<mode>"
12098 [(set (match_operand:SWI48 0 "register_operand" "=r")
12099 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12100 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12102 (clobber (reg:CC FLAGS_REG))]
12104 "bextr\t{%2, %1, %0|%0, %1, %2}"
12105 [(set_attr "type" "bitmanip")
12106 (set_attr "mode" "<MODE>")])
12108 (define_insn "*bmi_blsi_<mode>"
12109 [(set (match_operand:SWI48 0 "register_operand" "=r")
12112 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12114 (clobber (reg:CC FLAGS_REG))]
12116 "blsi\t{%1, %0|%0, %1}"
12117 [(set_attr "type" "bitmanip")
12118 (set_attr "mode" "<MODE>")])
12120 (define_insn "*bmi_blsmsk_<mode>"
12121 [(set (match_operand:SWI48 0 "register_operand" "=r")
12124 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12127 (clobber (reg:CC FLAGS_REG))]
12129 "blsmsk\t{%1, %0|%0, %1}"
12130 [(set_attr "type" "bitmanip")
12131 (set_attr "mode" "<MODE>")])
12133 (define_insn "*bmi_blsr_<mode>"
12134 [(set (match_operand:SWI48 0 "register_operand" "=r")
12137 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12140 (clobber (reg:CC FLAGS_REG))]
12142 "blsr\t{%1, %0|%0, %1}"
12143 [(set_attr "type" "bitmanip")
12144 (set_attr "mode" "<MODE>")])
12146 ;; BMI2 instructions.
12147 (define_insn "bmi2_bzhi_<mode>3"
12148 [(set (match_operand:SWI48 0 "register_operand" "=r")
12149 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12150 (lshiftrt:SWI48 (const_int -1)
12151 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12152 (clobber (reg:CC FLAGS_REG))]
12154 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12155 [(set_attr "type" "bitmanip")
12156 (set_attr "prefix" "vex")
12157 (set_attr "mode" "<MODE>")])
12159 (define_insn "bmi2_pdep_<mode>3"
12160 [(set (match_operand:SWI48 0 "register_operand" "=r")
12161 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12162 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12165 "pdep\t{%2, %1, %0|%0, %1, %2}"
12166 [(set_attr "type" "bitmanip")
12167 (set_attr "prefix" "vex")
12168 (set_attr "mode" "<MODE>")])
12170 (define_insn "bmi2_pext_<mode>3"
12171 [(set (match_operand:SWI48 0 "register_operand" "=r")
12172 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12173 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12176 "pext\t{%2, %1, %0|%0, %1, %2}"
12177 [(set_attr "type" "bitmanip")
12178 (set_attr "prefix" "vex")
12179 (set_attr "mode" "<MODE>")])
12181 ;; TBM instructions.
12182 (define_insn "tbm_bextri_<mode>"
12183 [(set (match_operand:SWI48 0 "register_operand" "=r")
12184 (zero_extract:SWI48
12185 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12186 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12187 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12188 (clobber (reg:CC FLAGS_REG))]
12191 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12192 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12194 [(set_attr "type" "bitmanip")
12195 (set_attr "mode" "<MODE>")])
12197 (define_insn "*tbm_blcfill_<mode>"
12198 [(set (match_operand:SWI48 0 "register_operand" "=r")
12201 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12204 (clobber (reg:CC FLAGS_REG))]
12206 "blcfill\t{%1, %0|%0, %1}"
12207 [(set_attr "type" "bitmanip")
12208 (set_attr "mode" "<MODE>")])
12210 (define_insn "*tbm_blci_<mode>"
12211 [(set (match_operand:SWI48 0 "register_operand" "=r")
12215 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12218 (clobber (reg:CC FLAGS_REG))]
12220 "blci\t{%1, %0|%0, %1}"
12221 [(set_attr "type" "bitmanip")
12222 (set_attr "mode" "<MODE>")])
12224 (define_insn "*tbm_blcic_<mode>"
12225 [(set (match_operand:SWI48 0 "register_operand" "=r")
12228 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12232 (clobber (reg:CC FLAGS_REG))]
12234 "blcic\t{%1, %0|%0, %1}"
12235 [(set_attr "type" "bitmanip")
12236 (set_attr "mode" "<MODE>")])
12238 (define_insn "*tbm_blcmsk_<mode>"
12239 [(set (match_operand:SWI48 0 "register_operand" "=r")
12242 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12245 (clobber (reg:CC FLAGS_REG))]
12247 "blcmsk\t{%1, %0|%0, %1}"
12248 [(set_attr "type" "bitmanip")
12249 (set_attr "mode" "<MODE>")])
12251 (define_insn "*tbm_blcs_<mode>"
12252 [(set (match_operand:SWI48 0 "register_operand" "=r")
12255 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12258 (clobber (reg:CC FLAGS_REG))]
12260 "blcs\t{%1, %0|%0, %1}"
12261 [(set_attr "type" "bitmanip")
12262 (set_attr "mode" "<MODE>")])
12264 (define_insn "*tbm_blsfill_<mode>"
12265 [(set (match_operand:SWI48 0 "register_operand" "=r")
12268 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12271 (clobber (reg:CC FLAGS_REG))]
12273 "blsfill\t{%1, %0|%0, %1}"
12274 [(set_attr "type" "bitmanip")
12275 (set_attr "mode" "<MODE>")])
12277 (define_insn "*tbm_blsic_<mode>"
12278 [(set (match_operand:SWI48 0 "register_operand" "=r")
12281 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12285 (clobber (reg:CC FLAGS_REG))]
12287 "blsic\t{%1, %0|%0, %1}"
12288 [(set_attr "type" "bitmanip")
12289 (set_attr "mode" "<MODE>")])
12291 (define_insn "*tbm_t1mskc_<mode>"
12292 [(set (match_operand:SWI48 0 "register_operand" "=r")
12295 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12299 (clobber (reg:CC FLAGS_REG))]
12301 "t1mskc\t{%1, %0|%0, %1}"
12302 [(set_attr "type" "bitmanip")
12303 (set_attr "mode" "<MODE>")])
12305 (define_insn "*tbm_tzmsk_<mode>"
12306 [(set (match_operand:SWI48 0 "register_operand" "=r")
12309 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12313 (clobber (reg:CC FLAGS_REG))]
12315 "tzmsk\t{%1, %0|%0, %1}"
12316 [(set_attr "type" "bitmanip")
12317 (set_attr "mode" "<MODE>")])
12319 (define_insn "bsr_rex64"
12320 [(set (match_operand:DI 0 "register_operand" "=r")
12321 (minus:DI (const_int 63)
12322 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12323 (clobber (reg:CC FLAGS_REG))]
12325 "bsr{q}\t{%1, %0|%0, %1}"
12326 [(set_attr "type" "alu1")
12327 (set_attr "prefix_0f" "1")
12328 (set_attr "mode" "DI")])
12331 [(set (match_operand:SI 0 "register_operand" "=r")
12332 (minus:SI (const_int 31)
12333 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12334 (clobber (reg:CC FLAGS_REG))]
12336 "bsr{l}\t{%1, %0|%0, %1}"
12337 [(set_attr "type" "alu1")
12338 (set_attr "prefix_0f" "1")
12339 (set_attr "mode" "SI")])
12341 (define_insn "*bsrhi"
12342 [(set (match_operand:HI 0 "register_operand" "=r")
12343 (minus:HI (const_int 15)
12344 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12345 (clobber (reg:CC FLAGS_REG))]
12347 "bsr{w}\t{%1, %0|%0, %1}"
12348 [(set_attr "type" "alu1")
12349 (set_attr "prefix_0f" "1")
12350 (set_attr "mode" "HI")])
12352 (define_insn "popcount<mode>2"
12353 [(set (match_operand:SWI248 0 "register_operand" "=r")
12355 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12356 (clobber (reg:CC FLAGS_REG))]
12360 return "popcnt\t{%1, %0|%0, %1}";
12362 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12365 [(set_attr "prefix_rep" "1")
12366 (set_attr "type" "bitmanip")
12367 (set_attr "mode" "<MODE>")])
12369 (define_insn "*popcount<mode>2_cmp"
12370 [(set (reg FLAGS_REG)
12373 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12375 (set (match_operand:SWI248 0 "register_operand" "=r")
12376 (popcount:SWI248 (match_dup 1)))]
12377 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12380 return "popcnt\t{%1, %0|%0, %1}";
12382 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12385 [(set_attr "prefix_rep" "1")
12386 (set_attr "type" "bitmanip")
12387 (set_attr "mode" "<MODE>")])
12389 (define_insn "*popcountsi2_cmp_zext"
12390 [(set (reg FLAGS_REG)
12392 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12394 (set (match_operand:DI 0 "register_operand" "=r")
12395 (zero_extend:DI(popcount:SI (match_dup 1))))]
12396 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12399 return "popcnt\t{%1, %0|%0, %1}";
12401 return "popcnt{l}\t{%1, %0|%0, %1}";
12404 [(set_attr "prefix_rep" "1")
12405 (set_attr "type" "bitmanip")
12406 (set_attr "mode" "SI")])
12408 (define_expand "bswap<mode>2"
12409 [(set (match_operand:SWI48 0 "register_operand" "")
12410 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12413 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12415 rtx x = operands[0];
12417 emit_move_insn (x, operands[1]);
12418 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12419 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12420 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12425 (define_insn "*bswap<mode>2_movbe"
12426 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12427 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12429 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12432 movbe\t{%1, %0|%0, %1}
12433 movbe\t{%1, %0|%0, %1}"
12434 [(set_attr "type" "bitmanip,imov,imov")
12435 (set_attr "modrm" "0,1,1")
12436 (set_attr "prefix_0f" "*,1,1")
12437 (set_attr "prefix_extra" "*,1,1")
12438 (set_attr "mode" "<MODE>")])
12440 (define_insn "*bswap<mode>2_1"
12441 [(set (match_operand:SWI48 0 "register_operand" "=r")
12442 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12445 [(set_attr "type" "bitmanip")
12446 (set_attr "modrm" "0")
12447 (set_attr "mode" "<MODE>")])
12449 (define_insn "*bswaphi_lowpart_1"
12450 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12451 (bswap:HI (match_dup 0)))
12452 (clobber (reg:CC FLAGS_REG))]
12453 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12455 xchg{b}\t{%h0, %b0|%b0, %h0}
12456 rol{w}\t{$8, %0|%0, 8}"
12457 [(set_attr "length" "2,4")
12458 (set_attr "mode" "QI,HI")])
12460 (define_insn "bswaphi_lowpart"
12461 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12462 (bswap:HI (match_dup 0)))
12463 (clobber (reg:CC FLAGS_REG))]
12465 "rol{w}\t{$8, %0|%0, 8}"
12466 [(set_attr "length" "4")
12467 (set_attr "mode" "HI")])
12469 (define_expand "paritydi2"
12470 [(set (match_operand:DI 0 "register_operand" "")
12471 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12474 rtx scratch = gen_reg_rtx (QImode);
12477 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12478 NULL_RTX, operands[1]));
12480 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12481 gen_rtx_REG (CCmode, FLAGS_REG),
12483 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12486 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12489 rtx tmp = gen_reg_rtx (SImode);
12491 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12492 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12497 (define_expand "paritysi2"
12498 [(set (match_operand:SI 0 "register_operand" "")
12499 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12502 rtx scratch = gen_reg_rtx (QImode);
12505 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12507 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12508 gen_rtx_REG (CCmode, FLAGS_REG),
12510 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12512 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12516 (define_insn_and_split "paritydi2_cmp"
12517 [(set (reg:CC FLAGS_REG)
12518 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12520 (clobber (match_scratch:DI 0 "=r"))
12521 (clobber (match_scratch:SI 1 "=&r"))
12522 (clobber (match_scratch:HI 2 "=Q"))]
12525 "&& reload_completed"
12527 [(set (match_dup 1)
12528 (xor:SI (match_dup 1) (match_dup 4)))
12529 (clobber (reg:CC FLAGS_REG))])
12531 [(set (reg:CC FLAGS_REG)
12532 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12533 (clobber (match_dup 1))
12534 (clobber (match_dup 2))])]
12536 operands[4] = gen_lowpart (SImode, operands[3]);
12540 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12541 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12544 operands[1] = gen_highpart (SImode, operands[3]);
12547 (define_insn_and_split "paritysi2_cmp"
12548 [(set (reg:CC FLAGS_REG)
12549 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12551 (clobber (match_scratch:SI 0 "=r"))
12552 (clobber (match_scratch:HI 1 "=&Q"))]
12555 "&& reload_completed"
12557 [(set (match_dup 1)
12558 (xor:HI (match_dup 1) (match_dup 3)))
12559 (clobber (reg:CC FLAGS_REG))])
12561 [(set (reg:CC FLAGS_REG)
12562 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12563 (clobber (match_dup 1))])]
12565 operands[3] = gen_lowpart (HImode, operands[2]);
12567 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12568 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12571 (define_insn "*parityhi2_cmp"
12572 [(set (reg:CC FLAGS_REG)
12573 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12575 (clobber (match_scratch:HI 0 "=Q"))]
12577 "xor{b}\t{%h0, %b0|%b0, %h0}"
12578 [(set_attr "length" "2")
12579 (set_attr "mode" "HI")])
12582 ;; Thread-local storage patterns for ELF.
12584 ;; Note that these code sequences must appear exactly as shown
12585 ;; in order to allow linker relaxation.
12587 (define_insn "*tls_global_dynamic_32_gnu"
12588 [(set (match_operand:SI 0 "register_operand" "=a")
12590 [(match_operand:SI 1 "register_operand" "b")
12591 (match_operand:SI 2 "tls_symbolic_operand" "")
12592 (match_operand:SI 3 "constant_call_address_operand" "z")]
12594 (clobber (match_scratch:SI 4 "=d"))
12595 (clobber (match_scratch:SI 5 "=c"))
12596 (clobber (reg:CC FLAGS_REG))]
12597 "!TARGET_64BIT && TARGET_GNU_TLS"
12600 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12601 if (TARGET_SUN_TLS)
12602 #ifdef HAVE_AS_IX86_TLSGDPLT
12603 return "call\t%a2@tlsgdplt";
12605 return "call\t%p3@plt";
12607 return "call\t%P3";
12609 [(set_attr "type" "multi")
12610 (set_attr "length" "12")])
12612 (define_expand "tls_global_dynamic_32"
12614 [(set (match_operand:SI 0 "register_operand" "")
12615 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12616 (match_operand:SI 1 "tls_symbolic_operand" "")
12617 (match_operand:SI 3 "constant_call_address_operand" "")]
12619 (clobber (match_scratch:SI 4 ""))
12620 (clobber (match_scratch:SI 5 ""))
12621 (clobber (reg:CC FLAGS_REG))])])
12623 (define_insn "*tls_global_dynamic_64"
12624 [(set (match_operand:DI 0 "register_operand" "=a")
12626 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12627 (match_operand:DI 3 "" "")))
12628 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12633 fputs (ASM_BYTE "0x66\n", asm_out_file);
12635 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12636 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12637 fputs ("\trex64\n", asm_out_file);
12638 if (TARGET_SUN_TLS)
12639 return "call\t%p2@plt";
12640 return "call\t%P2";
12642 [(set_attr "type" "multi")
12643 (set (attr "length")
12644 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12646 (define_expand "tls_global_dynamic_64"
12648 [(set (match_operand:DI 0 "register_operand" "")
12650 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12652 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12655 (define_insn "*tls_local_dynamic_base_32_gnu"
12656 [(set (match_operand:SI 0 "register_operand" "=a")
12658 [(match_operand:SI 1 "register_operand" "b")
12659 (match_operand:SI 2 "constant_call_address_operand" "z")]
12660 UNSPEC_TLS_LD_BASE))
12661 (clobber (match_scratch:SI 3 "=d"))
12662 (clobber (match_scratch:SI 4 "=c"))
12663 (clobber (reg:CC FLAGS_REG))]
12664 "!TARGET_64BIT && TARGET_GNU_TLS"
12667 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12668 if (TARGET_SUN_TLS)
12669 #ifdef HAVE_AS_IX86_TLSLDMPLT
12670 return "call\t%&@tlsldmplt";
12672 return "call\t%p2@plt";
12674 return "call\t%P2";
12676 [(set_attr "type" "multi")
12677 (set_attr "length" "11")])
12679 (define_expand "tls_local_dynamic_base_32"
12681 [(set (match_operand:SI 0 "register_operand" "")
12683 [(match_operand:SI 1 "register_operand" "")
12684 (match_operand:SI 2 "constant_call_address_operand" "")]
12685 UNSPEC_TLS_LD_BASE))
12686 (clobber (match_scratch:SI 3 ""))
12687 (clobber (match_scratch:SI 4 ""))
12688 (clobber (reg:CC FLAGS_REG))])])
12690 (define_insn "*tls_local_dynamic_base_64"
12691 [(set (match_operand:DI 0 "register_operand" "=a")
12693 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12694 (match_operand:DI 2 "" "")))
12695 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12699 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12700 if (TARGET_SUN_TLS)
12701 return "call\t%p1@plt";
12702 return "call\t%P1";
12704 [(set_attr "type" "multi")
12705 (set_attr "length" "12")])
12707 (define_expand "tls_local_dynamic_base_64"
12709 [(set (match_operand:DI 0 "register_operand" "")
12711 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12713 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12715 ;; Local dynamic of a single variable is a lose. Show combine how
12716 ;; to convert that back to global dynamic.
12718 (define_insn_and_split "*tls_local_dynamic_32_once"
12719 [(set (match_operand:SI 0 "register_operand" "=a")
12721 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12722 (match_operand:SI 2 "constant_call_address_operand" "z")]
12723 UNSPEC_TLS_LD_BASE)
12724 (const:SI (unspec:SI
12725 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12727 (clobber (match_scratch:SI 4 "=d"))
12728 (clobber (match_scratch:SI 5 "=c"))
12729 (clobber (reg:CC FLAGS_REG))]
12734 [(set (match_dup 0)
12735 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12737 (clobber (match_dup 4))
12738 (clobber (match_dup 5))
12739 (clobber (reg:CC FLAGS_REG))])])
12741 ;; Segment register for the thread base ptr load
12742 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12744 ;; Load and add the thread base pointer from %<tp_seg>:0.
12745 (define_insn "*load_tp_x32"
12746 [(set (match_operand:SI 0 "register_operand" "=r")
12747 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12749 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12750 [(set_attr "type" "imov")
12751 (set_attr "modrm" "0")
12752 (set_attr "length" "7")
12753 (set_attr "memory" "load")
12754 (set_attr "imm_disp" "false")])
12756 (define_insn "*load_tp_x32_zext"
12757 [(set (match_operand:DI 0 "register_operand" "=r")
12758 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12760 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12761 [(set_attr "type" "imov")
12762 (set_attr "modrm" "0")
12763 (set_attr "length" "7")
12764 (set_attr "memory" "load")
12765 (set_attr "imm_disp" "false")])
12767 (define_insn "*load_tp_<mode>"
12768 [(set (match_operand:P 0 "register_operand" "=r")
12769 (unspec:P [(const_int 0)] UNSPEC_TP))]
12771 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12772 [(set_attr "type" "imov")
12773 (set_attr "modrm" "0")
12774 (set_attr "length" "7")
12775 (set_attr "memory" "load")
12776 (set_attr "imm_disp" "false")])
12778 (define_insn "*add_tp_x32"
12779 [(set (match_operand:SI 0 "register_operand" "=r")
12780 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12781 (match_operand:SI 1 "register_operand" "0")))
12782 (clobber (reg:CC FLAGS_REG))]
12784 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12785 [(set_attr "type" "alu")
12786 (set_attr "modrm" "0")
12787 (set_attr "length" "7")
12788 (set_attr "memory" "load")
12789 (set_attr "imm_disp" "false")])
12791 (define_insn "*add_tp_x32_zext"
12792 [(set (match_operand:DI 0 "register_operand" "=r")
12794 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12795 (match_operand:SI 1 "register_operand" "0"))))
12796 (clobber (reg:CC FLAGS_REG))]
12798 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12799 [(set_attr "type" "alu")
12800 (set_attr "modrm" "0")
12801 (set_attr "length" "7")
12802 (set_attr "memory" "load")
12803 (set_attr "imm_disp" "false")])
12805 (define_insn "*add_tp_<mode>"
12806 [(set (match_operand:P 0 "register_operand" "=r")
12807 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12808 (match_operand:P 1 "register_operand" "0")))
12809 (clobber (reg:CC FLAGS_REG))]
12811 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12812 [(set_attr "type" "alu")
12813 (set_attr "modrm" "0")
12814 (set_attr "length" "7")
12815 (set_attr "memory" "load")
12816 (set_attr "imm_disp" "false")])
12818 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12819 ;; %rax as destination of the initial executable code sequence.
12820 (define_insn "tls_initial_exec_64_sun"
12821 [(set (match_operand:DI 0 "register_operand" "=a")
12823 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12824 UNSPEC_TLS_IE_SUN))
12825 (clobber (reg:CC FLAGS_REG))]
12826 "TARGET_64BIT && TARGET_SUN_TLS"
12829 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12830 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12832 [(set_attr "type" "multi")])
12834 ;; GNU2 TLS patterns can be split.
12836 (define_expand "tls_dynamic_gnu2_32"
12837 [(set (match_dup 3)
12838 (plus:SI (match_operand:SI 2 "register_operand" "")
12840 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12843 [(set (match_operand:SI 0 "register_operand" "")
12844 (unspec:SI [(match_dup 1) (match_dup 3)
12845 (match_dup 2) (reg:SI SP_REG)]
12847 (clobber (reg:CC FLAGS_REG))])]
12848 "!TARGET_64BIT && TARGET_GNU2_TLS"
12850 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12851 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12854 (define_insn "*tls_dynamic_gnu2_lea_32"
12855 [(set (match_operand:SI 0 "register_operand" "=r")
12856 (plus:SI (match_operand:SI 1 "register_operand" "b")
12858 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12859 UNSPEC_TLSDESC))))]
12860 "!TARGET_64BIT && TARGET_GNU2_TLS"
12861 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12862 [(set_attr "type" "lea")
12863 (set_attr "mode" "SI")
12864 (set_attr "length" "6")
12865 (set_attr "length_address" "4")])
12867 (define_insn "*tls_dynamic_gnu2_call_32"
12868 [(set (match_operand:SI 0 "register_operand" "=a")
12869 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12870 (match_operand:SI 2 "register_operand" "0")
12871 ;; we have to make sure %ebx still points to the GOT
12872 (match_operand:SI 3 "register_operand" "b")
12875 (clobber (reg:CC FLAGS_REG))]
12876 "!TARGET_64BIT && TARGET_GNU2_TLS"
12877 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12878 [(set_attr "type" "call")
12879 (set_attr "length" "2")
12880 (set_attr "length_address" "0")])
12882 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12883 [(set (match_operand:SI 0 "register_operand" "=&a")
12885 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12886 (match_operand:SI 4 "" "")
12887 (match_operand:SI 2 "register_operand" "b")
12890 (const:SI (unspec:SI
12891 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12893 (clobber (reg:CC FLAGS_REG))]
12894 "!TARGET_64BIT && TARGET_GNU2_TLS"
12897 [(set (match_dup 0) (match_dup 5))]
12899 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12900 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12903 (define_expand "tls_dynamic_gnu2_64"
12904 [(set (match_dup 2)
12905 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12908 [(set (match_operand:DI 0 "register_operand" "")
12909 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12911 (clobber (reg:CC FLAGS_REG))])]
12912 "TARGET_64BIT && TARGET_GNU2_TLS"
12914 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12915 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12918 (define_insn "*tls_dynamic_gnu2_lea_64"
12919 [(set (match_operand:DI 0 "register_operand" "=r")
12920 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12922 "TARGET_64BIT && TARGET_GNU2_TLS"
12923 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12924 [(set_attr "type" "lea")
12925 (set_attr "mode" "DI")
12926 (set_attr "length" "7")
12927 (set_attr "length_address" "4")])
12929 (define_insn "*tls_dynamic_gnu2_call_64"
12930 [(set (match_operand:DI 0 "register_operand" "=a")
12931 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12932 (match_operand:DI 2 "register_operand" "0")
12935 (clobber (reg:CC FLAGS_REG))]
12936 "TARGET_64BIT && TARGET_GNU2_TLS"
12937 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12938 [(set_attr "type" "call")
12939 (set_attr "length" "2")
12940 (set_attr "length_address" "0")])
12942 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12943 [(set (match_operand:DI 0 "register_operand" "=&a")
12945 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12946 (match_operand:DI 3 "" "")
12949 (const:DI (unspec:DI
12950 [(match_operand 1 "tls_symbolic_operand" "")]
12952 (clobber (reg:CC FLAGS_REG))]
12953 "TARGET_64BIT && TARGET_GNU2_TLS"
12956 [(set (match_dup 0) (match_dup 4))]
12958 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12959 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12962 ;; These patterns match the binary 387 instructions for addM3, subM3,
12963 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12964 ;; SFmode. The first is the normal insn, the second the same insn but
12965 ;; with one operand a conversion, and the third the same insn but with
12966 ;; the other operand a conversion. The conversion may be SFmode or
12967 ;; SImode if the target mode DFmode, but only SImode if the target mode
12970 ;; Gcc is slightly more smart about handling normal two address instructions
12971 ;; so use special patterns for add and mull.
12973 (define_insn "*fop_<mode>_comm_mixed"
12974 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12975 (match_operator:MODEF 3 "binary_fp_operator"
12976 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12977 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12978 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12979 && COMMUTATIVE_ARITH_P (operands[3])
12980 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12981 "* return output_387_binary_op (insn, operands);"
12982 [(set (attr "type")
12983 (if_then_else (eq_attr "alternative" "1,2")
12984 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12985 (const_string "ssemul")
12986 (const_string "sseadd"))
12987 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12988 (const_string "fmul")
12989 (const_string "fop"))))
12990 (set_attr "isa" "*,noavx,avx")
12991 (set_attr "prefix" "orig,orig,vex")
12992 (set_attr "mode" "<MODE>")])
12994 (define_insn "*fop_<mode>_comm_sse"
12995 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12996 (match_operator:MODEF 3 "binary_fp_operator"
12997 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12998 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12999 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13000 && COMMUTATIVE_ARITH_P (operands[3])
13001 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13002 "* return output_387_binary_op (insn, operands);"
13003 [(set (attr "type")
13004 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13005 (const_string "ssemul")
13006 (const_string "sseadd")))
13007 (set_attr "isa" "noavx,avx")
13008 (set_attr "prefix" "orig,vex")
13009 (set_attr "mode" "<MODE>")])
13011 (define_insn "*fop_<mode>_comm_i387"
13012 [(set (match_operand:MODEF 0 "register_operand" "=f")
13013 (match_operator:MODEF 3 "binary_fp_operator"
13014 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13015 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13016 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13017 && COMMUTATIVE_ARITH_P (operands[3])
13018 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13019 "* return output_387_binary_op (insn, operands);"
13020 [(set (attr "type")
13021 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13022 (const_string "fmul")
13023 (const_string "fop")))
13024 (set_attr "mode" "<MODE>")])
13026 (define_insn "*fop_<mode>_1_mixed"
13027 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13028 (match_operator:MODEF 3 "binary_fp_operator"
13029 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13030 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13031 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13032 && !COMMUTATIVE_ARITH_P (operands[3])
13033 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13034 "* return output_387_binary_op (insn, operands);"
13035 [(set (attr "type")
13036 (cond [(and (eq_attr "alternative" "2,3")
13037 (match_operand:MODEF 3 "mult_operator" ""))
13038 (const_string "ssemul")
13039 (and (eq_attr "alternative" "2,3")
13040 (match_operand:MODEF 3 "div_operator" ""))
13041 (const_string "ssediv")
13042 (eq_attr "alternative" "2,3")
13043 (const_string "sseadd")
13044 (match_operand:MODEF 3 "mult_operator" "")
13045 (const_string "fmul")
13046 (match_operand:MODEF 3 "div_operator" "")
13047 (const_string "fdiv")
13049 (const_string "fop")))
13050 (set_attr "isa" "*,*,noavx,avx")
13051 (set_attr "prefix" "orig,orig,orig,vex")
13052 (set_attr "mode" "<MODE>")])
13054 (define_insn "*rcpsf2_sse"
13055 [(set (match_operand:SF 0 "register_operand" "=x")
13056 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13059 "%vrcpss\t{%1, %d0|%d0, %1}"
13060 [(set_attr "type" "sse")
13061 (set_attr "atom_sse_attr" "rcp")
13062 (set_attr "prefix" "maybe_vex")
13063 (set_attr "mode" "SF")])
13065 (define_insn "*fop_<mode>_1_sse"
13066 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13067 (match_operator:MODEF 3 "binary_fp_operator"
13068 [(match_operand:MODEF 1 "register_operand" "0,x")
13069 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13070 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13071 && !COMMUTATIVE_ARITH_P (operands[3])"
13072 "* return output_387_binary_op (insn, operands);"
13073 [(set (attr "type")
13074 (cond [(match_operand:MODEF 3 "mult_operator" "")
13075 (const_string "ssemul")
13076 (match_operand:MODEF 3 "div_operator" "")
13077 (const_string "ssediv")
13079 (const_string "sseadd")))
13080 (set_attr "isa" "noavx,avx")
13081 (set_attr "prefix" "orig,vex")
13082 (set_attr "mode" "<MODE>")])
13084 ;; This pattern is not fully shadowed by the pattern above.
13085 (define_insn "*fop_<mode>_1_i387"
13086 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13087 (match_operator:MODEF 3 "binary_fp_operator"
13088 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13089 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13090 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13091 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13092 && !COMMUTATIVE_ARITH_P (operands[3])
13093 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13094 "* return output_387_binary_op (insn, operands);"
13095 [(set (attr "type")
13096 (cond [(match_operand:MODEF 3 "mult_operator" "")
13097 (const_string "fmul")
13098 (match_operand:MODEF 3 "div_operator" "")
13099 (const_string "fdiv")
13101 (const_string "fop")))
13102 (set_attr "mode" "<MODE>")])
13104 ;; ??? Add SSE splitters for these!
13105 (define_insn "*fop_<MODEF:mode>_2_i387"
13106 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13107 (match_operator:MODEF 3 "binary_fp_operator"
13109 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13110 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13111 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13112 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13113 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13114 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13115 [(set (attr "type")
13116 (cond [(match_operand:MODEF 3 "mult_operator" "")
13117 (const_string "fmul")
13118 (match_operand:MODEF 3 "div_operator" "")
13119 (const_string "fdiv")
13121 (const_string "fop")))
13122 (set_attr "fp_int_src" "true")
13123 (set_attr "mode" "<SWI24:MODE>")])
13125 (define_insn "*fop_<MODEF:mode>_3_i387"
13126 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13127 (match_operator:MODEF 3 "binary_fp_operator"
13128 [(match_operand:MODEF 1 "register_operand" "0,0")
13130 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13131 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13132 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13133 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13134 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13135 [(set (attr "type")
13136 (cond [(match_operand:MODEF 3 "mult_operator" "")
13137 (const_string "fmul")
13138 (match_operand:MODEF 3 "div_operator" "")
13139 (const_string "fdiv")
13141 (const_string "fop")))
13142 (set_attr "fp_int_src" "true")
13143 (set_attr "mode" "<MODE>")])
13145 (define_insn "*fop_df_4_i387"
13146 [(set (match_operand:DF 0 "register_operand" "=f,f")
13147 (match_operator:DF 3 "binary_fp_operator"
13149 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13150 (match_operand:DF 2 "register_operand" "0,f")]))]
13151 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13152 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13153 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13154 "* return output_387_binary_op (insn, operands);"
13155 [(set (attr "type")
13156 (cond [(match_operand:DF 3 "mult_operator" "")
13157 (const_string "fmul")
13158 (match_operand:DF 3 "div_operator" "")
13159 (const_string "fdiv")
13161 (const_string "fop")))
13162 (set_attr "mode" "SF")])
13164 (define_insn "*fop_df_5_i387"
13165 [(set (match_operand:DF 0 "register_operand" "=f,f")
13166 (match_operator:DF 3 "binary_fp_operator"
13167 [(match_operand:DF 1 "register_operand" "0,f")
13169 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13170 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13171 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13172 "* return output_387_binary_op (insn, operands);"
13173 [(set (attr "type")
13174 (cond [(match_operand:DF 3 "mult_operator" "")
13175 (const_string "fmul")
13176 (match_operand:DF 3 "div_operator" "")
13177 (const_string "fdiv")
13179 (const_string "fop")))
13180 (set_attr "mode" "SF")])
13182 (define_insn "*fop_df_6_i387"
13183 [(set (match_operand:DF 0 "register_operand" "=f,f")
13184 (match_operator:DF 3 "binary_fp_operator"
13186 (match_operand:SF 1 "register_operand" "0,f"))
13188 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13189 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13190 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13191 "* return output_387_binary_op (insn, operands);"
13192 [(set (attr "type")
13193 (cond [(match_operand:DF 3 "mult_operator" "")
13194 (const_string "fmul")
13195 (match_operand:DF 3 "div_operator" "")
13196 (const_string "fdiv")
13198 (const_string "fop")))
13199 (set_attr "mode" "SF")])
13201 (define_insn "*fop_xf_comm_i387"
13202 [(set (match_operand:XF 0 "register_operand" "=f")
13203 (match_operator:XF 3 "binary_fp_operator"
13204 [(match_operand:XF 1 "register_operand" "%0")
13205 (match_operand:XF 2 "register_operand" "f")]))]
13207 && COMMUTATIVE_ARITH_P (operands[3])"
13208 "* return output_387_binary_op (insn, operands);"
13209 [(set (attr "type")
13210 (if_then_else (match_operand:XF 3 "mult_operator" "")
13211 (const_string "fmul")
13212 (const_string "fop")))
13213 (set_attr "mode" "XF")])
13215 (define_insn "*fop_xf_1_i387"
13216 [(set (match_operand:XF 0 "register_operand" "=f,f")
13217 (match_operator:XF 3 "binary_fp_operator"
13218 [(match_operand:XF 1 "register_operand" "0,f")
13219 (match_operand:XF 2 "register_operand" "f,0")]))]
13221 && !COMMUTATIVE_ARITH_P (operands[3])"
13222 "* return output_387_binary_op (insn, operands);"
13223 [(set (attr "type")
13224 (cond [(match_operand:XF 3 "mult_operator" "")
13225 (const_string "fmul")
13226 (match_operand:XF 3 "div_operator" "")
13227 (const_string "fdiv")
13229 (const_string "fop")))
13230 (set_attr "mode" "XF")])
13232 (define_insn "*fop_xf_2_i387"
13233 [(set (match_operand:XF 0 "register_operand" "=f,f")
13234 (match_operator:XF 3 "binary_fp_operator"
13236 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13237 (match_operand:XF 2 "register_operand" "0,0")]))]
13238 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13239 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13240 [(set (attr "type")
13241 (cond [(match_operand:XF 3 "mult_operator" "")
13242 (const_string "fmul")
13243 (match_operand:XF 3 "div_operator" "")
13244 (const_string "fdiv")
13246 (const_string "fop")))
13247 (set_attr "fp_int_src" "true")
13248 (set_attr "mode" "<MODE>")])
13250 (define_insn "*fop_xf_3_i387"
13251 [(set (match_operand:XF 0 "register_operand" "=f,f")
13252 (match_operator:XF 3 "binary_fp_operator"
13253 [(match_operand:XF 1 "register_operand" "0,0")
13255 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13256 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13257 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13258 [(set (attr "type")
13259 (cond [(match_operand:XF 3 "mult_operator" "")
13260 (const_string "fmul")
13261 (match_operand:XF 3 "div_operator" "")
13262 (const_string "fdiv")
13264 (const_string "fop")))
13265 (set_attr "fp_int_src" "true")
13266 (set_attr "mode" "<MODE>")])
13268 (define_insn "*fop_xf_4_i387"
13269 [(set (match_operand:XF 0 "register_operand" "=f,f")
13270 (match_operator:XF 3 "binary_fp_operator"
13272 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13273 (match_operand:XF 2 "register_operand" "0,f")]))]
13275 "* return output_387_binary_op (insn, operands);"
13276 [(set (attr "type")
13277 (cond [(match_operand:XF 3 "mult_operator" "")
13278 (const_string "fmul")
13279 (match_operand:XF 3 "div_operator" "")
13280 (const_string "fdiv")
13282 (const_string "fop")))
13283 (set_attr "mode" "<MODE>")])
13285 (define_insn "*fop_xf_5_i387"
13286 [(set (match_operand:XF 0 "register_operand" "=f,f")
13287 (match_operator:XF 3 "binary_fp_operator"
13288 [(match_operand:XF 1 "register_operand" "0,f")
13290 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13292 "* return output_387_binary_op (insn, operands);"
13293 [(set (attr "type")
13294 (cond [(match_operand:XF 3 "mult_operator" "")
13295 (const_string "fmul")
13296 (match_operand:XF 3 "div_operator" "")
13297 (const_string "fdiv")
13299 (const_string "fop")))
13300 (set_attr "mode" "<MODE>")])
13302 (define_insn "*fop_xf_6_i387"
13303 [(set (match_operand:XF 0 "register_operand" "=f,f")
13304 (match_operator:XF 3 "binary_fp_operator"
13306 (match_operand:MODEF 1 "register_operand" "0,f"))
13308 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13310 "* return output_387_binary_op (insn, operands);"
13311 [(set (attr "type")
13312 (cond [(match_operand:XF 3 "mult_operator" "")
13313 (const_string "fmul")
13314 (match_operand:XF 3 "div_operator" "")
13315 (const_string "fdiv")
13317 (const_string "fop")))
13318 (set_attr "mode" "<MODE>")])
13321 [(set (match_operand 0 "register_operand" "")
13322 (match_operator 3 "binary_fp_operator"
13323 [(float (match_operand:SWI24 1 "register_operand" ""))
13324 (match_operand 2 "register_operand" "")]))]
13326 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13327 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13330 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13331 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13332 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13333 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13334 GET_MODE (operands[3]),
13337 ix86_free_from_memory (GET_MODE (operands[1]));
13342 [(set (match_operand 0 "register_operand" "")
13343 (match_operator 3 "binary_fp_operator"
13344 [(match_operand 1 "register_operand" "")
13345 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13347 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13348 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13351 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13352 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13353 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13354 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13355 GET_MODE (operands[3]),
13358 ix86_free_from_memory (GET_MODE (operands[2]));
13362 ;; FPU special functions.
13364 ;; This pattern implements a no-op XFmode truncation for
13365 ;; all fancy i386 XFmode math functions.
13367 (define_insn "truncxf<mode>2_i387_noop_unspec"
13368 [(set (match_operand:MODEF 0 "register_operand" "=f")
13369 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13370 UNSPEC_TRUNC_NOOP))]
13371 "TARGET_USE_FANCY_MATH_387"
13372 "* return output_387_reg_move (insn, operands);"
13373 [(set_attr "type" "fmov")
13374 (set_attr "mode" "<MODE>")])
13376 (define_insn "sqrtxf2"
13377 [(set (match_operand:XF 0 "register_operand" "=f")
13378 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13379 "TARGET_USE_FANCY_MATH_387"
13381 [(set_attr "type" "fpspc")
13382 (set_attr "mode" "XF")
13383 (set_attr "athlon_decode" "direct")
13384 (set_attr "amdfam10_decode" "direct")
13385 (set_attr "bdver1_decode" "direct")])
13387 (define_insn "sqrt_extend<mode>xf2_i387"
13388 [(set (match_operand:XF 0 "register_operand" "=f")
13391 (match_operand:MODEF 1 "register_operand" "0"))))]
13392 "TARGET_USE_FANCY_MATH_387"
13394 [(set_attr "type" "fpspc")
13395 (set_attr "mode" "XF")
13396 (set_attr "athlon_decode" "direct")
13397 (set_attr "amdfam10_decode" "direct")
13398 (set_attr "bdver1_decode" "direct")])
13400 (define_insn "*rsqrtsf2_sse"
13401 [(set (match_operand:SF 0 "register_operand" "=x")
13402 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13405 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13406 [(set_attr "type" "sse")
13407 (set_attr "atom_sse_attr" "rcp")
13408 (set_attr "prefix" "maybe_vex")
13409 (set_attr "mode" "SF")])
13411 (define_expand "rsqrtsf2"
13412 [(set (match_operand:SF 0 "register_operand" "")
13413 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13417 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13421 (define_insn "*sqrt<mode>2_sse"
13422 [(set (match_operand:MODEF 0 "register_operand" "=x")
13424 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13425 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13426 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13427 [(set_attr "type" "sse")
13428 (set_attr "atom_sse_attr" "sqrt")
13429 (set_attr "prefix" "maybe_vex")
13430 (set_attr "mode" "<MODE>")
13431 (set_attr "athlon_decode" "*")
13432 (set_attr "amdfam10_decode" "*")
13433 (set_attr "bdver1_decode" "*")])
13435 (define_expand "sqrt<mode>2"
13436 [(set (match_operand:MODEF 0 "register_operand" "")
13438 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13439 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13440 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13442 if (<MODE>mode == SFmode
13444 && TARGET_RECIP_SQRT
13445 && !optimize_function_for_size_p (cfun)
13446 && flag_finite_math_only && !flag_trapping_math
13447 && flag_unsafe_math_optimizations)
13449 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13453 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13455 rtx op0 = gen_reg_rtx (XFmode);
13456 rtx op1 = force_reg (<MODE>mode, operands[1]);
13458 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13459 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13464 (define_insn "fpremxf4_i387"
13465 [(set (match_operand:XF 0 "register_operand" "=f")
13466 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13467 (match_operand:XF 3 "register_operand" "1")]
13469 (set (match_operand:XF 1 "register_operand" "=u")
13470 (unspec:XF [(match_dup 2) (match_dup 3)]
13472 (set (reg:CCFP FPSR_REG)
13473 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13475 "TARGET_USE_FANCY_MATH_387"
13477 [(set_attr "type" "fpspc")
13478 (set_attr "mode" "XF")])
13480 (define_expand "fmodxf3"
13481 [(use (match_operand:XF 0 "register_operand" ""))
13482 (use (match_operand:XF 1 "general_operand" ""))
13483 (use (match_operand:XF 2 "general_operand" ""))]
13484 "TARGET_USE_FANCY_MATH_387"
13486 rtx label = gen_label_rtx ();
13488 rtx op1 = gen_reg_rtx (XFmode);
13489 rtx op2 = gen_reg_rtx (XFmode);
13491 emit_move_insn (op2, operands[2]);
13492 emit_move_insn (op1, operands[1]);
13494 emit_label (label);
13495 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13496 ix86_emit_fp_unordered_jump (label);
13497 LABEL_NUSES (label) = 1;
13499 emit_move_insn (operands[0], op1);
13503 (define_expand "fmod<mode>3"
13504 [(use (match_operand:MODEF 0 "register_operand" ""))
13505 (use (match_operand:MODEF 1 "general_operand" ""))
13506 (use (match_operand:MODEF 2 "general_operand" ""))]
13507 "TARGET_USE_FANCY_MATH_387"
13509 rtx (*gen_truncxf) (rtx, rtx);
13511 rtx label = gen_label_rtx ();
13513 rtx op1 = gen_reg_rtx (XFmode);
13514 rtx op2 = gen_reg_rtx (XFmode);
13516 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13517 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13519 emit_label (label);
13520 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13521 ix86_emit_fp_unordered_jump (label);
13522 LABEL_NUSES (label) = 1;
13524 /* Truncate the result properly for strict SSE math. */
13525 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13526 && !TARGET_MIX_SSE_I387)
13527 gen_truncxf = gen_truncxf<mode>2;
13529 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13531 emit_insn (gen_truncxf (operands[0], op1));
13535 (define_insn "fprem1xf4_i387"
13536 [(set (match_operand:XF 0 "register_operand" "=f")
13537 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13538 (match_operand:XF 3 "register_operand" "1")]
13540 (set (match_operand:XF 1 "register_operand" "=u")
13541 (unspec:XF [(match_dup 2) (match_dup 3)]
13543 (set (reg:CCFP FPSR_REG)
13544 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13546 "TARGET_USE_FANCY_MATH_387"
13548 [(set_attr "type" "fpspc")
13549 (set_attr "mode" "XF")])
13551 (define_expand "remainderxf3"
13552 [(use (match_operand:XF 0 "register_operand" ""))
13553 (use (match_operand:XF 1 "general_operand" ""))
13554 (use (match_operand:XF 2 "general_operand" ""))]
13555 "TARGET_USE_FANCY_MATH_387"
13557 rtx label = gen_label_rtx ();
13559 rtx op1 = gen_reg_rtx (XFmode);
13560 rtx op2 = gen_reg_rtx (XFmode);
13562 emit_move_insn (op2, operands[2]);
13563 emit_move_insn (op1, operands[1]);
13565 emit_label (label);
13566 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13567 ix86_emit_fp_unordered_jump (label);
13568 LABEL_NUSES (label) = 1;
13570 emit_move_insn (operands[0], op1);
13574 (define_expand "remainder<mode>3"
13575 [(use (match_operand:MODEF 0 "register_operand" ""))
13576 (use (match_operand:MODEF 1 "general_operand" ""))
13577 (use (match_operand:MODEF 2 "general_operand" ""))]
13578 "TARGET_USE_FANCY_MATH_387"
13580 rtx (*gen_truncxf) (rtx, rtx);
13582 rtx label = gen_label_rtx ();
13584 rtx op1 = gen_reg_rtx (XFmode);
13585 rtx op2 = gen_reg_rtx (XFmode);
13587 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13588 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13590 emit_label (label);
13592 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13593 ix86_emit_fp_unordered_jump (label);
13594 LABEL_NUSES (label) = 1;
13596 /* Truncate the result properly for strict SSE math. */
13597 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13598 && !TARGET_MIX_SSE_I387)
13599 gen_truncxf = gen_truncxf<mode>2;
13601 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13603 emit_insn (gen_truncxf (operands[0], op1));
13607 (define_insn "*sinxf2_i387"
13608 [(set (match_operand:XF 0 "register_operand" "=f")
13609 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13610 "TARGET_USE_FANCY_MATH_387
13611 && flag_unsafe_math_optimizations"
13613 [(set_attr "type" "fpspc")
13614 (set_attr "mode" "XF")])
13616 (define_insn "*sin_extend<mode>xf2_i387"
13617 [(set (match_operand:XF 0 "register_operand" "=f")
13618 (unspec:XF [(float_extend:XF
13619 (match_operand:MODEF 1 "register_operand" "0"))]
13621 "TARGET_USE_FANCY_MATH_387
13622 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13623 || TARGET_MIX_SSE_I387)
13624 && flag_unsafe_math_optimizations"
13626 [(set_attr "type" "fpspc")
13627 (set_attr "mode" "XF")])
13629 (define_insn "*cosxf2_i387"
13630 [(set (match_operand:XF 0 "register_operand" "=f")
13631 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13632 "TARGET_USE_FANCY_MATH_387
13633 && flag_unsafe_math_optimizations"
13635 [(set_attr "type" "fpspc")
13636 (set_attr "mode" "XF")])
13638 (define_insn "*cos_extend<mode>xf2_i387"
13639 [(set (match_operand:XF 0 "register_operand" "=f")
13640 (unspec:XF [(float_extend:XF
13641 (match_operand:MODEF 1 "register_operand" "0"))]
13643 "TARGET_USE_FANCY_MATH_387
13644 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13645 || TARGET_MIX_SSE_I387)
13646 && flag_unsafe_math_optimizations"
13648 [(set_attr "type" "fpspc")
13649 (set_attr "mode" "XF")])
13651 ;; When sincos pattern is defined, sin and cos builtin functions will be
13652 ;; expanded to sincos pattern with one of its outputs left unused.
13653 ;; CSE pass will figure out if two sincos patterns can be combined,
13654 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13655 ;; depending on the unused output.
13657 (define_insn "sincosxf3"
13658 [(set (match_operand:XF 0 "register_operand" "=f")
13659 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13660 UNSPEC_SINCOS_COS))
13661 (set (match_operand:XF 1 "register_operand" "=u")
13662 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13663 "TARGET_USE_FANCY_MATH_387
13664 && flag_unsafe_math_optimizations"
13666 [(set_attr "type" "fpspc")
13667 (set_attr "mode" "XF")])
13670 [(set (match_operand:XF 0 "register_operand" "")
13671 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13672 UNSPEC_SINCOS_COS))
13673 (set (match_operand:XF 1 "register_operand" "")
13674 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13675 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13676 && can_create_pseudo_p ()"
13677 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13680 [(set (match_operand:XF 0 "register_operand" "")
13681 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13682 UNSPEC_SINCOS_COS))
13683 (set (match_operand:XF 1 "register_operand" "")
13684 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13685 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13686 && can_create_pseudo_p ()"
13687 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13689 (define_insn "sincos_extend<mode>xf3_i387"
13690 [(set (match_operand:XF 0 "register_operand" "=f")
13691 (unspec:XF [(float_extend:XF
13692 (match_operand:MODEF 2 "register_operand" "0"))]
13693 UNSPEC_SINCOS_COS))
13694 (set (match_operand:XF 1 "register_operand" "=u")
13695 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13696 "TARGET_USE_FANCY_MATH_387
13697 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13698 || TARGET_MIX_SSE_I387)
13699 && flag_unsafe_math_optimizations"
13701 [(set_attr "type" "fpspc")
13702 (set_attr "mode" "XF")])
13705 [(set (match_operand:XF 0 "register_operand" "")
13706 (unspec:XF [(float_extend:XF
13707 (match_operand:MODEF 2 "register_operand" ""))]
13708 UNSPEC_SINCOS_COS))
13709 (set (match_operand:XF 1 "register_operand" "")
13710 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13711 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13712 && can_create_pseudo_p ()"
13713 [(set (match_dup 1)
13714 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13717 [(set (match_operand:XF 0 "register_operand" "")
13718 (unspec:XF [(float_extend:XF
13719 (match_operand:MODEF 2 "register_operand" ""))]
13720 UNSPEC_SINCOS_COS))
13721 (set (match_operand:XF 1 "register_operand" "")
13722 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13723 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13724 && can_create_pseudo_p ()"
13725 [(set (match_dup 0)
13726 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13728 (define_expand "sincos<mode>3"
13729 [(use (match_operand:MODEF 0 "register_operand" ""))
13730 (use (match_operand:MODEF 1 "register_operand" ""))
13731 (use (match_operand:MODEF 2 "register_operand" ""))]
13732 "TARGET_USE_FANCY_MATH_387
13733 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13734 || TARGET_MIX_SSE_I387)
13735 && flag_unsafe_math_optimizations"
13737 rtx op0 = gen_reg_rtx (XFmode);
13738 rtx op1 = gen_reg_rtx (XFmode);
13740 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13741 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13742 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13746 (define_insn "fptanxf4_i387"
13747 [(set (match_operand:XF 0 "register_operand" "=f")
13748 (match_operand:XF 3 "const_double_operand" "F"))
13749 (set (match_operand:XF 1 "register_operand" "=u")
13750 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13752 "TARGET_USE_FANCY_MATH_387
13753 && flag_unsafe_math_optimizations
13754 && standard_80387_constant_p (operands[3]) == 2"
13756 [(set_attr "type" "fpspc")
13757 (set_attr "mode" "XF")])
13759 (define_insn "fptan_extend<mode>xf4_i387"
13760 [(set (match_operand:MODEF 0 "register_operand" "=f")
13761 (match_operand:MODEF 3 "const_double_operand" "F"))
13762 (set (match_operand:XF 1 "register_operand" "=u")
13763 (unspec:XF [(float_extend:XF
13764 (match_operand:MODEF 2 "register_operand" "0"))]
13766 "TARGET_USE_FANCY_MATH_387
13767 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13768 || TARGET_MIX_SSE_I387)
13769 && flag_unsafe_math_optimizations
13770 && standard_80387_constant_p (operands[3]) == 2"
13772 [(set_attr "type" "fpspc")
13773 (set_attr "mode" "XF")])
13775 (define_expand "tanxf2"
13776 [(use (match_operand:XF 0 "register_operand" ""))
13777 (use (match_operand:XF 1 "register_operand" ""))]
13778 "TARGET_USE_FANCY_MATH_387
13779 && flag_unsafe_math_optimizations"
13781 rtx one = gen_reg_rtx (XFmode);
13782 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13784 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13788 (define_expand "tan<mode>2"
13789 [(use (match_operand:MODEF 0 "register_operand" ""))
13790 (use (match_operand:MODEF 1 "register_operand" ""))]
13791 "TARGET_USE_FANCY_MATH_387
13792 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13793 || TARGET_MIX_SSE_I387)
13794 && flag_unsafe_math_optimizations"
13796 rtx op0 = gen_reg_rtx (XFmode);
13798 rtx one = gen_reg_rtx (<MODE>mode);
13799 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13801 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13802 operands[1], op2));
13803 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13807 (define_insn "*fpatanxf3_i387"
13808 [(set (match_operand:XF 0 "register_operand" "=f")
13809 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13810 (match_operand:XF 2 "register_operand" "u")]
13812 (clobber (match_scratch:XF 3 "=2"))]
13813 "TARGET_USE_FANCY_MATH_387
13814 && flag_unsafe_math_optimizations"
13816 [(set_attr "type" "fpspc")
13817 (set_attr "mode" "XF")])
13819 (define_insn "fpatan_extend<mode>xf3_i387"
13820 [(set (match_operand:XF 0 "register_operand" "=f")
13821 (unspec:XF [(float_extend:XF
13822 (match_operand:MODEF 1 "register_operand" "0"))
13824 (match_operand:MODEF 2 "register_operand" "u"))]
13826 (clobber (match_scratch:XF 3 "=2"))]
13827 "TARGET_USE_FANCY_MATH_387
13828 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13829 || TARGET_MIX_SSE_I387)
13830 && flag_unsafe_math_optimizations"
13832 [(set_attr "type" "fpspc")
13833 (set_attr "mode" "XF")])
13835 (define_expand "atan2xf3"
13836 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13837 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13838 (match_operand:XF 1 "register_operand" "")]
13840 (clobber (match_scratch:XF 3 ""))])]
13841 "TARGET_USE_FANCY_MATH_387
13842 && flag_unsafe_math_optimizations")
13844 (define_expand "atan2<mode>3"
13845 [(use (match_operand:MODEF 0 "register_operand" ""))
13846 (use (match_operand:MODEF 1 "register_operand" ""))
13847 (use (match_operand:MODEF 2 "register_operand" ""))]
13848 "TARGET_USE_FANCY_MATH_387
13849 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13850 || TARGET_MIX_SSE_I387)
13851 && flag_unsafe_math_optimizations"
13853 rtx op0 = gen_reg_rtx (XFmode);
13855 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13856 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13860 (define_expand "atanxf2"
13861 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13862 (unspec:XF [(match_dup 2)
13863 (match_operand:XF 1 "register_operand" "")]
13865 (clobber (match_scratch:XF 3 ""))])]
13866 "TARGET_USE_FANCY_MATH_387
13867 && flag_unsafe_math_optimizations"
13869 operands[2] = gen_reg_rtx (XFmode);
13870 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13873 (define_expand "atan<mode>2"
13874 [(use (match_operand:MODEF 0 "register_operand" ""))
13875 (use (match_operand:MODEF 1 "register_operand" ""))]
13876 "TARGET_USE_FANCY_MATH_387
13877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13878 || TARGET_MIX_SSE_I387)
13879 && flag_unsafe_math_optimizations"
13881 rtx op0 = gen_reg_rtx (XFmode);
13883 rtx op2 = gen_reg_rtx (<MODE>mode);
13884 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13886 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13887 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13891 (define_expand "asinxf2"
13892 [(set (match_dup 2)
13893 (mult:XF (match_operand:XF 1 "register_operand" "")
13895 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13896 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13897 (parallel [(set (match_operand:XF 0 "register_operand" "")
13898 (unspec:XF [(match_dup 5) (match_dup 1)]
13900 (clobber (match_scratch:XF 6 ""))])]
13901 "TARGET_USE_FANCY_MATH_387
13902 && flag_unsafe_math_optimizations"
13906 if (optimize_insn_for_size_p ())
13909 for (i = 2; i < 6; i++)
13910 operands[i] = gen_reg_rtx (XFmode);
13912 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13915 (define_expand "asin<mode>2"
13916 [(use (match_operand:MODEF 0 "register_operand" ""))
13917 (use (match_operand:MODEF 1 "general_operand" ""))]
13918 "TARGET_USE_FANCY_MATH_387
13919 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13920 || TARGET_MIX_SSE_I387)
13921 && flag_unsafe_math_optimizations"
13923 rtx op0 = gen_reg_rtx (XFmode);
13924 rtx op1 = gen_reg_rtx (XFmode);
13926 if (optimize_insn_for_size_p ())
13929 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13930 emit_insn (gen_asinxf2 (op0, op1));
13931 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13935 (define_expand "acosxf2"
13936 [(set (match_dup 2)
13937 (mult:XF (match_operand:XF 1 "register_operand" "")
13939 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13940 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13941 (parallel [(set (match_operand:XF 0 "register_operand" "")
13942 (unspec:XF [(match_dup 1) (match_dup 5)]
13944 (clobber (match_scratch:XF 6 ""))])]
13945 "TARGET_USE_FANCY_MATH_387
13946 && flag_unsafe_math_optimizations"
13950 if (optimize_insn_for_size_p ())
13953 for (i = 2; i < 6; i++)
13954 operands[i] = gen_reg_rtx (XFmode);
13956 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13959 (define_expand "acos<mode>2"
13960 [(use (match_operand:MODEF 0 "register_operand" ""))
13961 (use (match_operand:MODEF 1 "general_operand" ""))]
13962 "TARGET_USE_FANCY_MATH_387
13963 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13964 || TARGET_MIX_SSE_I387)
13965 && flag_unsafe_math_optimizations"
13967 rtx op0 = gen_reg_rtx (XFmode);
13968 rtx op1 = gen_reg_rtx (XFmode);
13970 if (optimize_insn_for_size_p ())
13973 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13974 emit_insn (gen_acosxf2 (op0, op1));
13975 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13979 (define_insn "fyl2xxf3_i387"
13980 [(set (match_operand:XF 0 "register_operand" "=f")
13981 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13982 (match_operand:XF 2 "register_operand" "u")]
13984 (clobber (match_scratch:XF 3 "=2"))]
13985 "TARGET_USE_FANCY_MATH_387
13986 && flag_unsafe_math_optimizations"
13988 [(set_attr "type" "fpspc")
13989 (set_attr "mode" "XF")])
13991 (define_insn "fyl2x_extend<mode>xf3_i387"
13992 [(set (match_operand:XF 0 "register_operand" "=f")
13993 (unspec:XF [(float_extend:XF
13994 (match_operand:MODEF 1 "register_operand" "0"))
13995 (match_operand:XF 2 "register_operand" "u")]
13997 (clobber (match_scratch:XF 3 "=2"))]
13998 "TARGET_USE_FANCY_MATH_387
13999 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14000 || TARGET_MIX_SSE_I387)
14001 && flag_unsafe_math_optimizations"
14003 [(set_attr "type" "fpspc")
14004 (set_attr "mode" "XF")])
14006 (define_expand "logxf2"
14007 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14008 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14009 (match_dup 2)] UNSPEC_FYL2X))
14010 (clobber (match_scratch:XF 3 ""))])]
14011 "TARGET_USE_FANCY_MATH_387
14012 && flag_unsafe_math_optimizations"
14014 operands[2] = gen_reg_rtx (XFmode);
14015 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14018 (define_expand "log<mode>2"
14019 [(use (match_operand:MODEF 0 "register_operand" ""))
14020 (use (match_operand:MODEF 1 "register_operand" ""))]
14021 "TARGET_USE_FANCY_MATH_387
14022 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14023 || TARGET_MIX_SSE_I387)
14024 && flag_unsafe_math_optimizations"
14026 rtx op0 = gen_reg_rtx (XFmode);
14028 rtx op2 = gen_reg_rtx (XFmode);
14029 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14031 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14032 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14036 (define_expand "log10xf2"
14037 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14038 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14039 (match_dup 2)] UNSPEC_FYL2X))
14040 (clobber (match_scratch:XF 3 ""))])]
14041 "TARGET_USE_FANCY_MATH_387
14042 && flag_unsafe_math_optimizations"
14044 operands[2] = gen_reg_rtx (XFmode);
14045 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14048 (define_expand "log10<mode>2"
14049 [(use (match_operand:MODEF 0 "register_operand" ""))
14050 (use (match_operand:MODEF 1 "register_operand" ""))]
14051 "TARGET_USE_FANCY_MATH_387
14052 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14053 || TARGET_MIX_SSE_I387)
14054 && flag_unsafe_math_optimizations"
14056 rtx op0 = gen_reg_rtx (XFmode);
14058 rtx op2 = gen_reg_rtx (XFmode);
14059 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14061 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14062 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14066 (define_expand "log2xf2"
14067 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14068 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14069 (match_dup 2)] UNSPEC_FYL2X))
14070 (clobber (match_scratch:XF 3 ""))])]
14071 "TARGET_USE_FANCY_MATH_387
14072 && flag_unsafe_math_optimizations"
14074 operands[2] = gen_reg_rtx (XFmode);
14075 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14078 (define_expand "log2<mode>2"
14079 [(use (match_operand:MODEF 0 "register_operand" ""))
14080 (use (match_operand:MODEF 1 "register_operand" ""))]
14081 "TARGET_USE_FANCY_MATH_387
14082 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14083 || TARGET_MIX_SSE_I387)
14084 && flag_unsafe_math_optimizations"
14086 rtx op0 = gen_reg_rtx (XFmode);
14088 rtx op2 = gen_reg_rtx (XFmode);
14089 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14091 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14092 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14096 (define_insn "fyl2xp1xf3_i387"
14097 [(set (match_operand:XF 0 "register_operand" "=f")
14098 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14099 (match_operand:XF 2 "register_operand" "u")]
14101 (clobber (match_scratch:XF 3 "=2"))]
14102 "TARGET_USE_FANCY_MATH_387
14103 && flag_unsafe_math_optimizations"
14105 [(set_attr "type" "fpspc")
14106 (set_attr "mode" "XF")])
14108 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14109 [(set (match_operand:XF 0 "register_operand" "=f")
14110 (unspec:XF [(float_extend:XF
14111 (match_operand:MODEF 1 "register_operand" "0"))
14112 (match_operand:XF 2 "register_operand" "u")]
14114 (clobber (match_scratch:XF 3 "=2"))]
14115 "TARGET_USE_FANCY_MATH_387
14116 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14117 || TARGET_MIX_SSE_I387)
14118 && flag_unsafe_math_optimizations"
14120 [(set_attr "type" "fpspc")
14121 (set_attr "mode" "XF")])
14123 (define_expand "log1pxf2"
14124 [(use (match_operand:XF 0 "register_operand" ""))
14125 (use (match_operand:XF 1 "register_operand" ""))]
14126 "TARGET_USE_FANCY_MATH_387
14127 && flag_unsafe_math_optimizations"
14129 if (optimize_insn_for_size_p ())
14132 ix86_emit_i387_log1p (operands[0], operands[1]);
14136 (define_expand "log1p<mode>2"
14137 [(use (match_operand:MODEF 0 "register_operand" ""))
14138 (use (match_operand:MODEF 1 "register_operand" ""))]
14139 "TARGET_USE_FANCY_MATH_387
14140 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14141 || TARGET_MIX_SSE_I387)
14142 && flag_unsafe_math_optimizations"
14146 if (optimize_insn_for_size_p ())
14149 op0 = gen_reg_rtx (XFmode);
14151 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14153 ix86_emit_i387_log1p (op0, operands[1]);
14154 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14158 (define_insn "fxtractxf3_i387"
14159 [(set (match_operand:XF 0 "register_operand" "=f")
14160 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14161 UNSPEC_XTRACT_FRACT))
14162 (set (match_operand:XF 1 "register_operand" "=u")
14163 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14164 "TARGET_USE_FANCY_MATH_387
14165 && flag_unsafe_math_optimizations"
14167 [(set_attr "type" "fpspc")
14168 (set_attr "mode" "XF")])
14170 (define_insn "fxtract_extend<mode>xf3_i387"
14171 [(set (match_operand:XF 0 "register_operand" "=f")
14172 (unspec:XF [(float_extend:XF
14173 (match_operand:MODEF 2 "register_operand" "0"))]
14174 UNSPEC_XTRACT_FRACT))
14175 (set (match_operand:XF 1 "register_operand" "=u")
14176 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14177 "TARGET_USE_FANCY_MATH_387
14178 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14179 || TARGET_MIX_SSE_I387)
14180 && flag_unsafe_math_optimizations"
14182 [(set_attr "type" "fpspc")
14183 (set_attr "mode" "XF")])
14185 (define_expand "logbxf2"
14186 [(parallel [(set (match_dup 2)
14187 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14188 UNSPEC_XTRACT_FRACT))
14189 (set (match_operand:XF 0 "register_operand" "")
14190 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14191 "TARGET_USE_FANCY_MATH_387
14192 && flag_unsafe_math_optimizations"
14193 "operands[2] = gen_reg_rtx (XFmode);")
14195 (define_expand "logb<mode>2"
14196 [(use (match_operand:MODEF 0 "register_operand" ""))
14197 (use (match_operand:MODEF 1 "register_operand" ""))]
14198 "TARGET_USE_FANCY_MATH_387
14199 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14200 || TARGET_MIX_SSE_I387)
14201 && flag_unsafe_math_optimizations"
14203 rtx op0 = gen_reg_rtx (XFmode);
14204 rtx op1 = gen_reg_rtx (XFmode);
14206 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14207 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14211 (define_expand "ilogbxf2"
14212 [(use (match_operand:SI 0 "register_operand" ""))
14213 (use (match_operand:XF 1 "register_operand" ""))]
14214 "TARGET_USE_FANCY_MATH_387
14215 && flag_unsafe_math_optimizations"
14219 if (optimize_insn_for_size_p ())
14222 op0 = gen_reg_rtx (XFmode);
14223 op1 = gen_reg_rtx (XFmode);
14225 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14226 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14230 (define_expand "ilogb<mode>2"
14231 [(use (match_operand:SI 0 "register_operand" ""))
14232 (use (match_operand:MODEF 1 "register_operand" ""))]
14233 "TARGET_USE_FANCY_MATH_387
14234 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14235 || TARGET_MIX_SSE_I387)
14236 && flag_unsafe_math_optimizations"
14240 if (optimize_insn_for_size_p ())
14243 op0 = gen_reg_rtx (XFmode);
14244 op1 = gen_reg_rtx (XFmode);
14246 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14247 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14251 (define_insn "*f2xm1xf2_i387"
14252 [(set (match_operand:XF 0 "register_operand" "=f")
14253 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14255 "TARGET_USE_FANCY_MATH_387
14256 && flag_unsafe_math_optimizations"
14258 [(set_attr "type" "fpspc")
14259 (set_attr "mode" "XF")])
14261 (define_insn "*fscalexf4_i387"
14262 [(set (match_operand:XF 0 "register_operand" "=f")
14263 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14264 (match_operand:XF 3 "register_operand" "1")]
14265 UNSPEC_FSCALE_FRACT))
14266 (set (match_operand:XF 1 "register_operand" "=u")
14267 (unspec:XF [(match_dup 2) (match_dup 3)]
14268 UNSPEC_FSCALE_EXP))]
14269 "TARGET_USE_FANCY_MATH_387
14270 && flag_unsafe_math_optimizations"
14272 [(set_attr "type" "fpspc")
14273 (set_attr "mode" "XF")])
14275 (define_expand "expNcorexf3"
14276 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14277 (match_operand:XF 2 "register_operand" "")))
14278 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14279 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14280 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14281 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14282 (parallel [(set (match_operand:XF 0 "register_operand" "")
14283 (unspec:XF [(match_dup 8) (match_dup 4)]
14284 UNSPEC_FSCALE_FRACT))
14286 (unspec:XF [(match_dup 8) (match_dup 4)]
14287 UNSPEC_FSCALE_EXP))])]
14288 "TARGET_USE_FANCY_MATH_387
14289 && flag_unsafe_math_optimizations"
14293 if (optimize_insn_for_size_p ())
14296 for (i = 3; i < 10; i++)
14297 operands[i] = gen_reg_rtx (XFmode);
14299 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14302 (define_expand "expxf2"
14303 [(use (match_operand:XF 0 "register_operand" ""))
14304 (use (match_operand:XF 1 "register_operand" ""))]
14305 "TARGET_USE_FANCY_MATH_387
14306 && flag_unsafe_math_optimizations"
14310 if (optimize_insn_for_size_p ())
14313 op2 = gen_reg_rtx (XFmode);
14314 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14316 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14320 (define_expand "exp<mode>2"
14321 [(use (match_operand:MODEF 0 "register_operand" ""))
14322 (use (match_operand:MODEF 1 "general_operand" ""))]
14323 "TARGET_USE_FANCY_MATH_387
14324 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14325 || TARGET_MIX_SSE_I387)
14326 && flag_unsafe_math_optimizations"
14330 if (optimize_insn_for_size_p ())
14333 op0 = gen_reg_rtx (XFmode);
14334 op1 = gen_reg_rtx (XFmode);
14336 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14337 emit_insn (gen_expxf2 (op0, op1));
14338 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14342 (define_expand "exp10xf2"
14343 [(use (match_operand:XF 0 "register_operand" ""))
14344 (use (match_operand:XF 1 "register_operand" ""))]
14345 "TARGET_USE_FANCY_MATH_387
14346 && flag_unsafe_math_optimizations"
14350 if (optimize_insn_for_size_p ())
14353 op2 = gen_reg_rtx (XFmode);
14354 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14356 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14360 (define_expand "exp10<mode>2"
14361 [(use (match_operand:MODEF 0 "register_operand" ""))
14362 (use (match_operand:MODEF 1 "general_operand" ""))]
14363 "TARGET_USE_FANCY_MATH_387
14364 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14365 || TARGET_MIX_SSE_I387)
14366 && flag_unsafe_math_optimizations"
14370 if (optimize_insn_for_size_p ())
14373 op0 = gen_reg_rtx (XFmode);
14374 op1 = gen_reg_rtx (XFmode);
14376 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14377 emit_insn (gen_exp10xf2 (op0, op1));
14378 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14382 (define_expand "exp2xf2"
14383 [(use (match_operand:XF 0 "register_operand" ""))
14384 (use (match_operand:XF 1 "register_operand" ""))]
14385 "TARGET_USE_FANCY_MATH_387
14386 && flag_unsafe_math_optimizations"
14390 if (optimize_insn_for_size_p ())
14393 op2 = gen_reg_rtx (XFmode);
14394 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14396 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14400 (define_expand "exp2<mode>2"
14401 [(use (match_operand:MODEF 0 "register_operand" ""))
14402 (use (match_operand:MODEF 1 "general_operand" ""))]
14403 "TARGET_USE_FANCY_MATH_387
14404 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14405 || TARGET_MIX_SSE_I387)
14406 && flag_unsafe_math_optimizations"
14410 if (optimize_insn_for_size_p ())
14413 op0 = gen_reg_rtx (XFmode);
14414 op1 = gen_reg_rtx (XFmode);
14416 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14417 emit_insn (gen_exp2xf2 (op0, op1));
14418 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14422 (define_expand "expm1xf2"
14423 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14425 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14426 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14427 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14428 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14429 (parallel [(set (match_dup 7)
14430 (unspec:XF [(match_dup 6) (match_dup 4)]
14431 UNSPEC_FSCALE_FRACT))
14433 (unspec:XF [(match_dup 6) (match_dup 4)]
14434 UNSPEC_FSCALE_EXP))])
14435 (parallel [(set (match_dup 10)
14436 (unspec:XF [(match_dup 9) (match_dup 8)]
14437 UNSPEC_FSCALE_FRACT))
14438 (set (match_dup 11)
14439 (unspec:XF [(match_dup 9) (match_dup 8)]
14440 UNSPEC_FSCALE_EXP))])
14441 (set (match_dup 12) (minus:XF (match_dup 10)
14442 (float_extend:XF (match_dup 13))))
14443 (set (match_operand:XF 0 "register_operand" "")
14444 (plus:XF (match_dup 12) (match_dup 7)))]
14445 "TARGET_USE_FANCY_MATH_387
14446 && flag_unsafe_math_optimizations"
14450 if (optimize_insn_for_size_p ())
14453 for (i = 2; i < 13; i++)
14454 operands[i] = gen_reg_rtx (XFmode);
14457 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14459 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14462 (define_expand "expm1<mode>2"
14463 [(use (match_operand:MODEF 0 "register_operand" ""))
14464 (use (match_operand:MODEF 1 "general_operand" ""))]
14465 "TARGET_USE_FANCY_MATH_387
14466 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14467 || TARGET_MIX_SSE_I387)
14468 && flag_unsafe_math_optimizations"
14472 if (optimize_insn_for_size_p ())
14475 op0 = gen_reg_rtx (XFmode);
14476 op1 = gen_reg_rtx (XFmode);
14478 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14479 emit_insn (gen_expm1xf2 (op0, op1));
14480 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14484 (define_expand "ldexpxf3"
14485 [(set (match_dup 3)
14486 (float:XF (match_operand:SI 2 "register_operand" "")))
14487 (parallel [(set (match_operand:XF 0 " register_operand" "")
14488 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14490 UNSPEC_FSCALE_FRACT))
14492 (unspec:XF [(match_dup 1) (match_dup 3)]
14493 UNSPEC_FSCALE_EXP))])]
14494 "TARGET_USE_FANCY_MATH_387
14495 && flag_unsafe_math_optimizations"
14497 if (optimize_insn_for_size_p ())
14500 operands[3] = gen_reg_rtx (XFmode);
14501 operands[4] = gen_reg_rtx (XFmode);
14504 (define_expand "ldexp<mode>3"
14505 [(use (match_operand:MODEF 0 "register_operand" ""))
14506 (use (match_operand:MODEF 1 "general_operand" ""))
14507 (use (match_operand:SI 2 "register_operand" ""))]
14508 "TARGET_USE_FANCY_MATH_387
14509 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14510 || TARGET_MIX_SSE_I387)
14511 && flag_unsafe_math_optimizations"
14515 if (optimize_insn_for_size_p ())
14518 op0 = gen_reg_rtx (XFmode);
14519 op1 = gen_reg_rtx (XFmode);
14521 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14522 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14523 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14527 (define_expand "scalbxf3"
14528 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14529 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14530 (match_operand:XF 2 "register_operand" "")]
14531 UNSPEC_FSCALE_FRACT))
14533 (unspec:XF [(match_dup 1) (match_dup 2)]
14534 UNSPEC_FSCALE_EXP))])]
14535 "TARGET_USE_FANCY_MATH_387
14536 && flag_unsafe_math_optimizations"
14538 if (optimize_insn_for_size_p ())
14541 operands[3] = gen_reg_rtx (XFmode);
14544 (define_expand "scalb<mode>3"
14545 [(use (match_operand:MODEF 0 "register_operand" ""))
14546 (use (match_operand:MODEF 1 "general_operand" ""))
14547 (use (match_operand:MODEF 2 "general_operand" ""))]
14548 "TARGET_USE_FANCY_MATH_387
14549 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14550 || TARGET_MIX_SSE_I387)
14551 && flag_unsafe_math_optimizations"
14555 if (optimize_insn_for_size_p ())
14558 op0 = gen_reg_rtx (XFmode);
14559 op1 = gen_reg_rtx (XFmode);
14560 op2 = gen_reg_rtx (XFmode);
14562 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14563 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14564 emit_insn (gen_scalbxf3 (op0, op1, op2));
14565 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14569 (define_expand "significandxf2"
14570 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14571 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14572 UNSPEC_XTRACT_FRACT))
14574 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14575 "TARGET_USE_FANCY_MATH_387
14576 && flag_unsafe_math_optimizations"
14577 "operands[2] = gen_reg_rtx (XFmode);")
14579 (define_expand "significand<mode>2"
14580 [(use (match_operand:MODEF 0 "register_operand" ""))
14581 (use (match_operand:MODEF 1 "register_operand" ""))]
14582 "TARGET_USE_FANCY_MATH_387
14583 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14584 || TARGET_MIX_SSE_I387)
14585 && flag_unsafe_math_optimizations"
14587 rtx op0 = gen_reg_rtx (XFmode);
14588 rtx op1 = gen_reg_rtx (XFmode);
14590 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14591 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14596 (define_insn "sse4_1_round<mode>2"
14597 [(set (match_operand:MODEF 0 "register_operand" "=x")
14598 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14599 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14602 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14603 [(set_attr "type" "ssecvt")
14604 (set_attr "prefix_extra" "1")
14605 (set_attr "prefix" "maybe_vex")
14606 (set_attr "mode" "<MODE>")])
14608 (define_insn "rintxf2"
14609 [(set (match_operand:XF 0 "register_operand" "=f")
14610 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14612 "TARGET_USE_FANCY_MATH_387
14613 && flag_unsafe_math_optimizations"
14615 [(set_attr "type" "fpspc")
14616 (set_attr "mode" "XF")])
14618 (define_expand "rint<mode>2"
14619 [(use (match_operand:MODEF 0 "register_operand" ""))
14620 (use (match_operand:MODEF 1 "register_operand" ""))]
14621 "(TARGET_USE_FANCY_MATH_387
14622 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14623 || TARGET_MIX_SSE_I387)
14624 && flag_unsafe_math_optimizations)
14625 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14626 && !flag_trapping_math)"
14628 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14629 && !flag_trapping_math)
14632 emit_insn (gen_sse4_1_round<mode>2
14633 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14634 else if (optimize_insn_for_size_p ())
14637 ix86_expand_rint (operands[0], operands[1]);
14641 rtx op0 = gen_reg_rtx (XFmode);
14642 rtx op1 = gen_reg_rtx (XFmode);
14644 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14645 emit_insn (gen_rintxf2 (op0, op1));
14647 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14652 (define_expand "round<mode>2"
14653 [(match_operand:X87MODEF 0 "register_operand" "")
14654 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14655 "(TARGET_USE_FANCY_MATH_387
14656 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14657 || TARGET_MIX_SSE_I387)
14658 && flag_unsafe_math_optimizations)
14659 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14660 && !flag_trapping_math && !flag_rounding_math)"
14662 if (optimize_insn_for_size_p ())
14665 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14666 && !flag_trapping_math && !flag_rounding_math)
14670 operands[1] = force_reg (<MODE>mode, operands[1]);
14671 ix86_expand_round_sse4 (operands[0], operands[1]);
14673 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14674 ix86_expand_round (operands[0], operands[1]);
14676 ix86_expand_rounddf_32 (operands[0], operands[1]);
14680 operands[1] = force_reg (<MODE>mode, operands[1]);
14681 ix86_emit_i387_round (operands[0], operands[1]);
14686 (define_insn_and_split "*fistdi2_1"
14687 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14688 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14690 "TARGET_USE_FANCY_MATH_387
14691 && can_create_pseudo_p ()"
14696 if (memory_operand (operands[0], VOIDmode))
14697 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14700 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14701 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14706 [(set_attr "type" "fpspc")
14707 (set_attr "mode" "DI")])
14709 (define_insn "fistdi2"
14710 [(set (match_operand:DI 0 "memory_operand" "=m")
14711 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14713 (clobber (match_scratch:XF 2 "=&1f"))]
14714 "TARGET_USE_FANCY_MATH_387"
14715 "* return output_fix_trunc (insn, operands, false);"
14716 [(set_attr "type" "fpspc")
14717 (set_attr "mode" "DI")])
14719 (define_insn "fistdi2_with_temp"
14720 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14721 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14723 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14724 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14725 "TARGET_USE_FANCY_MATH_387"
14727 [(set_attr "type" "fpspc")
14728 (set_attr "mode" "DI")])
14731 [(set (match_operand:DI 0 "register_operand" "")
14732 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14734 (clobber (match_operand:DI 2 "memory_operand" ""))
14735 (clobber (match_scratch 3 ""))]
14737 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14738 (clobber (match_dup 3))])
14739 (set (match_dup 0) (match_dup 2))])
14742 [(set (match_operand:DI 0 "memory_operand" "")
14743 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14745 (clobber (match_operand:DI 2 "memory_operand" ""))
14746 (clobber (match_scratch 3 ""))]
14748 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14749 (clobber (match_dup 3))])])
14751 (define_insn_and_split "*fist<mode>2_1"
14752 [(set (match_operand:SWI24 0 "register_operand" "")
14753 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14755 "TARGET_USE_FANCY_MATH_387
14756 && can_create_pseudo_p ()"
14761 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14762 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14766 [(set_attr "type" "fpspc")
14767 (set_attr "mode" "<MODE>")])
14769 (define_insn "fist<mode>2"
14770 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14771 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14773 "TARGET_USE_FANCY_MATH_387"
14774 "* return output_fix_trunc (insn, operands, false);"
14775 [(set_attr "type" "fpspc")
14776 (set_attr "mode" "<MODE>")])
14778 (define_insn "fist<mode>2_with_temp"
14779 [(set (match_operand:SWI24 0 "register_operand" "=r")
14780 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14782 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14783 "TARGET_USE_FANCY_MATH_387"
14785 [(set_attr "type" "fpspc")
14786 (set_attr "mode" "<MODE>")])
14789 [(set (match_operand:SWI24 0 "register_operand" "")
14790 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14792 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14794 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14795 (set (match_dup 0) (match_dup 2))])
14798 [(set (match_operand:SWI24 0 "memory_operand" "")
14799 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14801 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14803 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14805 (define_expand "lrintxf<mode>2"
14806 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14807 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14809 "TARGET_USE_FANCY_MATH_387")
14811 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14812 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14813 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14814 UNSPEC_FIX_NOTRUNC))]
14815 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14816 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14818 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14819 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14820 (match_operand:X87MODEF 1 "register_operand" "")]
14821 "(TARGET_USE_FANCY_MATH_387
14822 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14823 || TARGET_MIX_SSE_I387)
14824 && flag_unsafe_math_optimizations)
14825 || (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)"
14830 if (optimize_insn_for_size_p ())
14833 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14834 && <SWI248x:MODE>mode != HImode
14835 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14836 && !flag_trapping_math && !flag_rounding_math)
14837 ix86_expand_lround (operands[0], operands[1]);
14839 ix86_emit_i387_round (operands[0], operands[1]);
14843 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14844 (define_insn_and_split "frndintxf2_floor"
14845 [(set (match_operand:XF 0 "register_operand" "")
14846 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14847 UNSPEC_FRNDINT_FLOOR))
14848 (clobber (reg:CC FLAGS_REG))]
14849 "TARGET_USE_FANCY_MATH_387
14850 && flag_unsafe_math_optimizations
14851 && can_create_pseudo_p ()"
14856 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14858 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14859 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14861 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14862 operands[2], operands[3]));
14865 [(set_attr "type" "frndint")
14866 (set_attr "i387_cw" "floor")
14867 (set_attr "mode" "XF")])
14869 (define_insn "frndintxf2_floor_i387"
14870 [(set (match_operand:XF 0 "register_operand" "=f")
14871 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14872 UNSPEC_FRNDINT_FLOOR))
14873 (use (match_operand:HI 2 "memory_operand" "m"))
14874 (use (match_operand:HI 3 "memory_operand" "m"))]
14875 "TARGET_USE_FANCY_MATH_387
14876 && flag_unsafe_math_optimizations"
14877 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14878 [(set_attr "type" "frndint")
14879 (set_attr "i387_cw" "floor")
14880 (set_attr "mode" "XF")])
14882 (define_expand "floorxf2"
14883 [(use (match_operand:XF 0 "register_operand" ""))
14884 (use (match_operand:XF 1 "register_operand" ""))]
14885 "TARGET_USE_FANCY_MATH_387
14886 && flag_unsafe_math_optimizations"
14888 if (optimize_insn_for_size_p ())
14890 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14894 (define_expand "floor<mode>2"
14895 [(use (match_operand:MODEF 0 "register_operand" ""))
14896 (use (match_operand:MODEF 1 "register_operand" ""))]
14897 "(TARGET_USE_FANCY_MATH_387
14898 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14899 || TARGET_MIX_SSE_I387)
14900 && flag_unsafe_math_optimizations)
14901 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14902 && !flag_trapping_math)"
14904 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14905 && !flag_trapping_math)
14908 emit_insn (gen_sse4_1_round<mode>2
14909 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14910 else if (optimize_insn_for_size_p ())
14912 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14913 ix86_expand_floorceil (operands[0], operands[1], true);
14915 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14921 if (optimize_insn_for_size_p ())
14924 op0 = gen_reg_rtx (XFmode);
14925 op1 = gen_reg_rtx (XFmode);
14926 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14927 emit_insn (gen_frndintxf2_floor (op0, op1));
14929 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14934 (define_insn_and_split "*fist<mode>2_floor_1"
14935 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14936 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14937 UNSPEC_FIST_FLOOR))
14938 (clobber (reg:CC FLAGS_REG))]
14939 "TARGET_USE_FANCY_MATH_387
14940 && flag_unsafe_math_optimizations
14941 && can_create_pseudo_p ()"
14946 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14948 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14949 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14950 if (memory_operand (operands[0], VOIDmode))
14951 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14952 operands[2], operands[3]));
14955 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14956 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14957 operands[2], operands[3],
14962 [(set_attr "type" "fistp")
14963 (set_attr "i387_cw" "floor")
14964 (set_attr "mode" "<MODE>")])
14966 (define_insn "fistdi2_floor"
14967 [(set (match_operand:DI 0 "memory_operand" "=m")
14968 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14969 UNSPEC_FIST_FLOOR))
14970 (use (match_operand:HI 2 "memory_operand" "m"))
14971 (use (match_operand:HI 3 "memory_operand" "m"))
14972 (clobber (match_scratch:XF 4 "=&1f"))]
14973 "TARGET_USE_FANCY_MATH_387
14974 && flag_unsafe_math_optimizations"
14975 "* return output_fix_trunc (insn, operands, false);"
14976 [(set_attr "type" "fistp")
14977 (set_attr "i387_cw" "floor")
14978 (set_attr "mode" "DI")])
14980 (define_insn "fistdi2_floor_with_temp"
14981 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14982 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14983 UNSPEC_FIST_FLOOR))
14984 (use (match_operand:HI 2 "memory_operand" "m,m"))
14985 (use (match_operand:HI 3 "memory_operand" "m,m"))
14986 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14987 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14988 "TARGET_USE_FANCY_MATH_387
14989 && flag_unsafe_math_optimizations"
14991 [(set_attr "type" "fistp")
14992 (set_attr "i387_cw" "floor")
14993 (set_attr "mode" "DI")])
14996 [(set (match_operand:DI 0 "register_operand" "")
14997 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14998 UNSPEC_FIST_FLOOR))
14999 (use (match_operand:HI 2 "memory_operand" ""))
15000 (use (match_operand:HI 3 "memory_operand" ""))
15001 (clobber (match_operand:DI 4 "memory_operand" ""))
15002 (clobber (match_scratch 5 ""))]
15004 [(parallel [(set (match_dup 4)
15005 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15006 (use (match_dup 2))
15007 (use (match_dup 3))
15008 (clobber (match_dup 5))])
15009 (set (match_dup 0) (match_dup 4))])
15012 [(set (match_operand:DI 0 "memory_operand" "")
15013 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15014 UNSPEC_FIST_FLOOR))
15015 (use (match_operand:HI 2 "memory_operand" ""))
15016 (use (match_operand:HI 3 "memory_operand" ""))
15017 (clobber (match_operand:DI 4 "memory_operand" ""))
15018 (clobber (match_scratch 5 ""))]
15020 [(parallel [(set (match_dup 0)
15021 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15022 (use (match_dup 2))
15023 (use (match_dup 3))
15024 (clobber (match_dup 5))])])
15026 (define_insn "fist<mode>2_floor"
15027 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15028 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15029 UNSPEC_FIST_FLOOR))
15030 (use (match_operand:HI 2 "memory_operand" "m"))
15031 (use (match_operand:HI 3 "memory_operand" "m"))]
15032 "TARGET_USE_FANCY_MATH_387
15033 && flag_unsafe_math_optimizations"
15034 "* return output_fix_trunc (insn, operands, false);"
15035 [(set_attr "type" "fistp")
15036 (set_attr "i387_cw" "floor")
15037 (set_attr "mode" "<MODE>")])
15039 (define_insn "fist<mode>2_floor_with_temp"
15040 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15041 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15042 UNSPEC_FIST_FLOOR))
15043 (use (match_operand:HI 2 "memory_operand" "m,m"))
15044 (use (match_operand:HI 3 "memory_operand" "m,m"))
15045 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15046 "TARGET_USE_FANCY_MATH_387
15047 && flag_unsafe_math_optimizations"
15049 [(set_attr "type" "fistp")
15050 (set_attr "i387_cw" "floor")
15051 (set_attr "mode" "<MODE>")])
15054 [(set (match_operand:SWI24 0 "register_operand" "")
15055 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15056 UNSPEC_FIST_FLOOR))
15057 (use (match_operand:HI 2 "memory_operand" ""))
15058 (use (match_operand:HI 3 "memory_operand" ""))
15059 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15061 [(parallel [(set (match_dup 4)
15062 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15063 (use (match_dup 2))
15064 (use (match_dup 3))])
15065 (set (match_dup 0) (match_dup 4))])
15068 [(set (match_operand:SWI24 0 "memory_operand" "")
15069 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15070 UNSPEC_FIST_FLOOR))
15071 (use (match_operand:HI 2 "memory_operand" ""))
15072 (use (match_operand:HI 3 "memory_operand" ""))
15073 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15075 [(parallel [(set (match_dup 0)
15076 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15077 (use (match_dup 2))
15078 (use (match_dup 3))])])
15080 (define_expand "lfloorxf<mode>2"
15081 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15082 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15083 UNSPEC_FIST_FLOOR))
15084 (clobber (reg:CC FLAGS_REG))])]
15085 "TARGET_USE_FANCY_MATH_387
15086 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15087 && flag_unsafe_math_optimizations")
15089 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15090 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15091 (match_operand:MODEF 1 "register_operand" "")]
15092 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15093 && !flag_trapping_math"
15095 if (TARGET_64BIT && optimize_insn_for_size_p ())
15097 ix86_expand_lfloorceil (operands[0], operands[1], true);
15101 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15102 (define_insn_and_split "frndintxf2_ceil"
15103 [(set (match_operand:XF 0 "register_operand" "")
15104 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15105 UNSPEC_FRNDINT_CEIL))
15106 (clobber (reg:CC FLAGS_REG))]
15107 "TARGET_USE_FANCY_MATH_387
15108 && flag_unsafe_math_optimizations
15109 && can_create_pseudo_p ()"
15114 ix86_optimize_mode_switching[I387_CEIL] = 1;
15116 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15117 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15119 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15120 operands[2], operands[3]));
15123 [(set_attr "type" "frndint")
15124 (set_attr "i387_cw" "ceil")
15125 (set_attr "mode" "XF")])
15127 (define_insn "frndintxf2_ceil_i387"
15128 [(set (match_operand:XF 0 "register_operand" "=f")
15129 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15130 UNSPEC_FRNDINT_CEIL))
15131 (use (match_operand:HI 2 "memory_operand" "m"))
15132 (use (match_operand:HI 3 "memory_operand" "m"))]
15133 "TARGET_USE_FANCY_MATH_387
15134 && flag_unsafe_math_optimizations"
15135 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15136 [(set_attr "type" "frndint")
15137 (set_attr "i387_cw" "ceil")
15138 (set_attr "mode" "XF")])
15140 (define_expand "ceilxf2"
15141 [(use (match_operand:XF 0 "register_operand" ""))
15142 (use (match_operand:XF 1 "register_operand" ""))]
15143 "TARGET_USE_FANCY_MATH_387
15144 && flag_unsafe_math_optimizations"
15146 if (optimize_insn_for_size_p ())
15148 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15152 (define_expand "ceil<mode>2"
15153 [(use (match_operand:MODEF 0 "register_operand" ""))
15154 (use (match_operand:MODEF 1 "register_operand" ""))]
15155 "(TARGET_USE_FANCY_MATH_387
15156 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15157 || TARGET_MIX_SSE_I387)
15158 && flag_unsafe_math_optimizations)
15159 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15160 && !flag_trapping_math)"
15162 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15163 && !flag_trapping_math)
15166 emit_insn (gen_sse4_1_round<mode>2
15167 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15168 else if (optimize_insn_for_size_p ())
15170 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15171 ix86_expand_floorceil (operands[0], operands[1], false);
15173 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15179 if (optimize_insn_for_size_p ())
15182 op0 = gen_reg_rtx (XFmode);
15183 op1 = gen_reg_rtx (XFmode);
15184 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15185 emit_insn (gen_frndintxf2_ceil (op0, op1));
15187 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15192 (define_insn_and_split "*fist<mode>2_ceil_1"
15193 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15194 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15196 (clobber (reg:CC FLAGS_REG))]
15197 "TARGET_USE_FANCY_MATH_387
15198 && flag_unsafe_math_optimizations
15199 && can_create_pseudo_p ()"
15204 ix86_optimize_mode_switching[I387_CEIL] = 1;
15206 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15207 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15208 if (memory_operand (operands[0], VOIDmode))
15209 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15210 operands[2], operands[3]));
15213 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15214 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15215 operands[2], operands[3],
15220 [(set_attr "type" "fistp")
15221 (set_attr "i387_cw" "ceil")
15222 (set_attr "mode" "<MODE>")])
15224 (define_insn "fistdi2_ceil"
15225 [(set (match_operand:DI 0 "memory_operand" "=m")
15226 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15228 (use (match_operand:HI 2 "memory_operand" "m"))
15229 (use (match_operand:HI 3 "memory_operand" "m"))
15230 (clobber (match_scratch:XF 4 "=&1f"))]
15231 "TARGET_USE_FANCY_MATH_387
15232 && flag_unsafe_math_optimizations"
15233 "* return output_fix_trunc (insn, operands, false);"
15234 [(set_attr "type" "fistp")
15235 (set_attr "i387_cw" "ceil")
15236 (set_attr "mode" "DI")])
15238 (define_insn "fistdi2_ceil_with_temp"
15239 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15240 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15242 (use (match_operand:HI 2 "memory_operand" "m,m"))
15243 (use (match_operand:HI 3 "memory_operand" "m,m"))
15244 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15245 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15246 "TARGET_USE_FANCY_MATH_387
15247 && flag_unsafe_math_optimizations"
15249 [(set_attr "type" "fistp")
15250 (set_attr "i387_cw" "ceil")
15251 (set_attr "mode" "DI")])
15254 [(set (match_operand:DI 0 "register_operand" "")
15255 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15257 (use (match_operand:HI 2 "memory_operand" ""))
15258 (use (match_operand:HI 3 "memory_operand" ""))
15259 (clobber (match_operand:DI 4 "memory_operand" ""))
15260 (clobber (match_scratch 5 ""))]
15262 [(parallel [(set (match_dup 4)
15263 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15264 (use (match_dup 2))
15265 (use (match_dup 3))
15266 (clobber (match_dup 5))])
15267 (set (match_dup 0) (match_dup 4))])
15270 [(set (match_operand:DI 0 "memory_operand" "")
15271 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15273 (use (match_operand:HI 2 "memory_operand" ""))
15274 (use (match_operand:HI 3 "memory_operand" ""))
15275 (clobber (match_operand:DI 4 "memory_operand" ""))
15276 (clobber (match_scratch 5 ""))]
15278 [(parallel [(set (match_dup 0)
15279 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15280 (use (match_dup 2))
15281 (use (match_dup 3))
15282 (clobber (match_dup 5))])])
15284 (define_insn "fist<mode>2_ceil"
15285 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15286 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15288 (use (match_operand:HI 2 "memory_operand" "m"))
15289 (use (match_operand:HI 3 "memory_operand" "m"))]
15290 "TARGET_USE_FANCY_MATH_387
15291 && flag_unsafe_math_optimizations"
15292 "* return output_fix_trunc (insn, operands, false);"
15293 [(set_attr "type" "fistp")
15294 (set_attr "i387_cw" "ceil")
15295 (set_attr "mode" "<MODE>")])
15297 (define_insn "fist<mode>2_ceil_with_temp"
15298 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15299 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15301 (use (match_operand:HI 2 "memory_operand" "m,m"))
15302 (use (match_operand:HI 3 "memory_operand" "m,m"))
15303 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15304 "TARGET_USE_FANCY_MATH_387
15305 && flag_unsafe_math_optimizations"
15307 [(set_attr "type" "fistp")
15308 (set_attr "i387_cw" "ceil")
15309 (set_attr "mode" "<MODE>")])
15312 [(set (match_operand:SWI24 0 "register_operand" "")
15313 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15315 (use (match_operand:HI 2 "memory_operand" ""))
15316 (use (match_operand:HI 3 "memory_operand" ""))
15317 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15319 [(parallel [(set (match_dup 4)
15320 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15321 (use (match_dup 2))
15322 (use (match_dup 3))])
15323 (set (match_dup 0) (match_dup 4))])
15326 [(set (match_operand:SWI24 0 "memory_operand" "")
15327 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15329 (use (match_operand:HI 2 "memory_operand" ""))
15330 (use (match_operand:HI 3 "memory_operand" ""))
15331 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15333 [(parallel [(set (match_dup 0)
15334 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15335 (use (match_dup 2))
15336 (use (match_dup 3))])])
15338 (define_expand "lceilxf<mode>2"
15339 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15340 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15342 (clobber (reg:CC FLAGS_REG))])]
15343 "TARGET_USE_FANCY_MATH_387
15344 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15345 && flag_unsafe_math_optimizations")
15347 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15348 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15349 (match_operand:MODEF 1 "register_operand" "")]
15350 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15351 && !flag_trapping_math"
15353 ix86_expand_lfloorceil (operands[0], operands[1], false);
15357 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15358 (define_insn_and_split "frndintxf2_trunc"
15359 [(set (match_operand:XF 0 "register_operand" "")
15360 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15361 UNSPEC_FRNDINT_TRUNC))
15362 (clobber (reg:CC FLAGS_REG))]
15363 "TARGET_USE_FANCY_MATH_387
15364 && flag_unsafe_math_optimizations
15365 && can_create_pseudo_p ()"
15370 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15372 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15373 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15375 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15376 operands[2], operands[3]));
15379 [(set_attr "type" "frndint")
15380 (set_attr "i387_cw" "trunc")
15381 (set_attr "mode" "XF")])
15383 (define_insn "frndintxf2_trunc_i387"
15384 [(set (match_operand:XF 0 "register_operand" "=f")
15385 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15386 UNSPEC_FRNDINT_TRUNC))
15387 (use (match_operand:HI 2 "memory_operand" "m"))
15388 (use (match_operand:HI 3 "memory_operand" "m"))]
15389 "TARGET_USE_FANCY_MATH_387
15390 && flag_unsafe_math_optimizations"
15391 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15392 [(set_attr "type" "frndint")
15393 (set_attr "i387_cw" "trunc")
15394 (set_attr "mode" "XF")])
15396 (define_expand "btruncxf2"
15397 [(use (match_operand:XF 0 "register_operand" ""))
15398 (use (match_operand:XF 1 "register_operand" ""))]
15399 "TARGET_USE_FANCY_MATH_387
15400 && flag_unsafe_math_optimizations"
15402 if (optimize_insn_for_size_p ())
15404 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15408 (define_expand "btrunc<mode>2"
15409 [(use (match_operand:MODEF 0 "register_operand" ""))
15410 (use (match_operand:MODEF 1 "register_operand" ""))]
15411 "(TARGET_USE_FANCY_MATH_387
15412 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15413 || TARGET_MIX_SSE_I387)
15414 && flag_unsafe_math_optimizations)
15415 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15416 && !flag_trapping_math)"
15418 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15419 && !flag_trapping_math)
15422 emit_insn (gen_sse4_1_round<mode>2
15423 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15424 else if (optimize_insn_for_size_p ())
15426 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15427 ix86_expand_trunc (operands[0], operands[1]);
15429 ix86_expand_truncdf_32 (operands[0], operands[1]);
15435 if (optimize_insn_for_size_p ())
15438 op0 = gen_reg_rtx (XFmode);
15439 op1 = gen_reg_rtx (XFmode);
15440 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15441 emit_insn (gen_frndintxf2_trunc (op0, op1));
15443 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15448 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15449 (define_insn_and_split "frndintxf2_mask_pm"
15450 [(set (match_operand:XF 0 "register_operand" "")
15451 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15452 UNSPEC_FRNDINT_MASK_PM))
15453 (clobber (reg:CC FLAGS_REG))]
15454 "TARGET_USE_FANCY_MATH_387
15455 && flag_unsafe_math_optimizations
15456 && can_create_pseudo_p ()"
15461 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15463 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15464 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15466 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15467 operands[2], operands[3]));
15470 [(set_attr "type" "frndint")
15471 (set_attr "i387_cw" "mask_pm")
15472 (set_attr "mode" "XF")])
15474 (define_insn "frndintxf2_mask_pm_i387"
15475 [(set (match_operand:XF 0 "register_operand" "=f")
15476 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15477 UNSPEC_FRNDINT_MASK_PM))
15478 (use (match_operand:HI 2 "memory_operand" "m"))
15479 (use (match_operand:HI 3 "memory_operand" "m"))]
15480 "TARGET_USE_FANCY_MATH_387
15481 && flag_unsafe_math_optimizations"
15482 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15483 [(set_attr "type" "frndint")
15484 (set_attr "i387_cw" "mask_pm")
15485 (set_attr "mode" "XF")])
15487 (define_expand "nearbyintxf2"
15488 [(use (match_operand:XF 0 "register_operand" ""))
15489 (use (match_operand:XF 1 "register_operand" ""))]
15490 "TARGET_USE_FANCY_MATH_387
15491 && flag_unsafe_math_optimizations"
15493 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15497 (define_expand "nearbyint<mode>2"
15498 [(use (match_operand:MODEF 0 "register_operand" ""))
15499 (use (match_operand:MODEF 1 "register_operand" ""))]
15500 "TARGET_USE_FANCY_MATH_387
15501 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15502 || TARGET_MIX_SSE_I387)
15503 && flag_unsafe_math_optimizations"
15505 rtx op0 = gen_reg_rtx (XFmode);
15506 rtx op1 = gen_reg_rtx (XFmode);
15508 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15509 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15511 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15515 (define_insn "fxam<mode>2_i387"
15516 [(set (match_operand:HI 0 "register_operand" "=a")
15518 [(match_operand:X87MODEF 1 "register_operand" "f")]
15520 "TARGET_USE_FANCY_MATH_387"
15521 "fxam\n\tfnstsw\t%0"
15522 [(set_attr "type" "multi")
15523 (set_attr "length" "4")
15524 (set_attr "unit" "i387")
15525 (set_attr "mode" "<MODE>")])
15527 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15528 [(set (match_operand:HI 0 "register_operand" "")
15530 [(match_operand:MODEF 1 "memory_operand" "")]
15532 "TARGET_USE_FANCY_MATH_387
15533 && can_create_pseudo_p ()"
15536 [(set (match_dup 2)(match_dup 1))
15538 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15540 operands[2] = gen_reg_rtx (<MODE>mode);
15542 MEM_VOLATILE_P (operands[1]) = 1;
15544 [(set_attr "type" "multi")
15545 (set_attr "unit" "i387")
15546 (set_attr "mode" "<MODE>")])
15548 (define_expand "isinfxf2"
15549 [(use (match_operand:SI 0 "register_operand" ""))
15550 (use (match_operand:XF 1 "register_operand" ""))]
15551 "TARGET_USE_FANCY_MATH_387
15552 && TARGET_C99_FUNCTIONS"
15554 rtx mask = GEN_INT (0x45);
15555 rtx val = GEN_INT (0x05);
15559 rtx scratch = gen_reg_rtx (HImode);
15560 rtx res = gen_reg_rtx (QImode);
15562 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15564 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15565 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15566 cond = gen_rtx_fmt_ee (EQ, QImode,
15567 gen_rtx_REG (CCmode, FLAGS_REG),
15569 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15570 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15574 (define_expand "isinf<mode>2"
15575 [(use (match_operand:SI 0 "register_operand" ""))
15576 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15577 "TARGET_USE_FANCY_MATH_387
15578 && TARGET_C99_FUNCTIONS
15579 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15581 rtx mask = GEN_INT (0x45);
15582 rtx val = GEN_INT (0x05);
15586 rtx scratch = gen_reg_rtx (HImode);
15587 rtx res = gen_reg_rtx (QImode);
15589 /* Remove excess precision by forcing value through memory. */
15590 if (memory_operand (operands[1], VOIDmode))
15591 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15594 enum ix86_stack_slot slot = (virtuals_instantiated
15597 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15599 emit_move_insn (temp, operands[1]);
15600 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15603 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15604 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15605 cond = gen_rtx_fmt_ee (EQ, QImode,
15606 gen_rtx_REG (CCmode, FLAGS_REG),
15608 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15609 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15613 (define_expand "signbitxf2"
15614 [(use (match_operand:SI 0 "register_operand" ""))
15615 (use (match_operand:XF 1 "register_operand" ""))]
15616 "TARGET_USE_FANCY_MATH_387"
15618 rtx scratch = gen_reg_rtx (HImode);
15620 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15621 emit_insn (gen_andsi3 (operands[0],
15622 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15626 (define_insn "movmsk_df"
15627 [(set (match_operand:SI 0 "register_operand" "=r")
15629 [(match_operand:DF 1 "register_operand" "x")]
15631 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15632 "%vmovmskpd\t{%1, %0|%0, %1}"
15633 [(set_attr "type" "ssemov")
15634 (set_attr "prefix" "maybe_vex")
15635 (set_attr "mode" "DF")])
15637 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15638 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15639 (define_expand "signbitdf2"
15640 [(use (match_operand:SI 0 "register_operand" ""))
15641 (use (match_operand:DF 1 "register_operand" ""))]
15642 "TARGET_USE_FANCY_MATH_387
15643 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15645 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15647 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15648 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15652 rtx scratch = gen_reg_rtx (HImode);
15654 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15655 emit_insn (gen_andsi3 (operands[0],
15656 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15661 (define_expand "signbitsf2"
15662 [(use (match_operand:SI 0 "register_operand" ""))
15663 (use (match_operand:SF 1 "register_operand" ""))]
15664 "TARGET_USE_FANCY_MATH_387
15665 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15667 rtx scratch = gen_reg_rtx (HImode);
15669 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15670 emit_insn (gen_andsi3 (operands[0],
15671 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15675 ;; Block operation instructions
15678 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15681 [(set_attr "length" "1")
15682 (set_attr "length_immediate" "0")
15683 (set_attr "modrm" "0")])
15685 (define_expand "movmem<mode>"
15686 [(use (match_operand:BLK 0 "memory_operand" ""))
15687 (use (match_operand:BLK 1 "memory_operand" ""))
15688 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15689 (use (match_operand:SWI48 3 "const_int_operand" ""))
15690 (use (match_operand:SI 4 "const_int_operand" ""))
15691 (use (match_operand:SI 5 "const_int_operand" ""))]
15694 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15695 operands[4], operands[5]))
15701 ;; Most CPUs don't like single string operations
15702 ;; Handle this case here to simplify previous expander.
15704 (define_expand "strmov"
15705 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15706 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15707 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15708 (clobber (reg:CC FLAGS_REG))])
15709 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15710 (clobber (reg:CC FLAGS_REG))])]
15713 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15715 /* If .md ever supports :P for Pmode, these can be directly
15716 in the pattern above. */
15717 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15718 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15720 /* Can't use this if the user has appropriated esi or edi. */
15721 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15722 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15724 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15725 operands[2], operands[3],
15726 operands[5], operands[6]));
15730 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15733 (define_expand "strmov_singleop"
15734 [(parallel [(set (match_operand 1 "memory_operand" "")
15735 (match_operand 3 "memory_operand" ""))
15736 (set (match_operand 0 "register_operand" "")
15737 (match_operand 4 "" ""))
15738 (set (match_operand 2 "register_operand" "")
15739 (match_operand 5 "" ""))])]
15741 "ix86_current_function_needs_cld = 1;")
15743 (define_insn "*strmovdi_rex_1"
15744 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15745 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15746 (set (match_operand:DI 0 "register_operand" "=D")
15747 (plus:DI (match_dup 2)
15749 (set (match_operand:DI 1 "register_operand" "=S")
15750 (plus:DI (match_dup 3)
15753 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15755 [(set_attr "type" "str")
15756 (set_attr "memory" "both")
15757 (set_attr "mode" "DI")])
15759 (define_insn "*strmovsi_1"
15760 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15761 (mem:SI (match_operand:P 3 "register_operand" "1")))
15762 (set (match_operand:P 0 "register_operand" "=D")
15763 (plus:P (match_dup 2)
15765 (set (match_operand:P 1 "register_operand" "=S")
15766 (plus:P (match_dup 3)
15768 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15770 [(set_attr "type" "str")
15771 (set_attr "memory" "both")
15772 (set_attr "mode" "SI")])
15774 (define_insn "*strmovhi_1"
15775 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15776 (mem:HI (match_operand:P 3 "register_operand" "1")))
15777 (set (match_operand:P 0 "register_operand" "=D")
15778 (plus:P (match_dup 2)
15780 (set (match_operand:P 1 "register_operand" "=S")
15781 (plus:P (match_dup 3)
15783 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15785 [(set_attr "type" "str")
15786 (set_attr "memory" "both")
15787 (set_attr "mode" "HI")])
15789 (define_insn "*strmovqi_1"
15790 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15791 (mem:QI (match_operand:P 3 "register_operand" "1")))
15792 (set (match_operand:P 0 "register_operand" "=D")
15793 (plus:P (match_dup 2)
15795 (set (match_operand:P 1 "register_operand" "=S")
15796 (plus:P (match_dup 3)
15798 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15800 [(set_attr "type" "str")
15801 (set_attr "memory" "both")
15802 (set (attr "prefix_rex")
15804 (match_test "<P:MODE>mode == DImode")
15806 (const_string "*")))
15807 (set_attr "mode" "QI")])
15809 (define_expand "rep_mov"
15810 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15811 (set (match_operand 0 "register_operand" "")
15812 (match_operand 5 "" ""))
15813 (set (match_operand 2 "register_operand" "")
15814 (match_operand 6 "" ""))
15815 (set (match_operand 1 "memory_operand" "")
15816 (match_operand 3 "memory_operand" ""))
15817 (use (match_dup 4))])]
15819 "ix86_current_function_needs_cld = 1;")
15821 (define_insn "*rep_movdi_rex64"
15822 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15823 (set (match_operand:DI 0 "register_operand" "=D")
15824 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15826 (match_operand:DI 3 "register_operand" "0")))
15827 (set (match_operand:DI 1 "register_operand" "=S")
15828 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15829 (match_operand:DI 4 "register_operand" "1")))
15830 (set (mem:BLK (match_dup 3))
15831 (mem:BLK (match_dup 4)))
15832 (use (match_dup 5))]
15834 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15836 [(set_attr "type" "str")
15837 (set_attr "prefix_rep" "1")
15838 (set_attr "memory" "both")
15839 (set_attr "mode" "DI")])
15841 (define_insn "*rep_movsi"
15842 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15843 (set (match_operand:P 0 "register_operand" "=D")
15844 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15846 (match_operand:P 3 "register_operand" "0")))
15847 (set (match_operand:P 1 "register_operand" "=S")
15848 (plus:P (ashift:P (match_dup 5) (const_int 2))
15849 (match_operand:P 4 "register_operand" "1")))
15850 (set (mem:BLK (match_dup 3))
15851 (mem:BLK (match_dup 4)))
15852 (use (match_dup 5))]
15853 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15854 "rep{%;} movs{l|d}"
15855 [(set_attr "type" "str")
15856 (set_attr "prefix_rep" "1")
15857 (set_attr "memory" "both")
15858 (set_attr "mode" "SI")])
15860 (define_insn "*rep_movqi"
15861 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15862 (set (match_operand:P 0 "register_operand" "=D")
15863 (plus:P (match_operand:P 3 "register_operand" "0")
15864 (match_operand:P 5 "register_operand" "2")))
15865 (set (match_operand:P 1 "register_operand" "=S")
15866 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15867 (set (mem:BLK (match_dup 3))
15868 (mem:BLK (match_dup 4)))
15869 (use (match_dup 5))]
15870 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15872 [(set_attr "type" "str")
15873 (set_attr "prefix_rep" "1")
15874 (set_attr "memory" "both")
15875 (set_attr "mode" "QI")])
15877 (define_expand "setmem<mode>"
15878 [(use (match_operand:BLK 0 "memory_operand" ""))
15879 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15880 (use (match_operand:QI 2 "nonmemory_operand" ""))
15881 (use (match_operand 3 "const_int_operand" ""))
15882 (use (match_operand:SI 4 "const_int_operand" ""))
15883 (use (match_operand:SI 5 "const_int_operand" ""))]
15886 if (ix86_expand_setmem (operands[0], operands[1],
15887 operands[2], operands[3],
15888 operands[4], operands[5]))
15894 ;; Most CPUs don't like single string operations
15895 ;; Handle this case here to simplify previous expander.
15897 (define_expand "strset"
15898 [(set (match_operand 1 "memory_operand" "")
15899 (match_operand 2 "register_operand" ""))
15900 (parallel [(set (match_operand 0 "register_operand" "")
15902 (clobber (reg:CC FLAGS_REG))])]
15905 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15906 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15908 /* If .md ever supports :P for Pmode, this can be directly
15909 in the pattern above. */
15910 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15911 GEN_INT (GET_MODE_SIZE (GET_MODE
15913 /* Can't use this if the user has appropriated eax or edi. */
15914 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15915 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15917 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15923 (define_expand "strset_singleop"
15924 [(parallel [(set (match_operand 1 "memory_operand" "")
15925 (match_operand 2 "register_operand" ""))
15926 (set (match_operand 0 "register_operand" "")
15927 (match_operand 3 "" ""))])]
15929 "ix86_current_function_needs_cld = 1;")
15931 (define_insn "*strsetdi_rex_1"
15932 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15933 (match_operand:DI 2 "register_operand" "a"))
15934 (set (match_operand:DI 0 "register_operand" "=D")
15935 (plus:DI (match_dup 1)
15938 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15940 [(set_attr "type" "str")
15941 (set_attr "memory" "store")
15942 (set_attr "mode" "DI")])
15944 (define_insn "*strsetsi_1"
15945 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15946 (match_operand:SI 2 "register_operand" "a"))
15947 (set (match_operand:P 0 "register_operand" "=D")
15948 (plus:P (match_dup 1)
15950 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15952 [(set_attr "type" "str")
15953 (set_attr "memory" "store")
15954 (set_attr "mode" "SI")])
15956 (define_insn "*strsethi_1"
15957 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15958 (match_operand:HI 2 "register_operand" "a"))
15959 (set (match_operand:P 0 "register_operand" "=D")
15960 (plus:P (match_dup 1)
15962 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15964 [(set_attr "type" "str")
15965 (set_attr "memory" "store")
15966 (set_attr "mode" "HI")])
15968 (define_insn "*strsetqi_1"
15969 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15970 (match_operand:QI 2 "register_operand" "a"))
15971 (set (match_operand:P 0 "register_operand" "=D")
15972 (plus:P (match_dup 1)
15974 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15976 [(set_attr "type" "str")
15977 (set_attr "memory" "store")
15978 (set (attr "prefix_rex")
15980 (match_test "<P:MODE>mode == DImode")
15982 (const_string "*")))
15983 (set_attr "mode" "QI")])
15985 (define_expand "rep_stos"
15986 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15987 (set (match_operand 0 "register_operand" "")
15988 (match_operand 4 "" ""))
15989 (set (match_operand 2 "memory_operand" "") (const_int 0))
15990 (use (match_operand 3 "register_operand" ""))
15991 (use (match_dup 1))])]
15993 "ix86_current_function_needs_cld = 1;")
15995 (define_insn "*rep_stosdi_rex64"
15996 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15997 (set (match_operand:DI 0 "register_operand" "=D")
15998 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16000 (match_operand:DI 3 "register_operand" "0")))
16001 (set (mem:BLK (match_dup 3))
16003 (use (match_operand:DI 2 "register_operand" "a"))
16004 (use (match_dup 4))]
16006 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16008 [(set_attr "type" "str")
16009 (set_attr "prefix_rep" "1")
16010 (set_attr "memory" "store")
16011 (set_attr "mode" "DI")])
16013 (define_insn "*rep_stossi"
16014 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16015 (set (match_operand:P 0 "register_operand" "=D")
16016 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16018 (match_operand:P 3 "register_operand" "0")))
16019 (set (mem:BLK (match_dup 3))
16021 (use (match_operand:SI 2 "register_operand" "a"))
16022 (use (match_dup 4))]
16023 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16024 "rep{%;} stos{l|d}"
16025 [(set_attr "type" "str")
16026 (set_attr "prefix_rep" "1")
16027 (set_attr "memory" "store")
16028 (set_attr "mode" "SI")])
16030 (define_insn "*rep_stosqi"
16031 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16032 (set (match_operand:P 0 "register_operand" "=D")
16033 (plus:P (match_operand:P 3 "register_operand" "0")
16034 (match_operand:P 4 "register_operand" "1")))
16035 (set (mem:BLK (match_dup 3))
16037 (use (match_operand:QI 2 "register_operand" "a"))
16038 (use (match_dup 4))]
16039 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16041 [(set_attr "type" "str")
16042 (set_attr "prefix_rep" "1")
16043 (set_attr "memory" "store")
16044 (set (attr "prefix_rex")
16046 (match_test "<P:MODE>mode == DImode")
16048 (const_string "*")))
16049 (set_attr "mode" "QI")])
16051 (define_expand "cmpstrnsi"
16052 [(set (match_operand:SI 0 "register_operand" "")
16053 (compare:SI (match_operand:BLK 1 "general_operand" "")
16054 (match_operand:BLK 2 "general_operand" "")))
16055 (use (match_operand 3 "general_operand" ""))
16056 (use (match_operand 4 "immediate_operand" ""))]
16059 rtx addr1, addr2, out, outlow, count, countreg, align;
16061 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16064 /* Can't use this if the user has appropriated ecx, esi or edi. */
16065 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16070 out = gen_reg_rtx (SImode);
16072 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16073 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16074 if (addr1 != XEXP (operands[1], 0))
16075 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16076 if (addr2 != XEXP (operands[2], 0))
16077 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16079 count = operands[3];
16080 countreg = ix86_zero_extend_to_Pmode (count);
16082 /* %%% Iff we are testing strict equality, we can use known alignment
16083 to good advantage. This may be possible with combine, particularly
16084 once cc0 is dead. */
16085 align = operands[4];
16087 if (CONST_INT_P (count))
16089 if (INTVAL (count) == 0)
16091 emit_move_insn (operands[0], const0_rtx);
16094 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16095 operands[1], operands[2]));
16099 rtx (*gen_cmp) (rtx, rtx);
16101 gen_cmp = (TARGET_64BIT
16102 ? gen_cmpdi_1 : gen_cmpsi_1);
16104 emit_insn (gen_cmp (countreg, countreg));
16105 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16106 operands[1], operands[2]));
16109 outlow = gen_lowpart (QImode, out);
16110 emit_insn (gen_cmpintqi (outlow));
16111 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16113 if (operands[0] != out)
16114 emit_move_insn (operands[0], out);
16119 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16121 (define_expand "cmpintqi"
16122 [(set (match_dup 1)
16123 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16125 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16126 (parallel [(set (match_operand:QI 0 "register_operand" "")
16127 (minus:QI (match_dup 1)
16129 (clobber (reg:CC FLAGS_REG))])]
16132 operands[1] = gen_reg_rtx (QImode);
16133 operands[2] = gen_reg_rtx (QImode);
16136 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16137 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16139 (define_expand "cmpstrnqi_nz_1"
16140 [(parallel [(set (reg:CC FLAGS_REG)
16141 (compare:CC (match_operand 4 "memory_operand" "")
16142 (match_operand 5 "memory_operand" "")))
16143 (use (match_operand 2 "register_operand" ""))
16144 (use (match_operand:SI 3 "immediate_operand" ""))
16145 (clobber (match_operand 0 "register_operand" ""))
16146 (clobber (match_operand 1 "register_operand" ""))
16147 (clobber (match_dup 2))])]
16149 "ix86_current_function_needs_cld = 1;")
16151 (define_insn "*cmpstrnqi_nz_1"
16152 [(set (reg:CC FLAGS_REG)
16153 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16154 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16155 (use (match_operand:P 6 "register_operand" "2"))
16156 (use (match_operand:SI 3 "immediate_operand" "i"))
16157 (clobber (match_operand:P 0 "register_operand" "=S"))
16158 (clobber (match_operand:P 1 "register_operand" "=D"))
16159 (clobber (match_operand:P 2 "register_operand" "=c"))]
16160 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16162 [(set_attr "type" "str")
16163 (set_attr "mode" "QI")
16164 (set (attr "prefix_rex")
16166 (match_test "<P:MODE>mode == DImode")
16168 (const_string "*")))
16169 (set_attr "prefix_rep" "1")])
16171 ;; The same, but the count is not known to not be zero.
16173 (define_expand "cmpstrnqi_1"
16174 [(parallel [(set (reg:CC FLAGS_REG)
16175 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16177 (compare:CC (match_operand 4 "memory_operand" "")
16178 (match_operand 5 "memory_operand" ""))
16180 (use (match_operand:SI 3 "immediate_operand" ""))
16181 (use (reg:CC FLAGS_REG))
16182 (clobber (match_operand 0 "register_operand" ""))
16183 (clobber (match_operand 1 "register_operand" ""))
16184 (clobber (match_dup 2))])]
16186 "ix86_current_function_needs_cld = 1;")
16188 (define_insn "*cmpstrnqi_1"
16189 [(set (reg:CC FLAGS_REG)
16190 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16192 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16193 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16195 (use (match_operand:SI 3 "immediate_operand" "i"))
16196 (use (reg:CC FLAGS_REG))
16197 (clobber (match_operand:P 0 "register_operand" "=S"))
16198 (clobber (match_operand:P 1 "register_operand" "=D"))
16199 (clobber (match_operand:P 2 "register_operand" "=c"))]
16200 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16202 [(set_attr "type" "str")
16203 (set_attr "mode" "QI")
16204 (set (attr "prefix_rex")
16206 (match_test "<P:MODE>mode == DImode")
16208 (const_string "*")))
16209 (set_attr "prefix_rep" "1")])
16211 (define_expand "strlen<mode>"
16212 [(set (match_operand:P 0 "register_operand" "")
16213 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16214 (match_operand:QI 2 "immediate_operand" "")
16215 (match_operand 3 "immediate_operand" "")]
16219 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16225 (define_expand "strlenqi_1"
16226 [(parallel [(set (match_operand 0 "register_operand" "")
16227 (match_operand 2 "" ""))
16228 (clobber (match_operand 1 "register_operand" ""))
16229 (clobber (reg:CC FLAGS_REG))])]
16231 "ix86_current_function_needs_cld = 1;")
16233 (define_insn "*strlenqi_1"
16234 [(set (match_operand:P 0 "register_operand" "=&c")
16235 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16236 (match_operand:QI 2 "register_operand" "a")
16237 (match_operand:P 3 "immediate_operand" "i")
16238 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16239 (clobber (match_operand:P 1 "register_operand" "=D"))
16240 (clobber (reg:CC FLAGS_REG))]
16241 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16243 [(set_attr "type" "str")
16244 (set_attr "mode" "QI")
16245 (set (attr "prefix_rex")
16247 (match_test "<P:MODE>mode == DImode")
16249 (const_string "*")))
16250 (set_attr "prefix_rep" "1")])
16252 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16253 ;; handled in combine, but it is not currently up to the task.
16254 ;; When used for their truth value, the cmpstrn* expanders generate
16263 ;; The intermediate three instructions are unnecessary.
16265 ;; This one handles cmpstrn*_nz_1...
16268 (set (reg:CC FLAGS_REG)
16269 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16270 (mem:BLK (match_operand 5 "register_operand" ""))))
16271 (use (match_operand 6 "register_operand" ""))
16272 (use (match_operand:SI 3 "immediate_operand" ""))
16273 (clobber (match_operand 0 "register_operand" ""))
16274 (clobber (match_operand 1 "register_operand" ""))
16275 (clobber (match_operand 2 "register_operand" ""))])
16276 (set (match_operand:QI 7 "register_operand" "")
16277 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16278 (set (match_operand:QI 8 "register_operand" "")
16279 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16280 (set (reg FLAGS_REG)
16281 (compare (match_dup 7) (match_dup 8)))
16283 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16285 (set (reg:CC FLAGS_REG)
16286 (compare:CC (mem:BLK (match_dup 4))
16287 (mem:BLK (match_dup 5))))
16288 (use (match_dup 6))
16289 (use (match_dup 3))
16290 (clobber (match_dup 0))
16291 (clobber (match_dup 1))
16292 (clobber (match_dup 2))])])
16294 ;; ...and this one handles cmpstrn*_1.
16297 (set (reg:CC FLAGS_REG)
16298 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16300 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16301 (mem:BLK (match_operand 5 "register_operand" "")))
16303 (use (match_operand:SI 3 "immediate_operand" ""))
16304 (use (reg:CC FLAGS_REG))
16305 (clobber (match_operand 0 "register_operand" ""))
16306 (clobber (match_operand 1 "register_operand" ""))
16307 (clobber (match_operand 2 "register_operand" ""))])
16308 (set (match_operand:QI 7 "register_operand" "")
16309 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16310 (set (match_operand:QI 8 "register_operand" "")
16311 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16312 (set (reg FLAGS_REG)
16313 (compare (match_dup 7) (match_dup 8)))
16315 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16317 (set (reg:CC FLAGS_REG)
16318 (if_then_else:CC (ne (match_dup 6)
16320 (compare:CC (mem:BLK (match_dup 4))
16321 (mem:BLK (match_dup 5)))
16323 (use (match_dup 3))
16324 (use (reg:CC FLAGS_REG))
16325 (clobber (match_dup 0))
16326 (clobber (match_dup 1))
16327 (clobber (match_dup 2))])])
16329 ;; Conditional move instructions.
16331 (define_expand "mov<mode>cc"
16332 [(set (match_operand:SWIM 0 "register_operand" "")
16333 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16334 (match_operand:SWIM 2 "<general_operand>" "")
16335 (match_operand:SWIM 3 "<general_operand>" "")))]
16337 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16339 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16340 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16341 ;; So just document what we're doing explicitly.
16343 (define_expand "x86_mov<mode>cc_0_m1"
16345 [(set (match_operand:SWI48 0 "register_operand" "")
16346 (if_then_else:SWI48
16347 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16348 [(match_operand 1 "flags_reg_operand" "")
16352 (clobber (reg:CC FLAGS_REG))])])
16354 (define_insn "*x86_mov<mode>cc_0_m1"
16355 [(set (match_operand:SWI48 0 "register_operand" "=r")
16356 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16357 [(reg FLAGS_REG) (const_int 0)])
16360 (clobber (reg:CC FLAGS_REG))]
16362 "sbb{<imodesuffix>}\t%0, %0"
16363 ; Since we don't have the proper number of operands for an alu insn,
16364 ; fill in all the blanks.
16365 [(set_attr "type" "alu")
16366 (set_attr "use_carry" "1")
16367 (set_attr "pent_pair" "pu")
16368 (set_attr "memory" "none")
16369 (set_attr "imm_disp" "false")
16370 (set_attr "mode" "<MODE>")
16371 (set_attr "length_immediate" "0")])
16373 (define_insn "*x86_mov<mode>cc_0_m1_se"
16374 [(set (match_operand:SWI48 0 "register_operand" "=r")
16375 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16376 [(reg FLAGS_REG) (const_int 0)])
16379 (clobber (reg:CC FLAGS_REG))]
16381 "sbb{<imodesuffix>}\t%0, %0"
16382 [(set_attr "type" "alu")
16383 (set_attr "use_carry" "1")
16384 (set_attr "pent_pair" "pu")
16385 (set_attr "memory" "none")
16386 (set_attr "imm_disp" "false")
16387 (set_attr "mode" "<MODE>")
16388 (set_attr "length_immediate" "0")])
16390 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16391 [(set (match_operand:SWI48 0 "register_operand" "=r")
16392 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16393 [(reg FLAGS_REG) (const_int 0)])))
16394 (clobber (reg:CC FLAGS_REG))]
16396 "sbb{<imodesuffix>}\t%0, %0"
16397 [(set_attr "type" "alu")
16398 (set_attr "use_carry" "1")
16399 (set_attr "pent_pair" "pu")
16400 (set_attr "memory" "none")
16401 (set_attr "imm_disp" "false")
16402 (set_attr "mode" "<MODE>")
16403 (set_attr "length_immediate" "0")])
16405 (define_insn "*mov<mode>cc_noc"
16406 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16407 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16408 [(reg FLAGS_REG) (const_int 0)])
16409 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16410 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16411 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16413 cmov%O2%C1\t{%2, %0|%0, %2}
16414 cmov%O2%c1\t{%3, %0|%0, %3}"
16415 [(set_attr "type" "icmov")
16416 (set_attr "mode" "<MODE>")])
16418 (define_insn "*movqicc_noc"
16419 [(set (match_operand:QI 0 "register_operand" "=r,r")
16420 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16421 [(reg FLAGS_REG) (const_int 0)])
16422 (match_operand:QI 2 "register_operand" "r,0")
16423 (match_operand:QI 3 "register_operand" "0,r")))]
16424 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16426 [(set_attr "type" "icmov")
16427 (set_attr "mode" "QI")])
16430 [(set (match_operand 0 "register_operand")
16431 (if_then_else (match_operator 1 "ix86_comparison_operator"
16432 [(reg FLAGS_REG) (const_int 0)])
16433 (match_operand 2 "register_operand")
16434 (match_operand 3 "register_operand")))]
16435 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16436 && (GET_MODE (operands[0]) == QImode
16437 || GET_MODE (operands[0]) == HImode)
16438 && reload_completed"
16439 [(set (match_dup 0)
16440 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16442 operands[0] = gen_lowpart (SImode, operands[0]);
16443 operands[2] = gen_lowpart (SImode, operands[2]);
16444 operands[3] = gen_lowpart (SImode, operands[3]);
16447 (define_expand "mov<mode>cc"
16448 [(set (match_operand:X87MODEF 0 "register_operand" "")
16449 (if_then_else:X87MODEF
16450 (match_operand 1 "ix86_fp_comparison_operator" "")
16451 (match_operand:X87MODEF 2 "register_operand" "")
16452 (match_operand:X87MODEF 3 "register_operand" "")))]
16453 "(TARGET_80387 && TARGET_CMOVE)
16454 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16455 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16457 (define_insn "*movxfcc_1"
16458 [(set (match_operand:XF 0 "register_operand" "=f,f")
16459 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16460 [(reg FLAGS_REG) (const_int 0)])
16461 (match_operand:XF 2 "register_operand" "f,0")
16462 (match_operand:XF 3 "register_operand" "0,f")))]
16463 "TARGET_80387 && TARGET_CMOVE"
16465 fcmov%F1\t{%2, %0|%0, %2}
16466 fcmov%f1\t{%3, %0|%0, %3}"
16467 [(set_attr "type" "fcmov")
16468 (set_attr "mode" "XF")])
16470 (define_insn "*movdfcc_1_rex64"
16471 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16472 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16473 [(reg FLAGS_REG) (const_int 0)])
16474 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16475 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16476 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16477 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16479 fcmov%F1\t{%2, %0|%0, %2}
16480 fcmov%f1\t{%3, %0|%0, %3}
16481 cmov%O2%C1\t{%2, %0|%0, %2}
16482 cmov%O2%c1\t{%3, %0|%0, %3}"
16483 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16484 (set_attr "mode" "DF,DF,DI,DI")])
16486 (define_insn "*movdfcc_1"
16487 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16488 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16489 [(reg FLAGS_REG) (const_int 0)])
16490 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16491 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16492 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16493 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16495 fcmov%F1\t{%2, %0|%0, %2}
16496 fcmov%f1\t{%3, %0|%0, %3}
16499 [(set_attr "type" "fcmov,fcmov,multi,multi")
16500 (set_attr "mode" "DF,DF,DI,DI")])
16503 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16504 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16505 [(reg FLAGS_REG) (const_int 0)])
16506 (match_operand:DF 2 "nonimmediate_operand")
16507 (match_operand:DF 3 "nonimmediate_operand")))]
16508 "!TARGET_64BIT && reload_completed"
16509 [(set (match_dup 2)
16510 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16512 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16514 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16515 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16518 (define_insn "*movsfcc_1_387"
16519 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16520 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16521 [(reg FLAGS_REG) (const_int 0)])
16522 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16523 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16524 "TARGET_80387 && TARGET_CMOVE
16525 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16527 fcmov%F1\t{%2, %0|%0, %2}
16528 fcmov%f1\t{%3, %0|%0, %3}
16529 cmov%O2%C1\t{%2, %0|%0, %2}
16530 cmov%O2%c1\t{%3, %0|%0, %3}"
16531 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16532 (set_attr "mode" "SF,SF,SI,SI")])
16534 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16535 ;; the scalar versions to have only XMM registers as operands.
16537 ;; XOP conditional move
16538 (define_insn "*xop_pcmov_<mode>"
16539 [(set (match_operand:MODEF 0 "register_operand" "=x")
16540 (if_then_else:MODEF
16541 (match_operand:MODEF 1 "register_operand" "x")
16542 (match_operand:MODEF 2 "register_operand" "x")
16543 (match_operand:MODEF 3 "register_operand" "x")))]
16545 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16546 [(set_attr "type" "sse4arg")])
16548 ;; These versions of the min/max patterns are intentionally ignorant of
16549 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16550 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16551 ;; are undefined in this condition, we're certain this is correct.
16553 (define_insn "<code><mode>3"
16554 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16556 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16557 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16558 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16560 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16561 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16562 [(set_attr "isa" "noavx,avx")
16563 (set_attr "prefix" "orig,vex")
16564 (set_attr "type" "sseadd")
16565 (set_attr "mode" "<MODE>")])
16567 ;; These versions of the min/max patterns implement exactly the operations
16568 ;; min = (op1 < op2 ? op1 : op2)
16569 ;; max = (!(op1 < op2) ? op1 : op2)
16570 ;; Their operands are not commutative, and thus they may be used in the
16571 ;; presence of -0.0 and NaN.
16573 (define_insn "*ieee_smin<mode>3"
16574 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16576 [(match_operand:MODEF 1 "register_operand" "0,x")
16577 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16579 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16581 min<ssemodesuffix>\t{%2, %0|%0, %2}
16582 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16583 [(set_attr "isa" "noavx,avx")
16584 (set_attr "prefix" "orig,vex")
16585 (set_attr "type" "sseadd")
16586 (set_attr "mode" "<MODE>")])
16588 (define_insn "*ieee_smax<mode>3"
16589 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16591 [(match_operand:MODEF 1 "register_operand" "0,x")
16592 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16594 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16596 max<ssemodesuffix>\t{%2, %0|%0, %2}
16597 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16598 [(set_attr "isa" "noavx,avx")
16599 (set_attr "prefix" "orig,vex")
16600 (set_attr "type" "sseadd")
16601 (set_attr "mode" "<MODE>")])
16603 ;; Make two stack loads independent:
16605 ;; fld %st(0) -> fld bb
16606 ;; fmul bb fmul %st(1), %st
16608 ;; Actually we only match the last two instructions for simplicity.
16610 [(set (match_operand 0 "fp_register_operand" "")
16611 (match_operand 1 "fp_register_operand" ""))
16613 (match_operator 2 "binary_fp_operator"
16615 (match_operand 3 "memory_operand" "")]))]
16616 "REGNO (operands[0]) != REGNO (operands[1])"
16617 [(set (match_dup 0) (match_dup 3))
16618 (set (match_dup 0) (match_dup 4))]
16620 ;; The % modifier is not operational anymore in peephole2's, so we have to
16621 ;; swap the operands manually in the case of addition and multiplication.
16625 if (COMMUTATIVE_ARITH_P (operands[2]))
16626 op0 = operands[0], op1 = operands[1];
16628 op0 = operands[1], op1 = operands[0];
16630 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16631 GET_MODE (operands[2]),
16635 ;; Conditional addition patterns
16636 (define_expand "add<mode>cc"
16637 [(match_operand:SWI 0 "register_operand" "")
16638 (match_operand 1 "ordered_comparison_operator" "")
16639 (match_operand:SWI 2 "register_operand" "")
16640 (match_operand:SWI 3 "const_int_operand" "")]
16642 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16644 ;; Misc patterns (?)
16646 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16647 ;; Otherwise there will be nothing to keep
16649 ;; [(set (reg ebp) (reg esp))]
16650 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16651 ;; (clobber (eflags)]
16652 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16654 ;; in proper program order.
16656 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16657 [(set (match_operand:P 0 "register_operand" "=r,r")
16658 (plus:P (match_operand:P 1 "register_operand" "0,r")
16659 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16660 (clobber (reg:CC FLAGS_REG))
16661 (clobber (mem:BLK (scratch)))]
16664 switch (get_attr_type (insn))
16667 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16670 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16671 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16672 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16674 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16677 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16678 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16681 [(set (attr "type")
16682 (cond [(and (eq_attr "alternative" "0")
16683 (not (match_test "TARGET_OPT_AGU")))
16684 (const_string "alu")
16685 (match_operand:<MODE> 2 "const0_operand" "")
16686 (const_string "imov")
16688 (const_string "lea")))
16689 (set (attr "length_immediate")
16690 (cond [(eq_attr "type" "imov")
16692 (and (eq_attr "type" "alu")
16693 (match_operand 2 "const128_operand" ""))
16696 (const_string "*")))
16697 (set_attr "mode" "<MODE>")])
16699 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16700 [(set (match_operand:P 0 "register_operand" "=r")
16701 (minus:P (match_operand:P 1 "register_operand" "0")
16702 (match_operand:P 2 "register_operand" "r")))
16703 (clobber (reg:CC FLAGS_REG))
16704 (clobber (mem:BLK (scratch)))]
16706 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16707 [(set_attr "type" "alu")
16708 (set_attr "mode" "<MODE>")])
16710 (define_insn "allocate_stack_worker_probe_<mode>"
16711 [(set (match_operand:P 0 "register_operand" "=a")
16712 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16713 UNSPECV_STACK_PROBE))
16714 (clobber (reg:CC FLAGS_REG))]
16715 "ix86_target_stack_probe ()"
16716 "call\t___chkstk_ms"
16717 [(set_attr "type" "multi")
16718 (set_attr "length" "5")])
16720 (define_expand "allocate_stack"
16721 [(match_operand 0 "register_operand" "")
16722 (match_operand 1 "general_operand" "")]
16723 "ix86_target_stack_probe ()"
16727 #ifndef CHECK_STACK_LIMIT
16728 #define CHECK_STACK_LIMIT 0
16731 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16732 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16734 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16735 stack_pointer_rtx, 0, OPTAB_DIRECT);
16736 if (x != stack_pointer_rtx)
16737 emit_move_insn (stack_pointer_rtx, x);
16741 x = copy_to_mode_reg (Pmode, operands[1]);
16743 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16745 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16746 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16747 stack_pointer_rtx, 0, OPTAB_DIRECT);
16748 if (x != stack_pointer_rtx)
16749 emit_move_insn (stack_pointer_rtx, x);
16752 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16756 ;; Use IOR for stack probes, this is shorter.
16757 (define_expand "probe_stack"
16758 [(match_operand 0 "memory_operand" "")]
16761 rtx (*gen_ior3) (rtx, rtx, rtx);
16763 gen_ior3 = (GET_MODE (operands[0]) == DImode
16764 ? gen_iordi3 : gen_iorsi3);
16766 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16770 (define_insn "adjust_stack_and_probe<mode>"
16771 [(set (match_operand:P 0 "register_operand" "=r")
16772 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16773 UNSPECV_PROBE_STACK_RANGE))
16774 (set (reg:P SP_REG)
16775 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16776 (clobber (reg:CC FLAGS_REG))
16777 (clobber (mem:BLK (scratch)))]
16779 "* return output_adjust_stack_and_probe (operands[0]);"
16780 [(set_attr "type" "multi")])
16782 (define_insn "probe_stack_range<mode>"
16783 [(set (match_operand:P 0 "register_operand" "=r")
16784 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16785 (match_operand:P 2 "const_int_operand" "n")]
16786 UNSPECV_PROBE_STACK_RANGE))
16787 (clobber (reg:CC FLAGS_REG))]
16789 "* return output_probe_stack_range (operands[0], operands[2]);"
16790 [(set_attr "type" "multi")])
16792 (define_expand "builtin_setjmp_receiver"
16793 [(label_ref (match_operand 0 "" ""))]
16794 "!TARGET_64BIT && flag_pic"
16800 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16801 rtx label_rtx = gen_label_rtx ();
16802 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16803 xops[0] = xops[1] = picreg;
16804 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16805 ix86_expand_binary_operator (MINUS, SImode, xops);
16809 emit_insn (gen_set_got (pic_offset_table_rtx));
16813 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16816 [(set (match_operand 0 "register_operand" "")
16817 (match_operator 3 "promotable_binary_operator"
16818 [(match_operand 1 "register_operand" "")
16819 (match_operand 2 "aligned_operand" "")]))
16820 (clobber (reg:CC FLAGS_REG))]
16821 "! TARGET_PARTIAL_REG_STALL && reload_completed
16822 && ((GET_MODE (operands[0]) == HImode
16823 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16824 /* ??? next two lines just !satisfies_constraint_K (...) */
16825 || !CONST_INT_P (operands[2])
16826 || satisfies_constraint_K (operands[2])))
16827 || (GET_MODE (operands[0]) == QImode
16828 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16829 [(parallel [(set (match_dup 0)
16830 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16831 (clobber (reg:CC FLAGS_REG))])]
16833 operands[0] = gen_lowpart (SImode, operands[0]);
16834 operands[1] = gen_lowpart (SImode, operands[1]);
16835 if (GET_CODE (operands[3]) != ASHIFT)
16836 operands[2] = gen_lowpart (SImode, operands[2]);
16837 PUT_MODE (operands[3], SImode);
16840 ; Promote the QImode tests, as i386 has encoding of the AND
16841 ; instruction with 32-bit sign-extended immediate and thus the
16842 ; instruction size is unchanged, except in the %eax case for
16843 ; which it is increased by one byte, hence the ! optimize_size.
16845 [(set (match_operand 0 "flags_reg_operand" "")
16846 (match_operator 2 "compare_operator"
16847 [(and (match_operand 3 "aligned_operand" "")
16848 (match_operand 4 "const_int_operand" ""))
16850 (set (match_operand 1 "register_operand" "")
16851 (and (match_dup 3) (match_dup 4)))]
16852 "! TARGET_PARTIAL_REG_STALL && reload_completed
16853 && optimize_insn_for_speed_p ()
16854 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16855 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16856 /* Ensure that the operand will remain sign-extended immediate. */
16857 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16858 [(parallel [(set (match_dup 0)
16859 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16862 (and:SI (match_dup 3) (match_dup 4)))])]
16865 = gen_int_mode (INTVAL (operands[4])
16866 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16867 operands[1] = gen_lowpart (SImode, operands[1]);
16868 operands[3] = gen_lowpart (SImode, operands[3]);
16871 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16872 ; the TEST instruction with 32-bit sign-extended immediate and thus
16873 ; the instruction size would at least double, which is not what we
16874 ; want even with ! optimize_size.
16876 [(set (match_operand 0 "flags_reg_operand" "")
16877 (match_operator 1 "compare_operator"
16878 [(and (match_operand:HI 2 "aligned_operand" "")
16879 (match_operand:HI 3 "const_int_operand" ""))
16881 "! TARGET_PARTIAL_REG_STALL && reload_completed
16882 && ! TARGET_FAST_PREFIX
16883 && optimize_insn_for_speed_p ()
16884 /* Ensure that the operand will remain sign-extended immediate. */
16885 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16886 [(set (match_dup 0)
16887 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16891 = gen_int_mode (INTVAL (operands[3])
16892 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16893 operands[2] = gen_lowpart (SImode, operands[2]);
16897 [(set (match_operand 0 "register_operand" "")
16898 (neg (match_operand 1 "register_operand" "")))
16899 (clobber (reg:CC FLAGS_REG))]
16900 "! TARGET_PARTIAL_REG_STALL && reload_completed
16901 && (GET_MODE (operands[0]) == HImode
16902 || (GET_MODE (operands[0]) == QImode
16903 && (TARGET_PROMOTE_QImode
16904 || optimize_insn_for_size_p ())))"
16905 [(parallel [(set (match_dup 0)
16906 (neg:SI (match_dup 1)))
16907 (clobber (reg:CC FLAGS_REG))])]
16909 operands[0] = gen_lowpart (SImode, operands[0]);
16910 operands[1] = gen_lowpart (SImode, operands[1]);
16914 [(set (match_operand 0 "register_operand" "")
16915 (not (match_operand 1 "register_operand" "")))]
16916 "! TARGET_PARTIAL_REG_STALL && reload_completed
16917 && (GET_MODE (operands[0]) == HImode
16918 || (GET_MODE (operands[0]) == QImode
16919 && (TARGET_PROMOTE_QImode
16920 || optimize_insn_for_size_p ())))"
16921 [(set (match_dup 0)
16922 (not:SI (match_dup 1)))]
16924 operands[0] = gen_lowpart (SImode, operands[0]);
16925 operands[1] = gen_lowpart (SImode, operands[1]);
16928 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16929 ;; transform a complex memory operation into two memory to register operations.
16931 ;; Don't push memory operands
16933 [(set (match_operand:SWI 0 "push_operand" "")
16934 (match_operand:SWI 1 "memory_operand" ""))
16935 (match_scratch:SWI 2 "<r>")]
16936 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16937 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16938 [(set (match_dup 2) (match_dup 1))
16939 (set (match_dup 0) (match_dup 2))])
16941 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16944 [(set (match_operand:SF 0 "push_operand" "")
16945 (match_operand:SF 1 "memory_operand" ""))
16946 (match_scratch:SF 2 "r")]
16947 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16948 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16949 [(set (match_dup 2) (match_dup 1))
16950 (set (match_dup 0) (match_dup 2))])
16952 ;; Don't move an immediate directly to memory when the instruction
16955 [(match_scratch:SWI124 1 "<r>")
16956 (set (match_operand:SWI124 0 "memory_operand" "")
16958 "optimize_insn_for_speed_p ()
16959 && !TARGET_USE_MOV0
16960 && TARGET_SPLIT_LONG_MOVES
16961 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16962 && peep2_regno_dead_p (0, FLAGS_REG)"
16963 [(parallel [(set (match_dup 2) (const_int 0))
16964 (clobber (reg:CC FLAGS_REG))])
16965 (set (match_dup 0) (match_dup 1))]
16966 "operands[2] = gen_lowpart (SImode, operands[1]);")
16969 [(match_scratch:SWI124 2 "<r>")
16970 (set (match_operand:SWI124 0 "memory_operand" "")
16971 (match_operand:SWI124 1 "immediate_operand" ""))]
16972 "optimize_insn_for_speed_p ()
16973 && TARGET_SPLIT_LONG_MOVES
16974 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16975 [(set (match_dup 2) (match_dup 1))
16976 (set (match_dup 0) (match_dup 2))])
16978 ;; Don't compare memory with zero, load and use a test instead.
16980 [(set (match_operand 0 "flags_reg_operand" "")
16981 (match_operator 1 "compare_operator"
16982 [(match_operand:SI 2 "memory_operand" "")
16984 (match_scratch:SI 3 "r")]
16985 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16986 [(set (match_dup 3) (match_dup 2))
16987 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16989 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16990 ;; Don't split NOTs with a displacement operand, because resulting XOR
16991 ;; will not be pairable anyway.
16993 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16994 ;; represented using a modRM byte. The XOR replacement is long decoded,
16995 ;; so this split helps here as well.
16997 ;; Note: Can't do this as a regular split because we can't get proper
16998 ;; lifetime information then.
17001 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17002 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17003 "optimize_insn_for_speed_p ()
17004 && ((TARGET_NOT_UNPAIRABLE
17005 && (!MEM_P (operands[0])
17006 || !memory_displacement_operand (operands[0], <MODE>mode)))
17007 || (TARGET_NOT_VECTORMODE
17008 && long_memory_operand (operands[0], <MODE>mode)))
17009 && peep2_regno_dead_p (0, FLAGS_REG)"
17010 [(parallel [(set (match_dup 0)
17011 (xor:SWI124 (match_dup 1) (const_int -1)))
17012 (clobber (reg:CC FLAGS_REG))])])
17014 ;; Non pairable "test imm, reg" instructions can be translated to
17015 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17016 ;; byte opcode instead of two, have a short form for byte operands),
17017 ;; so do it for other CPUs as well. Given that the value was dead,
17018 ;; this should not create any new dependencies. Pass on the sub-word
17019 ;; versions if we're concerned about partial register stalls.
17022 [(set (match_operand 0 "flags_reg_operand" "")
17023 (match_operator 1 "compare_operator"
17024 [(and:SI (match_operand:SI 2 "register_operand" "")
17025 (match_operand:SI 3 "immediate_operand" ""))
17027 "ix86_match_ccmode (insn, CCNOmode)
17028 && (true_regnum (operands[2]) != AX_REG
17029 || satisfies_constraint_K (operands[3]))
17030 && peep2_reg_dead_p (1, operands[2])"
17032 [(set (match_dup 0)
17033 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17036 (and:SI (match_dup 2) (match_dup 3)))])])
17038 ;; We don't need to handle HImode case, because it will be promoted to SImode
17039 ;; on ! TARGET_PARTIAL_REG_STALL
17042 [(set (match_operand 0 "flags_reg_operand" "")
17043 (match_operator 1 "compare_operator"
17044 [(and:QI (match_operand:QI 2 "register_operand" "")
17045 (match_operand:QI 3 "immediate_operand" ""))
17047 "! TARGET_PARTIAL_REG_STALL
17048 && ix86_match_ccmode (insn, CCNOmode)
17049 && true_regnum (operands[2]) != AX_REG
17050 && peep2_reg_dead_p (1, operands[2])"
17052 [(set (match_dup 0)
17053 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17056 (and:QI (match_dup 2) (match_dup 3)))])])
17059 [(set (match_operand 0 "flags_reg_operand" "")
17060 (match_operator 1 "compare_operator"
17063 (match_operand 2 "ext_register_operand" "")
17066 (match_operand 3 "const_int_operand" ""))
17068 "! TARGET_PARTIAL_REG_STALL
17069 && ix86_match_ccmode (insn, CCNOmode)
17070 && true_regnum (operands[2]) != AX_REG
17071 && peep2_reg_dead_p (1, operands[2])"
17072 [(parallel [(set (match_dup 0)
17081 (set (zero_extract:SI (match_dup 2)
17089 (match_dup 3)))])])
17091 ;; Don't do logical operations with memory inputs.
17093 [(match_scratch:SI 2 "r")
17094 (parallel [(set (match_operand:SI 0 "register_operand" "")
17095 (match_operator:SI 3 "arith_or_logical_operator"
17097 (match_operand:SI 1 "memory_operand" "")]))
17098 (clobber (reg:CC FLAGS_REG))])]
17099 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17100 [(set (match_dup 2) (match_dup 1))
17101 (parallel [(set (match_dup 0)
17102 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17103 (clobber (reg:CC FLAGS_REG))])])
17106 [(match_scratch:SI 2 "r")
17107 (parallel [(set (match_operand:SI 0 "register_operand" "")
17108 (match_operator:SI 3 "arith_or_logical_operator"
17109 [(match_operand:SI 1 "memory_operand" "")
17111 (clobber (reg:CC FLAGS_REG))])]
17112 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17113 [(set (match_dup 2) (match_dup 1))
17114 (parallel [(set (match_dup 0)
17115 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17116 (clobber (reg:CC FLAGS_REG))])])
17118 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17119 ;; refers to the destination of the load!
17122 [(set (match_operand:SI 0 "register_operand" "")
17123 (match_operand:SI 1 "register_operand" ""))
17124 (parallel [(set (match_dup 0)
17125 (match_operator:SI 3 "commutative_operator"
17127 (match_operand:SI 2 "memory_operand" "")]))
17128 (clobber (reg:CC FLAGS_REG))])]
17129 "REGNO (operands[0]) != REGNO (operands[1])
17130 && GENERAL_REGNO_P (REGNO (operands[0]))
17131 && GENERAL_REGNO_P (REGNO (operands[1]))"
17132 [(set (match_dup 0) (match_dup 4))
17133 (parallel [(set (match_dup 0)
17134 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17135 (clobber (reg:CC FLAGS_REG))])]
17136 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17139 [(set (match_operand 0 "register_operand" "")
17140 (match_operand 1 "register_operand" ""))
17142 (match_operator 3 "commutative_operator"
17144 (match_operand 2 "memory_operand" "")]))]
17145 "REGNO (operands[0]) != REGNO (operands[1])
17146 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17147 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17148 [(set (match_dup 0) (match_dup 2))
17150 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17152 ; Don't do logical operations with memory outputs
17154 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17155 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17156 ; the same decoder scheduling characteristics as the original.
17159 [(match_scratch:SI 2 "r")
17160 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17161 (match_operator:SI 3 "arith_or_logical_operator"
17163 (match_operand:SI 1 "nonmemory_operand" "")]))
17164 (clobber (reg:CC FLAGS_REG))])]
17165 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17166 /* Do not split stack checking probes. */
17167 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17168 [(set (match_dup 2) (match_dup 0))
17169 (parallel [(set (match_dup 2)
17170 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17171 (clobber (reg:CC FLAGS_REG))])
17172 (set (match_dup 0) (match_dup 2))])
17175 [(match_scratch:SI 2 "r")
17176 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17177 (match_operator:SI 3 "arith_or_logical_operator"
17178 [(match_operand:SI 1 "nonmemory_operand" "")
17180 (clobber (reg:CC FLAGS_REG))])]
17181 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17182 /* Do not split stack checking probes. */
17183 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17184 [(set (match_dup 2) (match_dup 0))
17185 (parallel [(set (match_dup 2)
17186 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17187 (clobber (reg:CC FLAGS_REG))])
17188 (set (match_dup 0) (match_dup 2))])
17190 ;; Attempt to use arith or logical operations with memory outputs with
17191 ;; setting of flags.
17193 [(set (match_operand:SWI 0 "register_operand" "")
17194 (match_operand:SWI 1 "memory_operand" ""))
17195 (parallel [(set (match_dup 0)
17196 (match_operator:SWI 3 "plusminuslogic_operator"
17198 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17199 (clobber (reg:CC FLAGS_REG))])
17200 (set (match_dup 1) (match_dup 0))
17201 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17202 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17203 && peep2_reg_dead_p (4, operands[0])
17204 && !reg_overlap_mentioned_p (operands[0], operands[1])
17205 && (<MODE>mode != QImode
17206 || immediate_operand (operands[2], QImode)
17207 || q_regs_operand (operands[2], QImode))
17208 && ix86_match_ccmode (peep2_next_insn (3),
17209 (GET_CODE (operands[3]) == PLUS
17210 || GET_CODE (operands[3]) == MINUS)
17211 ? CCGOCmode : CCNOmode)"
17212 [(parallel [(set (match_dup 4) (match_dup 5))
17213 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17214 (match_dup 2)]))])]
17216 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17217 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17218 copy_rtx (operands[1]),
17219 copy_rtx (operands[2]));
17220 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17221 operands[5], const0_rtx);
17225 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17226 (match_operator:SWI 2 "plusminuslogic_operator"
17228 (match_operand:SWI 1 "memory_operand" "")]))
17229 (clobber (reg:CC FLAGS_REG))])
17230 (set (match_dup 1) (match_dup 0))
17231 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17232 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17233 && GET_CODE (operands[2]) != MINUS
17234 && peep2_reg_dead_p (3, operands[0])
17235 && !reg_overlap_mentioned_p (operands[0], operands[1])
17236 && ix86_match_ccmode (peep2_next_insn (2),
17237 GET_CODE (operands[2]) == PLUS
17238 ? CCGOCmode : CCNOmode)"
17239 [(parallel [(set (match_dup 3) (match_dup 4))
17240 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17241 (match_dup 0)]))])]
17243 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17244 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17245 copy_rtx (operands[1]),
17246 copy_rtx (operands[0]));
17247 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17248 operands[4], const0_rtx);
17252 [(set (match_operand:SWI12 0 "register_operand" "")
17253 (match_operand:SWI12 1 "memory_operand" ""))
17254 (parallel [(set (match_operand:SI 4 "register_operand" "")
17255 (match_operator:SI 3 "plusminuslogic_operator"
17257 (match_operand:SI 2 "nonmemory_operand" "")]))
17258 (clobber (reg:CC FLAGS_REG))])
17259 (set (match_dup 1) (match_dup 0))
17260 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17261 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17262 && REG_P (operands[0]) && REG_P (operands[4])
17263 && REGNO (operands[0]) == REGNO (operands[4])
17264 && peep2_reg_dead_p (4, operands[0])
17265 && (<MODE>mode != QImode
17266 || immediate_operand (operands[2], SImode)
17267 || q_regs_operand (operands[2], SImode))
17268 && !reg_overlap_mentioned_p (operands[0], operands[1])
17269 && ix86_match_ccmode (peep2_next_insn (3),
17270 (GET_CODE (operands[3]) == PLUS
17271 || GET_CODE (operands[3]) == MINUS)
17272 ? CCGOCmode : CCNOmode)"
17273 [(parallel [(set (match_dup 4) (match_dup 5))
17274 (set (match_dup 1) (match_dup 6))])]
17276 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17277 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17278 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17279 copy_rtx (operands[1]), operands[2]);
17280 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17281 operands[5], const0_rtx);
17282 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17283 copy_rtx (operands[1]),
17284 copy_rtx (operands[2]));
17287 ;; Attempt to always use XOR for zeroing registers.
17289 [(set (match_operand 0 "register_operand" "")
17290 (match_operand 1 "const0_operand" ""))]
17291 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17292 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17293 && GENERAL_REG_P (operands[0])
17294 && peep2_regno_dead_p (0, FLAGS_REG)"
17295 [(parallel [(set (match_dup 0) (const_int 0))
17296 (clobber (reg:CC FLAGS_REG))])]
17297 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17300 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17302 "(GET_MODE (operands[0]) == QImode
17303 || GET_MODE (operands[0]) == HImode)
17304 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17305 && peep2_regno_dead_p (0, FLAGS_REG)"
17306 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17307 (clobber (reg:CC FLAGS_REG))])])
17309 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17311 [(set (match_operand:SWI248 0 "register_operand" "")
17313 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17314 && peep2_regno_dead_p (0, FLAGS_REG)"
17315 [(parallel [(set (match_dup 0) (const_int -1))
17316 (clobber (reg:CC FLAGS_REG))])]
17318 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17319 operands[0] = gen_lowpart (SImode, operands[0]);
17322 ;; Attempt to convert simple lea to add/shift.
17323 ;; These can be created by move expanders.
17326 [(set (match_operand:SWI48 0 "register_operand" "")
17327 (plus:SWI48 (match_dup 0)
17328 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17329 "peep2_regno_dead_p (0, FLAGS_REG)"
17330 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17331 (clobber (reg:CC FLAGS_REG))])])
17334 [(set (match_operand:SI 0 "register_operand" "")
17335 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17336 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17338 && peep2_regno_dead_p (0, FLAGS_REG)
17339 && REGNO (operands[0]) == REGNO (operands[1])"
17340 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17341 (clobber (reg:CC FLAGS_REG))])]
17342 "operands[2] = gen_lowpart (SImode, operands[2]);")
17345 [(set (match_operand:SWI48 0 "register_operand" "")
17346 (mult:SWI48 (match_dup 0)
17347 (match_operand:SWI48 1 "const_int_operand" "")))]
17348 "exact_log2 (INTVAL (operands[1])) >= 0
17349 && peep2_regno_dead_p (0, FLAGS_REG)"
17350 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17351 (clobber (reg:CC FLAGS_REG))])]
17352 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17355 [(set (match_operand:SI 0 "register_operand" "")
17356 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17357 (match_operand:DI 2 "const_int_operand" "")) 0))]
17359 && exact_log2 (INTVAL (operands[2])) >= 0
17360 && REGNO (operands[0]) == REGNO (operands[1])
17361 && peep2_regno_dead_p (0, FLAGS_REG)"
17362 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17363 (clobber (reg:CC FLAGS_REG))])]
17364 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17366 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17367 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17368 ;; On many CPUs it is also faster, since special hardware to avoid esp
17369 ;; dependencies is present.
17371 ;; While some of these conversions may be done using splitters, we use
17372 ;; peepholes in order to allow combine_stack_adjustments pass to see
17373 ;; nonobfuscated RTL.
17375 ;; Convert prologue esp subtractions to push.
17376 ;; We need register to push. In order to keep verify_flow_info happy we have
17378 ;; - use scratch and clobber it in order to avoid dependencies
17379 ;; - use already live register
17380 ;; We can't use the second way right now, since there is no reliable way how to
17381 ;; verify that given register is live. First choice will also most likely in
17382 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17383 ;; call clobbered registers are dead. We may want to use base pointer as an
17384 ;; alternative when no register is available later.
17387 [(match_scratch:P 1 "r")
17388 (parallel [(set (reg:P SP_REG)
17389 (plus:P (reg:P SP_REG)
17390 (match_operand:P 0 "const_int_operand" "")))
17391 (clobber (reg:CC FLAGS_REG))
17392 (clobber (mem:BLK (scratch)))])]
17393 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17394 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17395 [(clobber (match_dup 1))
17396 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17397 (clobber (mem:BLK (scratch)))])])
17400 [(match_scratch:P 1 "r")
17401 (parallel [(set (reg:P SP_REG)
17402 (plus:P (reg:P SP_REG)
17403 (match_operand:P 0 "const_int_operand" "")))
17404 (clobber (reg:CC FLAGS_REG))
17405 (clobber (mem:BLK (scratch)))])]
17406 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17407 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17408 [(clobber (match_dup 1))
17409 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17410 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17411 (clobber (mem:BLK (scratch)))])])
17413 ;; Convert esp subtractions to push.
17415 [(match_scratch:P 1 "r")
17416 (parallel [(set (reg:P SP_REG)
17417 (plus:P (reg:P SP_REG)
17418 (match_operand:P 0 "const_int_operand" "")))
17419 (clobber (reg:CC FLAGS_REG))])]
17420 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17421 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17422 [(clobber (match_dup 1))
17423 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17426 [(match_scratch:P 1 "r")
17427 (parallel [(set (reg:P SP_REG)
17428 (plus:P (reg:P SP_REG)
17429 (match_operand:P 0 "const_int_operand" "")))
17430 (clobber (reg:CC FLAGS_REG))])]
17431 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17432 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17433 [(clobber (match_dup 1))
17434 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17435 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17437 ;; Convert epilogue deallocator to pop.
17439 [(match_scratch:P 1 "r")
17440 (parallel [(set (reg:P SP_REG)
17441 (plus:P (reg:P SP_REG)
17442 (match_operand:P 0 "const_int_operand" "")))
17443 (clobber (reg:CC FLAGS_REG))
17444 (clobber (mem:BLK (scratch)))])]
17445 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17446 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17447 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17448 (clobber (mem:BLK (scratch)))])])
17450 ;; Two pops case is tricky, since pop causes dependency
17451 ;; on destination register. We use two registers if available.
17453 [(match_scratch:P 1 "r")
17454 (match_scratch:P 2 "r")
17455 (parallel [(set (reg:P SP_REG)
17456 (plus:P (reg:P SP_REG)
17457 (match_operand:P 0 "const_int_operand" "")))
17458 (clobber (reg:CC FLAGS_REG))
17459 (clobber (mem:BLK (scratch)))])]
17460 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17461 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17462 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17463 (clobber (mem:BLK (scratch)))])
17464 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17467 [(match_scratch:P 1 "r")
17468 (parallel [(set (reg:P SP_REG)
17469 (plus:P (reg:P SP_REG)
17470 (match_operand:P 0 "const_int_operand" "")))
17471 (clobber (reg:CC FLAGS_REG))
17472 (clobber (mem:BLK (scratch)))])]
17473 "optimize_insn_for_size_p ()
17474 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17475 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17476 (clobber (mem:BLK (scratch)))])
17477 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17479 ;; Convert esp additions to pop.
17481 [(match_scratch:P 1 "r")
17482 (parallel [(set (reg:P SP_REG)
17483 (plus:P (reg:P SP_REG)
17484 (match_operand:P 0 "const_int_operand" "")))
17485 (clobber (reg:CC FLAGS_REG))])]
17486 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17487 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17489 ;; Two pops case is tricky, since pop causes dependency
17490 ;; on destination register. We use two registers if available.
17492 [(match_scratch:P 1 "r")
17493 (match_scratch:P 2 "r")
17494 (parallel [(set (reg:P SP_REG)
17495 (plus:P (reg:P SP_REG)
17496 (match_operand:P 0 "const_int_operand" "")))
17497 (clobber (reg:CC FLAGS_REG))])]
17498 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17499 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17500 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17503 [(match_scratch:P 1 "r")
17504 (parallel [(set (reg:P SP_REG)
17505 (plus:P (reg:P SP_REG)
17506 (match_operand:P 0 "const_int_operand" "")))
17507 (clobber (reg:CC FLAGS_REG))])]
17508 "optimize_insn_for_size_p ()
17509 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17510 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17511 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17513 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17514 ;; required and register dies. Similarly for 128 to -128.
17516 [(set (match_operand 0 "flags_reg_operand" "")
17517 (match_operator 1 "compare_operator"
17518 [(match_operand 2 "register_operand" "")
17519 (match_operand 3 "const_int_operand" "")]))]
17520 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17521 && incdec_operand (operands[3], GET_MODE (operands[3])))
17522 || (!TARGET_FUSE_CMP_AND_BRANCH
17523 && INTVAL (operands[3]) == 128))
17524 && ix86_match_ccmode (insn, CCGCmode)
17525 && peep2_reg_dead_p (1, operands[2])"
17526 [(parallel [(set (match_dup 0)
17527 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17528 (clobber (match_dup 2))])])
17530 ;; Convert imul by three, five and nine into lea
17533 [(set (match_operand:SWI48 0 "register_operand" "")
17534 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17535 (match_operand:SWI48 2 "const359_operand" "")))
17536 (clobber (reg:CC FLAGS_REG))])]
17537 "!TARGET_PARTIAL_REG_STALL
17538 || <MODE>mode == SImode
17539 || optimize_function_for_size_p (cfun)"
17540 [(set (match_dup 0)
17541 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17543 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17547 [(set (match_operand:SWI48 0 "register_operand" "")
17548 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17549 (match_operand:SWI48 2 "const359_operand" "")))
17550 (clobber (reg:CC FLAGS_REG))])]
17551 "optimize_insn_for_speed_p ()
17552 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17553 [(set (match_dup 0) (match_dup 1))
17555 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17557 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17559 ;; imul $32bit_imm, mem, reg is vector decoded, while
17560 ;; imul $32bit_imm, reg, reg is direct decoded.
17562 [(match_scratch:SWI48 3 "r")
17563 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17564 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17565 (match_operand:SWI48 2 "immediate_operand" "")))
17566 (clobber (reg:CC FLAGS_REG))])]
17567 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17568 && !satisfies_constraint_K (operands[2])"
17569 [(set (match_dup 3) (match_dup 1))
17570 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17571 (clobber (reg:CC FLAGS_REG))])])
17574 [(match_scratch:SI 3 "r")
17575 (parallel [(set (match_operand:DI 0 "register_operand" "")
17577 (mult:SI (match_operand:SI 1 "memory_operand" "")
17578 (match_operand:SI 2 "immediate_operand" ""))))
17579 (clobber (reg:CC FLAGS_REG))])]
17581 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17582 && !satisfies_constraint_K (operands[2])"
17583 [(set (match_dup 3) (match_dup 1))
17584 (parallel [(set (match_dup 0)
17585 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17586 (clobber (reg:CC FLAGS_REG))])])
17588 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17589 ;; Convert it into imul reg, reg
17590 ;; It would be better to force assembler to encode instruction using long
17591 ;; immediate, but there is apparently no way to do so.
17593 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17595 (match_operand:SWI248 1 "nonimmediate_operand" "")
17596 (match_operand:SWI248 2 "const_int_operand" "")))
17597 (clobber (reg:CC FLAGS_REG))])
17598 (match_scratch:SWI248 3 "r")]
17599 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17600 && satisfies_constraint_K (operands[2])"
17601 [(set (match_dup 3) (match_dup 2))
17602 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17603 (clobber (reg:CC FLAGS_REG))])]
17605 if (!rtx_equal_p (operands[0], operands[1]))
17606 emit_move_insn (operands[0], operands[1]);
17609 ;; After splitting up read-modify operations, array accesses with memory
17610 ;; operands might end up in form:
17612 ;; movl 4(%esp), %edx
17614 ;; instead of pre-splitting:
17616 ;; addl 4(%esp), %eax
17618 ;; movl 4(%esp), %edx
17619 ;; leal (%edx,%eax,4), %eax
17622 [(match_scratch:P 5 "r")
17623 (parallel [(set (match_operand 0 "register_operand" "")
17624 (ashift (match_operand 1 "register_operand" "")
17625 (match_operand 2 "const_int_operand" "")))
17626 (clobber (reg:CC FLAGS_REG))])
17627 (parallel [(set (match_operand 3 "register_operand" "")
17628 (plus (match_dup 0)
17629 (match_operand 4 "x86_64_general_operand" "")))
17630 (clobber (reg:CC FLAGS_REG))])]
17631 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17632 /* Validate MODE for lea. */
17633 && ((!TARGET_PARTIAL_REG_STALL
17634 && (GET_MODE (operands[0]) == QImode
17635 || GET_MODE (operands[0]) == HImode))
17636 || GET_MODE (operands[0]) == SImode
17637 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17638 && (rtx_equal_p (operands[0], operands[3])
17639 || peep2_reg_dead_p (2, operands[0]))
17640 /* We reorder load and the shift. */
17641 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17642 [(set (match_dup 5) (match_dup 4))
17643 (set (match_dup 0) (match_dup 1))]
17645 enum machine_mode op1mode = GET_MODE (operands[1]);
17646 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17647 int scale = 1 << INTVAL (operands[2]);
17648 rtx index = gen_lowpart (Pmode, operands[1]);
17649 rtx base = gen_lowpart (Pmode, operands[5]);
17650 rtx dest = gen_lowpart (mode, operands[3]);
17652 operands[1] = gen_rtx_PLUS (Pmode, base,
17653 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17654 operands[5] = base;
17656 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17657 if (op1mode != Pmode)
17658 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17659 operands[0] = dest;
17662 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17663 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17664 ;; caught for use by garbage collectors and the like. Using an insn that
17665 ;; maps to SIGILL makes it more likely the program will rightfully die.
17666 ;; Keeping with tradition, "6" is in honor of #UD.
17667 (define_insn "trap"
17668 [(trap_if (const_int 1) (const_int 6))]
17670 { return ASM_SHORT "0x0b0f"; }
17671 [(set_attr "length" "2")])
17673 (define_expand "prefetch"
17674 [(prefetch (match_operand 0 "address_operand" "")
17675 (match_operand:SI 1 "const_int_operand" "")
17676 (match_operand:SI 2 "const_int_operand" ""))]
17677 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17679 int rw = INTVAL (operands[1]);
17680 int locality = INTVAL (operands[2]);
17682 gcc_assert (rw == 0 || rw == 1);
17683 gcc_assert (locality >= 0 && locality <= 3);
17684 gcc_assert (GET_MODE (operands[0]) == Pmode
17685 || GET_MODE (operands[0]) == VOIDmode);
17687 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17688 supported by SSE counterpart or the SSE prefetch is not available
17689 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17691 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17692 operands[2] = GEN_INT (3);
17694 operands[1] = const0_rtx;
17697 (define_insn "*prefetch_sse_<mode>"
17698 [(prefetch (match_operand:P 0 "address_operand" "p")
17700 (match_operand:SI 1 "const_int_operand" ""))]
17701 "TARGET_PREFETCH_SSE"
17703 static const char * const patterns[4] = {
17704 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17707 int locality = INTVAL (operands[1]);
17708 gcc_assert (locality >= 0 && locality <= 3);
17710 return patterns[locality];
17712 [(set_attr "type" "sse")
17713 (set_attr "atom_sse_attr" "prefetch")
17714 (set (attr "length_address")
17715 (symbol_ref "memory_address_length (operands[0])"))
17716 (set_attr "memory" "none")])
17718 (define_insn "*prefetch_3dnow_<mode>"
17719 [(prefetch (match_operand:P 0 "address_operand" "p")
17720 (match_operand:SI 1 "const_int_operand" "n")
17724 if (INTVAL (operands[1]) == 0)
17725 return "prefetch\t%a0";
17727 return "prefetchw\t%a0";
17729 [(set_attr "type" "mmx")
17730 (set (attr "length_address")
17731 (symbol_ref "memory_address_length (operands[0])"))
17732 (set_attr "memory" "none")])
17734 (define_expand "stack_protect_set"
17735 [(match_operand 0 "memory_operand" "")
17736 (match_operand 1 "memory_operand" "")]
17739 rtx (*insn)(rtx, rtx);
17741 #ifdef TARGET_THREAD_SSP_OFFSET
17742 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17743 insn = (TARGET_LP64
17744 ? gen_stack_tls_protect_set_di
17745 : gen_stack_tls_protect_set_si);
17747 insn = (TARGET_LP64
17748 ? gen_stack_protect_set_di
17749 : gen_stack_protect_set_si);
17752 emit_insn (insn (operands[0], operands[1]));
17756 (define_insn "stack_protect_set_<mode>"
17757 [(set (match_operand:PTR 0 "memory_operand" "=m")
17758 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17760 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17761 (clobber (reg:CC FLAGS_REG))]
17763 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17764 [(set_attr "type" "multi")])
17766 (define_insn "stack_tls_protect_set_<mode>"
17767 [(set (match_operand:PTR 0 "memory_operand" "=m")
17768 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17769 UNSPEC_SP_TLS_SET))
17770 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17771 (clobber (reg:CC FLAGS_REG))]
17773 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17774 [(set_attr "type" "multi")])
17776 (define_expand "stack_protect_test"
17777 [(match_operand 0 "memory_operand" "")
17778 (match_operand 1 "memory_operand" "")
17779 (match_operand 2 "" "")]
17782 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17784 rtx (*insn)(rtx, rtx, rtx);
17786 #ifdef TARGET_THREAD_SSP_OFFSET
17787 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17788 insn = (TARGET_LP64
17789 ? gen_stack_tls_protect_test_di
17790 : gen_stack_tls_protect_test_si);
17792 insn = (TARGET_LP64
17793 ? gen_stack_protect_test_di
17794 : gen_stack_protect_test_si);
17797 emit_insn (insn (flags, operands[0], operands[1]));
17799 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17800 flags, const0_rtx, operands[2]));
17804 (define_insn "stack_protect_test_<mode>"
17805 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17806 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17807 (match_operand:PTR 2 "memory_operand" "m")]
17809 (clobber (match_scratch:PTR 3 "=&r"))]
17811 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17812 [(set_attr "type" "multi")])
17814 (define_insn "stack_tls_protect_test_<mode>"
17815 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17816 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17817 (match_operand:PTR 2 "const_int_operand" "i")]
17818 UNSPEC_SP_TLS_TEST))
17819 (clobber (match_scratch:PTR 3 "=r"))]
17821 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17822 [(set_attr "type" "multi")])
17824 (define_insn "sse4_2_crc32<mode>"
17825 [(set (match_operand:SI 0 "register_operand" "=r")
17827 [(match_operand:SI 1 "register_operand" "0")
17828 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17830 "TARGET_SSE4_2 || TARGET_CRC32"
17831 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17832 [(set_attr "type" "sselog1")
17833 (set_attr "prefix_rep" "1")
17834 (set_attr "prefix_extra" "1")
17835 (set (attr "prefix_data16")
17836 (if_then_else (match_operand:HI 2 "" "")
17838 (const_string "*")))
17839 (set (attr "prefix_rex")
17840 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17842 (const_string "*")))
17843 (set_attr "mode" "SI")])
17845 (define_insn "sse4_2_crc32di"
17846 [(set (match_operand:DI 0 "register_operand" "=r")
17848 [(match_operand:DI 1 "register_operand" "0")
17849 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17851 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17852 "crc32{q}\t{%2, %0|%0, %2}"
17853 [(set_attr "type" "sselog1")
17854 (set_attr "prefix_rep" "1")
17855 (set_attr "prefix_extra" "1")
17856 (set_attr "mode" "DI")])
17858 (define_expand "rdpmc"
17859 [(match_operand:DI 0 "register_operand" "")
17860 (match_operand:SI 1 "register_operand" "")]
17863 rtx reg = gen_reg_rtx (DImode);
17866 /* Force operand 1 into ECX. */
17867 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17868 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17869 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17874 rtvec vec = rtvec_alloc (2);
17875 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17876 rtx upper = gen_reg_rtx (DImode);
17877 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17878 gen_rtvec (1, const0_rtx),
17880 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17881 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17883 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17884 NULL, 1, OPTAB_DIRECT);
17885 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17889 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17890 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17894 (define_insn "*rdpmc"
17895 [(set (match_operand:DI 0 "register_operand" "=A")
17896 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17900 [(set_attr "type" "other")
17901 (set_attr "length" "2")])
17903 (define_insn "*rdpmc_rex64"
17904 [(set (match_operand:DI 0 "register_operand" "=a")
17905 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17907 (set (match_operand:DI 1 "register_operand" "=d")
17908 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17911 [(set_attr "type" "other")
17912 (set_attr "length" "2")])
17914 (define_expand "rdtsc"
17915 [(set (match_operand:DI 0 "register_operand" "")
17916 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17921 rtvec vec = rtvec_alloc (2);
17922 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17923 rtx upper = gen_reg_rtx (DImode);
17924 rtx lower = gen_reg_rtx (DImode);
17925 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17926 gen_rtvec (1, const0_rtx),
17928 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17929 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17931 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17932 NULL, 1, OPTAB_DIRECT);
17933 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17935 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17940 (define_insn "*rdtsc"
17941 [(set (match_operand:DI 0 "register_operand" "=A")
17942 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17945 [(set_attr "type" "other")
17946 (set_attr "length" "2")])
17948 (define_insn "*rdtsc_rex64"
17949 [(set (match_operand:DI 0 "register_operand" "=a")
17950 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17951 (set (match_operand:DI 1 "register_operand" "=d")
17952 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17955 [(set_attr "type" "other")
17956 (set_attr "length" "2")])
17958 (define_expand "rdtscp"
17959 [(match_operand:DI 0 "register_operand" "")
17960 (match_operand:SI 1 "memory_operand" "")]
17963 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17964 gen_rtvec (1, const0_rtx),
17966 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17967 gen_rtvec (1, const0_rtx),
17969 rtx reg = gen_reg_rtx (DImode);
17970 rtx tmp = gen_reg_rtx (SImode);
17974 rtvec vec = rtvec_alloc (3);
17975 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17976 rtx upper = gen_reg_rtx (DImode);
17977 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17978 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17979 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17981 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17982 NULL, 1, OPTAB_DIRECT);
17983 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17988 rtvec vec = rtvec_alloc (2);
17989 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17990 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17991 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17994 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17995 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17999 (define_insn "*rdtscp"
18000 [(set (match_operand:DI 0 "register_operand" "=A")
18001 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18002 (set (match_operand:SI 1 "register_operand" "=c")
18003 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18006 [(set_attr "type" "other")
18007 (set_attr "length" "3")])
18009 (define_insn "*rdtscp_rex64"
18010 [(set (match_operand:DI 0 "register_operand" "=a")
18011 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18012 (set (match_operand:DI 1 "register_operand" "=d")
18013 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18014 (set (match_operand:SI 2 "register_operand" "=c")
18015 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18018 [(set_attr "type" "other")
18019 (set_attr "length" "3")])
18021 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18023 ;; LWP instructions
18025 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18027 (define_expand "lwp_llwpcb"
18028 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18029 UNSPECV_LLWP_INTRINSIC)]
18032 (define_insn "*lwp_llwpcb<mode>1"
18033 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18034 UNSPECV_LLWP_INTRINSIC)]
18037 [(set_attr "type" "lwp")
18038 (set_attr "mode" "<MODE>")
18039 (set_attr "length" "5")])
18041 (define_expand "lwp_slwpcb"
18042 [(set (match_operand 0 "register_operand" "=r")
18043 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18048 insn = (TARGET_64BIT
18050 : gen_lwp_slwpcbsi);
18052 emit_insn (insn (operands[0]));
18056 (define_insn "lwp_slwpcb<mode>"
18057 [(set (match_operand:P 0 "register_operand" "=r")
18058 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18061 [(set_attr "type" "lwp")
18062 (set_attr "mode" "<MODE>")
18063 (set_attr "length" "5")])
18065 (define_expand "lwp_lwpval<mode>3"
18066 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18067 (match_operand:SI 2 "nonimmediate_operand" "rm")
18068 (match_operand:SI 3 "const_int_operand" "i")]
18069 UNSPECV_LWPVAL_INTRINSIC)]
18071 ;; Avoid unused variable warning.
18072 "(void) operands[0];")
18074 (define_insn "*lwp_lwpval<mode>3_1"
18075 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18076 (match_operand:SI 1 "nonimmediate_operand" "rm")
18077 (match_operand:SI 2 "const_int_operand" "i")]
18078 UNSPECV_LWPVAL_INTRINSIC)]
18080 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18081 [(set_attr "type" "lwp")
18082 (set_attr "mode" "<MODE>")
18083 (set (attr "length")
18084 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18086 (define_expand "lwp_lwpins<mode>3"
18087 [(set (reg:CCC FLAGS_REG)
18088 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18089 (match_operand:SI 2 "nonimmediate_operand" "rm")
18090 (match_operand:SI 3 "const_int_operand" "i")]
18091 UNSPECV_LWPINS_INTRINSIC))
18092 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18093 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18096 (define_insn "*lwp_lwpins<mode>3_1"
18097 [(set (reg:CCC FLAGS_REG)
18098 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18099 (match_operand:SI 1 "nonimmediate_operand" "rm")
18100 (match_operand:SI 2 "const_int_operand" "i")]
18101 UNSPECV_LWPINS_INTRINSIC))]
18103 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18104 [(set_attr "type" "lwp")
18105 (set_attr "mode" "<MODE>")
18106 (set (attr "length")
18107 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18109 (define_insn "rdfsbase<mode>"
18110 [(set (match_operand:SWI48 0 "register_operand" "=r")
18111 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18112 "TARGET_64BIT && TARGET_FSGSBASE"
18114 [(set_attr "type" "other")
18115 (set_attr "prefix_extra" "2")])
18117 (define_insn "rdgsbase<mode>"
18118 [(set (match_operand:SWI48 0 "register_operand" "=r")
18119 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18120 "TARGET_64BIT && TARGET_FSGSBASE"
18122 [(set_attr "type" "other")
18123 (set_attr "prefix_extra" "2")])
18125 (define_insn "wrfsbase<mode>"
18126 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18128 "TARGET_64BIT && TARGET_FSGSBASE"
18130 [(set_attr "type" "other")
18131 (set_attr "prefix_extra" "2")])
18133 (define_insn "wrgsbase<mode>"
18134 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18136 "TARGET_64BIT && TARGET_FSGSBASE"
18138 [(set_attr "type" "other")
18139 (set_attr "prefix_extra" "2")])
18141 (define_insn "rdrand<mode>_1"
18142 [(set (match_operand:SWI248 0 "register_operand" "=r")
18143 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18144 (set (reg:CCC FLAGS_REG)
18145 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18148 [(set_attr "type" "other")
18149 (set_attr "prefix_extra" "1")])
18151 (define_expand "pause"
18152 [(set (match_dup 0)
18153 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18156 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18157 MEM_VOLATILE_P (operands[0]) = 1;
18160 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18161 ;; They have the same encoding.
18162 (define_insn "*pause"
18163 [(set (match_operand:BLK 0 "" "")
18164 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18167 [(set_attr "length" "2")
18168 (set_attr "memory" "unknown")])
18172 (include "sync.md")