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
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
87 UNSPEC_MEMORY_BLOCKAGE
97 ;; Other random patterns
106 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_DIV_ALREADY_SPLIT
109 UNSPEC_MS_TO_SYSV_CALL
110 UNSPEC_CALL_NEEDS_VZEROUPPER
113 ;; For SSE/MMX support:
121 ;; Generic math support
123 UNSPEC_IEEE_MIN ; not commutative
124 UNSPEC_IEEE_MAX ; not commutative
126 ;; x87 Floating point
142 UNSPEC_FRNDINT_MASK_PM
146 ;; x87 Double output FP
173 ;; For RDRAND support
184 (define_c_enum "unspecv" [
187 UNSPECV_PROBE_STACK_RANGE
190 UNSPECV_SPLIT_STACK_RETURN
196 UNSPECV_LLWP_INTRINSIC
197 UNSPECV_SLWP_INTRINSIC
198 UNSPECV_LWPVAL_INTRINSIC
199 UNSPECV_LWPINS_INTRINSIC
206 ;; Constants to represent rounding modes in the ROUND instruction
215 ;; Constants to represent pcomtrue/pcomfalse variants
225 ;; Constants used in the XOP pperm instruction
227 [(PPERM_SRC 0x00) /* copy source */
228 (PPERM_INVERT 0x20) /* invert source */
229 (PPERM_REVERSE 0x40) /* bit reverse source */
230 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
231 (PPERM_ZERO 0x80) /* all 0's */
232 (PPERM_ONES 0xa0) /* all 1's */
233 (PPERM_SIGN 0xc0) /* propagate sign bit */
234 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
235 (PPERM_SRC1 0x00) /* use first source byte */
236 (PPERM_SRC2 0x10) /* use second source byte */
239 ;; Registers by name.
292 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
295 ;; In C guard expressions, put expressions which may be compile-time
296 ;; constants first. This allows for better optimization. For
297 ;; example, write "TARGET_64BIT && reload_completed", not
298 ;; "reload_completed && TARGET_64BIT".
302 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
303 atom,generic64,amdfam10,bdver1,bdver2,btver1"
304 (const (symbol_ref "ix86_schedule")))
306 ;; A basic instruction type. Refinements due to arguments to be
307 ;; provided in other attributes.
310 alu,alu1,negnot,imov,imovx,lea,
311 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
312 icmp,test,ibr,setcc,icmov,
313 push,pop,call,callv,leave,
315 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
316 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
317 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
318 ssemuladd,sse4arg,lwp,
319 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
320 (const_string "other"))
322 ;; Main data type used by the insn
324 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
325 (const_string "unknown"))
327 ;; The CPU unit operations uses.
328 (define_attr "unit" "integer,i387,sse,mmx,unknown"
329 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
330 (const_string "i387")
331 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
332 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
333 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
335 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
337 (eq_attr "type" "other")
338 (const_string "unknown")]
339 (const_string "integer")))
341 ;; The (bounding maximum) length of an instruction immediate.
342 (define_attr "length_immediate" ""
343 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
346 (eq_attr "unit" "i387,sse,mmx")
348 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
349 rotate,rotatex,rotate1,imul,icmp,push,pop")
350 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
351 (eq_attr "type" "imov,test")
352 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
353 (eq_attr "type" "call")
354 (if_then_else (match_operand 0 "constant_call_address_operand" "")
357 (eq_attr "type" "callv")
358 (if_then_else (match_operand 1 "constant_call_address_operand" "")
361 ;; We don't know the size before shorten_branches. Expect
362 ;; the instruction to fit for better scheduling.
363 (eq_attr "type" "ibr")
366 (symbol_ref "/* Update immediate_length and other attributes! */
367 gcc_unreachable (),1")))
369 ;; The (bounding maximum) length of an instruction address.
370 (define_attr "length_address" ""
371 (cond [(eq_attr "type" "str,other,multi,fxch")
373 (and (eq_attr "type" "call")
374 (match_operand 0 "constant_call_address_operand" ""))
376 (and (eq_attr "type" "callv")
377 (match_operand 1 "constant_call_address_operand" ""))
380 (symbol_ref "ix86_attr_length_address_default (insn)")))
382 ;; Set when length prefix is used.
383 (define_attr "prefix_data16" ""
384 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
386 (eq_attr "mode" "HI")
388 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
393 ;; Set when string REP prefix is used.
394 (define_attr "prefix_rep" ""
395 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
397 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
402 ;; Set when 0f opcode prefix is used.
403 (define_attr "prefix_0f" ""
405 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
406 (eq_attr "unit" "sse,mmx"))
410 ;; Set when REX opcode prefix is used.
411 (define_attr "prefix_rex" ""
412 (cond [(not (match_test "TARGET_64BIT"))
414 (and (eq_attr "mode" "DI")
415 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
416 (eq_attr "unit" "!mmx")))
418 (and (eq_attr "mode" "QI")
419 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
421 (match_test "x86_extended_reg_mentioned_p (insn)")
423 (and (eq_attr "type" "imovx")
424 (match_operand:QI 1 "ext_QIreg_operand" ""))
429 ;; There are also additional prefixes in 3DNOW, SSSE3.
430 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
431 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
432 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
433 (define_attr "prefix_extra" ""
434 (cond [(eq_attr "type" "ssemuladd,sse4arg")
436 (eq_attr "type" "sseiadd1,ssecvt1")
441 ;; Prefix used: original, VEX or maybe VEX.
442 (define_attr "prefix" "orig,vex,maybe_vex"
443 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
445 (const_string "orig")))
447 ;; VEX W bit is used.
448 (define_attr "prefix_vex_w" "" (const_int 0))
450 ;; The length of VEX prefix
451 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
452 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
453 ;; still prefix_0f 1, with prefix_extra 1.
454 (define_attr "length_vex" ""
455 (if_then_else (and (eq_attr "prefix_0f" "1")
456 (eq_attr "prefix_extra" "0"))
457 (if_then_else (eq_attr "prefix_vex_w" "1")
458 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
459 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
460 (if_then_else (eq_attr "prefix_vex_w" "1")
461 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
462 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
464 ;; Set when modrm byte is used.
465 (define_attr "modrm" ""
466 (cond [(eq_attr "type" "str,leave")
468 (eq_attr "unit" "i387")
470 (and (eq_attr "type" "incdec")
471 (and (not (match_test "TARGET_64BIT"))
472 (ior (match_operand:SI 1 "register_operand" "")
473 (match_operand:HI 1 "register_operand" ""))))
475 (and (eq_attr "type" "push")
476 (not (match_operand 1 "memory_operand" "")))
478 (and (eq_attr "type" "pop")
479 (not (match_operand 0 "memory_operand" "")))
481 (and (eq_attr "type" "imov")
482 (and (not (eq_attr "mode" "DI"))
483 (ior (and (match_operand 0 "register_operand" "")
484 (match_operand 1 "immediate_operand" ""))
485 (ior (and (match_operand 0 "ax_reg_operand" "")
486 (match_operand 1 "memory_displacement_only_operand" ""))
487 (and (match_operand 0 "memory_displacement_only_operand" "")
488 (match_operand 1 "ax_reg_operand" ""))))))
490 (and (eq_attr "type" "call")
491 (match_operand 0 "constant_call_address_operand" ""))
493 (and (eq_attr "type" "callv")
494 (match_operand 1 "constant_call_address_operand" ""))
496 (and (eq_attr "type" "alu,alu1,icmp,test")
497 (match_operand 0 "ax_reg_operand" ""))
498 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
502 ;; The (bounding maximum) length of an instruction in bytes.
503 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
504 ;; Later we may want to split them and compute proper length as for
506 (define_attr "length" ""
507 (cond [(eq_attr "type" "other,multi,fistp,frndint")
509 (eq_attr "type" "fcmp")
511 (eq_attr "unit" "i387")
513 (plus (attr "prefix_data16")
514 (attr "length_address")))
515 (ior (eq_attr "prefix" "vex")
516 (and (eq_attr "prefix" "maybe_vex")
517 (match_test "TARGET_AVX")))
518 (plus (attr "length_vex")
519 (plus (attr "length_immediate")
521 (attr "length_address"))))]
522 (plus (plus (attr "modrm")
523 (plus (attr "prefix_0f")
524 (plus (attr "prefix_rex")
525 (plus (attr "prefix_extra")
527 (plus (attr "prefix_rep")
528 (plus (attr "prefix_data16")
529 (plus (attr "length_immediate")
530 (attr "length_address")))))))
532 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
533 ;; `store' if there is a simple memory reference therein, or `unknown'
534 ;; if the instruction is complex.
536 (define_attr "memory" "none,load,store,both,unknown"
537 (cond [(eq_attr "type" "other,multi,str,lwp")
538 (const_string "unknown")
539 (eq_attr "type" "lea,fcmov,fpspc")
540 (const_string "none")
541 (eq_attr "type" "fistp,leave")
542 (const_string "both")
543 (eq_attr "type" "frndint")
544 (const_string "load")
545 (eq_attr "type" "push")
546 (if_then_else (match_operand 1 "memory_operand" "")
547 (const_string "both")
548 (const_string "store"))
549 (eq_attr "type" "pop")
550 (if_then_else (match_operand 0 "memory_operand" "")
551 (const_string "both")
552 (const_string "load"))
553 (eq_attr "type" "setcc")
554 (if_then_else (match_operand 0 "memory_operand" "")
555 (const_string "store")
556 (const_string "none"))
557 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
558 (if_then_else (ior (match_operand 0 "memory_operand" "")
559 (match_operand 1 "memory_operand" ""))
560 (const_string "load")
561 (const_string "none"))
562 (eq_attr "type" "ibr")
563 (if_then_else (match_operand 0 "memory_operand" "")
564 (const_string "load")
565 (const_string "none"))
566 (eq_attr "type" "call")
567 (if_then_else (match_operand 0 "constant_call_address_operand" "")
568 (const_string "none")
569 (const_string "load"))
570 (eq_attr "type" "callv")
571 (if_then_else (match_operand 1 "constant_call_address_operand" "")
572 (const_string "none")
573 (const_string "load"))
574 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
575 (match_operand 1 "memory_operand" ""))
576 (const_string "both")
577 (and (match_operand 0 "memory_operand" "")
578 (match_operand 1 "memory_operand" ""))
579 (const_string "both")
580 (match_operand 0 "memory_operand" "")
581 (const_string "store")
582 (match_operand 1 "memory_operand" "")
583 (const_string "load")
585 "!alu1,negnot,ishift1,
586 imov,imovx,icmp,test,bitmanip,
588 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
589 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
590 (match_operand 2 "memory_operand" ""))
591 (const_string "load")
592 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
593 (match_operand 3 "memory_operand" ""))
594 (const_string "load")
596 (const_string "none")))
598 ;; Indicates if an instruction has both an immediate and a displacement.
600 (define_attr "imm_disp" "false,true,unknown"
601 (cond [(eq_attr "type" "other,multi")
602 (const_string "unknown")
603 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
604 (and (match_operand 0 "memory_displacement_operand" "")
605 (match_operand 1 "immediate_operand" "")))
606 (const_string "true")
607 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
608 (and (match_operand 0 "memory_displacement_operand" "")
609 (match_operand 2 "immediate_operand" "")))
610 (const_string "true")
612 (const_string "false")))
614 ;; Indicates if an FP operation has an integer source.
616 (define_attr "fp_int_src" "false,true"
617 (const_string "false"))
619 ;; Defines rounding mode of an FP operation.
621 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
622 (const_string "any"))
624 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
625 (define_attr "use_carry" "0,1" (const_string "0"))
627 ;; Define attribute to indicate unaligned ssemov insns
628 (define_attr "movu" "0,1" (const_string "0"))
630 ;; Used to control the "enabled" attribute on a per-instruction basis.
631 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
632 (const_string "base"))
634 (define_attr "enabled" ""
635 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
636 (eq_attr "isa" "sse2_noavx")
637 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
638 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
639 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
640 (eq_attr "isa" "sse4_noavx")
641 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
642 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
643 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
644 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
648 ;; Describe a user's asm statement.
649 (define_asm_attributes
650 [(set_attr "length" "128")
651 (set_attr "type" "multi")])
653 (define_code_iterator plusminus [plus minus])
655 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
657 ;; Base name for define_insn
658 (define_code_attr plusminus_insn
659 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
660 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
662 ;; Base name for insn mnemonic.
663 (define_code_attr plusminus_mnemonic
664 [(plus "add") (ss_plus "adds") (us_plus "addus")
665 (minus "sub") (ss_minus "subs") (us_minus "subus")])
666 (define_code_attr plusminus_carry_mnemonic
667 [(plus "adc") (minus "sbb")])
669 ;; Mark commutative operators as such in constraints.
670 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
671 (minus "") (ss_minus "") (us_minus "")])
673 ;; Mapping of max and min
674 (define_code_iterator maxmin [smax smin umax umin])
676 ;; Mapping of signed max and min
677 (define_code_iterator smaxmin [smax smin])
679 ;; Mapping of unsigned max and min
680 (define_code_iterator umaxmin [umax umin])
682 ;; Base name for integer and FP insn mnemonic
683 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
684 (umax "maxu") (umin "minu")])
685 (define_code_attr maxmin_float [(smax "max") (smin "min")])
687 ;; Mapping of logic operators
688 (define_code_iterator any_logic [and ior xor])
689 (define_code_iterator any_or [ior xor])
691 ;; Base name for insn mnemonic.
692 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
694 ;; Mapping of logic-shift operators
695 (define_code_iterator any_lshift [ashift lshiftrt])
697 ;; Mapping of shift-right operators
698 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
700 ;; Base name for define_insn
701 (define_code_attr shift_insn
702 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
704 ;; Base name for insn mnemonic.
705 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
706 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
708 ;; Mapping of rotate operators
709 (define_code_iterator any_rotate [rotate rotatert])
711 ;; Base name for define_insn
712 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
714 ;; Base name for insn mnemonic.
715 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
717 ;; Mapping of abs neg operators
718 (define_code_iterator absneg [abs neg])
720 ;; Base name for x87 insn mnemonic.
721 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
723 ;; Used in signed and unsigned widening multiplications.
724 (define_code_iterator any_extend [sign_extend zero_extend])
726 ;; Prefix for insn menmonic.
727 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
729 ;; Prefix for define_insn
730 (define_code_attr u [(sign_extend "") (zero_extend "u")])
731 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
733 ;; All integer modes.
734 (define_mode_iterator SWI1248x [QI HI SI DI])
736 ;; All integer modes without QImode.
737 (define_mode_iterator SWI248x [HI SI DI])
739 ;; All integer modes without QImode and HImode.
740 (define_mode_iterator SWI48x [SI DI])
742 ;; All integer modes without SImode and DImode.
743 (define_mode_iterator SWI12 [QI HI])
745 ;; All integer modes without DImode.
746 (define_mode_iterator SWI124 [QI HI SI])
748 ;; All integer modes without QImode and DImode.
749 (define_mode_iterator SWI24 [HI SI])
751 ;; Single word integer modes.
752 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
754 ;; Single word integer modes without QImode.
755 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
757 ;; Single word integer modes without QImode and HImode.
758 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
760 ;; All math-dependant single and double word integer modes.
761 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
762 (HI "TARGET_HIMODE_MATH")
763 SI DI (TI "TARGET_64BIT")])
765 ;; Math-dependant single word integer modes.
766 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
767 (HI "TARGET_HIMODE_MATH")
768 SI (DI "TARGET_64BIT")])
770 ;; Math-dependant integer modes without DImode.
771 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
772 (HI "TARGET_HIMODE_MATH")
775 ;; Math-dependant single word integer modes without QImode.
776 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
777 SI (DI "TARGET_64BIT")])
779 ;; Double word integer modes.
780 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
781 (TI "TARGET_64BIT")])
783 ;; Double word integer modes as mode attribute.
784 (define_mode_attr DWI [(SI "DI") (DI "TI")])
785 (define_mode_attr dwi [(SI "di") (DI "ti")])
787 ;; Half mode for double word integer modes.
788 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
789 (DI "TARGET_64BIT")])
791 ;; Instruction suffix for integer modes.
792 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
794 ;; Pointer size prefix for integer modes (Intel asm dialect)
795 (define_mode_attr iptrsize [(QI "BYTE")
800 ;; Register class for integer modes.
801 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
803 ;; Immediate operand constraint for integer modes.
804 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
806 ;; General operand constraint for word modes.
807 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
809 ;; Immediate operand constraint for double integer modes.
810 (define_mode_attr di [(SI "nF") (DI "e")])
812 ;; Immediate operand constraint for shifts.
813 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
815 ;; General operand predicate for integer modes.
816 (define_mode_attr general_operand
817 [(QI "general_operand")
818 (HI "general_operand")
819 (SI "x86_64_general_operand")
820 (DI "x86_64_general_operand")
821 (TI "x86_64_general_operand")])
823 ;; General sign/zero extend operand predicate for integer modes.
824 (define_mode_attr general_szext_operand
825 [(QI "general_operand")
826 (HI "general_operand")
827 (SI "x86_64_szext_general_operand")
828 (DI "x86_64_szext_general_operand")])
830 ;; Immediate operand predicate for integer modes.
831 (define_mode_attr immediate_operand
832 [(QI "immediate_operand")
833 (HI "immediate_operand")
834 (SI "x86_64_immediate_operand")
835 (DI "x86_64_immediate_operand")])
837 ;; Nonmemory operand predicate for integer modes.
838 (define_mode_attr nonmemory_operand
839 [(QI "nonmemory_operand")
840 (HI "nonmemory_operand")
841 (SI "x86_64_nonmemory_operand")
842 (DI "x86_64_nonmemory_operand")])
844 ;; Operand predicate for shifts.
845 (define_mode_attr shift_operand
846 [(QI "nonimmediate_operand")
847 (HI "nonimmediate_operand")
848 (SI "nonimmediate_operand")
849 (DI "shiftdi_operand")
850 (TI "register_operand")])
852 ;; Operand predicate for shift argument.
853 (define_mode_attr shift_immediate_operand
854 [(QI "const_1_to_31_operand")
855 (HI "const_1_to_31_operand")
856 (SI "const_1_to_31_operand")
857 (DI "const_1_to_63_operand")])
859 ;; Input operand predicate for arithmetic left shifts.
860 (define_mode_attr ashl_input_operand
861 [(QI "nonimmediate_operand")
862 (HI "nonimmediate_operand")
863 (SI "nonimmediate_operand")
864 (DI "ashldi_input_operand")
865 (TI "reg_or_pm1_operand")])
867 ;; SSE and x87 SFmode and DFmode floating point modes
868 (define_mode_iterator MODEF [SF DF])
870 ;; All x87 floating point modes
871 (define_mode_iterator X87MODEF [SF DF XF])
873 ;; SSE instruction suffix for various modes
874 (define_mode_attr ssemodesuffix
876 (V8SF "ps") (V4DF "pd")
877 (V4SF "ps") (V2DF "pd")
878 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
879 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
881 ;; SSE vector suffix for floating point modes
882 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
884 ;; SSE vector mode corresponding to a scalar mode
885 (define_mode_attr ssevecmode
886 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
888 ;; Instruction suffix for REX 64bit operators.
889 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
891 ;; This mode iterator allows :P to be used for patterns that operate on
892 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
893 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
895 ;; This mode iterator allows :PTR to be used for patterns that operate on
896 ;; ptr_mode sized quantities.
897 (define_mode_iterator PTR
898 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
900 ;; Scheduling descriptions
902 (include "pentium.md")
905 (include "athlon.md")
906 (include "bdver1.md")
912 ;; Operand and operator predicates and constraints
914 (include "predicates.md")
915 (include "constraints.md")
918 ;; Compare and branch/compare and store instructions.
920 (define_expand "cbranch<mode>4"
921 [(set (reg:CC FLAGS_REG)
922 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
923 (match_operand:SDWIM 2 "<general_operand>" "")))
924 (set (pc) (if_then_else
925 (match_operator 0 "ordered_comparison_operator"
926 [(reg:CC FLAGS_REG) (const_int 0)])
927 (label_ref (match_operand 3 "" ""))
931 if (MEM_P (operands[1]) && MEM_P (operands[2]))
932 operands[1] = force_reg (<MODE>mode, operands[1]);
933 ix86_expand_branch (GET_CODE (operands[0]),
934 operands[1], operands[2], operands[3]);
938 (define_expand "cstore<mode>4"
939 [(set (reg:CC FLAGS_REG)
940 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
941 (match_operand:SWIM 3 "<general_operand>" "")))
942 (set (match_operand:QI 0 "register_operand" "")
943 (match_operator 1 "ordered_comparison_operator"
944 [(reg:CC FLAGS_REG) (const_int 0)]))]
947 if (MEM_P (operands[2]) && MEM_P (operands[3]))
948 operands[2] = force_reg (<MODE>mode, operands[2]);
949 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
950 operands[2], operands[3]);
954 (define_expand "cmp<mode>_1"
955 [(set (reg:CC FLAGS_REG)
956 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
957 (match_operand:SWI48 1 "<general_operand>" "")))])
959 (define_insn "*cmp<mode>_ccno_1"
960 [(set (reg FLAGS_REG)
961 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
962 (match_operand:SWI 1 "const0_operand" "")))]
963 "ix86_match_ccmode (insn, CCNOmode)"
965 test{<imodesuffix>}\t%0, %0
966 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
967 [(set_attr "type" "test,icmp")
968 (set_attr "length_immediate" "0,1")
969 (set_attr "mode" "<MODE>")])
971 (define_insn "*cmp<mode>_1"
972 [(set (reg FLAGS_REG)
973 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
974 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
975 "ix86_match_ccmode (insn, CCmode)"
976 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
977 [(set_attr "type" "icmp")
978 (set_attr "mode" "<MODE>")])
980 (define_insn "*cmp<mode>_minus_1"
981 [(set (reg FLAGS_REG)
983 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
984 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
986 "ix86_match_ccmode (insn, CCGOCmode)"
987 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
988 [(set_attr "type" "icmp")
989 (set_attr "mode" "<MODE>")])
991 (define_insn "*cmpqi_ext_1"
992 [(set (reg FLAGS_REG)
994 (match_operand:QI 0 "general_operand" "Qm")
997 (match_operand 1 "ext_register_operand" "Q")
1000 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1001 "cmp{b}\t{%h1, %0|%0, %h1}"
1002 [(set_attr "type" "icmp")
1003 (set_attr "mode" "QI")])
1005 (define_insn "*cmpqi_ext_1_rex64"
1006 [(set (reg FLAGS_REG)
1008 (match_operand:QI 0 "register_operand" "Q")
1011 (match_operand 1 "ext_register_operand" "Q")
1013 (const_int 8)) 0)))]
1014 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1015 "cmp{b}\t{%h1, %0|%0, %h1}"
1016 [(set_attr "type" "icmp")
1017 (set_attr "mode" "QI")])
1019 (define_insn "*cmpqi_ext_2"
1020 [(set (reg FLAGS_REG)
1024 (match_operand 0 "ext_register_operand" "Q")
1027 (match_operand:QI 1 "const0_operand" "")))]
1028 "ix86_match_ccmode (insn, CCNOmode)"
1030 [(set_attr "type" "test")
1031 (set_attr "length_immediate" "0")
1032 (set_attr "mode" "QI")])
1034 (define_expand "cmpqi_ext_3"
1035 [(set (reg:CC FLAGS_REG)
1039 (match_operand 0 "ext_register_operand" "")
1042 (match_operand:QI 1 "immediate_operand" "")))])
1044 (define_insn "*cmpqi_ext_3_insn"
1045 [(set (reg FLAGS_REG)
1049 (match_operand 0 "ext_register_operand" "Q")
1052 (match_operand:QI 1 "general_operand" "Qmn")))]
1053 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1054 "cmp{b}\t{%1, %h0|%h0, %1}"
1055 [(set_attr "type" "icmp")
1056 (set_attr "modrm" "1")
1057 (set_attr "mode" "QI")])
1059 (define_insn "*cmpqi_ext_3_insn_rex64"
1060 [(set (reg FLAGS_REG)
1064 (match_operand 0 "ext_register_operand" "Q")
1067 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1068 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1069 "cmp{b}\t{%1, %h0|%h0, %1}"
1070 [(set_attr "type" "icmp")
1071 (set_attr "modrm" "1")
1072 (set_attr "mode" "QI")])
1074 (define_insn "*cmpqi_ext_4"
1075 [(set (reg FLAGS_REG)
1079 (match_operand 0 "ext_register_operand" "Q")
1084 (match_operand 1 "ext_register_operand" "Q")
1086 (const_int 8)) 0)))]
1087 "ix86_match_ccmode (insn, CCmode)"
1088 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1089 [(set_attr "type" "icmp")
1090 (set_attr "mode" "QI")])
1092 ;; These implement float point compares.
1093 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1094 ;; which would allow mix and match FP modes on the compares. Which is what
1095 ;; the old patterns did, but with many more of them.
1097 (define_expand "cbranchxf4"
1098 [(set (reg:CC FLAGS_REG)
1099 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1100 (match_operand:XF 2 "nonmemory_operand" "")))
1101 (set (pc) (if_then_else
1102 (match_operator 0 "ix86_fp_comparison_operator"
1105 (label_ref (match_operand 3 "" ""))
1109 ix86_expand_branch (GET_CODE (operands[0]),
1110 operands[1], operands[2], operands[3]);
1114 (define_expand "cstorexf4"
1115 [(set (reg:CC FLAGS_REG)
1116 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1117 (match_operand:XF 3 "nonmemory_operand" "")))
1118 (set (match_operand:QI 0 "register_operand" "")
1119 (match_operator 1 "ix86_fp_comparison_operator"
1124 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1125 operands[2], operands[3]);
1129 (define_expand "cbranch<mode>4"
1130 [(set (reg:CC FLAGS_REG)
1131 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1132 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1133 (set (pc) (if_then_else
1134 (match_operator 0 "ix86_fp_comparison_operator"
1137 (label_ref (match_operand 3 "" ""))
1139 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1141 ix86_expand_branch (GET_CODE (operands[0]),
1142 operands[1], operands[2], operands[3]);
1146 (define_expand "cstore<mode>4"
1147 [(set (reg:CC FLAGS_REG)
1148 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1149 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1150 (set (match_operand:QI 0 "register_operand" "")
1151 (match_operator 1 "ix86_fp_comparison_operator"
1154 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1156 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1157 operands[2], operands[3]);
1161 (define_expand "cbranchcc4"
1162 [(set (pc) (if_then_else
1163 (match_operator 0 "comparison_operator"
1164 [(match_operand 1 "flags_reg_operand" "")
1165 (match_operand 2 "const0_operand" "")])
1166 (label_ref (match_operand 3 "" ""))
1170 ix86_expand_branch (GET_CODE (operands[0]),
1171 operands[1], operands[2], operands[3]);
1175 (define_expand "cstorecc4"
1176 [(set (match_operand:QI 0 "register_operand" "")
1177 (match_operator 1 "comparison_operator"
1178 [(match_operand 2 "flags_reg_operand" "")
1179 (match_operand 3 "const0_operand" "")]))]
1182 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1183 operands[2], operands[3]);
1188 ;; FP compares, step 1:
1189 ;; Set the FP condition codes.
1191 ;; CCFPmode compare with exceptions
1192 ;; CCFPUmode compare with no exceptions
1194 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1195 ;; used to manage the reg stack popping would not be preserved.
1197 (define_insn "*cmpfp_0"
1198 [(set (match_operand:HI 0 "register_operand" "=a")
1201 (match_operand 1 "register_operand" "f")
1202 (match_operand 2 "const0_operand" ""))]
1204 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1205 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1206 "* return output_fp_compare (insn, operands, false, false);"
1207 [(set_attr "type" "multi")
1208 (set_attr "unit" "i387")
1210 (cond [(match_operand:SF 1 "" "")
1212 (match_operand:DF 1 "" "")
1215 (const_string "XF")))])
1217 (define_insn_and_split "*cmpfp_0_cc"
1218 [(set (reg:CCFP FLAGS_REG)
1220 (match_operand 1 "register_operand" "f")
1221 (match_operand 2 "const0_operand" "")))
1222 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1223 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1224 && TARGET_SAHF && !TARGET_CMOVE
1225 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1227 "&& reload_completed"
1230 [(compare:CCFP (match_dup 1)(match_dup 2))]
1232 (set (reg:CC FLAGS_REG)
1233 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1235 [(set_attr "type" "multi")
1236 (set_attr "unit" "i387")
1238 (cond [(match_operand:SF 1 "" "")
1240 (match_operand:DF 1 "" "")
1243 (const_string "XF")))])
1245 (define_insn "*cmpfp_xf"
1246 [(set (match_operand:HI 0 "register_operand" "=a")
1249 (match_operand:XF 1 "register_operand" "f")
1250 (match_operand:XF 2 "register_operand" "f"))]
1253 "* return output_fp_compare (insn, operands, false, false);"
1254 [(set_attr "type" "multi")
1255 (set_attr "unit" "i387")
1256 (set_attr "mode" "XF")])
1258 (define_insn_and_split "*cmpfp_xf_cc"
1259 [(set (reg:CCFP FLAGS_REG)
1261 (match_operand:XF 1 "register_operand" "f")
1262 (match_operand:XF 2 "register_operand" "f")))
1263 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1265 && TARGET_SAHF && !TARGET_CMOVE"
1267 "&& reload_completed"
1270 [(compare:CCFP (match_dup 1)(match_dup 2))]
1272 (set (reg:CC FLAGS_REG)
1273 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1275 [(set_attr "type" "multi")
1276 (set_attr "unit" "i387")
1277 (set_attr "mode" "XF")])
1279 (define_insn "*cmpfp_<mode>"
1280 [(set (match_operand:HI 0 "register_operand" "=a")
1283 (match_operand:MODEF 1 "register_operand" "f")
1284 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1287 "* return output_fp_compare (insn, operands, false, false);"
1288 [(set_attr "type" "multi")
1289 (set_attr "unit" "i387")
1290 (set_attr "mode" "<MODE>")])
1292 (define_insn_and_split "*cmpfp_<mode>_cc"
1293 [(set (reg:CCFP FLAGS_REG)
1295 (match_operand:MODEF 1 "register_operand" "f")
1296 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1297 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1299 && TARGET_SAHF && !TARGET_CMOVE"
1301 "&& reload_completed"
1304 [(compare:CCFP (match_dup 1)(match_dup 2))]
1306 (set (reg:CC FLAGS_REG)
1307 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1309 [(set_attr "type" "multi")
1310 (set_attr "unit" "i387")
1311 (set_attr "mode" "<MODE>")])
1313 (define_insn "*cmpfp_u"
1314 [(set (match_operand:HI 0 "register_operand" "=a")
1317 (match_operand 1 "register_operand" "f")
1318 (match_operand 2 "register_operand" "f"))]
1320 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1321 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1322 "* return output_fp_compare (insn, operands, false, true);"
1323 [(set_attr "type" "multi")
1324 (set_attr "unit" "i387")
1326 (cond [(match_operand:SF 1 "" "")
1328 (match_operand:DF 1 "" "")
1331 (const_string "XF")))])
1333 (define_insn_and_split "*cmpfp_u_cc"
1334 [(set (reg:CCFPU FLAGS_REG)
1336 (match_operand 1 "register_operand" "f")
1337 (match_operand 2 "register_operand" "f")))
1338 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1339 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1340 && TARGET_SAHF && !TARGET_CMOVE
1341 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1343 "&& reload_completed"
1346 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1348 (set (reg:CC FLAGS_REG)
1349 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1351 [(set_attr "type" "multi")
1352 (set_attr "unit" "i387")
1354 (cond [(match_operand:SF 1 "" "")
1356 (match_operand:DF 1 "" "")
1359 (const_string "XF")))])
1361 (define_insn "*cmpfp_<mode>"
1362 [(set (match_operand:HI 0 "register_operand" "=a")
1365 (match_operand 1 "register_operand" "f")
1366 (match_operator 3 "float_operator"
1367 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1369 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1370 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1371 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1372 "* return output_fp_compare (insn, operands, false, false);"
1373 [(set_attr "type" "multi")
1374 (set_attr "unit" "i387")
1375 (set_attr "fp_int_src" "true")
1376 (set_attr "mode" "<MODE>")])
1378 (define_insn_and_split "*cmpfp_<mode>_cc"
1379 [(set (reg:CCFP FLAGS_REG)
1381 (match_operand 1 "register_operand" "f")
1382 (match_operator 3 "float_operator"
1383 [(match_operand:SWI24 2 "memory_operand" "m")])))
1384 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1385 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1386 && TARGET_SAHF && !TARGET_CMOVE
1387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1388 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1390 "&& reload_completed"
1395 (match_op_dup 3 [(match_dup 2)]))]
1397 (set (reg:CC FLAGS_REG)
1398 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1400 [(set_attr "type" "multi")
1401 (set_attr "unit" "i387")
1402 (set_attr "fp_int_src" "true")
1403 (set_attr "mode" "<MODE>")])
1405 ;; FP compares, step 2
1406 ;; Move the fpsw to ax.
1408 (define_insn "x86_fnstsw_1"
1409 [(set (match_operand:HI 0 "register_operand" "=a")
1410 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1413 [(set (attr "length")
1414 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1415 (set_attr "mode" "SI")
1416 (set_attr "unit" "i387")])
1418 ;; FP compares, step 3
1419 ;; Get ax into flags, general case.
1421 (define_insn "x86_sahf_1"
1422 [(set (reg:CC FLAGS_REG)
1423 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1427 #ifndef HAVE_AS_IX86_SAHF
1429 return ASM_BYTE "0x9e";
1434 [(set_attr "length" "1")
1435 (set_attr "athlon_decode" "vector")
1436 (set_attr "amdfam10_decode" "direct")
1437 (set_attr "bdver1_decode" "direct")
1438 (set_attr "mode" "SI")])
1440 ;; Pentium Pro can do steps 1 through 3 in one go.
1441 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1442 ;; (these i387 instructions set flags directly)
1443 (define_insn "*cmpfp_i_mixed"
1444 [(set (reg:CCFP FLAGS_REG)
1445 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1446 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1447 "TARGET_MIX_SSE_I387
1448 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1449 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1450 "* return output_fp_compare (insn, operands, true, false);"
1451 [(set_attr "type" "fcmp,ssecomi")
1452 (set_attr "prefix" "orig,maybe_vex")
1454 (if_then_else (match_operand:SF 1 "" "")
1456 (const_string "DF")))
1457 (set (attr "prefix_rep")
1458 (if_then_else (eq_attr "type" "ssecomi")
1460 (const_string "*")))
1461 (set (attr "prefix_data16")
1462 (cond [(eq_attr "type" "fcmp")
1464 (eq_attr "mode" "DF")
1467 (const_string "0")))
1468 (set_attr "athlon_decode" "vector")
1469 (set_attr "amdfam10_decode" "direct")
1470 (set_attr "bdver1_decode" "double")])
1472 (define_insn "*cmpfp_i_sse"
1473 [(set (reg:CCFP FLAGS_REG)
1474 (compare:CCFP (match_operand 0 "register_operand" "x")
1475 (match_operand 1 "nonimmediate_operand" "xm")))]
1477 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1478 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1479 "* return output_fp_compare (insn, operands, true, false);"
1480 [(set_attr "type" "ssecomi")
1481 (set_attr "prefix" "maybe_vex")
1483 (if_then_else (match_operand:SF 1 "" "")
1485 (const_string "DF")))
1486 (set_attr "prefix_rep" "0")
1487 (set (attr "prefix_data16")
1488 (if_then_else (eq_attr "mode" "DF")
1490 (const_string "0")))
1491 (set_attr "athlon_decode" "vector")
1492 (set_attr "amdfam10_decode" "direct")
1493 (set_attr "bdver1_decode" "double")])
1495 (define_insn "*cmpfp_i_i387"
1496 [(set (reg:CCFP FLAGS_REG)
1497 (compare:CCFP (match_operand 0 "register_operand" "f")
1498 (match_operand 1 "register_operand" "f")))]
1499 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1501 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1502 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503 "* return output_fp_compare (insn, operands, true, false);"
1504 [(set_attr "type" "fcmp")
1506 (cond [(match_operand:SF 1 "" "")
1508 (match_operand:DF 1 "" "")
1511 (const_string "XF")))
1512 (set_attr "athlon_decode" "vector")
1513 (set_attr "amdfam10_decode" "direct")
1514 (set_attr "bdver1_decode" "double")])
1516 (define_insn "*cmpfp_iu_mixed"
1517 [(set (reg:CCFPU FLAGS_REG)
1518 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1519 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1520 "TARGET_MIX_SSE_I387
1521 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1522 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1523 "* return output_fp_compare (insn, operands, true, true);"
1524 [(set_attr "type" "fcmp,ssecomi")
1525 (set_attr "prefix" "orig,maybe_vex")
1527 (if_then_else (match_operand:SF 1 "" "")
1529 (const_string "DF")))
1530 (set (attr "prefix_rep")
1531 (if_then_else (eq_attr "type" "ssecomi")
1533 (const_string "*")))
1534 (set (attr "prefix_data16")
1535 (cond [(eq_attr "type" "fcmp")
1537 (eq_attr "mode" "DF")
1540 (const_string "0")))
1541 (set_attr "athlon_decode" "vector")
1542 (set_attr "amdfam10_decode" "direct")
1543 (set_attr "bdver1_decode" "double")])
1545 (define_insn "*cmpfp_iu_sse"
1546 [(set (reg:CCFPU FLAGS_REG)
1547 (compare:CCFPU (match_operand 0 "register_operand" "x")
1548 (match_operand 1 "nonimmediate_operand" "xm")))]
1550 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1551 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1552 "* return output_fp_compare (insn, operands, true, true);"
1553 [(set_attr "type" "ssecomi")
1554 (set_attr "prefix" "maybe_vex")
1556 (if_then_else (match_operand:SF 1 "" "")
1558 (const_string "DF")))
1559 (set_attr "prefix_rep" "0")
1560 (set (attr "prefix_data16")
1561 (if_then_else (eq_attr "mode" "DF")
1563 (const_string "0")))
1564 (set_attr "athlon_decode" "vector")
1565 (set_attr "amdfam10_decode" "direct")
1566 (set_attr "bdver1_decode" "double")])
1568 (define_insn "*cmpfp_iu_387"
1569 [(set (reg:CCFPU FLAGS_REG)
1570 (compare:CCFPU (match_operand 0 "register_operand" "f")
1571 (match_operand 1 "register_operand" "f")))]
1572 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1574 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1575 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576 "* return output_fp_compare (insn, operands, true, true);"
1577 [(set_attr "type" "fcmp")
1579 (cond [(match_operand:SF 1 "" "")
1581 (match_operand:DF 1 "" "")
1584 (const_string "XF")))
1585 (set_attr "athlon_decode" "vector")
1586 (set_attr "amdfam10_decode" "direct")
1587 (set_attr "bdver1_decode" "direct")])
1589 ;; Push/pop instructions.
1591 (define_insn "*push<mode>2"
1592 [(set (match_operand:DWI 0 "push_operand" "=<")
1593 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1596 [(set_attr "type" "multi")
1597 (set_attr "mode" "<MODE>")])
1600 [(set (match_operand:TI 0 "push_operand" "")
1601 (match_operand:TI 1 "general_operand" ""))]
1602 "TARGET_64BIT && reload_completed
1603 && !SSE_REG_P (operands[1])"
1605 "ix86_split_long_move (operands); DONE;")
1607 (define_insn "*pushdi2_rex64"
1608 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1609 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1614 [(set_attr "type" "push,multi")
1615 (set_attr "mode" "DI")])
1617 ;; Convert impossible pushes of immediate to existing instructions.
1618 ;; First try to get scratch register and go through it. In case this
1619 ;; fails, push sign extended lower part first and then overwrite
1620 ;; upper part by 32bit move.
1622 [(match_scratch:DI 2 "r")
1623 (set (match_operand:DI 0 "push_operand" "")
1624 (match_operand:DI 1 "immediate_operand" ""))]
1625 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1626 && !x86_64_immediate_operand (operands[1], DImode)"
1627 [(set (match_dup 2) (match_dup 1))
1628 (set (match_dup 0) (match_dup 2))])
1630 ;; We need to define this as both peepholer and splitter for case
1631 ;; peephole2 pass is not run.
1632 ;; "&& 1" is needed to keep it from matching the previous pattern.
1634 [(set (match_operand:DI 0 "push_operand" "")
1635 (match_operand:DI 1 "immediate_operand" ""))]
1636 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1637 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1638 [(set (match_dup 0) (match_dup 1))
1639 (set (match_dup 2) (match_dup 3))]
1641 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1643 operands[1] = gen_lowpart (DImode, operands[2]);
1644 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1649 [(set (match_operand:DI 0 "push_operand" "")
1650 (match_operand:DI 1 "immediate_operand" ""))]
1651 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1652 ? epilogue_completed : reload_completed)
1653 && !symbolic_operand (operands[1], DImode)
1654 && !x86_64_immediate_operand (operands[1], DImode)"
1655 [(set (match_dup 0) (match_dup 1))
1656 (set (match_dup 2) (match_dup 3))]
1658 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1660 operands[1] = gen_lowpart (DImode, operands[2]);
1661 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1666 [(set (match_operand:DI 0 "push_operand" "")
1667 (match_operand:DI 1 "general_operand" ""))]
1668 "!TARGET_64BIT && reload_completed
1669 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1671 "ix86_split_long_move (operands); DONE;")
1673 (define_insn "*pushsi2"
1674 [(set (match_operand:SI 0 "push_operand" "=<")
1675 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1678 [(set_attr "type" "push")
1679 (set_attr "mode" "SI")])
1681 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1682 ;; "push a byte/word". But actually we use pushl, which has the effect
1683 ;; of rounding the amount pushed up to a word.
1685 ;; For TARGET_64BIT we always round up to 8 bytes.
1686 (define_insn "*push<mode>2_rex64"
1687 [(set (match_operand:SWI124 0 "push_operand" "=X")
1688 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1691 [(set_attr "type" "push")
1692 (set_attr "mode" "DI")])
1694 (define_insn "*push<mode>2"
1695 [(set (match_operand:SWI12 0 "push_operand" "=X")
1696 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1699 [(set_attr "type" "push")
1700 (set_attr "mode" "SI")])
1702 (define_insn "*push<mode>2_prologue"
1703 [(set (match_operand:P 0 "push_operand" "=<")
1704 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1705 (clobber (mem:BLK (scratch)))]
1707 "push{<imodesuffix>}\t%1"
1708 [(set_attr "type" "push")
1709 (set_attr "mode" "<MODE>")])
1711 (define_insn "*pop<mode>1"
1712 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1713 (match_operand:P 1 "pop_operand" ">"))]
1715 "pop{<imodesuffix>}\t%0"
1716 [(set_attr "type" "pop")
1717 (set_attr "mode" "<MODE>")])
1719 (define_insn "*pop<mode>1_epilogue"
1720 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1721 (match_operand:P 1 "pop_operand" ">"))
1722 (clobber (mem:BLK (scratch)))]
1724 "pop{<imodesuffix>}\t%0"
1725 [(set_attr "type" "pop")
1726 (set_attr "mode" "<MODE>")])
1728 ;; Move instructions.
1730 (define_expand "movoi"
1731 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1732 (match_operand:OI 1 "general_operand" ""))]
1734 "ix86_expand_move (OImode, operands); DONE;")
1736 (define_expand "movti"
1737 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1738 (match_operand:TI 1 "nonimmediate_operand" ""))]
1739 "TARGET_64BIT || TARGET_SSE"
1742 ix86_expand_move (TImode, operands);
1743 else if (push_operand (operands[0], TImode))
1744 ix86_expand_push (TImode, operands[1]);
1746 ix86_expand_vector_move (TImode, operands);
1750 ;; This expands to what emit_move_complex would generate if we didn't
1751 ;; have a movti pattern. Having this avoids problems with reload on
1752 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1753 ;; to have around all the time.
1754 (define_expand "movcdi"
1755 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1756 (match_operand:CDI 1 "general_operand" ""))]
1759 if (push_operand (operands[0], CDImode))
1760 emit_move_complex_push (CDImode, operands[0], operands[1]);
1762 emit_move_complex_parts (operands[0], operands[1]);
1766 (define_expand "mov<mode>"
1767 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1768 (match_operand:SWI1248x 1 "general_operand" ""))]
1770 "ix86_expand_move (<MODE>mode, operands); DONE;")
1772 (define_insn "*mov<mode>_xor"
1773 [(set (match_operand:SWI48 0 "register_operand" "=r")
1774 (match_operand:SWI48 1 "const0_operand" ""))
1775 (clobber (reg:CC FLAGS_REG))]
1778 [(set_attr "type" "alu1")
1779 (set_attr "mode" "SI")
1780 (set_attr "length_immediate" "0")])
1782 (define_insn "*mov<mode>_or"
1783 [(set (match_operand:SWI48 0 "register_operand" "=r")
1784 (match_operand:SWI48 1 "const_int_operand" ""))
1785 (clobber (reg:CC FLAGS_REG))]
1787 && operands[1] == constm1_rtx"
1788 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1789 [(set_attr "type" "alu1")
1790 (set_attr "mode" "<MODE>")
1791 (set_attr "length_immediate" "1")])
1793 (define_insn "*movoi_internal_avx"
1794 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1795 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1796 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1798 switch (which_alternative)
1801 return standard_sse_constant_opcode (insn, operands[1]);
1804 if (misaligned_operand (operands[0], OImode)
1805 || misaligned_operand (operands[1], OImode))
1806 return "vmovdqu\t{%1, %0|%0, %1}";
1808 return "vmovdqa\t{%1, %0|%0, %1}";
1813 [(set_attr "type" "sselog1,ssemov,ssemov")
1814 (set_attr "prefix" "vex")
1815 (set_attr "mode" "OI")])
1817 (define_insn "*movti_internal_rex64"
1818 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1819 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1820 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1822 switch (which_alternative)
1828 return standard_sse_constant_opcode (insn, operands[1]);
1831 /* TDmode values are passed as TImode on the stack. Moving them
1832 to stack may result in unaligned memory access. */
1833 if (misaligned_operand (operands[0], TImode)
1834 || misaligned_operand (operands[1], TImode))
1836 if (get_attr_mode (insn) == MODE_V4SF)
1837 return "%vmovups\t{%1, %0|%0, %1}";
1839 return "%vmovdqu\t{%1, %0|%0, %1}";
1843 if (get_attr_mode (insn) == MODE_V4SF)
1844 return "%vmovaps\t{%1, %0|%0, %1}";
1846 return "%vmovdqa\t{%1, %0|%0, %1}";
1852 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1853 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1855 (cond [(eq_attr "alternative" "2,3")
1857 (match_test "optimize_function_for_size_p (cfun)")
1858 (const_string "V4SF")
1859 (const_string "TI"))
1860 (eq_attr "alternative" "4")
1862 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1863 (match_test "optimize_function_for_size_p (cfun)"))
1864 (const_string "V4SF")
1865 (const_string "TI"))]
1866 (const_string "DI")))])
1869 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1870 (match_operand:TI 1 "general_operand" ""))]
1872 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1874 "ix86_split_long_move (operands); DONE;")
1876 (define_insn "*movti_internal_sse"
1877 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1878 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1879 "TARGET_SSE && !TARGET_64BIT
1880 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1882 switch (which_alternative)
1885 return standard_sse_constant_opcode (insn, operands[1]);
1888 /* TDmode values are passed as TImode on the stack. Moving them
1889 to stack may result in unaligned memory access. */
1890 if (misaligned_operand (operands[0], TImode)
1891 || misaligned_operand (operands[1], TImode))
1893 if (get_attr_mode (insn) == MODE_V4SF)
1894 return "%vmovups\t{%1, %0|%0, %1}";
1896 return "%vmovdqu\t{%1, %0|%0, %1}";
1900 if (get_attr_mode (insn) == MODE_V4SF)
1901 return "%vmovaps\t{%1, %0|%0, %1}";
1903 return "%vmovdqa\t{%1, %0|%0, %1}";
1909 [(set_attr "type" "sselog1,ssemov,ssemov")
1910 (set_attr "prefix" "maybe_vex")
1912 (cond [(ior (not (match_test "TARGET_SSE2"))
1913 (match_test "optimize_function_for_size_p (cfun)"))
1914 (const_string "V4SF")
1915 (and (eq_attr "alternative" "2")
1916 (match_test "TARGET_SSE_TYPELESS_STORES"))
1917 (const_string "V4SF")]
1918 (const_string "TI")))])
1920 (define_insn "*movdi_internal_rex64"
1921 [(set (match_operand:DI 0 "nonimmediate_operand"
1922 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1923 (match_operand:DI 1 "general_operand"
1924 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1925 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1927 switch (get_attr_type (insn))
1930 if (SSE_REG_P (operands[0]))
1931 return "movq2dq\t{%1, %0|%0, %1}";
1933 return "movdq2q\t{%1, %0|%0, %1}";
1936 if (get_attr_mode (insn) == MODE_TI)
1937 return "%vmovdqa\t{%1, %0|%0, %1}";
1938 /* Handle broken assemblers that require movd instead of movq. */
1939 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1940 return "%vmovd\t{%1, %0|%0, %1}";
1942 return "%vmovq\t{%1, %0|%0, %1}";
1945 /* Handle broken assemblers that require movd instead of movq. */
1946 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1947 return "movd\t{%1, %0|%0, %1}";
1949 return "movq\t{%1, %0|%0, %1}";
1952 return standard_sse_constant_opcode (insn, operands[1]);
1955 return "pxor\t%0, %0";
1961 return "lea{q}\t{%a1, %0|%0, %a1}";
1964 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1965 if (get_attr_mode (insn) == MODE_SI)
1966 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1967 else if (which_alternative == 2)
1968 return "movabs{q}\t{%1, %0|%0, %1}";
1969 else if (ix86_use_lea_for_mov (insn, operands))
1970 return "lea{q}\t{%a1, %0|%0, %a1}";
1972 return "mov{q}\t{%1, %0|%0, %1}";
1976 (cond [(eq_attr "alternative" "4")
1977 (const_string "multi")
1978 (eq_attr "alternative" "5")
1979 (const_string "mmx")
1980 (eq_attr "alternative" "6,7,8,9")
1981 (const_string "mmxmov")
1982 (eq_attr "alternative" "10")
1983 (const_string "sselog1")
1984 (eq_attr "alternative" "11,12,13,14,15")
1985 (const_string "ssemov")
1986 (eq_attr "alternative" "16,17")
1987 (const_string "ssecvt")
1988 (match_operand 1 "pic_32bit_operand" "")
1989 (const_string "lea")
1991 (const_string "imov")))
1994 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1996 (const_string "*")))
1997 (set (attr "length_immediate")
1999 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2001 (const_string "*")))
2002 (set (attr "prefix_rex")
2003 (if_then_else (eq_attr "alternative" "8,9")
2005 (const_string "*")))
2006 (set (attr "prefix_data16")
2007 (if_then_else (eq_attr "alternative" "11")
2009 (const_string "*")))
2010 (set (attr "prefix")
2011 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2012 (const_string "maybe_vex")
2013 (const_string "orig")))
2014 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2016 ;; Reload patterns to support multi-word load/store
2017 ;; with non-offsetable address.
2018 (define_expand "reload_noff_store"
2019 [(parallel [(match_operand 0 "memory_operand" "=m")
2020 (match_operand 1 "register_operand" "r")
2021 (match_operand:DI 2 "register_operand" "=&r")])]
2024 rtx mem = operands[0];
2025 rtx addr = XEXP (mem, 0);
2027 emit_move_insn (operands[2], addr);
2028 mem = replace_equiv_address_nv (mem, operands[2]);
2030 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2034 (define_expand "reload_noff_load"
2035 [(parallel [(match_operand 0 "register_operand" "=r")
2036 (match_operand 1 "memory_operand" "m")
2037 (match_operand:DI 2 "register_operand" "=r")])]
2040 rtx mem = operands[1];
2041 rtx addr = XEXP (mem, 0);
2043 emit_move_insn (operands[2], addr);
2044 mem = replace_equiv_address_nv (mem, operands[2]);
2046 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2050 ;; Convert impossible stores of immediate to existing instructions.
2051 ;; First try to get scratch register and go through it. In case this
2052 ;; fails, move by 32bit parts.
2054 [(match_scratch:DI 2 "r")
2055 (set (match_operand:DI 0 "memory_operand" "")
2056 (match_operand:DI 1 "immediate_operand" ""))]
2057 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2058 && !x86_64_immediate_operand (operands[1], DImode)"
2059 [(set (match_dup 2) (match_dup 1))
2060 (set (match_dup 0) (match_dup 2))])
2062 ;; We need to define this as both peepholer and splitter for case
2063 ;; peephole2 pass is not run.
2064 ;; "&& 1" is needed to keep it from matching the previous pattern.
2066 [(set (match_operand:DI 0 "memory_operand" "")
2067 (match_operand:DI 1 "immediate_operand" ""))]
2068 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2069 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2070 [(set (match_dup 2) (match_dup 3))
2071 (set (match_dup 4) (match_dup 5))]
2072 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2075 [(set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2078 ? epilogue_completed : reload_completed)
2079 && !symbolic_operand (operands[1], DImode)
2080 && !x86_64_immediate_operand (operands[1], DImode)"
2081 [(set (match_dup 2) (match_dup 3))
2082 (set (match_dup 4) (match_dup 5))]
2083 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2085 (define_insn "*movdi_internal"
2086 [(set (match_operand:DI 0 "nonimmediate_operand"
2087 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2088 (match_operand:DI 1 "general_operand"
2089 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2090 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2092 switch (get_attr_type (insn))
2095 if (SSE_REG_P (operands[0]))
2096 return "movq2dq\t{%1, %0|%0, %1}";
2098 return "movdq2q\t{%1, %0|%0, %1}";
2101 switch (get_attr_mode (insn))
2104 return "%vmovdqa\t{%1, %0|%0, %1}";
2106 return "%vmovq\t{%1, %0|%0, %1}";
2108 return "movaps\t{%1, %0|%0, %1}";
2110 return "movlps\t{%1, %0|%0, %1}";
2116 return "movq\t{%1, %0|%0, %1}";
2119 return standard_sse_constant_opcode (insn, operands[1]);
2122 return "pxor\t%0, %0";
2132 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2133 (const_string "sse2")
2134 (eq_attr "alternative" "9,10,11,12")
2135 (const_string "noavx")
2137 (const_string "*")))
2139 (cond [(eq_attr "alternative" "0,1")
2140 (const_string "multi")
2141 (eq_attr "alternative" "2")
2142 (const_string "mmx")
2143 (eq_attr "alternative" "3,4")
2144 (const_string "mmxmov")
2145 (eq_attr "alternative" "5,9")
2146 (const_string "sselog1")
2147 (eq_attr "alternative" "13,14")
2148 (const_string "ssecvt")
2150 (const_string "ssemov")))
2151 (set (attr "prefix")
2152 (if_then_else (eq_attr "alternative" "5,6,7,8")
2153 (const_string "maybe_vex")
2154 (const_string "orig")))
2155 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2158 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2159 (match_operand:DI 1 "general_operand" ""))]
2160 "!TARGET_64BIT && reload_completed
2161 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2162 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2164 "ix86_split_long_move (operands); DONE;")
2166 (define_insn "*movsi_internal"
2167 [(set (match_operand:SI 0 "nonimmediate_operand"
2168 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2169 (match_operand:SI 1 "general_operand"
2170 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2171 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2173 switch (get_attr_type (insn))
2176 return standard_sse_constant_opcode (insn, operands[1]);
2179 switch (get_attr_mode (insn))
2182 return "%vmovdqa\t{%1, %0|%0, %1}";
2184 return "%vmovaps\t{%1, %0|%0, %1}";
2186 return "%vmovd\t{%1, %0|%0, %1}";
2188 return "%vmovss\t{%1, %0|%0, %1}";
2194 return "pxor\t%0, %0";
2197 if (get_attr_mode (insn) == MODE_DI)
2198 return "movq\t{%1, %0|%0, %1}";
2199 return "movd\t{%1, %0|%0, %1}";
2202 return "lea{l}\t{%a1, %0|%0, %a1}";
2205 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2206 if (ix86_use_lea_for_mov (insn, operands))
2207 return "lea{l}\t{%a1, %0|%0, %a1}";
2209 return "mov{l}\t{%1, %0|%0, %1}";
2213 (cond [(eq_attr "alternative" "2")
2214 (const_string "mmx")
2215 (eq_attr "alternative" "3,4,5")
2216 (const_string "mmxmov")
2217 (eq_attr "alternative" "6")
2218 (const_string "sselog1")
2219 (eq_attr "alternative" "7,8,9,10,11")
2220 (const_string "ssemov")
2221 (match_operand 1 "pic_32bit_operand" "")
2222 (const_string "lea")
2224 (const_string "imov")))
2225 (set (attr "prefix")
2226 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2227 (const_string "orig")
2228 (const_string "maybe_vex")))
2229 (set (attr "prefix_data16")
2230 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2232 (const_string "*")))
2234 (cond [(eq_attr "alternative" "2,3")
2236 (eq_attr "alternative" "6,7")
2238 (not (match_test "TARGET_SSE2"))
2239 (const_string "V4SF")
2240 (const_string "TI"))
2241 (and (eq_attr "alternative" "8,9,10,11")
2242 (not (match_test "TARGET_SSE2")))
2245 (const_string "SI")))])
2247 (define_insn "*movhi_internal"
2248 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2249 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2250 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2252 switch (get_attr_type (insn))
2255 /* movzwl is faster than movw on p2 due to partial word stalls,
2256 though not as fast as an aligned movl. */
2257 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2259 if (get_attr_mode (insn) == MODE_SI)
2260 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2262 return "mov{w}\t{%1, %0|%0, %1}";
2266 (cond [(match_test "optimize_function_for_size_p (cfun)")
2267 (const_string "imov")
2268 (and (eq_attr "alternative" "0")
2269 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2270 (not (match_test "TARGET_HIMODE_MATH"))))
2271 (const_string "imov")
2272 (and (eq_attr "alternative" "1,2")
2273 (match_operand:HI 1 "aligned_operand" ""))
2274 (const_string "imov")
2275 (and (match_test "TARGET_MOVX")
2276 (eq_attr "alternative" "0,2"))
2277 (const_string "imovx")
2279 (const_string "imov")))
2281 (cond [(eq_attr "type" "imovx")
2283 (and (eq_attr "alternative" "1,2")
2284 (match_operand:HI 1 "aligned_operand" ""))
2286 (and (eq_attr "alternative" "0")
2287 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2288 (not (match_test "TARGET_HIMODE_MATH"))))
2291 (const_string "HI")))])
2293 ;; Situation is quite tricky about when to choose full sized (SImode) move
2294 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2295 ;; partial register dependency machines (such as AMD Athlon), where QImode
2296 ;; moves issue extra dependency and for partial register stalls machines
2297 ;; that don't use QImode patterns (and QImode move cause stall on the next
2300 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2301 ;; register stall machines with, where we use QImode instructions, since
2302 ;; partial register stall can be caused there. Then we use movzx.
2303 (define_insn "*movqi_internal"
2304 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2305 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2306 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2308 switch (get_attr_type (insn))
2311 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2312 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2314 if (get_attr_mode (insn) == MODE_SI)
2315 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2317 return "mov{b}\t{%1, %0|%0, %1}";
2321 (cond [(and (eq_attr "alternative" "5")
2322 (not (match_operand:QI 1 "aligned_operand" "")))
2323 (const_string "imovx")
2324 (match_test "optimize_function_for_size_p (cfun)")
2325 (const_string "imov")
2326 (and (eq_attr "alternative" "3")
2327 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2328 (not (match_test "TARGET_QIMODE_MATH"))))
2329 (const_string "imov")
2330 (eq_attr "alternative" "3,5")
2331 (const_string "imovx")
2332 (and (match_test "TARGET_MOVX")
2333 (eq_attr "alternative" "2"))
2334 (const_string "imovx")
2336 (const_string "imov")))
2338 (cond [(eq_attr "alternative" "3,4,5")
2340 (eq_attr "alternative" "6")
2342 (eq_attr "type" "imovx")
2344 (and (eq_attr "type" "imov")
2345 (and (eq_attr "alternative" "0,1")
2346 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2347 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2348 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2350 ;; Avoid partial register stalls when not using QImode arithmetic
2351 (and (eq_attr "type" "imov")
2352 (and (eq_attr "alternative" "0,1")
2353 (and (match_test "TARGET_PARTIAL_REG_STALL")
2354 (not (match_test "TARGET_QIMODE_MATH")))))
2357 (const_string "QI")))])
2359 ;; Stores and loads of ax to arbitrary constant address.
2360 ;; We fake an second form of instruction to force reload to load address
2361 ;; into register when rax is not available
2362 (define_insn "*movabs<mode>_1"
2363 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2364 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2365 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2367 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2368 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2369 [(set_attr "type" "imov")
2370 (set_attr "modrm" "0,*")
2371 (set_attr "length_address" "8,0")
2372 (set_attr "length_immediate" "0,*")
2373 (set_attr "memory" "store")
2374 (set_attr "mode" "<MODE>")])
2376 (define_insn "*movabs<mode>_2"
2377 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2378 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2379 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2381 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2382 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2383 [(set_attr "type" "imov")
2384 (set_attr "modrm" "0,*")
2385 (set_attr "length_address" "8,0")
2386 (set_attr "length_immediate" "0")
2387 (set_attr "memory" "load")
2388 (set_attr "mode" "<MODE>")])
2390 (define_insn "*swap<mode>"
2391 [(set (match_operand:SWI48 0 "register_operand" "+r")
2392 (match_operand:SWI48 1 "register_operand" "+r"))
2396 "xchg{<imodesuffix>}\t%1, %0"
2397 [(set_attr "type" "imov")
2398 (set_attr "mode" "<MODE>")
2399 (set_attr "pent_pair" "np")
2400 (set_attr "athlon_decode" "vector")
2401 (set_attr "amdfam10_decode" "double")
2402 (set_attr "bdver1_decode" "double")])
2404 (define_insn "*swap<mode>_1"
2405 [(set (match_operand:SWI12 0 "register_operand" "+r")
2406 (match_operand:SWI12 1 "register_operand" "+r"))
2409 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2411 [(set_attr "type" "imov")
2412 (set_attr "mode" "SI")
2413 (set_attr "pent_pair" "np")
2414 (set_attr "athlon_decode" "vector")
2415 (set_attr "amdfam10_decode" "double")
2416 (set_attr "bdver1_decode" "double")])
2418 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2419 ;; is disabled for AMDFAM10
2420 (define_insn "*swap<mode>_2"
2421 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2422 (match_operand:SWI12 1 "register_operand" "+<r>"))
2425 "TARGET_PARTIAL_REG_STALL"
2426 "xchg{<imodesuffix>}\t%1, %0"
2427 [(set_attr "type" "imov")
2428 (set_attr "mode" "<MODE>")
2429 (set_attr "pent_pair" "np")
2430 (set_attr "athlon_decode" "vector")])
2432 (define_expand "movstrict<mode>"
2433 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2434 (match_operand:SWI12 1 "general_operand" ""))]
2437 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2439 if (GET_CODE (operands[0]) == SUBREG
2440 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2442 /* Don't generate memory->memory moves, go through a register */
2443 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2444 operands[1] = force_reg (<MODE>mode, operands[1]);
2447 (define_insn "*movstrict<mode>_1"
2448 [(set (strict_low_part
2449 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2450 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2451 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2452 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2453 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2454 [(set_attr "type" "imov")
2455 (set_attr "mode" "<MODE>")])
2457 (define_insn "*movstrict<mode>_xor"
2458 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2459 (match_operand:SWI12 1 "const0_operand" ""))
2460 (clobber (reg:CC FLAGS_REG))]
2462 "xor{<imodesuffix>}\t%0, %0"
2463 [(set_attr "type" "alu1")
2464 (set_attr "mode" "<MODE>")
2465 (set_attr "length_immediate" "0")])
2467 (define_insn "*mov<mode>_extv_1"
2468 [(set (match_operand:SWI24 0 "register_operand" "=R")
2469 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2473 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2474 [(set_attr "type" "imovx")
2475 (set_attr "mode" "SI")])
2477 (define_insn "*movqi_extv_1_rex64"
2478 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2479 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2484 switch (get_attr_type (insn))
2487 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2489 return "mov{b}\t{%h1, %0|%0, %h1}";
2493 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2494 (match_test "TARGET_MOVX"))
2495 (const_string "imovx")
2496 (const_string "imov")))
2498 (if_then_else (eq_attr "type" "imovx")
2500 (const_string "QI")))])
2502 (define_insn "*movqi_extv_1"
2503 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2504 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2509 switch (get_attr_type (insn))
2512 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2514 return "mov{b}\t{%h1, %0|%0, %h1}";
2518 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2519 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2520 (match_test "TARGET_MOVX")))
2521 (const_string "imovx")
2522 (const_string "imov")))
2524 (if_then_else (eq_attr "type" "imovx")
2526 (const_string "QI")))])
2528 (define_insn "*mov<mode>_extzv_1"
2529 [(set (match_operand:SWI48 0 "register_operand" "=R")
2530 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2534 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2535 [(set_attr "type" "imovx")
2536 (set_attr "mode" "SI")])
2538 (define_insn "*movqi_extzv_2_rex64"
2539 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2541 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2546 switch (get_attr_type (insn))
2549 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2551 return "mov{b}\t{%h1, %0|%0, %h1}";
2555 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2556 (match_test "TARGET_MOVX"))
2557 (const_string "imovx")
2558 (const_string "imov")))
2560 (if_then_else (eq_attr "type" "imovx")
2562 (const_string "QI")))])
2564 (define_insn "*movqi_extzv_2"
2565 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2567 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2572 switch (get_attr_type (insn))
2575 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2577 return "mov{b}\t{%h1, %0|%0, %h1}";
2581 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2582 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2583 (match_test "TARGET_MOVX")))
2584 (const_string "imovx")
2585 (const_string "imov")))
2587 (if_then_else (eq_attr "type" "imovx")
2589 (const_string "QI")))])
2591 (define_expand "mov<mode>_insv_1"
2592 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2595 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2597 (define_insn "*mov<mode>_insv_1_rex64"
2598 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2601 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2603 "mov{b}\t{%b1, %h0|%h0, %b1}"
2604 [(set_attr "type" "imov")
2605 (set_attr "mode" "QI")])
2607 (define_insn "*movsi_insv_1"
2608 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2611 (match_operand:SI 1 "general_operand" "Qmn"))]
2613 "mov{b}\t{%b1, %h0|%h0, %b1}"
2614 [(set_attr "type" "imov")
2615 (set_attr "mode" "QI")])
2617 (define_insn "*movqi_insv_2"
2618 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2621 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2624 "mov{b}\t{%h1, %h0|%h0, %h1}"
2625 [(set_attr "type" "imov")
2626 (set_attr "mode" "QI")])
2628 ;; Floating point push instructions.
2630 (define_insn "*pushtf"
2631 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2632 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2635 /* This insn should be already split before reg-stack. */
2638 [(set_attr "type" "multi")
2639 (set_attr "unit" "sse,*,*")
2640 (set_attr "mode" "TF,SI,SI")])
2642 ;; %%% Kill this when call knows how to work this out.
2644 [(set (match_operand:TF 0 "push_operand" "")
2645 (match_operand:TF 1 "sse_reg_operand" ""))]
2646 "TARGET_SSE2 && reload_completed"
2647 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2648 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2650 (define_insn "*pushxf"
2651 [(set (match_operand:XF 0 "push_operand" "=<,<")
2652 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2653 "optimize_function_for_speed_p (cfun)"
2655 /* This insn should be already split before reg-stack. */
2658 [(set_attr "type" "multi")
2659 (set_attr "unit" "i387,*")
2660 (set_attr "mode" "XF,SI")])
2662 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2664 ;; Pushing using integer instructions is longer except for constants
2665 ;; and direct memory references (assuming that any given constant is pushed
2666 ;; only once, but this ought to be handled elsewhere).
2668 (define_insn "*pushxf_nointeger"
2669 [(set (match_operand:XF 0 "push_operand" "=<,<")
2670 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2671 "optimize_function_for_size_p (cfun)"
2673 /* This insn should be already split before reg-stack. */
2676 [(set_attr "type" "multi")
2677 (set_attr "unit" "i387,*")
2678 (set_attr "mode" "XF,SI")])
2680 ;; %%% Kill this when call knows how to work this out.
2682 [(set (match_operand:XF 0 "push_operand" "")
2683 (match_operand:XF 1 "fp_register_operand" ""))]
2685 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2686 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2687 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2689 (define_insn "*pushdf_rex64"
2690 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2691 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2694 /* This insn should be already split before reg-stack. */
2697 [(set_attr "type" "multi")
2698 (set_attr "unit" "i387,*,*")
2699 (set_attr "mode" "DF,DI,DF")])
2701 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2702 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2703 ;; On the average, pushdf using integers can be still shorter.
2705 (define_insn "*pushdf"
2706 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2707 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2710 /* This insn should be already split before reg-stack. */
2713 [(set_attr "isa" "*,*,sse2")
2714 (set_attr "type" "multi")
2715 (set_attr "unit" "i387,*,*")
2716 (set_attr "mode" "DF,DI,DF")])
2718 ;; %%% Kill this when call knows how to work this out.
2720 [(set (match_operand:DF 0 "push_operand" "")
2721 (match_operand:DF 1 "any_fp_register_operand" ""))]
2723 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2724 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2726 (define_insn "*pushsf_rex64"
2727 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2728 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2731 /* Anything else should be already split before reg-stack. */
2732 gcc_assert (which_alternative == 1);
2733 return "push{q}\t%q1";
2735 [(set_attr "type" "multi,push,multi")
2736 (set_attr "unit" "i387,*,*")
2737 (set_attr "mode" "SF,DI,SF")])
2739 (define_insn "*pushsf"
2740 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2741 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2744 /* Anything else should be already split before reg-stack. */
2745 gcc_assert (which_alternative == 1);
2746 return "push{l}\t%1";
2748 [(set_attr "type" "multi,push,multi")
2749 (set_attr "unit" "i387,*,*")
2750 (set_attr "mode" "SF,SI,SF")])
2752 ;; %%% Kill this when call knows how to work this out.
2754 [(set (match_operand:SF 0 "push_operand" "")
2755 (match_operand:SF 1 "any_fp_register_operand" ""))]
2757 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2758 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2759 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2762 [(set (match_operand:SF 0 "push_operand" "")
2763 (match_operand:SF 1 "memory_operand" ""))]
2765 && (operands[2] = find_constant_src (insn))"
2766 [(set (match_dup 0) (match_dup 2))])
2769 [(set (match_operand 0 "push_operand" "")
2770 (match_operand 1 "general_operand" ""))]
2772 && (GET_MODE (operands[0]) == TFmode
2773 || GET_MODE (operands[0]) == XFmode
2774 || GET_MODE (operands[0]) == DFmode)
2775 && !ANY_FP_REG_P (operands[1])"
2777 "ix86_split_long_move (operands); DONE;")
2779 ;; Floating point move instructions.
2781 (define_expand "movtf"
2782 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2783 (match_operand:TF 1 "nonimmediate_operand" ""))]
2786 ix86_expand_move (TFmode, operands);
2790 (define_expand "mov<mode>"
2791 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2792 (match_operand:X87MODEF 1 "general_operand" ""))]
2794 "ix86_expand_move (<MODE>mode, operands); DONE;")
2796 (define_insn "*movtf_internal"
2797 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2798 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2800 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2801 && (!can_create_pseudo_p ()
2802 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2803 || GET_CODE (operands[1]) != CONST_DOUBLE
2804 || (optimize_function_for_size_p (cfun)
2805 && standard_sse_constant_p (operands[1])
2806 && !memory_operand (operands[0], TFmode))
2807 || (!TARGET_MEMORY_MISMATCH_STALL
2808 && memory_operand (operands[0], TFmode)))"
2810 switch (which_alternative)
2814 /* Handle misaligned load/store since we
2815 don't have movmisaligntf pattern. */
2816 if (misaligned_operand (operands[0], TFmode)
2817 || misaligned_operand (operands[1], TFmode))
2819 if (get_attr_mode (insn) == MODE_V4SF)
2820 return "%vmovups\t{%1, %0|%0, %1}";
2822 return "%vmovdqu\t{%1, %0|%0, %1}";
2826 if (get_attr_mode (insn) == MODE_V4SF)
2827 return "%vmovaps\t{%1, %0|%0, %1}";
2829 return "%vmovdqa\t{%1, %0|%0, %1}";
2833 return standard_sse_constant_opcode (insn, operands[1]);
2843 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2844 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2846 (cond [(eq_attr "alternative" "0,2")
2848 (match_test "optimize_function_for_size_p (cfun)")
2849 (const_string "V4SF")
2850 (const_string "TI"))
2851 (eq_attr "alternative" "1")
2853 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2854 (match_test "optimize_function_for_size_p (cfun)"))
2855 (const_string "V4SF")
2856 (const_string "TI"))]
2857 (const_string "DI")))])
2859 ;; Possible store forwarding (partial memory) stall in alternative 4.
2860 (define_insn "*movxf_internal"
2861 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2862 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2863 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2864 && (!can_create_pseudo_p ()
2865 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2866 || GET_CODE (operands[1]) != CONST_DOUBLE
2867 || (optimize_function_for_size_p (cfun)
2868 && standard_80387_constant_p (operands[1]) > 0
2869 && !memory_operand (operands[0], XFmode))
2870 || (!TARGET_MEMORY_MISMATCH_STALL
2871 && memory_operand (operands[0], XFmode)))"
2873 switch (which_alternative)
2877 return output_387_reg_move (insn, operands);
2880 return standard_80387_constant_opcode (operands[1]);
2890 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2891 (set_attr "mode" "XF,XF,XF,SI,SI")])
2893 (define_insn "*movdf_internal_rex64"
2894 [(set (match_operand:DF 0 "nonimmediate_operand"
2895 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2896 (match_operand:DF 1 "general_operand"
2897 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2898 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2899 && (!can_create_pseudo_p ()
2900 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2901 || GET_CODE (operands[1]) != CONST_DOUBLE
2902 || (optimize_function_for_size_p (cfun)
2903 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2904 && standard_80387_constant_p (operands[1]) > 0)
2905 || (TARGET_SSE2 && TARGET_SSE_MATH
2906 && standard_sse_constant_p (operands[1]))))
2907 || memory_operand (operands[0], DFmode))"
2909 switch (which_alternative)
2913 return output_387_reg_move (insn, operands);
2916 return standard_80387_constant_opcode (operands[1]);
2920 return "mov{q}\t{%1, %0|%0, %1}";
2923 return "movabs{q}\t{%1, %0|%0, %1}";
2929 return standard_sse_constant_opcode (insn, operands[1]);
2934 switch (get_attr_mode (insn))
2937 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2938 return "%vmovapd\t{%1, %0|%0, %1}";
2940 return "%vmovaps\t{%1, %0|%0, %1}";
2943 return "%vmovq\t{%1, %0|%0, %1}";
2945 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2946 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2947 return "%vmovsd\t{%1, %0|%0, %1}";
2949 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2951 return "%vmovlps\t{%1, %d0|%d0, %1}";
2958 /* Handle broken assemblers that require movd instead of movq. */
2959 return "%vmovd\t{%1, %0|%0, %1}";
2966 (cond [(eq_attr "alternative" "0,1,2")
2967 (const_string "fmov")
2968 (eq_attr "alternative" "3,4,5")
2969 (const_string "imov")
2970 (eq_attr "alternative" "6")
2971 (const_string "multi")
2972 (eq_attr "alternative" "7")
2973 (const_string "sselog1")
2975 (const_string "ssemov")))
2978 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2980 (const_string "*")))
2981 (set (attr "length_immediate")
2983 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2985 (const_string "*")))
2986 (set (attr "prefix")
2987 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2988 (const_string "orig")
2989 (const_string "maybe_vex")))
2990 (set (attr "prefix_data16")
2991 (if_then_else (eq_attr "mode" "V1DF")
2993 (const_string "*")))
2995 (cond [(eq_attr "alternative" "0,1,2")
2997 (eq_attr "alternative" "3,4,5,6,11,12")
3000 /* xorps is one byte shorter. */
3001 (eq_attr "alternative" "7")
3002 (cond [(match_test "optimize_function_for_size_p (cfun)")
3003 (const_string "V4SF")
3004 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3007 (const_string "V2DF"))
3009 /* For architectures resolving dependencies on
3010 whole SSE registers use APD move to break dependency
3011 chains, otherwise use short move to avoid extra work.
3013 movaps encodes one byte shorter. */
3014 (eq_attr "alternative" "8")
3016 [(match_test "optimize_function_for_size_p (cfun)")
3017 (const_string "V4SF")
3018 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3019 (const_string "V2DF")
3021 (const_string "DF"))
3022 /* For architectures resolving dependencies on register
3023 parts we may avoid extra work to zero out upper part
3025 (eq_attr "alternative" "9")
3027 (match_test "TARGET_SSE_SPLIT_REGS")
3028 (const_string "V1DF")
3029 (const_string "DF"))
3031 (const_string "DF")))])
3033 ;; Possible store forwarding (partial memory) stall in alternative 4.
3034 (define_insn "*movdf_internal"
3035 [(set (match_operand:DF 0 "nonimmediate_operand"
3036 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3037 (match_operand:DF 1 "general_operand"
3038 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3039 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3040 && (!can_create_pseudo_p ()
3041 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3042 || GET_CODE (operands[1]) != CONST_DOUBLE
3043 || (optimize_function_for_size_p (cfun)
3044 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3045 && standard_80387_constant_p (operands[1]) > 0)
3046 || (TARGET_SSE2 && TARGET_SSE_MATH
3047 && standard_sse_constant_p (operands[1])))
3048 && !memory_operand (operands[0], DFmode))
3049 || (!TARGET_MEMORY_MISMATCH_STALL
3050 && memory_operand (operands[0], DFmode)))"
3052 switch (which_alternative)
3056 return output_387_reg_move (insn, operands);
3059 return standard_80387_constant_opcode (operands[1]);
3067 return standard_sse_constant_opcode (insn, operands[1]);
3075 switch (get_attr_mode (insn))
3078 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3079 return "%vmovapd\t{%1, %0|%0, %1}";
3081 return "%vmovaps\t{%1, %0|%0, %1}";
3084 return "%vmovq\t{%1, %0|%0, %1}";
3086 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3087 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3088 return "%vmovsd\t{%1, %0|%0, %1}";
3090 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3092 return "%vmovlps\t{%1, %d0|%d0, %1}";
3102 (if_then_else (eq_attr "alternative" "5,6,7,8")
3103 (const_string "sse2")
3104 (const_string "*")))
3106 (cond [(eq_attr "alternative" "0,1,2")
3107 (const_string "fmov")
3108 (eq_attr "alternative" "3,4")
3109 (const_string "multi")
3110 (eq_attr "alternative" "5,9")
3111 (const_string "sselog1")
3113 (const_string "ssemov")))
3114 (set (attr "prefix")
3115 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3116 (const_string "orig")
3117 (const_string "maybe_vex")))
3118 (set (attr "prefix_data16")
3119 (if_then_else (eq_attr "mode" "V1DF")
3121 (const_string "*")))
3123 (cond [(eq_attr "alternative" "0,1,2")
3125 (eq_attr "alternative" "3,4")
3128 /* For SSE1, we have many fewer alternatives. */
3129 (not (match_test "TARGET_SSE2"))
3131 (eq_attr "alternative" "5,6,9,10")
3132 (const_string "V4SF")
3133 (const_string "V2SF"))
3135 /* xorps is one byte shorter. */
3136 (eq_attr "alternative" "5,9")
3137 (cond [(match_test "optimize_function_for_size_p (cfun)")
3138 (const_string "V4SF")
3139 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3142 (const_string "V2DF"))
3144 /* For architectures resolving dependencies on
3145 whole SSE registers use APD move to break dependency
3146 chains, otherwise use short move to avoid extra work.
3148 movaps encodes one byte shorter. */
3149 (eq_attr "alternative" "6,10")
3151 [(match_test "optimize_function_for_size_p (cfun)")
3152 (const_string "V4SF")
3153 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3154 (const_string "V2DF")
3156 (const_string "DF"))
3157 /* For architectures resolving dependencies on register
3158 parts we may avoid extra work to zero out upper part
3160 (eq_attr "alternative" "7,11")
3162 (match_test "TARGET_SSE_SPLIT_REGS")
3163 (const_string "V1DF")
3164 (const_string "DF"))
3166 (const_string "DF")))])
3168 (define_insn "*movsf_internal"
3169 [(set (match_operand:SF 0 "nonimmediate_operand"
3170 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3171 (match_operand:SF 1 "general_operand"
3172 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3173 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3174 && (!can_create_pseudo_p ()
3175 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3176 || GET_CODE (operands[1]) != CONST_DOUBLE
3177 || (optimize_function_for_size_p (cfun)
3178 && ((!TARGET_SSE_MATH
3179 && standard_80387_constant_p (operands[1]) > 0)
3181 && standard_sse_constant_p (operands[1]))))
3182 || memory_operand (operands[0], SFmode))"
3184 switch (which_alternative)
3188 return output_387_reg_move (insn, operands);
3191 return standard_80387_constant_opcode (operands[1]);
3195 return "mov{l}\t{%1, %0|%0, %1}";
3198 return standard_sse_constant_opcode (insn, operands[1]);
3201 if (get_attr_mode (insn) == MODE_V4SF)
3202 return "%vmovaps\t{%1, %0|%0, %1}";
3204 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3208 return "%vmovss\t{%1, %0|%0, %1}";
3214 return "movd\t{%1, %0|%0, %1}";
3217 return "movq\t{%1, %0|%0, %1}";
3221 return "%vmovd\t{%1, %0|%0, %1}";
3228 (cond [(eq_attr "alternative" "0,1,2")
3229 (const_string "fmov")
3230 (eq_attr "alternative" "3,4")
3231 (const_string "multi")
3232 (eq_attr "alternative" "5")
3233 (const_string "sselog1")
3234 (eq_attr "alternative" "9,10,11,14,15")
3235 (const_string "mmxmov")
3237 (const_string "ssemov")))
3238 (set (attr "prefix")
3239 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3240 (const_string "maybe_vex")
3241 (const_string "orig")))
3243 (cond [(eq_attr "alternative" "3,4,9,10")
3245 (eq_attr "alternative" "5")
3247 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3248 (match_test "TARGET_SSE2"))
3249 (not (match_test "optimize_function_for_size_p (cfun)")))
3251 (const_string "V4SF"))
3252 /* For architectures resolving dependencies on
3253 whole SSE registers use APS move to break dependency
3254 chains, otherwise use short move to avoid extra work.
3256 Do the same for architectures resolving dependencies on
3257 the parts. While in DF mode it is better to always handle
3258 just register parts, the SF mode is different due to lack
3259 of instructions to load just part of the register. It is
3260 better to maintain the whole registers in single format
3261 to avoid problems on using packed logical operations. */
3262 (eq_attr "alternative" "6")
3264 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3265 (match_test "TARGET_SSE_SPLIT_REGS"))
3266 (const_string "V4SF")
3267 (const_string "SF"))
3268 (eq_attr "alternative" "11")
3269 (const_string "DI")]
3270 (const_string "SF")))])
3273 [(set (match_operand 0 "any_fp_register_operand" "")
3274 (match_operand 1 "memory_operand" ""))]
3276 && (GET_MODE (operands[0]) == TFmode
3277 || GET_MODE (operands[0]) == XFmode
3278 || GET_MODE (operands[0]) == DFmode
3279 || GET_MODE (operands[0]) == SFmode)
3280 && (operands[2] = find_constant_src (insn))"
3281 [(set (match_dup 0) (match_dup 2))]
3283 rtx c = operands[2];
3284 int r = REGNO (operands[0]);
3286 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3287 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3292 [(set (match_operand 0 "any_fp_register_operand" "")
3293 (float_extend (match_operand 1 "memory_operand" "")))]
3295 && (GET_MODE (operands[0]) == TFmode
3296 || GET_MODE (operands[0]) == XFmode
3297 || GET_MODE (operands[0]) == DFmode)
3298 && (operands[2] = find_constant_src (insn))"
3299 [(set (match_dup 0) (match_dup 2))]
3301 rtx c = operands[2];
3302 int r = REGNO (operands[0]);
3304 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3305 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3309 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3311 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3312 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3314 && (standard_80387_constant_p (operands[1]) == 8
3315 || standard_80387_constant_p (operands[1]) == 9)"
3316 [(set (match_dup 0)(match_dup 1))
3318 (neg:X87MODEF (match_dup 0)))]
3322 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3323 if (real_isnegzero (&r))
3324 operands[1] = CONST0_RTX (<MODE>mode);
3326 operands[1] = CONST1_RTX (<MODE>mode);
3330 [(set (match_operand 0 "nonimmediate_operand" "")
3331 (match_operand 1 "general_operand" ""))]
3333 && (GET_MODE (operands[0]) == TFmode
3334 || GET_MODE (operands[0]) == XFmode
3335 || GET_MODE (operands[0]) == DFmode)
3336 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3338 "ix86_split_long_move (operands); DONE;")
3340 (define_insn "swapxf"
3341 [(set (match_operand:XF 0 "register_operand" "+f")
3342 (match_operand:XF 1 "register_operand" "+f"))
3347 if (STACK_TOP_P (operands[0]))
3352 [(set_attr "type" "fxch")
3353 (set_attr "mode" "XF")])
3355 (define_insn "*swap<mode>"
3356 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3357 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3360 "TARGET_80387 || reload_completed"
3362 if (STACK_TOP_P (operands[0]))
3367 [(set_attr "type" "fxch")
3368 (set_attr "mode" "<MODE>")])
3370 ;; Zero extension instructions
3372 (define_expand "zero_extendsidi2"
3373 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3374 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3379 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3384 (define_insn "*zero_extendsidi2_rex64"
3385 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3387 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3390 mov\t{%k1, %k0|%k0, %k1}
3392 movd\t{%1, %0|%0, %1}
3393 movd\t{%1, %0|%0, %1}
3394 %vmovd\t{%1, %0|%0, %1}
3395 %vmovd\t{%1, %0|%0, %1}"
3396 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3397 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3398 (set_attr "prefix_0f" "0,*,*,*,*,*")
3399 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3402 [(set (match_operand:DI 0 "memory_operand" "")
3403 (zero_extend:DI (match_dup 0)))]
3405 [(set (match_dup 4) (const_int 0))]
3406 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3408 ;; %%% Kill me once multi-word ops are sane.
3409 (define_insn "zero_extendsidi2_1"
3410 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3412 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3413 (clobber (reg:CC FLAGS_REG))]
3419 movd\t{%1, %0|%0, %1}
3420 movd\t{%1, %0|%0, %1}
3421 %vmovd\t{%1, %0|%0, %1}
3422 %vmovd\t{%1, %0|%0, %1}"
3423 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3424 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3425 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3426 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3429 [(set (match_operand:DI 0 "register_operand" "")
3430 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3431 (clobber (reg:CC FLAGS_REG))]
3432 "!TARGET_64BIT && reload_completed
3433 && true_regnum (operands[0]) == true_regnum (operands[1])"
3434 [(set (match_dup 4) (const_int 0))]
3435 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3438 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3439 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3440 (clobber (reg:CC FLAGS_REG))]
3441 "!TARGET_64BIT && reload_completed
3442 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3443 [(set (match_dup 3) (match_dup 1))
3444 (set (match_dup 4) (const_int 0))]
3445 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3447 (define_insn "zero_extend<mode>di2"
3448 [(set (match_operand:DI 0 "register_operand" "=r")
3450 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3452 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3453 [(set_attr "type" "imovx")
3454 (set_attr "mode" "SI")])
3456 (define_expand "zero_extendhisi2"
3457 [(set (match_operand:SI 0 "register_operand" "")
3458 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3461 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3463 operands[1] = force_reg (HImode, operands[1]);
3464 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3469 (define_insn_and_split "zero_extendhisi2_and"
3470 [(set (match_operand:SI 0 "register_operand" "=r")
3471 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3472 (clobber (reg:CC FLAGS_REG))]
3473 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3475 "&& reload_completed"
3476 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3477 (clobber (reg:CC FLAGS_REG))])]
3479 [(set_attr "type" "alu1")
3480 (set_attr "mode" "SI")])
3482 (define_insn "*zero_extendhisi2_movzwl"
3483 [(set (match_operand:SI 0 "register_operand" "=r")
3484 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3485 "!TARGET_ZERO_EXTEND_WITH_AND
3486 || optimize_function_for_size_p (cfun)"
3487 "movz{wl|x}\t{%1, %0|%0, %1}"
3488 [(set_attr "type" "imovx")
3489 (set_attr "mode" "SI")])
3491 (define_expand "zero_extendqi<mode>2"
3493 [(set (match_operand:SWI24 0 "register_operand" "")
3494 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3495 (clobber (reg:CC FLAGS_REG))])])
3497 (define_insn "*zero_extendqi<mode>2_and"
3498 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3499 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3500 (clobber (reg:CC FLAGS_REG))]
3501 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3503 [(set_attr "type" "alu1")
3504 (set_attr "mode" "<MODE>")])
3506 ;; When source and destination does not overlap, clear destination
3507 ;; first and then do the movb
3509 [(set (match_operand:SWI24 0 "register_operand" "")
3510 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3511 (clobber (reg:CC FLAGS_REG))]
3513 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3514 && ANY_QI_REG_P (operands[0])
3515 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3516 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3517 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3519 operands[2] = gen_lowpart (QImode, operands[0]);
3520 ix86_expand_clear (operands[0]);
3523 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3524 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3525 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3526 (clobber (reg:CC FLAGS_REG))]
3527 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3529 [(set_attr "type" "imovx,alu1")
3530 (set_attr "mode" "<MODE>")])
3532 ;; For the movzbl case strip only the clobber
3534 [(set (match_operand:SWI24 0 "register_operand" "")
3535 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3536 (clobber (reg:CC FLAGS_REG))]
3538 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3539 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3541 (zero_extend:SWI24 (match_dup 1)))])
3543 ; zero extend to SImode to avoid partial register stalls
3544 (define_insn "*zero_extendqi<mode>2_movzbl"
3545 [(set (match_operand:SWI24 0 "register_operand" "=r")
3546 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3548 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3549 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3550 [(set_attr "type" "imovx")
3551 (set_attr "mode" "SI")])
3553 ;; Rest is handled by single and.
3555 [(set (match_operand:SWI24 0 "register_operand" "")
3556 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3557 (clobber (reg:CC FLAGS_REG))]
3559 && true_regnum (operands[0]) == true_regnum (operands[1])"
3560 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3561 (clobber (reg:CC FLAGS_REG))])])
3563 ;; Sign extension instructions
3565 (define_expand "extendsidi2"
3566 [(set (match_operand:DI 0 "register_operand" "")
3567 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3572 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3577 (define_insn "*extendsidi2_rex64"
3578 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3579 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3583 movs{lq|x}\t{%1, %0|%0, %1}"
3584 [(set_attr "type" "imovx")
3585 (set_attr "mode" "DI")
3586 (set_attr "prefix_0f" "0")
3587 (set_attr "modrm" "0,1")])
3589 (define_insn "extendsidi2_1"
3590 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3591 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3592 (clobber (reg:CC FLAGS_REG))
3593 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3597 ;; Extend to memory case when source register does die.
3599 [(set (match_operand:DI 0 "memory_operand" "")
3600 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3601 (clobber (reg:CC FLAGS_REG))
3602 (clobber (match_operand:SI 2 "register_operand" ""))]
3604 && dead_or_set_p (insn, operands[1])
3605 && !reg_mentioned_p (operands[1], operands[0]))"
3606 [(set (match_dup 3) (match_dup 1))
3607 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3608 (clobber (reg:CC FLAGS_REG))])
3609 (set (match_dup 4) (match_dup 1))]
3610 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3612 ;; Extend to memory case when source register does not die.
3614 [(set (match_operand:DI 0 "memory_operand" "")
3615 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3616 (clobber (reg:CC FLAGS_REG))
3617 (clobber (match_operand:SI 2 "register_operand" ""))]
3621 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3623 emit_move_insn (operands[3], operands[1]);
3625 /* Generate a cltd if possible and doing so it profitable. */
3626 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3627 && true_regnum (operands[1]) == AX_REG
3628 && true_regnum (operands[2]) == DX_REG)
3630 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3634 emit_move_insn (operands[2], operands[1]);
3635 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3637 emit_move_insn (operands[4], operands[2]);
3641 ;; Extend to register case. Optimize case where source and destination
3642 ;; registers match and cases where we can use cltd.
3644 [(set (match_operand:DI 0 "register_operand" "")
3645 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3646 (clobber (reg:CC FLAGS_REG))
3647 (clobber (match_scratch:SI 2 ""))]
3651 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3653 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3654 emit_move_insn (operands[3], operands[1]);
3656 /* Generate a cltd if possible and doing so it profitable. */
3657 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3658 && true_regnum (operands[3]) == AX_REG
3659 && true_regnum (operands[4]) == DX_REG)
3661 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3665 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3666 emit_move_insn (operands[4], operands[1]);
3668 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3672 (define_insn "extend<mode>di2"
3673 [(set (match_operand:DI 0 "register_operand" "=r")
3675 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3677 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3678 [(set_attr "type" "imovx")
3679 (set_attr "mode" "DI")])
3681 (define_insn "extendhisi2"
3682 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3683 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3686 switch (get_attr_prefix_0f (insn))
3689 return "{cwtl|cwde}";
3691 return "movs{wl|x}\t{%1, %0|%0, %1}";
3694 [(set_attr "type" "imovx")
3695 (set_attr "mode" "SI")
3696 (set (attr "prefix_0f")
3697 ;; movsx is short decodable while cwtl is vector decoded.
3698 (if_then_else (and (eq_attr "cpu" "!k6")
3699 (eq_attr "alternative" "0"))
3701 (const_string "1")))
3703 (if_then_else (eq_attr "prefix_0f" "0")
3705 (const_string "1")))])
3707 (define_insn "*extendhisi2_zext"
3708 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3711 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3714 switch (get_attr_prefix_0f (insn))
3717 return "{cwtl|cwde}";
3719 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3722 [(set_attr "type" "imovx")
3723 (set_attr "mode" "SI")
3724 (set (attr "prefix_0f")
3725 ;; movsx is short decodable while cwtl is vector decoded.
3726 (if_then_else (and (eq_attr "cpu" "!k6")
3727 (eq_attr "alternative" "0"))
3729 (const_string "1")))
3731 (if_then_else (eq_attr "prefix_0f" "0")
3733 (const_string "1")))])
3735 (define_insn "extendqisi2"
3736 [(set (match_operand:SI 0 "register_operand" "=r")
3737 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3739 "movs{bl|x}\t{%1, %0|%0, %1}"
3740 [(set_attr "type" "imovx")
3741 (set_attr "mode" "SI")])
3743 (define_insn "*extendqisi2_zext"
3744 [(set (match_operand:DI 0 "register_operand" "=r")
3746 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3748 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3749 [(set_attr "type" "imovx")
3750 (set_attr "mode" "SI")])
3752 (define_insn "extendqihi2"
3753 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3754 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3757 switch (get_attr_prefix_0f (insn))
3760 return "{cbtw|cbw}";
3762 return "movs{bw|x}\t{%1, %0|%0, %1}";
3765 [(set_attr "type" "imovx")
3766 (set_attr "mode" "HI")
3767 (set (attr "prefix_0f")
3768 ;; movsx is short decodable while cwtl is vector decoded.
3769 (if_then_else (and (eq_attr "cpu" "!k6")
3770 (eq_attr "alternative" "0"))
3772 (const_string "1")))
3774 (if_then_else (eq_attr "prefix_0f" "0")
3776 (const_string "1")))])
3778 ;; Conversions between float and double.
3780 ;; These are all no-ops in the model used for the 80387.
3781 ;; So just emit moves.
3783 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3785 [(set (match_operand:DF 0 "push_operand" "")
3786 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3788 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3789 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3792 [(set (match_operand:XF 0 "push_operand" "")
3793 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3795 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3796 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3797 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3799 (define_expand "extendsfdf2"
3800 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3801 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3802 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3804 /* ??? Needed for compress_float_constant since all fp constants
3805 are TARGET_LEGITIMATE_CONSTANT_P. */
3806 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3808 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3809 && standard_80387_constant_p (operands[1]) > 0)
3811 operands[1] = simplify_const_unary_operation
3812 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3813 emit_move_insn_1 (operands[0], operands[1]);
3816 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3820 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3822 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3824 We do the conversion post reload to avoid producing of 128bit spills
3825 that might lead to ICE on 32bit target. The sequence unlikely combine
3828 [(set (match_operand:DF 0 "register_operand" "")
3830 (match_operand:SF 1 "nonimmediate_operand" "")))]
3831 "TARGET_USE_VECTOR_FP_CONVERTS
3832 && optimize_insn_for_speed_p ()
3833 && reload_completed && SSE_REG_P (operands[0])"
3838 (parallel [(const_int 0) (const_int 1)]))))]
3840 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3841 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3842 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3843 Try to avoid move when unpacking can be done in source. */
3844 if (REG_P (operands[1]))
3846 /* If it is unsafe to overwrite upper half of source, we need
3847 to move to destination and unpack there. */
3848 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3849 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3850 && true_regnum (operands[0]) != true_regnum (operands[1]))
3852 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3853 emit_move_insn (tmp, operands[1]);
3856 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3857 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3861 emit_insn (gen_vec_setv4sf_0 (operands[3],
3862 CONST0_RTX (V4SFmode), operands[1]));
3865 (define_insn "*extendsfdf2_mixed"
3866 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3868 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3869 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3871 switch (which_alternative)
3875 return output_387_reg_move (insn, operands);
3878 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3884 [(set_attr "type" "fmov,fmov,ssecvt")
3885 (set_attr "prefix" "orig,orig,maybe_vex")
3886 (set_attr "mode" "SF,XF,DF")])
3888 (define_insn "*extendsfdf2_sse"
3889 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3890 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3891 "TARGET_SSE2 && TARGET_SSE_MATH"
3892 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3893 [(set_attr "type" "ssecvt")
3894 (set_attr "prefix" "maybe_vex")
3895 (set_attr "mode" "DF")])
3897 (define_insn "*extendsfdf2_i387"
3898 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3899 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3901 "* return output_387_reg_move (insn, operands);"
3902 [(set_attr "type" "fmov")
3903 (set_attr "mode" "SF,XF")])
3905 (define_expand "extend<mode>xf2"
3906 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3907 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3910 /* ??? Needed for compress_float_constant since all fp constants
3911 are TARGET_LEGITIMATE_CONSTANT_P. */
3912 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3914 if (standard_80387_constant_p (operands[1]) > 0)
3916 operands[1] = simplify_const_unary_operation
3917 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3918 emit_move_insn_1 (operands[0], operands[1]);
3921 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3925 (define_insn "*extend<mode>xf2_i387"
3926 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3928 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3930 "* return output_387_reg_move (insn, operands);"
3931 [(set_attr "type" "fmov")
3932 (set_attr "mode" "<MODE>,XF")])
3934 ;; %%% This seems bad bad news.
3935 ;; This cannot output into an f-reg because there is no way to be sure
3936 ;; of truncating in that case. Otherwise this is just like a simple move
3937 ;; insn. So we pretend we can output to a reg in order to get better
3938 ;; register preferencing, but we really use a stack slot.
3940 ;; Conversion from DFmode to SFmode.
3942 (define_expand "truncdfsf2"
3943 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3945 (match_operand:DF 1 "nonimmediate_operand" "")))]
3946 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3948 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3950 else if (flag_unsafe_math_optimizations)
3954 enum ix86_stack_slot slot = (virtuals_instantiated
3957 rtx temp = assign_386_stack_local (SFmode, slot);
3958 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3963 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3965 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3967 We do the conversion post reload to avoid producing of 128bit spills
3968 that might lead to ICE on 32bit target. The sequence unlikely combine
3971 [(set (match_operand:SF 0 "register_operand" "")
3973 (match_operand:DF 1 "nonimmediate_operand" "")))]
3974 "TARGET_USE_VECTOR_FP_CONVERTS
3975 && optimize_insn_for_speed_p ()
3976 && reload_completed && SSE_REG_P (operands[0])"
3979 (float_truncate:V2SF
3983 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3984 operands[3] = CONST0_RTX (V2SFmode);
3985 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3986 /* Use movsd for loading from memory, unpcklpd for registers.
3987 Try to avoid move when unpacking can be done in source, or SSE3
3988 movddup is available. */
3989 if (REG_P (operands[1]))
3992 && true_regnum (operands[0]) != true_regnum (operands[1])
3993 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3994 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3996 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3997 emit_move_insn (tmp, operands[1]);
4000 else if (!TARGET_SSE3)
4001 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4002 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4005 emit_insn (gen_sse2_loadlpd (operands[4],
4006 CONST0_RTX (V2DFmode), operands[1]));
4009 (define_expand "truncdfsf2_with_temp"
4010 [(parallel [(set (match_operand:SF 0 "" "")
4011 (float_truncate:SF (match_operand:DF 1 "" "")))
4012 (clobber (match_operand:SF 2 "" ""))])])
4014 (define_insn "*truncdfsf_fast_mixed"
4015 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4017 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4018 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4020 switch (which_alternative)
4023 return output_387_reg_move (insn, operands);
4025 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4030 [(set_attr "type" "fmov,ssecvt")
4031 (set_attr "prefix" "orig,maybe_vex")
4032 (set_attr "mode" "SF")])
4034 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4035 ;; because nothing we do here is unsafe.
4036 (define_insn "*truncdfsf_fast_sse"
4037 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4039 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4040 "TARGET_SSE2 && TARGET_SSE_MATH"
4041 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4042 [(set_attr "type" "ssecvt")
4043 (set_attr "prefix" "maybe_vex")
4044 (set_attr "mode" "SF")])
4046 (define_insn "*truncdfsf_fast_i387"
4047 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4049 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4050 "TARGET_80387 && flag_unsafe_math_optimizations"
4051 "* return output_387_reg_move (insn, operands);"
4052 [(set_attr "type" "fmov")
4053 (set_attr "mode" "SF")])
4055 (define_insn "*truncdfsf_mixed"
4056 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4058 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4059 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4060 "TARGET_MIX_SSE_I387"
4062 switch (which_alternative)
4065 return output_387_reg_move (insn, operands);
4067 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4073 [(set_attr "isa" "*,sse2,*,*,*")
4074 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4075 (set_attr "unit" "*,*,i387,i387,i387")
4076 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4077 (set_attr "mode" "SF")])
4079 (define_insn "*truncdfsf_i387"
4080 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4082 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4083 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4086 switch (which_alternative)
4089 return output_387_reg_move (insn, operands);
4095 [(set_attr "type" "fmov,multi,multi,multi")
4096 (set_attr "unit" "*,i387,i387,i387")
4097 (set_attr "mode" "SF")])
4099 (define_insn "*truncdfsf2_i387_1"
4100 [(set (match_operand:SF 0 "memory_operand" "=m")
4102 (match_operand:DF 1 "register_operand" "f")))]
4104 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4105 && !TARGET_MIX_SSE_I387"
4106 "* return output_387_reg_move (insn, operands);"
4107 [(set_attr "type" "fmov")
4108 (set_attr "mode" "SF")])
4111 [(set (match_operand:SF 0 "register_operand" "")
4113 (match_operand:DF 1 "fp_register_operand" "")))
4114 (clobber (match_operand 2 "" ""))]
4116 [(set (match_dup 2) (match_dup 1))
4117 (set (match_dup 0) (match_dup 2))]
4118 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4120 ;; Conversion from XFmode to {SF,DF}mode
4122 (define_expand "truncxf<mode>2"
4123 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4124 (float_truncate:MODEF
4125 (match_operand:XF 1 "register_operand" "")))
4126 (clobber (match_dup 2))])]
4129 if (flag_unsafe_math_optimizations)
4131 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4132 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4133 if (reg != operands[0])
4134 emit_move_insn (operands[0], reg);
4139 enum ix86_stack_slot slot = (virtuals_instantiated
4142 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4146 (define_insn "*truncxfsf2_mixed"
4147 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4149 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4150 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4153 gcc_assert (!which_alternative);
4154 return output_387_reg_move (insn, operands);
4156 [(set_attr "type" "fmov,multi,multi,multi")
4157 (set_attr "unit" "*,i387,i387,i387")
4158 (set_attr "mode" "SF")])
4160 (define_insn "*truncxfdf2_mixed"
4161 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4163 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4164 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4167 gcc_assert (!which_alternative);
4168 return output_387_reg_move (insn, operands);
4170 [(set_attr "isa" "*,*,sse2,*")
4171 (set_attr "type" "fmov,multi,multi,multi")
4172 (set_attr "unit" "*,i387,i387,i387")
4173 (set_attr "mode" "DF")])
4175 (define_insn "truncxf<mode>2_i387_noop"
4176 [(set (match_operand:MODEF 0 "register_operand" "=f")
4177 (float_truncate:MODEF
4178 (match_operand:XF 1 "register_operand" "f")))]
4179 "TARGET_80387 && flag_unsafe_math_optimizations"
4180 "* return output_387_reg_move (insn, operands);"
4181 [(set_attr "type" "fmov")
4182 (set_attr "mode" "<MODE>")])
4184 (define_insn "*truncxf<mode>2_i387"
4185 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4186 (float_truncate:MODEF
4187 (match_operand:XF 1 "register_operand" "f")))]
4189 "* return output_387_reg_move (insn, operands);"
4190 [(set_attr "type" "fmov")
4191 (set_attr "mode" "<MODE>")])
4194 [(set (match_operand:MODEF 0 "register_operand" "")
4195 (float_truncate:MODEF
4196 (match_operand:XF 1 "register_operand" "")))
4197 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4198 "TARGET_80387 && reload_completed"
4199 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4200 (set (match_dup 0) (match_dup 2))])
4203 [(set (match_operand:MODEF 0 "memory_operand" "")
4204 (float_truncate:MODEF
4205 (match_operand:XF 1 "register_operand" "")))
4206 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4208 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4210 ;; Signed conversion to DImode.
4212 (define_expand "fix_truncxfdi2"
4213 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4214 (fix:DI (match_operand:XF 1 "register_operand" "")))
4215 (clobber (reg:CC FLAGS_REG))])]
4220 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4225 (define_expand "fix_trunc<mode>di2"
4226 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4227 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4228 (clobber (reg:CC FLAGS_REG))])]
4229 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4232 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4234 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4237 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4239 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4240 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4241 if (out != operands[0])
4242 emit_move_insn (operands[0], out);
4247 ;; Signed conversion to SImode.
4249 (define_expand "fix_truncxfsi2"
4250 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4251 (fix:SI (match_operand:XF 1 "register_operand" "")))
4252 (clobber (reg:CC FLAGS_REG))])]
4257 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4262 (define_expand "fix_trunc<mode>si2"
4263 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4264 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4265 (clobber (reg:CC FLAGS_REG))])]
4266 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4269 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4271 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4274 if (SSE_FLOAT_MODE_P (<MODE>mode))
4276 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4277 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4278 if (out != operands[0])
4279 emit_move_insn (operands[0], out);
4284 ;; Signed conversion to HImode.
4286 (define_expand "fix_trunc<mode>hi2"
4287 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4288 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4289 (clobber (reg:CC FLAGS_REG))])]
4291 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4295 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4300 ;; Unsigned conversion to SImode.
4302 (define_expand "fixuns_trunc<mode>si2"
4304 [(set (match_operand:SI 0 "register_operand" "")
4306 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4308 (clobber (match_scratch:<ssevecmode> 3 ""))
4309 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4310 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4312 enum machine_mode mode = <MODE>mode;
4313 enum machine_mode vecmode = <ssevecmode>mode;
4314 REAL_VALUE_TYPE TWO31r;
4317 if (optimize_insn_for_size_p ())
4320 real_ldexp (&TWO31r, &dconst1, 31);
4321 two31 = const_double_from_real_value (TWO31r, mode);
4322 two31 = ix86_build_const_vector (vecmode, true, two31);
4323 operands[2] = force_reg (vecmode, two31);
4326 (define_insn_and_split "*fixuns_trunc<mode>_1"
4327 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4329 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4330 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4331 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4332 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4333 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4334 && optimize_function_for_speed_p (cfun)"
4336 "&& reload_completed"
4339 ix86_split_convert_uns_si_sse (operands);
4343 ;; Unsigned conversion to HImode.
4344 ;; Without these patterns, we'll try the unsigned SI conversion which
4345 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4347 (define_expand "fixuns_trunc<mode>hi2"
4349 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4350 (set (match_operand:HI 0 "nonimmediate_operand" "")
4351 (subreg:HI (match_dup 2) 0))]
4352 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4353 "operands[2] = gen_reg_rtx (SImode);")
4355 ;; When SSE is available, it is always faster to use it!
4356 (define_insn "fix_trunc<mode>di_sse"
4357 [(set (match_operand:DI 0 "register_operand" "=r,r")
4358 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4359 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4360 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4361 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4362 [(set_attr "type" "sseicvt")
4363 (set_attr "prefix" "maybe_vex")
4364 (set_attr "prefix_rex" "1")
4365 (set_attr "mode" "<MODE>")
4366 (set_attr "athlon_decode" "double,vector")
4367 (set_attr "amdfam10_decode" "double,double")
4368 (set_attr "bdver1_decode" "double,double")])
4370 (define_insn "fix_trunc<mode>si_sse"
4371 [(set (match_operand:SI 0 "register_operand" "=r,r")
4372 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4373 "SSE_FLOAT_MODE_P (<MODE>mode)
4374 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4375 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4376 [(set_attr "type" "sseicvt")
4377 (set_attr "prefix" "maybe_vex")
4378 (set_attr "mode" "<MODE>")
4379 (set_attr "athlon_decode" "double,vector")
4380 (set_attr "amdfam10_decode" "double,double")
4381 (set_attr "bdver1_decode" "double,double")])
4383 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4385 [(set (match_operand:MODEF 0 "register_operand" "")
4386 (match_operand:MODEF 1 "memory_operand" ""))
4387 (set (match_operand:SWI48x 2 "register_operand" "")
4388 (fix:SWI48x (match_dup 0)))]
4389 "TARGET_SHORTEN_X87_SSE
4390 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4391 && peep2_reg_dead_p (2, operands[0])"
4392 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4394 ;; Avoid vector decoded forms of the instruction.
4396 [(match_scratch:DF 2 "x")
4397 (set (match_operand:SWI48x 0 "register_operand" "")
4398 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4399 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4400 [(set (match_dup 2) (match_dup 1))
4401 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4404 [(match_scratch:SF 2 "x")
4405 (set (match_operand:SWI48x 0 "register_operand" "")
4406 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4407 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4408 [(set (match_dup 2) (match_dup 1))
4409 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4411 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4412 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4413 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4414 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4416 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4417 && (TARGET_64BIT || <MODE>mode != DImode))
4419 && can_create_pseudo_p ()"
4424 if (memory_operand (operands[0], VOIDmode))
4425 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4428 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4429 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4435 [(set_attr "type" "fisttp")
4436 (set_attr "mode" "<MODE>")])
4438 (define_insn "fix_trunc<mode>_i387_fisttp"
4439 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4440 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4441 (clobber (match_scratch:XF 2 "=&1f"))]
4442 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4444 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4445 && (TARGET_64BIT || <MODE>mode != DImode))
4446 && TARGET_SSE_MATH)"
4447 "* return output_fix_trunc (insn, operands, true);"
4448 [(set_attr "type" "fisttp")
4449 (set_attr "mode" "<MODE>")])
4451 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4452 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4453 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4454 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4455 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4456 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4458 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4459 && (TARGET_64BIT || <MODE>mode != DImode))
4460 && TARGET_SSE_MATH)"
4462 [(set_attr "type" "fisttp")
4463 (set_attr "mode" "<MODE>")])
4466 [(set (match_operand:SWI248x 0 "register_operand" "")
4467 (fix:SWI248x (match_operand 1 "register_operand" "")))
4468 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4469 (clobber (match_scratch 3 ""))]
4471 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4472 (clobber (match_dup 3))])
4473 (set (match_dup 0) (match_dup 2))])
4476 [(set (match_operand:SWI248x 0 "memory_operand" "")
4477 (fix:SWI248x (match_operand 1 "register_operand" "")))
4478 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4479 (clobber (match_scratch 3 ""))]
4481 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4482 (clobber (match_dup 3))])])
4484 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4485 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4486 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4487 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4488 ;; function in i386.c.
4489 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4490 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4491 (fix:SWI248x (match_operand 1 "register_operand" "")))
4492 (clobber (reg:CC FLAGS_REG))]
4493 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4495 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4496 && (TARGET_64BIT || <MODE>mode != DImode))
4497 && can_create_pseudo_p ()"
4502 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4504 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4505 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4506 if (memory_operand (operands[0], VOIDmode))
4507 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4508 operands[2], operands[3]));
4511 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4512 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4513 operands[2], operands[3],
4518 [(set_attr "type" "fistp")
4519 (set_attr "i387_cw" "trunc")
4520 (set_attr "mode" "<MODE>")])
4522 (define_insn "fix_truncdi_i387"
4523 [(set (match_operand:DI 0 "memory_operand" "=m")
4524 (fix:DI (match_operand 1 "register_operand" "f")))
4525 (use (match_operand:HI 2 "memory_operand" "m"))
4526 (use (match_operand:HI 3 "memory_operand" "m"))
4527 (clobber (match_scratch:XF 4 "=&1f"))]
4528 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4530 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4531 "* return output_fix_trunc (insn, operands, false);"
4532 [(set_attr "type" "fistp")
4533 (set_attr "i387_cw" "trunc")
4534 (set_attr "mode" "DI")])
4536 (define_insn "fix_truncdi_i387_with_temp"
4537 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4538 (fix:DI (match_operand 1 "register_operand" "f,f")))
4539 (use (match_operand:HI 2 "memory_operand" "m,m"))
4540 (use (match_operand:HI 3 "memory_operand" "m,m"))
4541 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4542 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4543 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4545 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4547 [(set_attr "type" "fistp")
4548 (set_attr "i387_cw" "trunc")
4549 (set_attr "mode" "DI")])
4552 [(set (match_operand:DI 0 "register_operand" "")
4553 (fix:DI (match_operand 1 "register_operand" "")))
4554 (use (match_operand:HI 2 "memory_operand" ""))
4555 (use (match_operand:HI 3 "memory_operand" ""))
4556 (clobber (match_operand:DI 4 "memory_operand" ""))
4557 (clobber (match_scratch 5 ""))]
4559 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4562 (clobber (match_dup 5))])
4563 (set (match_dup 0) (match_dup 4))])
4566 [(set (match_operand:DI 0 "memory_operand" "")
4567 (fix:DI (match_operand 1 "register_operand" "")))
4568 (use (match_operand:HI 2 "memory_operand" ""))
4569 (use (match_operand:HI 3 "memory_operand" ""))
4570 (clobber (match_operand:DI 4 "memory_operand" ""))
4571 (clobber (match_scratch 5 ""))]
4573 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4576 (clobber (match_dup 5))])])
4578 (define_insn "fix_trunc<mode>_i387"
4579 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4580 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4581 (use (match_operand:HI 2 "memory_operand" "m"))
4582 (use (match_operand:HI 3 "memory_operand" "m"))]
4583 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4585 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4586 "* return output_fix_trunc (insn, operands, false);"
4587 [(set_attr "type" "fistp")
4588 (set_attr "i387_cw" "trunc")
4589 (set_attr "mode" "<MODE>")])
4591 (define_insn "fix_trunc<mode>_i387_with_temp"
4592 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4593 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4594 (use (match_operand:HI 2 "memory_operand" "m,m"))
4595 (use (match_operand:HI 3 "memory_operand" "m,m"))
4596 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4597 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4599 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4601 [(set_attr "type" "fistp")
4602 (set_attr "i387_cw" "trunc")
4603 (set_attr "mode" "<MODE>")])
4606 [(set (match_operand:SWI24 0 "register_operand" "")
4607 (fix:SWI24 (match_operand 1 "register_operand" "")))
4608 (use (match_operand:HI 2 "memory_operand" ""))
4609 (use (match_operand:HI 3 "memory_operand" ""))
4610 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4612 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4614 (use (match_dup 3))])
4615 (set (match_dup 0) (match_dup 4))])
4618 [(set (match_operand:SWI24 0 "memory_operand" "")
4619 (fix:SWI24 (match_operand 1 "register_operand" "")))
4620 (use (match_operand:HI 2 "memory_operand" ""))
4621 (use (match_operand:HI 3 "memory_operand" ""))
4622 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4624 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4626 (use (match_dup 3))])])
4628 (define_insn "x86_fnstcw_1"
4629 [(set (match_operand:HI 0 "memory_operand" "=m")
4630 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4633 [(set (attr "length")
4634 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4635 (set_attr "mode" "HI")
4636 (set_attr "unit" "i387")
4637 (set_attr "bdver1_decode" "vector")])
4639 (define_insn "x86_fldcw_1"
4640 [(set (reg:HI FPCR_REG)
4641 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4644 [(set (attr "length")
4645 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4646 (set_attr "mode" "HI")
4647 (set_attr "unit" "i387")
4648 (set_attr "athlon_decode" "vector")
4649 (set_attr "amdfam10_decode" "vector")
4650 (set_attr "bdver1_decode" "vector")])
4652 ;; Conversion between fixed point and floating point.
4654 ;; Even though we only accept memory inputs, the backend _really_
4655 ;; wants to be able to do this between registers.
4657 (define_expand "floathi<mode>2"
4658 [(set (match_operand:X87MODEF 0 "register_operand" "")
4659 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4662 || TARGET_MIX_SSE_I387)")
4664 ;; Pre-reload splitter to add memory clobber to the pattern.
4665 (define_insn_and_split "*floathi<mode>2_1"
4666 [(set (match_operand:X87MODEF 0 "register_operand" "")
4667 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4669 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4670 || TARGET_MIX_SSE_I387)
4671 && can_create_pseudo_p ()"
4674 [(parallel [(set (match_dup 0)
4675 (float:X87MODEF (match_dup 1)))
4676 (clobber (match_dup 2))])]
4677 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4679 (define_insn "*floathi<mode>2_i387_with_temp"
4680 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4681 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4682 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4684 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4685 || TARGET_MIX_SSE_I387)"
4687 [(set_attr "type" "fmov,multi")
4688 (set_attr "mode" "<MODE>")
4689 (set_attr "unit" "*,i387")
4690 (set_attr "fp_int_src" "true")])
4692 (define_insn "*floathi<mode>2_i387"
4693 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4694 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4697 || TARGET_MIX_SSE_I387)"
4699 [(set_attr "type" "fmov")
4700 (set_attr "mode" "<MODE>")
4701 (set_attr "fp_int_src" "true")])
4704 [(set (match_operand:X87MODEF 0 "register_operand" "")
4705 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4706 (clobber (match_operand:HI 2 "memory_operand" ""))]
4708 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4709 || TARGET_MIX_SSE_I387)
4710 && reload_completed"
4711 [(set (match_dup 2) (match_dup 1))
4712 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4715 [(set (match_operand:X87MODEF 0 "register_operand" "")
4716 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4717 (clobber (match_operand:HI 2 "memory_operand" ""))]
4719 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4720 || TARGET_MIX_SSE_I387)
4721 && reload_completed"
4722 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4724 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4725 [(set (match_operand:X87MODEF 0 "register_operand" "")
4727 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4729 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4730 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4732 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4733 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4734 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4736 rtx reg = gen_reg_rtx (XFmode);
4737 rtx (*insn)(rtx, rtx);
4739 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4741 if (<X87MODEF:MODE>mode == SFmode)
4742 insn = gen_truncxfsf2;
4743 else if (<X87MODEF:MODE>mode == DFmode)
4744 insn = gen_truncxfdf2;
4748 emit_insn (insn (operands[0], reg));
4753 ;; Pre-reload splitter to add memory clobber to the pattern.
4754 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4755 [(set (match_operand:X87MODEF 0 "register_operand" "")
4756 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4758 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4759 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4760 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4761 || TARGET_MIX_SSE_I387))
4762 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4763 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4764 && ((<SWI48x:MODE>mode == SImode
4765 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4766 && optimize_function_for_speed_p (cfun)
4767 && flag_trapping_math)
4768 || !(TARGET_INTER_UNIT_CONVERSIONS
4769 || optimize_function_for_size_p (cfun)))))
4770 && can_create_pseudo_p ()"
4773 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4774 (clobber (match_dup 2))])]
4776 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4778 /* Avoid store forwarding (partial memory) stall penalty
4779 by passing DImode value through XMM registers. */
4780 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4781 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4782 && optimize_function_for_speed_p (cfun))
4784 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4791 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4792 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4794 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4795 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4796 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4797 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4799 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4800 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4801 (set_attr "unit" "*,i387,*,*,*")
4802 (set_attr "athlon_decode" "*,*,double,direct,double")
4803 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4804 (set_attr "bdver1_decode" "*,*,double,direct,double")
4805 (set_attr "fp_int_src" "true")])
4807 (define_insn "*floatsi<mode>2_vector_mixed"
4808 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4809 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4810 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4811 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4815 [(set_attr "type" "fmov,sseicvt")
4816 (set_attr "mode" "<MODE>,<ssevecmode>")
4817 (set_attr "unit" "i387,*")
4818 (set_attr "athlon_decode" "*,direct")
4819 (set_attr "amdfam10_decode" "*,double")
4820 (set_attr "bdver1_decode" "*,direct")
4821 (set_attr "fp_int_src" "true")])
4823 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4824 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4826 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4827 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4828 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4829 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4831 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4832 (set_attr "mode" "<MODEF:MODE>")
4833 (set_attr "unit" "*,i387,*,*")
4834 (set_attr "athlon_decode" "*,*,double,direct")
4835 (set_attr "amdfam10_decode" "*,*,vector,double")
4836 (set_attr "bdver1_decode" "*,*,double,direct")
4837 (set_attr "fp_int_src" "true")])
4840 [(set (match_operand:MODEF 0 "register_operand" "")
4841 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4842 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4843 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4844 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4845 && TARGET_INTER_UNIT_CONVERSIONS
4847 && (SSE_REG_P (operands[0])
4848 || (GET_CODE (operands[0]) == SUBREG
4849 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4850 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4853 [(set (match_operand:MODEF 0 "register_operand" "")
4854 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4855 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4856 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4857 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4858 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4860 && (SSE_REG_P (operands[0])
4861 || (GET_CODE (operands[0]) == SUBREG
4862 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4863 [(set (match_dup 2) (match_dup 1))
4864 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4866 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4867 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4869 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4870 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4871 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4872 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4875 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4876 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4877 [(set_attr "type" "fmov,sseicvt,sseicvt")
4878 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4879 (set_attr "mode" "<MODEF:MODE>")
4880 (set (attr "prefix_rex")
4882 (and (eq_attr "prefix" "maybe_vex")
4883 (match_test "<SWI48x:MODE>mode == DImode"))
4885 (const_string "*")))
4886 (set_attr "unit" "i387,*,*")
4887 (set_attr "athlon_decode" "*,double,direct")
4888 (set_attr "amdfam10_decode" "*,vector,double")
4889 (set_attr "bdver1_decode" "*,double,direct")
4890 (set_attr "fp_int_src" "true")])
4892 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4893 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4895 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4896 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4897 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4898 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4901 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4902 [(set_attr "type" "fmov,sseicvt")
4903 (set_attr "prefix" "orig,maybe_vex")
4904 (set_attr "mode" "<MODEF:MODE>")
4905 (set (attr "prefix_rex")
4907 (and (eq_attr "prefix" "maybe_vex")
4908 (match_test "<SWI48x:MODE>mode == DImode"))
4910 (const_string "*")))
4911 (set_attr "athlon_decode" "*,direct")
4912 (set_attr "amdfam10_decode" "*,double")
4913 (set_attr "bdver1_decode" "*,direct")
4914 (set_attr "fp_int_src" "true")])
4916 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4917 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4919 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4920 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4921 "TARGET_SSE2 && TARGET_SSE_MATH
4922 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4924 [(set_attr "type" "sseicvt")
4925 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4926 (set_attr "athlon_decode" "double,direct,double")
4927 (set_attr "amdfam10_decode" "vector,double,double")
4928 (set_attr "bdver1_decode" "double,direct,double")
4929 (set_attr "fp_int_src" "true")])
4931 (define_insn "*floatsi<mode>2_vector_sse"
4932 [(set (match_operand:MODEF 0 "register_operand" "=x")
4933 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4934 "TARGET_SSE2 && TARGET_SSE_MATH
4935 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4937 [(set_attr "type" "sseicvt")
4938 (set_attr "mode" "<MODE>")
4939 (set_attr "athlon_decode" "direct")
4940 (set_attr "amdfam10_decode" "double")
4941 (set_attr "bdver1_decode" "direct")
4942 (set_attr "fp_int_src" "true")])
4945 [(set (match_operand:MODEF 0 "register_operand" "")
4946 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4947 (clobber (match_operand:SI 2 "memory_operand" ""))]
4948 "TARGET_SSE2 && TARGET_SSE_MATH
4949 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4951 && (SSE_REG_P (operands[0])
4952 || (GET_CODE (operands[0]) == SUBREG
4953 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4956 rtx op1 = operands[1];
4958 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4960 if (GET_CODE (op1) == SUBREG)
4961 op1 = SUBREG_REG (op1);
4963 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4965 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4966 emit_insn (gen_sse2_loadld (operands[4],
4967 CONST0_RTX (V4SImode), operands[1]));
4969 /* We can ignore possible trapping value in the
4970 high part of SSE register for non-trapping math. */
4971 else if (SSE_REG_P (op1) && !flag_trapping_math)
4972 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4975 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4976 emit_move_insn (operands[2], operands[1]);
4977 emit_insn (gen_sse2_loadld (operands[4],
4978 CONST0_RTX (V4SImode), operands[2]));
4980 if (<ssevecmode>mode == V4SFmode)
4981 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4983 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4988 [(set (match_operand:MODEF 0 "register_operand" "")
4989 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4990 (clobber (match_operand:SI 2 "memory_operand" ""))]
4991 "TARGET_SSE2 && TARGET_SSE_MATH
4992 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4994 && (SSE_REG_P (operands[0])
4995 || (GET_CODE (operands[0]) == SUBREG
4996 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4999 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5001 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5003 emit_insn (gen_sse2_loadld (operands[4],
5004 CONST0_RTX (V4SImode), operands[1]));
5005 if (<ssevecmode>mode == V4SFmode)
5006 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5008 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5013 [(set (match_operand:MODEF 0 "register_operand" "")
5014 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5015 "TARGET_SSE2 && TARGET_SSE_MATH
5016 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5018 && (SSE_REG_P (operands[0])
5019 || (GET_CODE (operands[0]) == SUBREG
5020 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5023 rtx op1 = operands[1];
5025 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5027 if (GET_CODE (op1) == SUBREG)
5028 op1 = SUBREG_REG (op1);
5030 if (GENERAL_REG_P (op1))
5032 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5033 if (TARGET_INTER_UNIT_MOVES)
5034 emit_insn (gen_sse2_loadld (operands[4],
5035 CONST0_RTX (V4SImode), operands[1]));
5038 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5040 emit_insn (gen_sse2_loadld (operands[4],
5041 CONST0_RTX (V4SImode), operands[5]));
5042 ix86_free_from_memory (GET_MODE (operands[1]));
5045 /* We can ignore possible trapping value in the
5046 high part of SSE register for non-trapping math. */
5047 else if (SSE_REG_P (op1) && !flag_trapping_math)
5048 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5051 if (<ssevecmode>mode == V4SFmode)
5052 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5054 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5059 [(set (match_operand:MODEF 0 "register_operand" "")
5060 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5061 "TARGET_SSE2 && TARGET_SSE_MATH
5062 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5064 && (SSE_REG_P (operands[0])
5065 || (GET_CODE (operands[0]) == SUBREG
5066 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5069 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5071 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5073 emit_insn (gen_sse2_loadld (operands[4],
5074 CONST0_RTX (V4SImode), operands[1]));
5075 if (<ssevecmode>mode == V4SFmode)
5076 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5078 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5082 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5083 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5085 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5086 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5087 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5088 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5090 [(set_attr "type" "sseicvt")
5091 (set_attr "mode" "<MODEF:MODE>")
5092 (set_attr "athlon_decode" "double,direct")
5093 (set_attr "amdfam10_decode" "vector,double")
5094 (set_attr "bdver1_decode" "double,direct")
5095 (set_attr "fp_int_src" "true")])
5097 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5098 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5100 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5101 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5102 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5103 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5104 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5105 [(set_attr "type" "sseicvt")
5106 (set_attr "prefix" "maybe_vex")
5107 (set_attr "mode" "<MODEF:MODE>")
5108 (set (attr "prefix_rex")
5110 (and (eq_attr "prefix" "maybe_vex")
5111 (match_test "<SWI48x:MODE>mode == DImode"))
5113 (const_string "*")))
5114 (set_attr "athlon_decode" "double,direct")
5115 (set_attr "amdfam10_decode" "vector,double")
5116 (set_attr "bdver1_decode" "double,direct")
5117 (set_attr "fp_int_src" "true")])
5120 [(set (match_operand:MODEF 0 "register_operand" "")
5121 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5122 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5123 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5124 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5125 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5127 && (SSE_REG_P (operands[0])
5128 || (GET_CODE (operands[0]) == SUBREG
5129 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5130 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5132 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5133 [(set (match_operand:MODEF 0 "register_operand" "=x")
5135 (match_operand:SWI48x 1 "memory_operand" "m")))]
5136 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5137 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5138 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5139 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5140 [(set_attr "type" "sseicvt")
5141 (set_attr "prefix" "maybe_vex")
5142 (set_attr "mode" "<MODEF:MODE>")
5143 (set (attr "prefix_rex")
5145 (and (eq_attr "prefix" "maybe_vex")
5146 (match_test "<SWI48x:MODE>mode == DImode"))
5148 (const_string "*")))
5149 (set_attr "athlon_decode" "direct")
5150 (set_attr "amdfam10_decode" "double")
5151 (set_attr "bdver1_decode" "direct")
5152 (set_attr "fp_int_src" "true")])
5155 [(set (match_operand:MODEF 0 "register_operand" "")
5156 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5157 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5158 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5159 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5160 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5162 && (SSE_REG_P (operands[0])
5163 || (GET_CODE (operands[0]) == SUBREG
5164 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5165 [(set (match_dup 2) (match_dup 1))
5166 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5169 [(set (match_operand:MODEF 0 "register_operand" "")
5170 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5171 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5172 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5173 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5175 && (SSE_REG_P (operands[0])
5176 || (GET_CODE (operands[0]) == SUBREG
5177 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5178 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5180 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5181 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5183 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5184 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5186 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5190 [(set_attr "type" "fmov,multi")
5191 (set_attr "mode" "<X87MODEF:MODE>")
5192 (set_attr "unit" "*,i387")
5193 (set_attr "fp_int_src" "true")])
5195 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5196 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5198 (match_operand:SWI48x 1 "memory_operand" "m")))]
5200 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5202 [(set_attr "type" "fmov")
5203 (set_attr "mode" "<X87MODEF:MODE>")
5204 (set_attr "fp_int_src" "true")])
5207 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5208 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5209 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5211 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5212 && reload_completed"
5213 [(set (match_dup 2) (match_dup 1))
5214 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5217 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5218 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5219 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5221 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5222 && reload_completed"
5223 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5225 ;; Avoid store forwarding (partial memory) stall penalty
5226 ;; by passing DImode value through XMM registers. */
5228 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5229 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5231 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5232 (clobber (match_scratch:V4SI 3 "=X,x"))
5233 (clobber (match_scratch:V4SI 4 "=X,x"))
5234 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5235 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5236 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5237 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5239 [(set_attr "type" "multi")
5240 (set_attr "mode" "<X87MODEF:MODE>")
5241 (set_attr "unit" "i387")
5242 (set_attr "fp_int_src" "true")])
5245 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5246 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5247 (clobber (match_scratch:V4SI 3 ""))
5248 (clobber (match_scratch:V4SI 4 ""))
5249 (clobber (match_operand:DI 2 "memory_operand" ""))]
5250 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5251 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5252 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5253 && reload_completed"
5254 [(set (match_dup 2) (match_dup 3))
5255 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5257 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5258 Assemble the 64-bit DImode value in an xmm register. */
5259 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5260 gen_rtx_SUBREG (SImode, operands[1], 0)));
5261 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5262 gen_rtx_SUBREG (SImode, operands[1], 4)));
5263 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5266 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5270 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5271 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5272 (clobber (match_scratch:V4SI 3 ""))
5273 (clobber (match_scratch:V4SI 4 ""))
5274 (clobber (match_operand:DI 2 "memory_operand" ""))]
5275 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5276 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5277 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5278 && reload_completed"
5279 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5281 ;; Avoid store forwarding (partial memory) stall penalty by extending
5282 ;; SImode value to DImode through XMM register instead of pushing two
5283 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5284 ;; targets benefit from this optimization. Also note that fild
5285 ;; loads from memory only.
5287 (define_insn "*floatunssi<mode>2_1"
5288 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5289 (unsigned_float:X87MODEF
5290 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5291 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5292 (clobber (match_scratch:SI 3 "=X,x"))]
5294 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5297 [(set_attr "type" "multi")
5298 (set_attr "mode" "<MODE>")])
5301 [(set (match_operand:X87MODEF 0 "register_operand" "")
5302 (unsigned_float:X87MODEF
5303 (match_operand:SI 1 "register_operand" "")))
5304 (clobber (match_operand:DI 2 "memory_operand" ""))
5305 (clobber (match_scratch:SI 3 ""))]
5307 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5309 && reload_completed"
5310 [(set (match_dup 2) (match_dup 1))
5312 (float:X87MODEF (match_dup 2)))]
5313 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5316 [(set (match_operand:X87MODEF 0 "register_operand" "")
5317 (unsigned_float:X87MODEF
5318 (match_operand:SI 1 "memory_operand" "")))
5319 (clobber (match_operand:DI 2 "memory_operand" ""))
5320 (clobber (match_scratch:SI 3 ""))]
5322 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5324 && reload_completed"
5325 [(set (match_dup 2) (match_dup 3))
5327 (float:X87MODEF (match_dup 2)))]
5329 emit_move_insn (operands[3], operands[1]);
5330 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5333 (define_expand "floatunssi<mode>2"
5335 [(set (match_operand:X87MODEF 0 "register_operand" "")
5336 (unsigned_float:X87MODEF
5337 (match_operand:SI 1 "nonimmediate_operand" "")))
5338 (clobber (match_dup 2))
5339 (clobber (match_scratch:SI 3 ""))])]
5341 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5343 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5345 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5347 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5352 enum ix86_stack_slot slot = (virtuals_instantiated
5355 operands[2] = assign_386_stack_local (DImode, slot);
5359 (define_expand "floatunsdisf2"
5360 [(use (match_operand:SF 0 "register_operand" ""))
5361 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5362 "TARGET_64BIT && TARGET_SSE_MATH"
5363 "x86_emit_floatuns (operands); DONE;")
5365 (define_expand "floatunsdidf2"
5366 [(use (match_operand:DF 0 "register_operand" ""))
5367 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5368 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5369 && TARGET_SSE2 && TARGET_SSE_MATH"
5372 x86_emit_floatuns (operands);
5374 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5380 (define_expand "add<mode>3"
5381 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5382 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5383 (match_operand:SDWIM 2 "<general_operand>" "")))]
5385 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5387 (define_insn_and_split "*add<dwi>3_doubleword"
5388 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5390 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5391 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5392 (clobber (reg:CC FLAGS_REG))]
5393 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5396 [(parallel [(set (reg:CC FLAGS_REG)
5397 (unspec:CC [(match_dup 1) (match_dup 2)]
5400 (plus:DWIH (match_dup 1) (match_dup 2)))])
5401 (parallel [(set (match_dup 3)
5405 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5407 (clobber (reg:CC FLAGS_REG))])]
5408 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5410 (define_insn "*add<mode>3_cc"
5411 [(set (reg:CC FLAGS_REG)
5413 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5414 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5416 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5417 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5418 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5419 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5420 [(set_attr "type" "alu")
5421 (set_attr "mode" "<MODE>")])
5423 (define_insn "addqi3_cc"
5424 [(set (reg:CC FLAGS_REG)
5426 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5427 (match_operand:QI 2 "general_operand" "qn,qm")]
5429 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5430 (plus:QI (match_dup 1) (match_dup 2)))]
5431 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5432 "add{b}\t{%2, %0|%0, %2}"
5433 [(set_attr "type" "alu")
5434 (set_attr "mode" "QI")])
5436 (define_insn_and_split "*lea_1"
5437 [(set (match_operand:SI 0 "register_operand" "=r")
5438 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5440 "lea{l}\t{%a1, %0|%0, %a1}"
5441 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5444 ix86_split_lea_for_addr (operands, SImode);
5447 [(set_attr "type" "lea")
5448 (set_attr "mode" "SI")])
5450 (define_insn_and_split "*lea<mode>_2"
5451 [(set (match_operand:SWI48 0 "register_operand" "=r")
5452 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5454 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5455 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5458 ix86_split_lea_for_addr (operands, <MODE>mode);
5461 [(set_attr "type" "lea")
5462 (set_attr "mode" "<MODE>")])
5464 (define_insn "*lea_3_zext"
5465 [(set (match_operand:DI 0 "register_operand" "=r")
5467 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5469 "lea{l}\t{%a1, %k0|%k0, %a1}"
5470 [(set_attr "type" "lea")
5471 (set_attr "mode" "SI")])
5473 (define_insn "*lea_4_zext"
5474 [(set (match_operand:DI 0 "register_operand" "=r")
5476 (match_operand:SI 1 "lea_address_operand" "j")))]
5478 "lea{l}\t{%a1, %k0|%k0, %a1}"
5479 [(set_attr "type" "lea")
5480 (set_attr "mode" "SI")])
5482 (define_insn "*lea_5_zext"
5483 [(set (match_operand:DI 0 "register_operand" "=r")
5485 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5486 (match_operand:DI 2 "const_32bit_mask" "n")))]
5488 "lea{l}\t{%a1, %k0|%k0, %a1}"
5489 [(set_attr "type" "lea")
5490 (set_attr "mode" "SI")])
5492 (define_insn "*lea_6_zext"
5493 [(set (match_operand:DI 0 "register_operand" "=r")
5495 (match_operand:DI 1 "lea_address_operand" "p")
5496 (match_operand:DI 2 "const_32bit_mask" "n")))]
5498 "lea{l}\t{%a1, %k0|%k0, %a1}"
5499 [(set_attr "type" "lea")
5500 (set_attr "mode" "SI")])
5502 (define_insn "*add<mode>_1"
5503 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5505 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5506 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5507 (clobber (reg:CC FLAGS_REG))]
5508 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5510 switch (get_attr_type (insn))
5516 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5517 if (operands[2] == const1_rtx)
5518 return "inc{<imodesuffix>}\t%0";
5521 gcc_assert (operands[2] == constm1_rtx);
5522 return "dec{<imodesuffix>}\t%0";
5526 /* For most processors, ADD is faster than LEA. This alternative
5527 was added to use ADD as much as possible. */
5528 if (which_alternative == 2)
5531 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5534 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5535 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5536 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5538 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5542 (cond [(eq_attr "alternative" "3")
5543 (const_string "lea")
5544 (match_operand:SWI48 2 "incdec_operand" "")
5545 (const_string "incdec")
5547 (const_string "alu")))
5548 (set (attr "length_immediate")
5550 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5552 (const_string "*")))
5553 (set_attr "mode" "<MODE>")])
5555 ;; It may seem that nonimmediate operand is proper one for operand 1.
5556 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5557 ;; we take care in ix86_binary_operator_ok to not allow two memory
5558 ;; operands so proper swapping will be done in reload. This allow
5559 ;; patterns constructed from addsi_1 to match.
5561 (define_insn "addsi_1_zext"
5562 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5564 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5565 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5566 (clobber (reg:CC FLAGS_REG))]
5567 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5569 switch (get_attr_type (insn))
5575 if (operands[2] == const1_rtx)
5576 return "inc{l}\t%k0";
5579 gcc_assert (operands[2] == constm1_rtx);
5580 return "dec{l}\t%k0";
5584 /* For most processors, ADD is faster than LEA. This alternative
5585 was added to use ADD as much as possible. */
5586 if (which_alternative == 1)
5589 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5592 if (x86_maybe_negate_const_int (&operands[2], SImode))
5593 return "sub{l}\t{%2, %k0|%k0, %2}";
5595 return "add{l}\t{%2, %k0|%k0, %2}";
5599 (cond [(eq_attr "alternative" "2")
5600 (const_string "lea")
5601 (match_operand:SI 2 "incdec_operand" "")
5602 (const_string "incdec")
5604 (const_string "alu")))
5605 (set (attr "length_immediate")
5607 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5609 (const_string "*")))
5610 (set_attr "mode" "SI")])
5612 (define_insn "*addhi_1"
5613 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5614 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5615 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5616 (clobber (reg:CC FLAGS_REG))]
5617 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5619 switch (get_attr_type (insn))
5625 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5626 if (operands[2] == const1_rtx)
5627 return "inc{w}\t%0";
5630 gcc_assert (operands[2] == constm1_rtx);
5631 return "dec{w}\t%0";
5635 /* For most processors, ADD is faster than LEA. This alternative
5636 was added to use ADD as much as possible. */
5637 if (which_alternative == 2)
5640 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5643 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644 if (x86_maybe_negate_const_int (&operands[2], HImode))
5645 return "sub{w}\t{%2, %0|%0, %2}";
5647 return "add{w}\t{%2, %0|%0, %2}";
5651 (cond [(eq_attr "alternative" "3")
5652 (const_string "lea")
5653 (match_operand:HI 2 "incdec_operand" "")
5654 (const_string "incdec")
5656 (const_string "alu")))
5657 (set (attr "length_immediate")
5659 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5661 (const_string "*")))
5662 (set_attr "mode" "HI,HI,HI,SI")])
5664 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5665 (define_insn "*addqi_1"
5666 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5667 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5668 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5669 (clobber (reg:CC FLAGS_REG))]
5670 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5672 bool widen = (which_alternative == 3 || which_alternative == 4);
5674 switch (get_attr_type (insn))
5680 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5681 if (operands[2] == const1_rtx)
5682 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5685 gcc_assert (operands[2] == constm1_rtx);
5686 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5690 /* For most processors, ADD is faster than LEA. These alternatives
5691 were added to use ADD as much as possible. */
5692 if (which_alternative == 2 || which_alternative == 4)
5695 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5698 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5699 if (x86_maybe_negate_const_int (&operands[2], QImode))
5702 return "sub{l}\t{%2, %k0|%k0, %2}";
5704 return "sub{b}\t{%2, %0|%0, %2}";
5707 return "add{l}\t{%k2, %k0|%k0, %k2}";
5709 return "add{b}\t{%2, %0|%0, %2}";
5713 (cond [(eq_attr "alternative" "5")
5714 (const_string "lea")
5715 (match_operand:QI 2 "incdec_operand" "")
5716 (const_string "incdec")
5718 (const_string "alu")))
5719 (set (attr "length_immediate")
5721 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5723 (const_string "*")))
5724 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5726 (define_insn "*addqi_1_slp"
5727 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5728 (plus:QI (match_dup 0)
5729 (match_operand:QI 1 "general_operand" "qn,qm")))
5730 (clobber (reg:CC FLAGS_REG))]
5731 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5732 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5734 switch (get_attr_type (insn))
5737 if (operands[1] == const1_rtx)
5738 return "inc{b}\t%0";
5741 gcc_assert (operands[1] == constm1_rtx);
5742 return "dec{b}\t%0";
5746 if (x86_maybe_negate_const_int (&operands[1], QImode))
5747 return "sub{b}\t{%1, %0|%0, %1}";
5749 return "add{b}\t{%1, %0|%0, %1}";
5753 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5754 (const_string "incdec")
5755 (const_string "alu1")))
5756 (set (attr "memory")
5757 (if_then_else (match_operand 1 "memory_operand" "")
5758 (const_string "load")
5759 (const_string "none")))
5760 (set_attr "mode" "QI")])
5762 ;; Split non destructive adds if we cannot use lea.
5764 [(set (match_operand:SWI48 0 "register_operand" "")
5765 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5766 (match_operand:SWI48 2 "nonmemory_operand" "")))
5767 (clobber (reg:CC FLAGS_REG))]
5768 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5769 [(set (match_dup 0) (match_dup 1))
5770 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5771 (clobber (reg:CC FLAGS_REG))])])
5773 ;; Convert add to the lea pattern to avoid flags dependency.
5775 [(set (match_operand:SWI 0 "register_operand" "")
5776 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5777 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5778 (clobber (reg:CC FLAGS_REG))]
5779 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5782 enum machine_mode mode = <MODE>mode;
5785 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5788 operands[0] = gen_lowpart (mode, operands[0]);
5789 operands[1] = gen_lowpart (mode, operands[1]);
5790 operands[2] = gen_lowpart (mode, operands[2]);
5793 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5795 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5799 ;; Convert add to the lea pattern to avoid flags dependency.
5801 [(set (match_operand:DI 0 "register_operand" "")
5803 (plus:SI (match_operand:SI 1 "register_operand" "")
5804 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5805 (clobber (reg:CC FLAGS_REG))]
5806 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5808 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5810 (define_insn "*add<mode>_2"
5811 [(set (reg FLAGS_REG)
5814 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5815 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5817 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5818 (plus:SWI (match_dup 1) (match_dup 2)))]
5819 "ix86_match_ccmode (insn, CCGOCmode)
5820 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5822 switch (get_attr_type (insn))
5825 if (operands[2] == const1_rtx)
5826 return "inc{<imodesuffix>}\t%0";
5829 gcc_assert (operands[2] == constm1_rtx);
5830 return "dec{<imodesuffix>}\t%0";
5834 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5835 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5837 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5841 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5842 (const_string "incdec")
5843 (const_string "alu")))
5844 (set (attr "length_immediate")
5846 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5848 (const_string "*")))
5849 (set_attr "mode" "<MODE>")])
5851 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5852 (define_insn "*addsi_2_zext"
5853 [(set (reg FLAGS_REG)
5855 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5856 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5858 (set (match_operand:DI 0 "register_operand" "=r")
5859 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5860 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5861 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5863 switch (get_attr_type (insn))
5866 if (operands[2] == const1_rtx)
5867 return "inc{l}\t%k0";
5870 gcc_assert (operands[2] == constm1_rtx);
5871 return "dec{l}\t%k0";
5875 if (x86_maybe_negate_const_int (&operands[2], SImode))
5876 return "sub{l}\t{%2, %k0|%k0, %2}";
5878 return "add{l}\t{%2, %k0|%k0, %2}";
5882 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5883 (const_string "incdec")
5884 (const_string "alu")))
5885 (set (attr "length_immediate")
5887 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5889 (const_string "*")))
5890 (set_attr "mode" "SI")])
5892 (define_insn "*add<mode>_3"
5893 [(set (reg FLAGS_REG)
5895 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5896 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5897 (clobber (match_scratch:SWI 0 "=<r>"))]
5898 "ix86_match_ccmode (insn, CCZmode)
5899 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5901 switch (get_attr_type (insn))
5904 if (operands[2] == const1_rtx)
5905 return "inc{<imodesuffix>}\t%0";
5908 gcc_assert (operands[2] == constm1_rtx);
5909 return "dec{<imodesuffix>}\t%0";
5913 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5914 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5916 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5920 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5921 (const_string "incdec")
5922 (const_string "alu")))
5923 (set (attr "length_immediate")
5925 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5927 (const_string "*")))
5928 (set_attr "mode" "<MODE>")])
5930 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5931 (define_insn "*addsi_3_zext"
5932 [(set (reg FLAGS_REG)
5934 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5935 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5936 (set (match_operand:DI 0 "register_operand" "=r")
5937 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5938 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5939 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5941 switch (get_attr_type (insn))
5944 if (operands[2] == const1_rtx)
5945 return "inc{l}\t%k0";
5948 gcc_assert (operands[2] == constm1_rtx);
5949 return "dec{l}\t%k0";
5953 if (x86_maybe_negate_const_int (&operands[2], SImode))
5954 return "sub{l}\t{%2, %k0|%k0, %2}";
5956 return "add{l}\t{%2, %k0|%k0, %2}";
5960 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5961 (const_string "incdec")
5962 (const_string "alu")))
5963 (set (attr "length_immediate")
5965 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5967 (const_string "*")))
5968 (set_attr "mode" "SI")])
5970 ; For comparisons against 1, -1 and 128, we may generate better code
5971 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5972 ; is matched then. We can't accept general immediate, because for
5973 ; case of overflows, the result is messed up.
5974 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5975 ; only for comparisons not depending on it.
5977 (define_insn "*adddi_4"
5978 [(set (reg FLAGS_REG)
5980 (match_operand:DI 1 "nonimmediate_operand" "0")
5981 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5982 (clobber (match_scratch:DI 0 "=rm"))]
5984 && ix86_match_ccmode (insn, CCGCmode)"
5986 switch (get_attr_type (insn))
5989 if (operands[2] == constm1_rtx)
5990 return "inc{q}\t%0";
5993 gcc_assert (operands[2] == const1_rtx);
5994 return "dec{q}\t%0";
5998 if (x86_maybe_negate_const_int (&operands[2], DImode))
5999 return "add{q}\t{%2, %0|%0, %2}";
6001 return "sub{q}\t{%2, %0|%0, %2}";
6005 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6006 (const_string "incdec")
6007 (const_string "alu")))
6008 (set (attr "length_immediate")
6010 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6012 (const_string "*")))
6013 (set_attr "mode" "DI")])
6015 ; For comparisons against 1, -1 and 128, we may generate better code
6016 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6017 ; is matched then. We can't accept general immediate, because for
6018 ; case of overflows, the result is messed up.
6019 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6020 ; only for comparisons not depending on it.
6022 (define_insn "*add<mode>_4"
6023 [(set (reg FLAGS_REG)
6025 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6026 (match_operand:SWI124 2 "const_int_operand" "n")))
6027 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6028 "ix86_match_ccmode (insn, CCGCmode)"
6030 switch (get_attr_type (insn))
6033 if (operands[2] == constm1_rtx)
6034 return "inc{<imodesuffix>}\t%0";
6037 gcc_assert (operands[2] == const1_rtx);
6038 return "dec{<imodesuffix>}\t%0";
6042 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6043 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6045 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6049 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6050 (const_string "incdec")
6051 (const_string "alu")))
6052 (set (attr "length_immediate")
6054 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6056 (const_string "*")))
6057 (set_attr "mode" "<MODE>")])
6059 (define_insn "*add<mode>_5"
6060 [(set (reg FLAGS_REG)
6063 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6064 (match_operand:SWI 2 "<general_operand>" "<g>"))
6066 (clobber (match_scratch:SWI 0 "=<r>"))]
6067 "ix86_match_ccmode (insn, CCGOCmode)
6068 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6070 switch (get_attr_type (insn))
6073 if (operands[2] == const1_rtx)
6074 return "inc{<imodesuffix>}\t%0";
6077 gcc_assert (operands[2] == constm1_rtx);
6078 return "dec{<imodesuffix>}\t%0";
6082 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6083 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6085 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6089 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6090 (const_string "incdec")
6091 (const_string "alu")))
6092 (set (attr "length_immediate")
6094 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6096 (const_string "*")))
6097 (set_attr "mode" "<MODE>")])
6099 (define_insn "*addqi_ext_1_rex64"
6100 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6105 (match_operand 1 "ext_register_operand" "0")
6108 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6109 (clobber (reg:CC FLAGS_REG))]
6112 switch (get_attr_type (insn))
6115 if (operands[2] == const1_rtx)
6116 return "inc{b}\t%h0";
6119 gcc_assert (operands[2] == constm1_rtx);
6120 return "dec{b}\t%h0";
6124 return "add{b}\t{%2, %h0|%h0, %2}";
6128 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6129 (const_string "incdec")
6130 (const_string "alu")))
6131 (set_attr "modrm" "1")
6132 (set_attr "mode" "QI")])
6134 (define_insn "addqi_ext_1"
6135 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6140 (match_operand 1 "ext_register_operand" "0")
6143 (match_operand:QI 2 "general_operand" "Qmn")))
6144 (clobber (reg:CC FLAGS_REG))]
6147 switch (get_attr_type (insn))
6150 if (operands[2] == const1_rtx)
6151 return "inc{b}\t%h0";
6154 gcc_assert (operands[2] == constm1_rtx);
6155 return "dec{b}\t%h0";
6159 return "add{b}\t{%2, %h0|%h0, %2}";
6163 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6164 (const_string "incdec")
6165 (const_string "alu")))
6166 (set_attr "modrm" "1")
6167 (set_attr "mode" "QI")])
6169 (define_insn "*addqi_ext_2"
6170 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6175 (match_operand 1 "ext_register_operand" "%0")
6179 (match_operand 2 "ext_register_operand" "Q")
6182 (clobber (reg:CC FLAGS_REG))]
6184 "add{b}\t{%h2, %h0|%h0, %h2}"
6185 [(set_attr "type" "alu")
6186 (set_attr "mode" "QI")])
6188 ;; The lea patterns for modes less than 32 bits need to be matched by
6189 ;; several insns converted to real lea by splitters.
6191 (define_insn_and_split "*lea_general_1"
6192 [(set (match_operand 0 "register_operand" "=r")
6193 (plus (plus (match_operand 1 "index_register_operand" "l")
6194 (match_operand 2 "register_operand" "r"))
6195 (match_operand 3 "immediate_operand" "i")))]
6196 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6197 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6198 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6199 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6200 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6201 || GET_MODE (operands[3]) == VOIDmode)"
6203 "&& reload_completed"
6206 enum machine_mode mode = SImode;
6209 operands[0] = gen_lowpart (mode, operands[0]);
6210 operands[1] = gen_lowpart (mode, operands[1]);
6211 operands[2] = gen_lowpart (mode, operands[2]);
6212 operands[3] = gen_lowpart (mode, operands[3]);
6214 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6217 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6220 [(set_attr "type" "lea")
6221 (set_attr "mode" "SI")])
6223 (define_insn_and_split "*lea_general_2"
6224 [(set (match_operand 0 "register_operand" "=r")
6225 (plus (mult (match_operand 1 "index_register_operand" "l")
6226 (match_operand 2 "const248_operand" "n"))
6227 (match_operand 3 "nonmemory_operand" "ri")))]
6228 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6229 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6230 && GET_MODE (operands[0]) == GET_MODE (operands[1])
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[3] = gen_lowpart (mode, operands[3]);
6244 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6247 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6250 [(set_attr "type" "lea")
6251 (set_attr "mode" "SI")])
6253 (define_insn_and_split "*lea_general_3"
6254 [(set (match_operand 0 "register_operand" "=r")
6255 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6256 (match_operand 2 "const248_operand" "n"))
6257 (match_operand 3 "register_operand" "r"))
6258 (match_operand 4 "immediate_operand" "i")))]
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])"
6264 "&& reload_completed"
6267 enum machine_mode mode = SImode;
6270 operands[0] = gen_lowpart (mode, operands[0]);
6271 operands[1] = gen_lowpart (mode, operands[1]);
6272 operands[3] = gen_lowpart (mode, operands[3]);
6273 operands[4] = gen_lowpart (mode, operands[4]);
6275 pat = gen_rtx_PLUS (mode,
6277 gen_rtx_MULT (mode, operands[1],
6282 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6285 [(set_attr "type" "lea")
6286 (set_attr "mode" "SI")])
6288 (define_insn_and_split "*lea_general_4"
6289 [(set (match_operand 0 "register_operand" "=r")
6291 (match_operand 1 "index_register_operand" "l")
6292 (match_operand 2 "const_int_operand" "n"))
6293 (match_operand 3 "const_int_operand" "n")))]
6294 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6295 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6296 || GET_MODE (operands[0]) == SImode
6297 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6298 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6299 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6300 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6301 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6303 "&& reload_completed"
6306 enum machine_mode mode = GET_MODE (operands[0]);
6309 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6312 operands[0] = gen_lowpart (mode, operands[0]);
6313 operands[1] = gen_lowpart (mode, operands[1]);
6316 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6318 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6319 INTVAL (operands[3]));
6321 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6324 [(set_attr "type" "lea")
6326 (if_then_else (match_operand:DI 0 "" "")
6328 (const_string "SI")))])
6330 ;; Subtract instructions
6332 (define_expand "sub<mode>3"
6333 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6334 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6335 (match_operand:SDWIM 2 "<general_operand>" "")))]
6337 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6339 (define_insn_and_split "*sub<dwi>3_doubleword"
6340 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6342 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6343 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6344 (clobber (reg:CC FLAGS_REG))]
6345 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6348 [(parallel [(set (reg:CC FLAGS_REG)
6349 (compare:CC (match_dup 1) (match_dup 2)))
6351 (minus:DWIH (match_dup 1) (match_dup 2)))])
6352 (parallel [(set (match_dup 3)
6356 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6358 (clobber (reg:CC FLAGS_REG))])]
6359 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6361 (define_insn "*sub<mode>_1"
6362 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6364 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6365 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6366 (clobber (reg:CC FLAGS_REG))]
6367 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6368 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6369 [(set_attr "type" "alu")
6370 (set_attr "mode" "<MODE>")])
6372 (define_insn "*subsi_1_zext"
6373 [(set (match_operand:DI 0 "register_operand" "=r")
6375 (minus:SI (match_operand:SI 1 "register_operand" "0")
6376 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6377 (clobber (reg:CC FLAGS_REG))]
6378 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6379 "sub{l}\t{%2, %k0|%k0, %2}"
6380 [(set_attr "type" "alu")
6381 (set_attr "mode" "SI")])
6383 (define_insn "*subqi_1_slp"
6384 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6385 (minus:QI (match_dup 0)
6386 (match_operand:QI 1 "general_operand" "qn,qm")))
6387 (clobber (reg:CC FLAGS_REG))]
6388 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6389 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6390 "sub{b}\t{%1, %0|%0, %1}"
6391 [(set_attr "type" "alu1")
6392 (set_attr "mode" "QI")])
6394 (define_insn "*sub<mode>_2"
6395 [(set (reg FLAGS_REG)
6398 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6399 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6401 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6402 (minus:SWI (match_dup 1) (match_dup 2)))]
6403 "ix86_match_ccmode (insn, CCGOCmode)
6404 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6405 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6406 [(set_attr "type" "alu")
6407 (set_attr "mode" "<MODE>")])
6409 (define_insn "*subsi_2_zext"
6410 [(set (reg FLAGS_REG)
6412 (minus:SI (match_operand:SI 1 "register_operand" "0")
6413 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6415 (set (match_operand:DI 0 "register_operand" "=r")
6417 (minus:SI (match_dup 1)
6419 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6420 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6421 "sub{l}\t{%2, %k0|%k0, %2}"
6422 [(set_attr "type" "alu")
6423 (set_attr "mode" "SI")])
6425 (define_insn "*sub<mode>_3"
6426 [(set (reg FLAGS_REG)
6427 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6428 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6429 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6430 (minus:SWI (match_dup 1) (match_dup 2)))]
6431 "ix86_match_ccmode (insn, CCmode)
6432 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6433 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6434 [(set_attr "type" "alu")
6435 (set_attr "mode" "<MODE>")])
6437 (define_insn "*subsi_3_zext"
6438 [(set (reg FLAGS_REG)
6439 (compare (match_operand:SI 1 "register_operand" "0")
6440 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6441 (set (match_operand:DI 0 "register_operand" "=r")
6443 (minus:SI (match_dup 1)
6445 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6446 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6447 "sub{l}\t{%2, %1|%1, %2}"
6448 [(set_attr "type" "alu")
6449 (set_attr "mode" "SI")])
6451 ;; Add with carry and subtract with borrow
6453 (define_expand "<plusminus_insn><mode>3_carry"
6455 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6457 (match_operand:SWI 1 "nonimmediate_operand" "")
6458 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6459 [(match_operand 3 "flags_reg_operand" "")
6461 (match_operand:SWI 2 "<general_operand>" ""))))
6462 (clobber (reg:CC FLAGS_REG))])]
6463 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6465 (define_insn "*<plusminus_insn><mode>3_carry"
6466 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6468 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6470 (match_operator 3 "ix86_carry_flag_operator"
6471 [(reg FLAGS_REG) (const_int 0)])
6472 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6473 (clobber (reg:CC FLAGS_REG))]
6474 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6475 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6476 [(set_attr "type" "alu")
6477 (set_attr "use_carry" "1")
6478 (set_attr "pent_pair" "pu")
6479 (set_attr "mode" "<MODE>")])
6481 (define_insn "*addsi3_carry_zext"
6482 [(set (match_operand:DI 0 "register_operand" "=r")
6484 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6485 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6486 [(reg FLAGS_REG) (const_int 0)])
6487 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6488 (clobber (reg:CC FLAGS_REG))]
6489 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6490 "adc{l}\t{%2, %k0|%k0, %2}"
6491 [(set_attr "type" "alu")
6492 (set_attr "use_carry" "1")
6493 (set_attr "pent_pair" "pu")
6494 (set_attr "mode" "SI")])
6496 (define_insn "*subsi3_carry_zext"
6497 [(set (match_operand:DI 0 "register_operand" "=r")
6499 (minus:SI (match_operand:SI 1 "register_operand" "0")
6500 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6501 [(reg FLAGS_REG) (const_int 0)])
6502 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6503 (clobber (reg:CC FLAGS_REG))]
6504 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6505 "sbb{l}\t{%2, %k0|%k0, %2}"
6506 [(set_attr "type" "alu")
6507 (set_attr "pent_pair" "pu")
6508 (set_attr "mode" "SI")])
6510 ;; Overflow setting add and subtract instructions
6512 (define_insn "*add<mode>3_cconly_overflow"
6513 [(set (reg:CCC FLAGS_REG)
6516 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6517 (match_operand:SWI 2 "<general_operand>" "<g>"))
6519 (clobber (match_scratch:SWI 0 "=<r>"))]
6520 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6521 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6522 [(set_attr "type" "alu")
6523 (set_attr "mode" "<MODE>")])
6525 (define_insn "*sub<mode>3_cconly_overflow"
6526 [(set (reg:CCC FLAGS_REG)
6529 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6530 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6533 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6534 [(set_attr "type" "icmp")
6535 (set_attr "mode" "<MODE>")])
6537 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6538 [(set (reg:CCC FLAGS_REG)
6541 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6542 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6544 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6545 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6546 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6547 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6548 [(set_attr "type" "alu")
6549 (set_attr "mode" "<MODE>")])
6551 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6552 [(set (reg:CCC FLAGS_REG)
6555 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6556 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6558 (set (match_operand:DI 0 "register_operand" "=r")
6559 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6560 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6561 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6562 [(set_attr "type" "alu")
6563 (set_attr "mode" "SI")])
6565 ;; The patterns that match these are at the end of this file.
6567 (define_expand "<plusminus_insn>xf3"
6568 [(set (match_operand:XF 0 "register_operand" "")
6570 (match_operand:XF 1 "register_operand" "")
6571 (match_operand:XF 2 "register_operand" "")))]
6574 (define_expand "<plusminus_insn><mode>3"
6575 [(set (match_operand:MODEF 0 "register_operand" "")
6577 (match_operand:MODEF 1 "register_operand" "")
6578 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6579 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6580 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6582 ;; Multiply instructions
6584 (define_expand "mul<mode>3"
6585 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6587 (match_operand:SWIM248 1 "register_operand" "")
6588 (match_operand:SWIM248 2 "<general_operand>" "")))
6589 (clobber (reg:CC FLAGS_REG))])])
6591 (define_expand "mulqi3"
6592 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6594 (match_operand:QI 1 "register_operand" "")
6595 (match_operand:QI 2 "nonimmediate_operand" "")))
6596 (clobber (reg:CC FLAGS_REG))])]
6597 "TARGET_QIMODE_MATH")
6600 ;; IMUL reg32/64, reg32/64, imm8 Direct
6601 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6602 ;; IMUL reg32/64, reg32/64, imm32 Direct
6603 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6604 ;; IMUL reg32/64, reg32/64 Direct
6605 ;; IMUL reg32/64, mem32/64 Direct
6607 ;; On BDVER1, all above IMULs use DirectPath
6609 (define_insn "*mul<mode>3_1"
6610 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6612 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6613 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6614 (clobber (reg:CC FLAGS_REG))]
6615 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6617 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6618 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6619 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6620 [(set_attr "type" "imul")
6621 (set_attr "prefix_0f" "0,0,1")
6622 (set (attr "athlon_decode")
6623 (cond [(eq_attr "cpu" "athlon")
6624 (const_string "vector")
6625 (eq_attr "alternative" "1")
6626 (const_string "vector")
6627 (and (eq_attr "alternative" "2")
6628 (match_operand 1 "memory_operand" ""))
6629 (const_string "vector")]
6630 (const_string "direct")))
6631 (set (attr "amdfam10_decode")
6632 (cond [(and (eq_attr "alternative" "0,1")
6633 (match_operand 1 "memory_operand" ""))
6634 (const_string "vector")]
6635 (const_string "direct")))
6636 (set_attr "bdver1_decode" "direct")
6637 (set_attr "mode" "<MODE>")])
6639 (define_insn "*mulsi3_1_zext"
6640 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6642 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6643 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6644 (clobber (reg:CC FLAGS_REG))]
6646 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6648 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6649 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6650 imul{l}\t{%2, %k0|%k0, %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" "SI")])
6671 ;; IMUL reg16, reg16, imm8 VectorPath
6672 ;; IMUL reg16, mem16, imm8 VectorPath
6673 ;; IMUL reg16, reg16, imm16 VectorPath
6674 ;; IMUL reg16, mem16, imm16 VectorPath
6675 ;; IMUL reg16, reg16 Direct
6676 ;; IMUL reg16, mem16 Direct
6678 ;; On BDVER1, all HI MULs use DoublePath
6680 (define_insn "*mulhi3_1"
6681 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6682 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6683 (match_operand:HI 2 "general_operand" "K,n,mr")))
6684 (clobber (reg:CC FLAGS_REG))]
6686 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6688 imul{w}\t{%2, %1, %0|%0, %1, %2}
6689 imul{w}\t{%2, %1, %0|%0, %1, %2}
6690 imul{w}\t{%2, %0|%0, %2}"
6691 [(set_attr "type" "imul")
6692 (set_attr "prefix_0f" "0,0,1")
6693 (set (attr "athlon_decode")
6694 (cond [(eq_attr "cpu" "athlon")
6695 (const_string "vector")
6696 (eq_attr "alternative" "1,2")
6697 (const_string "vector")]
6698 (const_string "direct")))
6699 (set (attr "amdfam10_decode")
6700 (cond [(eq_attr "alternative" "0,1")
6701 (const_string "vector")]
6702 (const_string "direct")))
6703 (set_attr "bdver1_decode" "double")
6704 (set_attr "mode" "HI")])
6706 ;;On AMDFAM10 and BDVER1
6710 (define_insn "*mulqi3_1"
6711 [(set (match_operand:QI 0 "register_operand" "=a")
6712 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6713 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6714 (clobber (reg:CC FLAGS_REG))]
6716 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6718 [(set_attr "type" "imul")
6719 (set_attr "length_immediate" "0")
6720 (set (attr "athlon_decode")
6721 (if_then_else (eq_attr "cpu" "athlon")
6722 (const_string "vector")
6723 (const_string "direct")))
6724 (set_attr "amdfam10_decode" "direct")
6725 (set_attr "bdver1_decode" "direct")
6726 (set_attr "mode" "QI")])
6728 (define_expand "<u>mul<mode><dwi>3"
6729 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6732 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6734 (match_operand:DWIH 2 "register_operand" ""))))
6735 (clobber (reg:CC FLAGS_REG))])])
6737 (define_expand "<u>mulqihi3"
6738 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6741 (match_operand:QI 1 "nonimmediate_operand" ""))
6743 (match_operand:QI 2 "register_operand" ""))))
6744 (clobber (reg:CC FLAGS_REG))])]
6745 "TARGET_QIMODE_MATH")
6747 (define_insn "*bmi2_umulditi3_1"
6748 [(set (match_operand:DI 0 "register_operand" "=r")
6750 (match_operand:DI 2 "nonimmediate_operand" "%d")
6751 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6752 (set (match_operand:DI 1 "register_operand" "=r")
6755 (mult:TI (zero_extend:TI (match_dup 2))
6756 (zero_extend:TI (match_dup 3)))
6758 "TARGET_64BIT && TARGET_BMI2
6759 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6760 "mulx\t{%3, %0, %1|%1, %0, %3}"
6761 [(set_attr "type" "imulx")
6762 (set_attr "prefix" "vex")
6763 (set_attr "mode" "DI")])
6765 (define_insn "*bmi2_umulsidi3_1"
6766 [(set (match_operand:SI 0 "register_operand" "=r")
6768 (match_operand:SI 2 "nonimmediate_operand" "%d")
6769 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6770 (set (match_operand:SI 1 "register_operand" "=r")
6773 (mult:DI (zero_extend:DI (match_dup 2))
6774 (zero_extend:DI (match_dup 3)))
6776 "!TARGET_64BIT && TARGET_BMI2
6777 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6778 "mulx\t{%3, %0, %1|%1, %0, %3}"
6779 [(set_attr "type" "imulx")
6780 (set_attr "prefix" "vex")
6781 (set_attr "mode" "SI")])
6783 (define_insn "*umul<mode><dwi>3_1"
6784 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6787 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6789 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6790 (clobber (reg:CC FLAGS_REG))]
6791 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6793 mul{<imodesuffix>}\t%2
6795 [(set_attr "isa" "*,bmi2")
6796 (set_attr "type" "imul,imulx")
6797 (set_attr "length_immediate" "0,*")
6798 (set (attr "athlon_decode")
6799 (cond [(eq_attr "alternative" "0")
6800 (if_then_else (eq_attr "cpu" "athlon")
6801 (const_string "vector")
6802 (const_string "double"))]
6803 (const_string "*")))
6804 (set_attr "amdfam10_decode" "double,*")
6805 (set_attr "bdver1_decode" "direct,*")
6806 (set_attr "prefix" "orig,vex")
6807 (set_attr "mode" "<MODE>")])
6809 ;; Convert mul to the mulx pattern to avoid flags dependency.
6811 [(set (match_operand:<DWI> 0 "register_operand" "")
6814 (match_operand:DWIH 1 "register_operand" ""))
6816 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6817 (clobber (reg:CC FLAGS_REG))]
6818 "TARGET_BMI2 && reload_completed
6819 && true_regnum (operands[1]) == DX_REG"
6820 [(parallel [(set (match_dup 3)
6821 (mult:DWIH (match_dup 1) (match_dup 2)))
6825 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6826 (zero_extend:<DWI> (match_dup 2)))
6829 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6831 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6834 (define_insn "*mul<mode><dwi>3_1"
6835 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6838 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6840 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6841 (clobber (reg:CC FLAGS_REG))]
6842 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6843 "imul{<imodesuffix>}\t%2"
6844 [(set_attr "type" "imul")
6845 (set_attr "length_immediate" "0")
6846 (set (attr "athlon_decode")
6847 (if_then_else (eq_attr "cpu" "athlon")
6848 (const_string "vector")
6849 (const_string "double")))
6850 (set_attr "amdfam10_decode" "double")
6851 (set_attr "bdver1_decode" "direct")
6852 (set_attr "mode" "<MODE>")])
6854 (define_insn "*<u>mulqihi3_1"
6855 [(set (match_operand:HI 0 "register_operand" "=a")
6858 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6860 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6861 (clobber (reg:CC FLAGS_REG))]
6863 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6864 "<sgnprefix>mul{b}\t%2"
6865 [(set_attr "type" "imul")
6866 (set_attr "length_immediate" "0")
6867 (set (attr "athlon_decode")
6868 (if_then_else (eq_attr "cpu" "athlon")
6869 (const_string "vector")
6870 (const_string "direct")))
6871 (set_attr "amdfam10_decode" "direct")
6872 (set_attr "bdver1_decode" "direct")
6873 (set_attr "mode" "QI")])
6875 (define_expand "<s>mul<mode>3_highpart"
6876 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6881 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6883 (match_operand:SWI48 2 "register_operand" "")))
6885 (clobber (match_scratch:SWI48 3 ""))
6886 (clobber (reg:CC FLAGS_REG))])]
6888 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6890 (define_insn "*<s>muldi3_highpart_1"
6891 [(set (match_operand:DI 0 "register_operand" "=d")
6896 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6898 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6900 (clobber (match_scratch:DI 3 "=1"))
6901 (clobber (reg:CC FLAGS_REG))]
6903 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6904 "<sgnprefix>mul{q}\t%2"
6905 [(set_attr "type" "imul")
6906 (set_attr "length_immediate" "0")
6907 (set (attr "athlon_decode")
6908 (if_then_else (eq_attr "cpu" "athlon")
6909 (const_string "vector")
6910 (const_string "double")))
6911 (set_attr "amdfam10_decode" "double")
6912 (set_attr "bdver1_decode" "direct")
6913 (set_attr "mode" "DI")])
6915 (define_insn "*<s>mulsi3_highpart_1"
6916 [(set (match_operand:SI 0 "register_operand" "=d")
6921 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6923 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6925 (clobber (match_scratch:SI 3 "=1"))
6926 (clobber (reg:CC FLAGS_REG))]
6927 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6928 "<sgnprefix>mul{l}\t%2"
6929 [(set_attr "type" "imul")
6930 (set_attr "length_immediate" "0")
6931 (set (attr "athlon_decode")
6932 (if_then_else (eq_attr "cpu" "athlon")
6933 (const_string "vector")
6934 (const_string "double")))
6935 (set_attr "amdfam10_decode" "double")
6936 (set_attr "bdver1_decode" "direct")
6937 (set_attr "mode" "SI")])
6939 (define_insn "*<s>mulsi3_highpart_zext"
6940 [(set (match_operand:DI 0 "register_operand" "=d")
6941 (zero_extend:DI (truncate:SI
6943 (mult:DI (any_extend:DI
6944 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6946 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6948 (clobber (match_scratch:SI 3 "=1"))
6949 (clobber (reg:CC FLAGS_REG))]
6951 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6952 "<sgnprefix>mul{l}\t%2"
6953 [(set_attr "type" "imul")
6954 (set_attr "length_immediate" "0")
6955 (set (attr "athlon_decode")
6956 (if_then_else (eq_attr "cpu" "athlon")
6957 (const_string "vector")
6958 (const_string "double")))
6959 (set_attr "amdfam10_decode" "double")
6960 (set_attr "bdver1_decode" "direct")
6961 (set_attr "mode" "SI")])
6963 ;; The patterns that match these are at the end of this file.
6965 (define_expand "mulxf3"
6966 [(set (match_operand:XF 0 "register_operand" "")
6967 (mult:XF (match_operand:XF 1 "register_operand" "")
6968 (match_operand:XF 2 "register_operand" "")))]
6971 (define_expand "mul<mode>3"
6972 [(set (match_operand:MODEF 0 "register_operand" "")
6973 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6974 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6975 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6976 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6978 ;; Divide instructions
6980 ;; The patterns that match these are at the end of this file.
6982 (define_expand "divxf3"
6983 [(set (match_operand:XF 0 "register_operand" "")
6984 (div:XF (match_operand:XF 1 "register_operand" "")
6985 (match_operand:XF 2 "register_operand" "")))]
6988 (define_expand "divdf3"
6989 [(set (match_operand:DF 0 "register_operand" "")
6990 (div:DF (match_operand:DF 1 "register_operand" "")
6991 (match_operand:DF 2 "nonimmediate_operand" "")))]
6992 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6993 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6995 (define_expand "divsf3"
6996 [(set (match_operand:SF 0 "register_operand" "")
6997 (div:SF (match_operand:SF 1 "register_operand" "")
6998 (match_operand:SF 2 "nonimmediate_operand" "")))]
6999 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7004 && optimize_insn_for_speed_p ()
7005 && flag_finite_math_only && !flag_trapping_math
7006 && flag_unsafe_math_optimizations)
7008 ix86_emit_swdivsf (operands[0], operands[1],
7009 operands[2], SFmode);
7014 ;; Divmod instructions.
7016 (define_expand "divmod<mode>4"
7017 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7019 (match_operand:SWIM248 1 "register_operand" "")
7020 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7021 (set (match_operand:SWIM248 3 "register_operand" "")
7022 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7023 (clobber (reg:CC FLAGS_REG))])])
7025 ;; Split with 8bit unsigned divide:
7026 ;; if (dividend an divisor are in [0-255])
7027 ;; use 8bit unsigned integer divide
7029 ;; use original integer divide
7031 [(set (match_operand:SWI48 0 "register_operand" "")
7032 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7033 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7034 (set (match_operand:SWI48 1 "register_operand" "")
7035 (mod:SWI48 (match_dup 2) (match_dup 3)))
7036 (clobber (reg:CC FLAGS_REG))]
7037 "TARGET_USE_8BIT_IDIV
7038 && TARGET_QIMODE_MATH
7039 && can_create_pseudo_p ()
7040 && !optimize_insn_for_size_p ()"
7042 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7044 (define_insn_and_split "divmod<mode>4_1"
7045 [(set (match_operand:SWI48 0 "register_operand" "=a")
7046 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7047 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7048 (set (match_operand:SWI48 1 "register_operand" "=&d")
7049 (mod:SWI48 (match_dup 2) (match_dup 3)))
7050 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7051 (clobber (reg:CC FLAGS_REG))]
7055 [(parallel [(set (match_dup 1)
7056 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7057 (clobber (reg:CC FLAGS_REG))])
7058 (parallel [(set (match_dup 0)
7059 (div:SWI48 (match_dup 2) (match_dup 3)))
7061 (mod:SWI48 (match_dup 2) (match_dup 3)))
7063 (clobber (reg:CC FLAGS_REG))])]
7065 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7067 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7068 operands[4] = operands[2];
7071 /* Avoid use of cltd in favor of a mov+shift. */
7072 emit_move_insn (operands[1], operands[2]);
7073 operands[4] = operands[1];
7076 [(set_attr "type" "multi")
7077 (set_attr "mode" "<MODE>")])
7079 (define_insn_and_split "*divmod<mode>4"
7080 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7081 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7082 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7083 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7084 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7085 (clobber (reg:CC FLAGS_REG))]
7089 [(parallel [(set (match_dup 1)
7090 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7091 (clobber (reg:CC FLAGS_REG))])
7092 (parallel [(set (match_dup 0)
7093 (div:SWIM248 (match_dup 2) (match_dup 3)))
7095 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7097 (clobber (reg:CC FLAGS_REG))])]
7099 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7101 if (<MODE>mode != HImode
7102 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7103 operands[4] = operands[2];
7106 /* Avoid use of cltd in favor of a mov+shift. */
7107 emit_move_insn (operands[1], operands[2]);
7108 operands[4] = operands[1];
7111 [(set_attr "type" "multi")
7112 (set_attr "mode" "<MODE>")])
7114 (define_insn "*divmod<mode>4_noext"
7115 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7116 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7117 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7118 (set (match_operand:SWIM248 1 "register_operand" "=d")
7119 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7120 (use (match_operand:SWIM248 4 "register_operand" "1"))
7121 (clobber (reg:CC FLAGS_REG))]
7123 "idiv{<imodesuffix>}\t%3"
7124 [(set_attr "type" "idiv")
7125 (set_attr "mode" "<MODE>")])
7127 (define_expand "divmodqi4"
7128 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7130 (match_operand:QI 1 "register_operand" "")
7131 (match_operand:QI 2 "nonimmediate_operand" "")))
7132 (set (match_operand:QI 3 "register_operand" "")
7133 (mod:QI (match_dup 1) (match_dup 2)))
7134 (clobber (reg:CC FLAGS_REG))])]
7135 "TARGET_QIMODE_MATH"
7140 tmp0 = gen_reg_rtx (HImode);
7141 tmp1 = gen_reg_rtx (HImode);
7143 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7145 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7146 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7148 /* Extract remainder from AH. */
7149 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7150 insn = emit_move_insn (operands[3], tmp1);
7152 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7153 set_unique_reg_note (insn, REG_EQUAL, mod);
7155 /* Extract quotient from AL. */
7156 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7158 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7159 set_unique_reg_note (insn, REG_EQUAL, div);
7164 ;; Divide AX by r/m8, with result stored in
7167 ;; Change div/mod to HImode and extend the second argument to HImode
7168 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7169 ;; combine may fail.
7170 (define_insn "divmodhiqi3"
7171 [(set (match_operand:HI 0 "register_operand" "=a")
7176 (mod:HI (match_operand:HI 1 "register_operand" "0")
7178 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7182 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7183 (clobber (reg:CC FLAGS_REG))]
7184 "TARGET_QIMODE_MATH"
7186 [(set_attr "type" "idiv")
7187 (set_attr "mode" "QI")])
7189 (define_expand "udivmod<mode>4"
7190 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7192 (match_operand:SWIM248 1 "register_operand" "")
7193 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7194 (set (match_operand:SWIM248 3 "register_operand" "")
7195 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7196 (clobber (reg:CC FLAGS_REG))])])
7198 ;; Split with 8bit unsigned divide:
7199 ;; if (dividend an divisor are in [0-255])
7200 ;; use 8bit unsigned integer divide
7202 ;; use original integer divide
7204 [(set (match_operand:SWI48 0 "register_operand" "")
7205 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7206 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7207 (set (match_operand:SWI48 1 "register_operand" "")
7208 (umod:SWI48 (match_dup 2) (match_dup 3)))
7209 (clobber (reg:CC FLAGS_REG))]
7210 "TARGET_USE_8BIT_IDIV
7211 && TARGET_QIMODE_MATH
7212 && can_create_pseudo_p ()
7213 && !optimize_insn_for_size_p ()"
7215 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7217 (define_insn_and_split "udivmod<mode>4_1"
7218 [(set (match_operand:SWI48 0 "register_operand" "=a")
7219 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7220 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7221 (set (match_operand:SWI48 1 "register_operand" "=&d")
7222 (umod:SWI48 (match_dup 2) (match_dup 3)))
7223 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7224 (clobber (reg:CC FLAGS_REG))]
7228 [(set (match_dup 1) (const_int 0))
7229 (parallel [(set (match_dup 0)
7230 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7232 (umod:SWI48 (match_dup 2) (match_dup 3)))
7234 (clobber (reg:CC FLAGS_REG))])]
7236 [(set_attr "type" "multi")
7237 (set_attr "mode" "<MODE>")])
7239 (define_insn_and_split "*udivmod<mode>4"
7240 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7241 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7242 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7243 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7244 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7245 (clobber (reg:CC FLAGS_REG))]
7249 [(set (match_dup 1) (const_int 0))
7250 (parallel [(set (match_dup 0)
7251 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7253 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7255 (clobber (reg:CC FLAGS_REG))])]
7257 [(set_attr "type" "multi")
7258 (set_attr "mode" "<MODE>")])
7260 (define_insn "*udivmod<mode>4_noext"
7261 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7262 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7263 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7264 (set (match_operand:SWIM248 1 "register_operand" "=d")
7265 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7266 (use (match_operand:SWIM248 4 "register_operand" "1"))
7267 (clobber (reg:CC FLAGS_REG))]
7269 "div{<imodesuffix>}\t%3"
7270 [(set_attr "type" "idiv")
7271 (set_attr "mode" "<MODE>")])
7273 (define_expand "udivmodqi4"
7274 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7276 (match_operand:QI 1 "register_operand" "")
7277 (match_operand:QI 2 "nonimmediate_operand" "")))
7278 (set (match_operand:QI 3 "register_operand" "")
7279 (umod:QI (match_dup 1) (match_dup 2)))
7280 (clobber (reg:CC FLAGS_REG))])]
7281 "TARGET_QIMODE_MATH"
7286 tmp0 = gen_reg_rtx (HImode);
7287 tmp1 = gen_reg_rtx (HImode);
7289 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7291 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7292 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7294 /* Extract remainder from AH. */
7295 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7296 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7297 insn = emit_move_insn (operands[3], tmp1);
7299 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7300 set_unique_reg_note (insn, REG_EQUAL, mod);
7302 /* Extract quotient from AL. */
7303 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7305 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7306 set_unique_reg_note (insn, REG_EQUAL, div);
7311 (define_insn "udivmodhiqi3"
7312 [(set (match_operand:HI 0 "register_operand" "=a")
7317 (mod:HI (match_operand:HI 1 "register_operand" "0")
7319 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7323 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7324 (clobber (reg:CC FLAGS_REG))]
7325 "TARGET_QIMODE_MATH"
7327 [(set_attr "type" "idiv")
7328 (set_attr "mode" "QI")])
7330 ;; We cannot use div/idiv for double division, because it causes
7331 ;; "division by zero" on the overflow and that's not what we expect
7332 ;; from truncate. Because true (non truncating) double division is
7333 ;; never generated, we can't create this insn anyway.
7336 ; [(set (match_operand:SI 0 "register_operand" "=a")
7338 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7340 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7341 ; (set (match_operand:SI 3 "register_operand" "=d")
7343 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7344 ; (clobber (reg:CC FLAGS_REG))]
7346 ; "div{l}\t{%2, %0|%0, %2}"
7347 ; [(set_attr "type" "idiv")])
7349 ;;- Logical AND instructions
7351 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7352 ;; Note that this excludes ah.
7354 (define_expand "testsi_ccno_1"
7355 [(set (reg:CCNO FLAGS_REG)
7357 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7358 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7361 (define_expand "testqi_ccz_1"
7362 [(set (reg:CCZ FLAGS_REG)
7363 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7364 (match_operand:QI 1 "nonmemory_operand" ""))
7367 (define_expand "testdi_ccno_1"
7368 [(set (reg:CCNO FLAGS_REG)
7370 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7371 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7373 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7375 (define_insn "*testdi_1"
7376 [(set (reg FLAGS_REG)
7379 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7380 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7382 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7383 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7385 test{l}\t{%k1, %k0|%k0, %k1}
7386 test{l}\t{%k1, %k0|%k0, %k1}
7387 test{q}\t{%1, %0|%0, %1}
7388 test{q}\t{%1, %0|%0, %1}
7389 test{q}\t{%1, %0|%0, %1}"
7390 [(set_attr "type" "test")
7391 (set_attr "modrm" "0,1,0,1,1")
7392 (set_attr "mode" "SI,SI,DI,DI,DI")])
7394 (define_insn "*testqi_1_maybe_si"
7395 [(set (reg FLAGS_REG)
7398 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7399 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7401 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7402 && ix86_match_ccmode (insn,
7403 CONST_INT_P (operands[1])
7404 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7406 if (which_alternative == 3)
7408 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7409 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7410 return "test{l}\t{%1, %k0|%k0, %1}";
7412 return "test{b}\t{%1, %0|%0, %1}";
7414 [(set_attr "type" "test")
7415 (set_attr "modrm" "0,1,1,1")
7416 (set_attr "mode" "QI,QI,QI,SI")
7417 (set_attr "pent_pair" "uv,np,uv,np")])
7419 (define_insn "*test<mode>_1"
7420 [(set (reg FLAGS_REG)
7423 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7424 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7426 "ix86_match_ccmode (insn, CCNOmode)
7427 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7428 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7429 [(set_attr "type" "test")
7430 (set_attr "modrm" "0,1,1")
7431 (set_attr "mode" "<MODE>")
7432 (set_attr "pent_pair" "uv,np,uv")])
7434 (define_expand "testqi_ext_ccno_0"
7435 [(set (reg:CCNO FLAGS_REG)
7439 (match_operand 0 "ext_register_operand" "")
7442 (match_operand 1 "const_int_operand" ""))
7445 (define_insn "*testqi_ext_0"
7446 [(set (reg FLAGS_REG)
7450 (match_operand 0 "ext_register_operand" "Q")
7453 (match_operand 1 "const_int_operand" "n"))
7455 "ix86_match_ccmode (insn, CCNOmode)"
7456 "test{b}\t{%1, %h0|%h0, %1}"
7457 [(set_attr "type" "test")
7458 (set_attr "mode" "QI")
7459 (set_attr "length_immediate" "1")
7460 (set_attr "modrm" "1")
7461 (set_attr "pent_pair" "np")])
7463 (define_insn "*testqi_ext_1_rex64"
7464 [(set (reg FLAGS_REG)
7468 (match_operand 0 "ext_register_operand" "Q")
7472 (match_operand:QI 1 "register_operand" "Q")))
7474 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7475 "test{b}\t{%1, %h0|%h0, %1}"
7476 [(set_attr "type" "test")
7477 (set_attr "mode" "QI")])
7479 (define_insn "*testqi_ext_1"
7480 [(set (reg FLAGS_REG)
7484 (match_operand 0 "ext_register_operand" "Q")
7488 (match_operand:QI 1 "general_operand" "Qm")))
7490 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7491 "test{b}\t{%1, %h0|%h0, %1}"
7492 [(set_attr "type" "test")
7493 (set_attr "mode" "QI")])
7495 (define_insn "*testqi_ext_2"
7496 [(set (reg FLAGS_REG)
7500 (match_operand 0 "ext_register_operand" "Q")
7504 (match_operand 1 "ext_register_operand" "Q")
7508 "ix86_match_ccmode (insn, CCNOmode)"
7509 "test{b}\t{%h1, %h0|%h0, %h1}"
7510 [(set_attr "type" "test")
7511 (set_attr "mode" "QI")])
7513 (define_insn "*testqi_ext_3_rex64"
7514 [(set (reg FLAGS_REG)
7515 (compare (zero_extract:DI
7516 (match_operand 0 "nonimmediate_operand" "rm")
7517 (match_operand:DI 1 "const_int_operand" "")
7518 (match_operand:DI 2 "const_int_operand" ""))
7521 && ix86_match_ccmode (insn, CCNOmode)
7522 && INTVAL (operands[1]) > 0
7523 && INTVAL (operands[2]) >= 0
7524 /* Ensure that resulting mask is zero or sign extended operand. */
7525 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7526 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7527 && INTVAL (operands[1]) > 32))
7528 && (GET_MODE (operands[0]) == SImode
7529 || GET_MODE (operands[0]) == DImode
7530 || GET_MODE (operands[0]) == HImode
7531 || GET_MODE (operands[0]) == QImode)"
7534 ;; Combine likes to form bit extractions for some tests. Humor it.
7535 (define_insn "*testqi_ext_3"
7536 [(set (reg FLAGS_REG)
7537 (compare (zero_extract:SI
7538 (match_operand 0 "nonimmediate_operand" "rm")
7539 (match_operand:SI 1 "const_int_operand" "")
7540 (match_operand:SI 2 "const_int_operand" ""))
7542 "ix86_match_ccmode (insn, CCNOmode)
7543 && INTVAL (operands[1]) > 0
7544 && INTVAL (operands[2]) >= 0
7545 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7546 && (GET_MODE (operands[0]) == SImode
7547 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7548 || GET_MODE (operands[0]) == HImode
7549 || GET_MODE (operands[0]) == QImode)"
7553 [(set (match_operand 0 "flags_reg_operand" "")
7554 (match_operator 1 "compare_operator"
7556 (match_operand 2 "nonimmediate_operand" "")
7557 (match_operand 3 "const_int_operand" "")
7558 (match_operand 4 "const_int_operand" ""))
7560 "ix86_match_ccmode (insn, CCNOmode)"
7561 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7563 rtx val = operands[2];
7564 HOST_WIDE_INT len = INTVAL (operands[3]);
7565 HOST_WIDE_INT pos = INTVAL (operands[4]);
7567 enum machine_mode mode, submode;
7569 mode = GET_MODE (val);
7572 /* ??? Combine likes to put non-volatile mem extractions in QImode
7573 no matter the size of the test. So find a mode that works. */
7574 if (! MEM_VOLATILE_P (val))
7576 mode = smallest_mode_for_size (pos + len, MODE_INT);
7577 val = adjust_address (val, mode, 0);
7580 else if (GET_CODE (val) == SUBREG
7581 && (submode = GET_MODE (SUBREG_REG (val)),
7582 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7583 && pos + len <= GET_MODE_BITSIZE (submode)
7584 && GET_MODE_CLASS (submode) == MODE_INT)
7586 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7588 val = SUBREG_REG (val);
7590 else if (mode == HImode && pos + len <= 8)
7592 /* Small HImode tests can be converted to QImode. */
7594 val = gen_lowpart (QImode, val);
7597 if (len == HOST_BITS_PER_WIDE_INT)
7600 mask = ((HOST_WIDE_INT)1 << len) - 1;
7603 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7606 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7607 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7608 ;; this is relatively important trick.
7609 ;; Do the conversion only post-reload to avoid limiting of the register class
7612 [(set (match_operand 0 "flags_reg_operand" "")
7613 (match_operator 1 "compare_operator"
7614 [(and (match_operand 2 "register_operand" "")
7615 (match_operand 3 "const_int_operand" ""))
7618 && QI_REG_P (operands[2])
7619 && GET_MODE (operands[2]) != QImode
7620 && ((ix86_match_ccmode (insn, CCZmode)
7621 && !(INTVAL (operands[3]) & ~(255 << 8)))
7622 || (ix86_match_ccmode (insn, CCNOmode)
7623 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7626 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7630 operands[2] = gen_lowpart (SImode, operands[2]);
7631 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7635 [(set (match_operand 0 "flags_reg_operand" "")
7636 (match_operator 1 "compare_operator"
7637 [(and (match_operand 2 "nonimmediate_operand" "")
7638 (match_operand 3 "const_int_operand" ""))
7641 && GET_MODE (operands[2]) != QImode
7642 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7643 && ((ix86_match_ccmode (insn, CCZmode)
7644 && !(INTVAL (operands[3]) & ~255))
7645 || (ix86_match_ccmode (insn, CCNOmode)
7646 && !(INTVAL (operands[3]) & ~127)))"
7648 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7651 operands[2] = gen_lowpart (QImode, operands[2]);
7652 operands[3] = gen_lowpart (QImode, operands[3]);
7655 ;; %%% This used to optimize known byte-wide and operations to memory,
7656 ;; and sometimes to QImode registers. If this is considered useful,
7657 ;; it should be done with splitters.
7659 (define_expand "and<mode>3"
7660 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7661 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7662 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7664 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7666 (define_insn "*anddi_1"
7667 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7669 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7670 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7671 (clobber (reg:CC FLAGS_REG))]
7672 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7674 switch (get_attr_type (insn))
7678 enum machine_mode mode;
7680 gcc_assert (CONST_INT_P (operands[2]));
7681 if (INTVAL (operands[2]) == 0xff)
7685 gcc_assert (INTVAL (operands[2]) == 0xffff);
7689 operands[1] = gen_lowpart (mode, operands[1]);
7691 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7693 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7697 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7698 if (get_attr_mode (insn) == MODE_SI)
7699 return "and{l}\t{%k2, %k0|%k0, %k2}";
7701 return "and{q}\t{%2, %0|%0, %2}";
7704 [(set_attr "type" "alu,alu,alu,imovx")
7705 (set_attr "length_immediate" "*,*,*,0")
7706 (set (attr "prefix_rex")
7708 (and (eq_attr "type" "imovx")
7709 (and (match_test "INTVAL (operands[2]) == 0xff")
7710 (match_operand 1 "ext_QIreg_operand" "")))
7712 (const_string "*")))
7713 (set_attr "mode" "SI,DI,DI,SI")])
7715 (define_insn "*andsi_1"
7716 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7717 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7718 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7719 (clobber (reg:CC FLAGS_REG))]
7720 "ix86_binary_operator_ok (AND, SImode, operands)"
7722 switch (get_attr_type (insn))
7726 enum machine_mode mode;
7728 gcc_assert (CONST_INT_P (operands[2]));
7729 if (INTVAL (operands[2]) == 0xff)
7733 gcc_assert (INTVAL (operands[2]) == 0xffff);
7737 operands[1] = gen_lowpart (mode, operands[1]);
7739 return "movz{bl|x}\t{%1, %0|%0, %1}";
7741 return "movz{wl|x}\t{%1, %0|%0, %1}";
7745 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7746 return "and{l}\t{%2, %0|%0, %2}";
7749 [(set_attr "type" "alu,alu,imovx")
7750 (set (attr "prefix_rex")
7752 (and (eq_attr "type" "imovx")
7753 (and (match_test "INTVAL (operands[2]) == 0xff")
7754 (match_operand 1 "ext_QIreg_operand" "")))
7756 (const_string "*")))
7757 (set_attr "length_immediate" "*,*,0")
7758 (set_attr "mode" "SI")])
7760 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7761 (define_insn "*andsi_1_zext"
7762 [(set (match_operand:DI 0 "register_operand" "=r")
7764 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7765 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7766 (clobber (reg:CC FLAGS_REG))]
7767 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7768 "and{l}\t{%2, %k0|%k0, %2}"
7769 [(set_attr "type" "alu")
7770 (set_attr "mode" "SI")])
7772 (define_insn "*andhi_1"
7773 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7774 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7775 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7776 (clobber (reg:CC FLAGS_REG))]
7777 "ix86_binary_operator_ok (AND, HImode, operands)"
7779 switch (get_attr_type (insn))
7782 gcc_assert (CONST_INT_P (operands[2]));
7783 gcc_assert (INTVAL (operands[2]) == 0xff);
7784 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7787 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7789 return "and{w}\t{%2, %0|%0, %2}";
7792 [(set_attr "type" "alu,alu,imovx")
7793 (set_attr "length_immediate" "*,*,0")
7794 (set (attr "prefix_rex")
7796 (and (eq_attr "type" "imovx")
7797 (match_operand 1 "ext_QIreg_operand" ""))
7799 (const_string "*")))
7800 (set_attr "mode" "HI,HI,SI")])
7802 ;; %%% Potential partial reg stall on alternative 2. What to do?
7803 (define_insn "*andqi_1"
7804 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7805 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7806 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7807 (clobber (reg:CC FLAGS_REG))]
7808 "ix86_binary_operator_ok (AND, QImode, operands)"
7810 and{b}\t{%2, %0|%0, %2}
7811 and{b}\t{%2, %0|%0, %2}
7812 and{l}\t{%k2, %k0|%k0, %k2}"
7813 [(set_attr "type" "alu")
7814 (set_attr "mode" "QI,QI,SI")])
7816 (define_insn "*andqi_1_slp"
7817 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7818 (and:QI (match_dup 0)
7819 (match_operand:QI 1 "general_operand" "qn,qmn")))
7820 (clobber (reg:CC FLAGS_REG))]
7821 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7822 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7823 "and{b}\t{%1, %0|%0, %1}"
7824 [(set_attr "type" "alu1")
7825 (set_attr "mode" "QI")])
7828 [(set (match_operand 0 "register_operand" "")
7830 (const_int -65536)))
7831 (clobber (reg:CC FLAGS_REG))]
7832 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7833 || optimize_function_for_size_p (cfun)"
7834 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7835 "operands[1] = gen_lowpart (HImode, operands[0]);")
7838 [(set (match_operand 0 "ext_register_operand" "")
7841 (clobber (reg:CC FLAGS_REG))]
7842 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7843 && reload_completed"
7844 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7845 "operands[1] = gen_lowpart (QImode, operands[0]);")
7848 [(set (match_operand 0 "ext_register_operand" "")
7850 (const_int -65281)))
7851 (clobber (reg:CC FLAGS_REG))]
7852 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7853 && reload_completed"
7854 [(parallel [(set (zero_extract:SI (match_dup 0)
7858 (zero_extract:SI (match_dup 0)
7861 (zero_extract:SI (match_dup 0)
7864 (clobber (reg:CC FLAGS_REG))])]
7865 "operands[0] = gen_lowpart (SImode, operands[0]);")
7867 (define_insn "*anddi_2"
7868 [(set (reg FLAGS_REG)
7871 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7872 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7874 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7875 (and:DI (match_dup 1) (match_dup 2)))]
7876 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7877 && ix86_binary_operator_ok (AND, DImode, operands)"
7879 and{l}\t{%k2, %k0|%k0, %k2}
7880 and{q}\t{%2, %0|%0, %2}
7881 and{q}\t{%2, %0|%0, %2}"
7882 [(set_attr "type" "alu")
7883 (set_attr "mode" "SI,DI,DI")])
7885 (define_insn "*andqi_2_maybe_si"
7886 [(set (reg FLAGS_REG)
7888 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7889 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7891 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7892 (and:QI (match_dup 1) (match_dup 2)))]
7893 "ix86_binary_operator_ok (AND, QImode, operands)
7894 && ix86_match_ccmode (insn,
7895 CONST_INT_P (operands[2])
7896 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7898 if (which_alternative == 2)
7900 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7901 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7902 return "and{l}\t{%2, %k0|%k0, %2}";
7904 return "and{b}\t{%2, %0|%0, %2}";
7906 [(set_attr "type" "alu")
7907 (set_attr "mode" "QI,QI,SI")])
7909 (define_insn "*and<mode>_2"
7910 [(set (reg FLAGS_REG)
7911 (compare (and:SWI124
7912 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7913 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7915 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7916 (and:SWI124 (match_dup 1) (match_dup 2)))]
7917 "ix86_match_ccmode (insn, CCNOmode)
7918 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7919 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7920 [(set_attr "type" "alu")
7921 (set_attr "mode" "<MODE>")])
7923 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7924 (define_insn "*andsi_2_zext"
7925 [(set (reg FLAGS_REG)
7927 (match_operand:SI 1 "nonimmediate_operand" "%0")
7928 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7930 (set (match_operand:DI 0 "register_operand" "=r")
7931 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7932 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7933 && ix86_binary_operator_ok (AND, SImode, operands)"
7934 "and{l}\t{%2, %k0|%k0, %2}"
7935 [(set_attr "type" "alu")
7936 (set_attr "mode" "SI")])
7938 (define_insn "*andqi_2_slp"
7939 [(set (reg FLAGS_REG)
7941 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7942 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7944 (set (strict_low_part (match_dup 0))
7945 (and:QI (match_dup 0) (match_dup 1)))]
7946 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7947 && ix86_match_ccmode (insn, CCNOmode)
7948 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7949 "and{b}\t{%1, %0|%0, %1}"
7950 [(set_attr "type" "alu1")
7951 (set_attr "mode" "QI")])
7953 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7954 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7955 ;; for a QImode operand, which of course failed.
7956 (define_insn "andqi_ext_0"
7957 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7962 (match_operand 1 "ext_register_operand" "0")
7965 (match_operand 2 "const_int_operand" "n")))
7966 (clobber (reg:CC FLAGS_REG))]
7968 "and{b}\t{%2, %h0|%h0, %2}"
7969 [(set_attr "type" "alu")
7970 (set_attr "length_immediate" "1")
7971 (set_attr "modrm" "1")
7972 (set_attr "mode" "QI")])
7974 ;; Generated by peephole translating test to and. This shows up
7975 ;; often in fp comparisons.
7976 (define_insn "*andqi_ext_0_cc"
7977 [(set (reg FLAGS_REG)
7981 (match_operand 1 "ext_register_operand" "0")
7984 (match_operand 2 "const_int_operand" "n"))
7986 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7995 "ix86_match_ccmode (insn, CCNOmode)"
7996 "and{b}\t{%2, %h0|%h0, %2}"
7997 [(set_attr "type" "alu")
7998 (set_attr "length_immediate" "1")
7999 (set_attr "modrm" "1")
8000 (set_attr "mode" "QI")])
8002 (define_insn "*andqi_ext_1_rex64"
8003 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8008 (match_operand 1 "ext_register_operand" "0")
8012 (match_operand 2 "ext_register_operand" "Q"))))
8013 (clobber (reg:CC FLAGS_REG))]
8015 "and{b}\t{%2, %h0|%h0, %2}"
8016 [(set_attr "type" "alu")
8017 (set_attr "length_immediate" "0")
8018 (set_attr "mode" "QI")])
8020 (define_insn "*andqi_ext_1"
8021 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8026 (match_operand 1 "ext_register_operand" "0")
8030 (match_operand:QI 2 "general_operand" "Qm"))))
8031 (clobber (reg:CC FLAGS_REG))]
8033 "and{b}\t{%2, %h0|%h0, %2}"
8034 [(set_attr "type" "alu")
8035 (set_attr "length_immediate" "0")
8036 (set_attr "mode" "QI")])
8038 (define_insn "*andqi_ext_2"
8039 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8044 (match_operand 1 "ext_register_operand" "%0")
8048 (match_operand 2 "ext_register_operand" "Q")
8051 (clobber (reg:CC FLAGS_REG))]
8053 "and{b}\t{%h2, %h0|%h0, %h2}"
8054 [(set_attr "type" "alu")
8055 (set_attr "length_immediate" "0")
8056 (set_attr "mode" "QI")])
8058 ;; Convert wide AND instructions with immediate operand to shorter QImode
8059 ;; equivalents when possible.
8060 ;; Don't do the splitting with memory operands, since it introduces risk
8061 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8062 ;; for size, but that can (should?) be handled by generic code instead.
8064 [(set (match_operand 0 "register_operand" "")
8065 (and (match_operand 1 "register_operand" "")
8066 (match_operand 2 "const_int_operand" "")))
8067 (clobber (reg:CC FLAGS_REG))]
8069 && QI_REG_P (operands[0])
8070 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8071 && !(~INTVAL (operands[2]) & ~(255 << 8))
8072 && GET_MODE (operands[0]) != QImode"
8073 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8074 (and:SI (zero_extract:SI (match_dup 1)
8075 (const_int 8) (const_int 8))
8077 (clobber (reg:CC FLAGS_REG))])]
8079 operands[0] = gen_lowpart (SImode, operands[0]);
8080 operands[1] = gen_lowpart (SImode, operands[1]);
8081 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8084 ;; Since AND can be encoded with sign extended immediate, this is only
8085 ;; profitable when 7th bit is not set.
8087 [(set (match_operand 0 "register_operand" "")
8088 (and (match_operand 1 "general_operand" "")
8089 (match_operand 2 "const_int_operand" "")))
8090 (clobber (reg:CC FLAGS_REG))]
8092 && ANY_QI_REG_P (operands[0])
8093 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8094 && !(~INTVAL (operands[2]) & ~255)
8095 && !(INTVAL (operands[2]) & 128)
8096 && GET_MODE (operands[0]) != QImode"
8097 [(parallel [(set (strict_low_part (match_dup 0))
8098 (and:QI (match_dup 1)
8100 (clobber (reg:CC FLAGS_REG))])]
8102 operands[0] = gen_lowpart (QImode, operands[0]);
8103 operands[1] = gen_lowpart (QImode, operands[1]);
8104 operands[2] = gen_lowpart (QImode, operands[2]);
8107 ;; Logical inclusive and exclusive OR instructions
8109 ;; %%% This used to optimize known byte-wide and operations to memory.
8110 ;; If this is considered useful, it should be done with splitters.
8112 (define_expand "<code><mode>3"
8113 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8114 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8115 (match_operand:SWIM 2 "<general_operand>" "")))]
8117 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8119 (define_insn "*<code><mode>_1"
8120 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8122 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8123 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8124 (clobber (reg:CC FLAGS_REG))]
8125 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8126 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8127 [(set_attr "type" "alu")
8128 (set_attr "mode" "<MODE>")])
8130 ;; %%% Potential partial reg stall on alternative 2. What to do?
8131 (define_insn "*<code>qi_1"
8132 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8133 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8134 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8135 (clobber (reg:CC FLAGS_REG))]
8136 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8138 <logic>{b}\t{%2, %0|%0, %2}
8139 <logic>{b}\t{%2, %0|%0, %2}
8140 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8141 [(set_attr "type" "alu")
8142 (set_attr "mode" "QI,QI,SI")])
8144 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8145 (define_insn "*<code>si_1_zext"
8146 [(set (match_operand:DI 0 "register_operand" "=r")
8148 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8149 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8150 (clobber (reg:CC FLAGS_REG))]
8151 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8152 "<logic>{l}\t{%2, %k0|%k0, %2}"
8153 [(set_attr "type" "alu")
8154 (set_attr "mode" "SI")])
8156 (define_insn "*<code>si_1_zext_imm"
8157 [(set (match_operand:DI 0 "register_operand" "=r")
8159 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8160 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8161 (clobber (reg:CC FLAGS_REG))]
8162 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8163 "<logic>{l}\t{%2, %k0|%k0, %2}"
8164 [(set_attr "type" "alu")
8165 (set_attr "mode" "SI")])
8167 (define_insn "*<code>qi_1_slp"
8168 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8169 (any_or:QI (match_dup 0)
8170 (match_operand:QI 1 "general_operand" "qmn,qn")))
8171 (clobber (reg:CC FLAGS_REG))]
8172 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8173 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8174 "<logic>{b}\t{%1, %0|%0, %1}"
8175 [(set_attr "type" "alu1")
8176 (set_attr "mode" "QI")])
8178 (define_insn "*<code><mode>_2"
8179 [(set (reg FLAGS_REG)
8180 (compare (any_or:SWI
8181 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8182 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8184 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8185 (any_or:SWI (match_dup 1) (match_dup 2)))]
8186 "ix86_match_ccmode (insn, CCNOmode)
8187 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8188 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8189 [(set_attr "type" "alu")
8190 (set_attr "mode" "<MODE>")])
8192 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8193 ;; ??? Special case for immediate operand is missing - it is tricky.
8194 (define_insn "*<code>si_2_zext"
8195 [(set (reg FLAGS_REG)
8196 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8197 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8199 (set (match_operand:DI 0 "register_operand" "=r")
8200 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8201 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8202 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8203 "<logic>{l}\t{%2, %k0|%k0, %2}"
8204 [(set_attr "type" "alu")
8205 (set_attr "mode" "SI")])
8207 (define_insn "*<code>si_2_zext_imm"
8208 [(set (reg FLAGS_REG)
8210 (match_operand:SI 1 "nonimmediate_operand" "%0")
8211 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8213 (set (match_operand:DI 0 "register_operand" "=r")
8214 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8215 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8216 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8217 "<logic>{l}\t{%2, %k0|%k0, %2}"
8218 [(set_attr "type" "alu")
8219 (set_attr "mode" "SI")])
8221 (define_insn "*<code>qi_2_slp"
8222 [(set (reg FLAGS_REG)
8223 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8224 (match_operand:QI 1 "general_operand" "qmn,qn"))
8226 (set (strict_low_part (match_dup 0))
8227 (any_or:QI (match_dup 0) (match_dup 1)))]
8228 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8229 && ix86_match_ccmode (insn, CCNOmode)
8230 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8231 "<logic>{b}\t{%1, %0|%0, %1}"
8232 [(set_attr "type" "alu1")
8233 (set_attr "mode" "QI")])
8235 (define_insn "*<code><mode>_3"
8236 [(set (reg FLAGS_REG)
8237 (compare (any_or:SWI
8238 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8239 (match_operand:SWI 2 "<general_operand>" "<g>"))
8241 (clobber (match_scratch:SWI 0 "=<r>"))]
8242 "ix86_match_ccmode (insn, CCNOmode)
8243 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8244 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8245 [(set_attr "type" "alu")
8246 (set_attr "mode" "<MODE>")])
8248 (define_insn "*<code>qi_ext_0"
8249 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8254 (match_operand 1 "ext_register_operand" "0")
8257 (match_operand 2 "const_int_operand" "n")))
8258 (clobber (reg:CC FLAGS_REG))]
8259 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8260 "<logic>{b}\t{%2, %h0|%h0, %2}"
8261 [(set_attr "type" "alu")
8262 (set_attr "length_immediate" "1")
8263 (set_attr "modrm" "1")
8264 (set_attr "mode" "QI")])
8266 (define_insn "*<code>qi_ext_1_rex64"
8267 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8272 (match_operand 1 "ext_register_operand" "0")
8276 (match_operand 2 "ext_register_operand" "Q"))))
8277 (clobber (reg:CC FLAGS_REG))]
8279 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8280 "<logic>{b}\t{%2, %h0|%h0, %2}"
8281 [(set_attr "type" "alu")
8282 (set_attr "length_immediate" "0")
8283 (set_attr "mode" "QI")])
8285 (define_insn "*<code>qi_ext_1"
8286 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8291 (match_operand 1 "ext_register_operand" "0")
8295 (match_operand:QI 2 "general_operand" "Qm"))))
8296 (clobber (reg:CC FLAGS_REG))]
8298 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8299 "<logic>{b}\t{%2, %h0|%h0, %2}"
8300 [(set_attr "type" "alu")
8301 (set_attr "length_immediate" "0")
8302 (set_attr "mode" "QI")])
8304 (define_insn "*<code>qi_ext_2"
8305 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8309 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8312 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8315 (clobber (reg:CC FLAGS_REG))]
8316 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8317 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8318 [(set_attr "type" "alu")
8319 (set_attr "length_immediate" "0")
8320 (set_attr "mode" "QI")])
8323 [(set (match_operand 0 "register_operand" "")
8324 (any_or (match_operand 1 "register_operand" "")
8325 (match_operand 2 "const_int_operand" "")))
8326 (clobber (reg:CC FLAGS_REG))]
8328 && QI_REG_P (operands[0])
8329 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8330 && !(INTVAL (operands[2]) & ~(255 << 8))
8331 && GET_MODE (operands[0]) != QImode"
8332 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8333 (any_or:SI (zero_extract:SI (match_dup 1)
8334 (const_int 8) (const_int 8))
8336 (clobber (reg:CC FLAGS_REG))])]
8338 operands[0] = gen_lowpart (SImode, operands[0]);
8339 operands[1] = gen_lowpart (SImode, operands[1]);
8340 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8343 ;; Since OR can be encoded with sign extended immediate, this is only
8344 ;; profitable when 7th bit is set.
8346 [(set (match_operand 0 "register_operand" "")
8347 (any_or (match_operand 1 "general_operand" "")
8348 (match_operand 2 "const_int_operand" "")))
8349 (clobber (reg:CC FLAGS_REG))]
8351 && ANY_QI_REG_P (operands[0])
8352 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8353 && !(INTVAL (operands[2]) & ~255)
8354 && (INTVAL (operands[2]) & 128)
8355 && GET_MODE (operands[0]) != QImode"
8356 [(parallel [(set (strict_low_part (match_dup 0))
8357 (any_or:QI (match_dup 1)
8359 (clobber (reg:CC FLAGS_REG))])]
8361 operands[0] = gen_lowpart (QImode, operands[0]);
8362 operands[1] = gen_lowpart (QImode, operands[1]);
8363 operands[2] = gen_lowpart (QImode, operands[2]);
8366 (define_expand "xorqi_cc_ext_1"
8368 (set (reg:CCNO FLAGS_REG)
8372 (match_operand 1 "ext_register_operand" "")
8375 (match_operand:QI 2 "general_operand" ""))
8377 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8387 (define_insn "*xorqi_cc_ext_1_rex64"
8388 [(set (reg FLAGS_REG)
8392 (match_operand 1 "ext_register_operand" "0")
8395 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8397 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8406 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8407 "xor{b}\t{%2, %h0|%h0, %2}"
8408 [(set_attr "type" "alu")
8409 (set_attr "modrm" "1")
8410 (set_attr "mode" "QI")])
8412 (define_insn "*xorqi_cc_ext_1"
8413 [(set (reg FLAGS_REG)
8417 (match_operand 1 "ext_register_operand" "0")
8420 (match_operand:QI 2 "general_operand" "qmn"))
8422 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8431 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8432 "xor{b}\t{%2, %h0|%h0, %2}"
8433 [(set_attr "type" "alu")
8434 (set_attr "modrm" "1")
8435 (set_attr "mode" "QI")])
8437 ;; Negation instructions
8439 (define_expand "neg<mode>2"
8440 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8441 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8443 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8445 (define_insn_and_split "*neg<dwi>2_doubleword"
8446 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8447 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8448 (clobber (reg:CC FLAGS_REG))]
8449 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8453 [(set (reg:CCZ FLAGS_REG)
8454 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8455 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8458 (plus:DWIH (match_dup 3)
8459 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8461 (clobber (reg:CC FLAGS_REG))])
8464 (neg:DWIH (match_dup 2)))
8465 (clobber (reg:CC FLAGS_REG))])]
8466 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8468 (define_insn "*neg<mode>2_1"
8469 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8470 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8471 (clobber (reg:CC FLAGS_REG))]
8472 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8473 "neg{<imodesuffix>}\t%0"
8474 [(set_attr "type" "negnot")
8475 (set_attr "mode" "<MODE>")])
8477 ;; Combine is quite creative about this pattern.
8478 (define_insn "*negsi2_1_zext"
8479 [(set (match_operand:DI 0 "register_operand" "=r")
8481 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8484 (clobber (reg:CC FLAGS_REG))]
8485 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8487 [(set_attr "type" "negnot")
8488 (set_attr "mode" "SI")])
8490 ;; The problem with neg is that it does not perform (compare x 0),
8491 ;; it really performs (compare 0 x), which leaves us with the zero
8492 ;; flag being the only useful item.
8494 (define_insn "*neg<mode>2_cmpz"
8495 [(set (reg:CCZ FLAGS_REG)
8497 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8499 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8500 (neg:SWI (match_dup 1)))]
8501 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8502 "neg{<imodesuffix>}\t%0"
8503 [(set_attr "type" "negnot")
8504 (set_attr "mode" "<MODE>")])
8506 (define_insn "*negsi2_cmpz_zext"
8507 [(set (reg:CCZ FLAGS_REG)
8511 (match_operand:DI 1 "register_operand" "0")
8515 (set (match_operand:DI 0 "register_operand" "=r")
8516 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8519 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8521 [(set_attr "type" "negnot")
8522 (set_attr "mode" "SI")])
8524 ;; Changing of sign for FP values is doable using integer unit too.
8526 (define_expand "<code><mode>2"
8527 [(set (match_operand:X87MODEF 0 "register_operand" "")
8528 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8529 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8530 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8532 (define_insn "*absneg<mode>2_mixed"
8533 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8534 (match_operator:MODEF 3 "absneg_operator"
8535 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8536 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8537 (clobber (reg:CC FLAGS_REG))]
8538 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8541 (define_insn "*absneg<mode>2_sse"
8542 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8543 (match_operator:MODEF 3 "absneg_operator"
8544 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8545 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8546 (clobber (reg:CC FLAGS_REG))]
8547 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8550 (define_insn "*absneg<mode>2_i387"
8551 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8552 (match_operator:X87MODEF 3 "absneg_operator"
8553 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8554 (use (match_operand 2 "" ""))
8555 (clobber (reg:CC FLAGS_REG))]
8556 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8559 (define_expand "<code>tf2"
8560 [(set (match_operand:TF 0 "register_operand" "")
8561 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8563 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8565 (define_insn "*absnegtf2_sse"
8566 [(set (match_operand:TF 0 "register_operand" "=x,x")
8567 (match_operator:TF 3 "absneg_operator"
8568 [(match_operand:TF 1 "register_operand" "0,x")]))
8569 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8570 (clobber (reg:CC FLAGS_REG))]
8574 ;; Splitters for fp abs and neg.
8577 [(set (match_operand 0 "fp_register_operand" "")
8578 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8579 (use (match_operand 2 "" ""))
8580 (clobber (reg:CC FLAGS_REG))]
8582 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8585 [(set (match_operand 0 "register_operand" "")
8586 (match_operator 3 "absneg_operator"
8587 [(match_operand 1 "register_operand" "")]))
8588 (use (match_operand 2 "nonimmediate_operand" ""))
8589 (clobber (reg:CC FLAGS_REG))]
8590 "reload_completed && SSE_REG_P (operands[0])"
8591 [(set (match_dup 0) (match_dup 3))]
8593 enum machine_mode mode = GET_MODE (operands[0]);
8594 enum machine_mode vmode = GET_MODE (operands[2]);
8597 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8598 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8599 if (operands_match_p (operands[0], operands[2]))
8602 operands[1] = operands[2];
8605 if (GET_CODE (operands[3]) == ABS)
8606 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8608 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8613 [(set (match_operand:SF 0 "register_operand" "")
8614 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8615 (use (match_operand:V4SF 2 "" ""))
8616 (clobber (reg:CC FLAGS_REG))]
8618 [(parallel [(set (match_dup 0) (match_dup 1))
8619 (clobber (reg:CC FLAGS_REG))])]
8622 operands[0] = gen_lowpart (SImode, operands[0]);
8623 if (GET_CODE (operands[1]) == ABS)
8625 tmp = gen_int_mode (0x7fffffff, SImode);
8626 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8630 tmp = gen_int_mode (0x80000000, SImode);
8631 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8637 [(set (match_operand:DF 0 "register_operand" "")
8638 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8639 (use (match_operand 2 "" ""))
8640 (clobber (reg:CC FLAGS_REG))]
8642 [(parallel [(set (match_dup 0) (match_dup 1))
8643 (clobber (reg:CC FLAGS_REG))])]
8648 tmp = gen_lowpart (DImode, operands[0]);
8649 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8652 if (GET_CODE (operands[1]) == ABS)
8655 tmp = gen_rtx_NOT (DImode, tmp);
8659 operands[0] = gen_highpart (SImode, operands[0]);
8660 if (GET_CODE (operands[1]) == ABS)
8662 tmp = gen_int_mode (0x7fffffff, SImode);
8663 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8667 tmp = gen_int_mode (0x80000000, SImode);
8668 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8675 [(set (match_operand:XF 0 "register_operand" "")
8676 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8677 (use (match_operand 2 "" ""))
8678 (clobber (reg:CC FLAGS_REG))]
8680 [(parallel [(set (match_dup 0) (match_dup 1))
8681 (clobber (reg:CC FLAGS_REG))])]
8684 operands[0] = gen_rtx_REG (SImode,
8685 true_regnum (operands[0])
8686 + (TARGET_64BIT ? 1 : 2));
8687 if (GET_CODE (operands[1]) == ABS)
8689 tmp = GEN_INT (0x7fff);
8690 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8694 tmp = GEN_INT (0x8000);
8695 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8700 ;; Conditionalize these after reload. If they match before reload, we
8701 ;; lose the clobber and ability to use integer instructions.
8703 (define_insn "*<code><mode>2_1"
8704 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8705 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8707 && (reload_completed
8708 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8709 "f<absneg_mnemonic>"
8710 [(set_attr "type" "fsgn")
8711 (set_attr "mode" "<MODE>")])
8713 (define_insn "*<code>extendsfdf2"
8714 [(set (match_operand:DF 0 "register_operand" "=f")
8715 (absneg:DF (float_extend:DF
8716 (match_operand:SF 1 "register_operand" "0"))))]
8717 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8718 "f<absneg_mnemonic>"
8719 [(set_attr "type" "fsgn")
8720 (set_attr "mode" "DF")])
8722 (define_insn "*<code>extendsfxf2"
8723 [(set (match_operand:XF 0 "register_operand" "=f")
8724 (absneg:XF (float_extend:XF
8725 (match_operand:SF 1 "register_operand" "0"))))]
8727 "f<absneg_mnemonic>"
8728 [(set_attr "type" "fsgn")
8729 (set_attr "mode" "XF")])
8731 (define_insn "*<code>extenddfxf2"
8732 [(set (match_operand:XF 0 "register_operand" "=f")
8733 (absneg:XF (float_extend:XF
8734 (match_operand:DF 1 "register_operand" "0"))))]
8736 "f<absneg_mnemonic>"
8737 [(set_attr "type" "fsgn")
8738 (set_attr "mode" "XF")])
8740 ;; Copysign instructions
8742 (define_mode_iterator CSGNMODE [SF DF TF])
8743 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8745 (define_expand "copysign<mode>3"
8746 [(match_operand:CSGNMODE 0 "register_operand" "")
8747 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8748 (match_operand:CSGNMODE 2 "register_operand" "")]
8749 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8750 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8751 "ix86_expand_copysign (operands); DONE;")
8753 (define_insn_and_split "copysign<mode>3_const"
8754 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8756 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8757 (match_operand:CSGNMODE 2 "register_operand" "0")
8758 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8760 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8761 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8763 "&& reload_completed"
8765 "ix86_split_copysign_const (operands); DONE;")
8767 (define_insn "copysign<mode>3_var"
8768 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8770 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8771 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8772 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8773 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8775 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8776 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8777 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8781 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8783 [(match_operand:CSGNMODE 2 "register_operand" "")
8784 (match_operand:CSGNMODE 3 "register_operand" "")
8785 (match_operand:<CSGNVMODE> 4 "" "")
8786 (match_operand:<CSGNVMODE> 5 "" "")]
8788 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8789 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8790 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8791 && reload_completed"
8793 "ix86_split_copysign_var (operands); DONE;")
8795 ;; One complement instructions
8797 (define_expand "one_cmpl<mode>2"
8798 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8799 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8801 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8803 (define_insn "*one_cmpl<mode>2_1"
8804 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8805 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8806 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8807 "not{<imodesuffix>}\t%0"
8808 [(set_attr "type" "negnot")
8809 (set_attr "mode" "<MODE>")])
8811 ;; %%% Potential partial reg stall on alternative 1. What to do?
8812 (define_insn "*one_cmplqi2_1"
8813 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8814 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8815 "ix86_unary_operator_ok (NOT, QImode, operands)"
8819 [(set_attr "type" "negnot")
8820 (set_attr "mode" "QI,SI")])
8822 ;; ??? Currently never generated - xor is used instead.
8823 (define_insn "*one_cmplsi2_1_zext"
8824 [(set (match_operand:DI 0 "register_operand" "=r")
8826 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8827 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8829 [(set_attr "type" "negnot")
8830 (set_attr "mode" "SI")])
8832 (define_insn "*one_cmpl<mode>2_2"
8833 [(set (reg FLAGS_REG)
8834 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8836 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8837 (not:SWI (match_dup 1)))]
8838 "ix86_match_ccmode (insn, CCNOmode)
8839 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8841 [(set_attr "type" "alu1")
8842 (set_attr "mode" "<MODE>")])
8845 [(set (match_operand 0 "flags_reg_operand" "")
8846 (match_operator 2 "compare_operator"
8847 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8849 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8850 (not:SWI (match_dup 3)))]
8851 "ix86_match_ccmode (insn, CCNOmode)"
8852 [(parallel [(set (match_dup 0)
8853 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8856 (xor:SWI (match_dup 3) (const_int -1)))])])
8858 ;; ??? Currently never generated - xor is used instead.
8859 (define_insn "*one_cmplsi2_2_zext"
8860 [(set (reg FLAGS_REG)
8861 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8863 (set (match_operand:DI 0 "register_operand" "=r")
8864 (zero_extend:DI (not:SI (match_dup 1))))]
8865 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8866 && ix86_unary_operator_ok (NOT, SImode, operands)"
8868 [(set_attr "type" "alu1")
8869 (set_attr "mode" "SI")])
8872 [(set (match_operand 0 "flags_reg_operand" "")
8873 (match_operator 2 "compare_operator"
8874 [(not:SI (match_operand:SI 3 "register_operand" ""))
8876 (set (match_operand:DI 1 "register_operand" "")
8877 (zero_extend:DI (not:SI (match_dup 3))))]
8878 "ix86_match_ccmode (insn, CCNOmode)"
8879 [(parallel [(set (match_dup 0)
8880 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8883 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8885 ;; Shift instructions
8887 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8888 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8889 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8890 ;; from the assembler input.
8892 ;; This instruction shifts the target reg/mem as usual, but instead of
8893 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8894 ;; is a left shift double, bits are taken from the high order bits of
8895 ;; reg, else if the insn is a shift right double, bits are taken from the
8896 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8897 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8899 ;; Since sh[lr]d does not change the `reg' operand, that is done
8900 ;; separately, making all shifts emit pairs of shift double and normal
8901 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8902 ;; support a 63 bit shift, each shift where the count is in a reg expands
8903 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8905 ;; If the shift count is a constant, we need never emit more than one
8906 ;; shift pair, instead using moves and sign extension for counts greater
8909 (define_expand "ashl<mode>3"
8910 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8911 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8912 (match_operand:QI 2 "nonmemory_operand" "")))]
8914 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8916 (define_insn "*ashl<mode>3_doubleword"
8917 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8918 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8919 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8920 (clobber (reg:CC FLAGS_REG))]
8923 [(set_attr "type" "multi")])
8926 [(set (match_operand:DWI 0 "register_operand" "")
8927 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8928 (match_operand:QI 2 "nonmemory_operand" "")))
8929 (clobber (reg:CC FLAGS_REG))]
8930 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8932 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8934 ;; By default we don't ask for a scratch register, because when DWImode
8935 ;; values are manipulated, registers are already at a premium. But if
8936 ;; we have one handy, we won't turn it away.
8939 [(match_scratch:DWIH 3 "r")
8940 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8942 (match_operand:<DWI> 1 "nonmemory_operand" "")
8943 (match_operand:QI 2 "nonmemory_operand" "")))
8944 (clobber (reg:CC FLAGS_REG))])
8948 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8950 (define_insn "x86_64_shld"
8951 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8952 (ior:DI (ashift:DI (match_dup 0)
8953 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8954 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8955 (minus:QI (const_int 64) (match_dup 2)))))
8956 (clobber (reg:CC FLAGS_REG))]
8958 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8959 [(set_attr "type" "ishift")
8960 (set_attr "prefix_0f" "1")
8961 (set_attr "mode" "DI")
8962 (set_attr "athlon_decode" "vector")
8963 (set_attr "amdfam10_decode" "vector")
8964 (set_attr "bdver1_decode" "vector")])
8966 (define_insn "x86_shld"
8967 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8968 (ior:SI (ashift:SI (match_dup 0)
8969 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8970 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8971 (minus:QI (const_int 32) (match_dup 2)))))
8972 (clobber (reg:CC FLAGS_REG))]
8974 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8975 [(set_attr "type" "ishift")
8976 (set_attr "prefix_0f" "1")
8977 (set_attr "mode" "SI")
8978 (set_attr "pent_pair" "np")
8979 (set_attr "athlon_decode" "vector")
8980 (set_attr "amdfam10_decode" "vector")
8981 (set_attr "bdver1_decode" "vector")])
8983 (define_expand "x86_shift<mode>_adj_1"
8984 [(set (reg:CCZ FLAGS_REG)
8985 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8988 (set (match_operand:SWI48 0 "register_operand" "")
8989 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8990 (match_operand:SWI48 1 "register_operand" "")
8993 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8994 (match_operand:SWI48 3 "register_operand" "r")
8997 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8999 (define_expand "x86_shift<mode>_adj_2"
9000 [(use (match_operand:SWI48 0 "register_operand" ""))
9001 (use (match_operand:SWI48 1 "register_operand" ""))
9002 (use (match_operand:QI 2 "register_operand" ""))]
9005 rtx label = gen_label_rtx ();
9008 emit_insn (gen_testqi_ccz_1 (operands[2],
9009 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9011 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9012 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9013 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9014 gen_rtx_LABEL_REF (VOIDmode, label),
9016 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9017 JUMP_LABEL (tmp) = label;
9019 emit_move_insn (operands[0], operands[1]);
9020 ix86_expand_clear (operands[1]);
9023 LABEL_NUSES (label) = 1;
9028 ;; Avoid useless masking of count operand.
9029 (define_insn_and_split "*ashl<mode>3_mask"
9030 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9032 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9035 (match_operand:SI 2 "nonimmediate_operand" "c")
9036 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9037 (clobber (reg:CC FLAGS_REG))]
9038 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9039 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9040 == GET_MODE_BITSIZE (<MODE>mode)-1"
9043 [(parallel [(set (match_dup 0)
9044 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9045 (clobber (reg:CC FLAGS_REG))])]
9047 if (can_create_pseudo_p ())
9048 operands [2] = force_reg (SImode, operands[2]);
9050 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9052 [(set_attr "type" "ishift")
9053 (set_attr "mode" "<MODE>")])
9055 (define_insn "*bmi2_ashl<mode>3_1"
9056 [(set (match_operand:SWI48 0 "register_operand" "=r")
9057 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9058 (match_operand:SWI48 2 "register_operand" "r")))]
9060 "shlx\t{%2, %1, %0|%0, %1, %2}"
9061 [(set_attr "type" "ishiftx")
9062 (set_attr "mode" "<MODE>")])
9064 (define_insn "*ashl<mode>3_1"
9065 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9066 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9067 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9068 (clobber (reg:CC FLAGS_REG))]
9069 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9071 switch (get_attr_type (insn))
9078 gcc_assert (operands[2] == const1_rtx);
9079 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9080 return "add{<imodesuffix>}\t%0, %0";
9083 if (operands[2] == const1_rtx
9084 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9085 return "sal{<imodesuffix>}\t%0";
9087 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9090 [(set_attr "isa" "*,*,bmi2")
9092 (cond [(eq_attr "alternative" "1")
9093 (const_string "lea")
9094 (eq_attr "alternative" "2")
9095 (const_string "ishiftx")
9096 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9097 (match_operand 0 "register_operand" ""))
9098 (match_operand 2 "const1_operand" ""))
9099 (const_string "alu")
9101 (const_string "ishift")))
9102 (set (attr "length_immediate")
9104 (ior (eq_attr "type" "alu")
9105 (and (eq_attr "type" "ishift")
9106 (and (match_operand 2 "const1_operand" "")
9107 (ior (match_test "TARGET_SHIFT1")
9108 (match_test "optimize_function_for_size_p (cfun)")))))
9110 (const_string "*")))
9111 (set_attr "mode" "<MODE>")])
9113 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9115 [(set (match_operand:SWI48 0 "register_operand" "")
9116 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9117 (match_operand:QI 2 "register_operand" "")))
9118 (clobber (reg:CC FLAGS_REG))]
9119 "TARGET_BMI2 && reload_completed"
9121 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9122 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9124 (define_insn "*bmi2_ashlsi3_1_zext"
9125 [(set (match_operand:DI 0 "register_operand" "=r")
9127 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9128 (match_operand:SI 2 "register_operand" "r"))))]
9129 "TARGET_64BIT && TARGET_BMI2"
9130 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9131 [(set_attr "type" "ishiftx")
9132 (set_attr "mode" "SI")])
9134 (define_insn "*ashlsi3_1_zext"
9135 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9137 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9138 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9139 (clobber (reg:CC FLAGS_REG))]
9140 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9142 switch (get_attr_type (insn))
9149 gcc_assert (operands[2] == const1_rtx);
9150 return "add{l}\t%k0, %k0";
9153 if (operands[2] == const1_rtx
9154 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9155 return "sal{l}\t%k0";
9157 return "sal{l}\t{%2, %k0|%k0, %2}";
9160 [(set_attr "isa" "*,*,bmi2")
9162 (cond [(eq_attr "alternative" "1")
9163 (const_string "lea")
9164 (eq_attr "alternative" "2")
9165 (const_string "ishiftx")
9166 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9167 (match_operand 2 "const1_operand" ""))
9168 (const_string "alu")
9170 (const_string "ishift")))
9171 (set (attr "length_immediate")
9173 (ior (eq_attr "type" "alu")
9174 (and (eq_attr "type" "ishift")
9175 (and (match_operand 2 "const1_operand" "")
9176 (ior (match_test "TARGET_SHIFT1")
9177 (match_test "optimize_function_for_size_p (cfun)")))))
9179 (const_string "*")))
9180 (set_attr "mode" "SI")])
9182 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9184 [(set (match_operand:DI 0 "register_operand" "")
9186 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9187 (match_operand:QI 2 "register_operand" ""))))
9188 (clobber (reg:CC FLAGS_REG))]
9189 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9191 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9192 "operands[2] = gen_lowpart (SImode, operands[2]);")
9194 (define_insn "*ashlhi3_1"
9195 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9196 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9197 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9198 (clobber (reg:CC FLAGS_REG))]
9199 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9201 switch (get_attr_type (insn))
9207 gcc_assert (operands[2] == const1_rtx);
9208 return "add{w}\t%0, %0";
9211 if (operands[2] == const1_rtx
9212 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9213 return "sal{w}\t%0";
9215 return "sal{w}\t{%2, %0|%0, %2}";
9219 (cond [(eq_attr "alternative" "1")
9220 (const_string "lea")
9221 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9222 (match_operand 0 "register_operand" ""))
9223 (match_operand 2 "const1_operand" ""))
9224 (const_string "alu")
9226 (const_string "ishift")))
9227 (set (attr "length_immediate")
9229 (ior (eq_attr "type" "alu")
9230 (and (eq_attr "type" "ishift")
9231 (and (match_operand 2 "const1_operand" "")
9232 (ior (match_test "TARGET_SHIFT1")
9233 (match_test "optimize_function_for_size_p (cfun)")))))
9235 (const_string "*")))
9236 (set_attr "mode" "HI,SI")])
9238 ;; %%% Potential partial reg stall on alternative 1. What to do?
9239 (define_insn "*ashlqi3_1"
9240 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9241 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9242 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9243 (clobber (reg:CC FLAGS_REG))]
9244 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9246 switch (get_attr_type (insn))
9252 gcc_assert (operands[2] == const1_rtx);
9253 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9254 return "add{l}\t%k0, %k0";
9256 return "add{b}\t%0, %0";
9259 if (operands[2] == const1_rtx
9260 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9262 if (get_attr_mode (insn) == MODE_SI)
9263 return "sal{l}\t%k0";
9265 return "sal{b}\t%0";
9269 if (get_attr_mode (insn) == MODE_SI)
9270 return "sal{l}\t{%2, %k0|%k0, %2}";
9272 return "sal{b}\t{%2, %0|%0, %2}";
9277 (cond [(eq_attr "alternative" "2")
9278 (const_string "lea")
9279 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9280 (match_operand 0 "register_operand" ""))
9281 (match_operand 2 "const1_operand" ""))
9282 (const_string "alu")
9284 (const_string "ishift")))
9285 (set (attr "length_immediate")
9287 (ior (eq_attr "type" "alu")
9288 (and (eq_attr "type" "ishift")
9289 (and (match_operand 2 "const1_operand" "")
9290 (ior (match_test "TARGET_SHIFT1")
9291 (match_test "optimize_function_for_size_p (cfun)")))))
9293 (const_string "*")))
9294 (set_attr "mode" "QI,SI,SI")])
9296 (define_insn "*ashlqi3_1_slp"
9297 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9298 (ashift:QI (match_dup 0)
9299 (match_operand:QI 1 "nonmemory_operand" "cI")))
9300 (clobber (reg:CC FLAGS_REG))]
9301 "(optimize_function_for_size_p (cfun)
9302 || !TARGET_PARTIAL_FLAG_REG_STALL
9303 || (operands[1] == const1_rtx
9305 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9307 switch (get_attr_type (insn))
9310 gcc_assert (operands[1] == const1_rtx);
9311 return "add{b}\t%0, %0";
9314 if (operands[1] == const1_rtx
9315 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9316 return "sal{b}\t%0";
9318 return "sal{b}\t{%1, %0|%0, %1}";
9322 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9323 (match_operand 0 "register_operand" ""))
9324 (match_operand 1 "const1_operand" ""))
9325 (const_string "alu")
9327 (const_string "ishift1")))
9328 (set (attr "length_immediate")
9330 (ior (eq_attr "type" "alu")
9331 (and (eq_attr "type" "ishift1")
9332 (and (match_operand 1 "const1_operand" "")
9333 (ior (match_test "TARGET_SHIFT1")
9334 (match_test "optimize_function_for_size_p (cfun)")))))
9336 (const_string "*")))
9337 (set_attr "mode" "QI")])
9339 ;; Convert ashift to the lea pattern to avoid flags dependency.
9341 [(set (match_operand 0 "register_operand" "")
9342 (ashift (match_operand 1 "index_register_operand" "")
9343 (match_operand:QI 2 "const_int_operand" "")))
9344 (clobber (reg:CC FLAGS_REG))]
9345 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9347 && true_regnum (operands[0]) != true_regnum (operands[1])"
9350 enum machine_mode mode = GET_MODE (operands[0]);
9353 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9356 operands[0] = gen_lowpart (mode, operands[0]);
9357 operands[1] = gen_lowpart (mode, operands[1]);
9360 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9362 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9364 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9368 ;; Convert ashift to the lea pattern to avoid flags dependency.
9370 [(set (match_operand:DI 0 "register_operand" "")
9372 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9373 (match_operand:QI 2 "const_int_operand" ""))))
9374 (clobber (reg:CC FLAGS_REG))]
9375 "TARGET_64BIT && reload_completed
9376 && true_regnum (operands[0]) != true_regnum (operands[1])"
9378 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9380 operands[1] = gen_lowpart (DImode, operands[1]);
9381 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9384 ;; This pattern can't accept a variable shift count, since shifts by
9385 ;; zero don't affect the flags. We assume that shifts by constant
9386 ;; zero are optimized away.
9387 (define_insn "*ashl<mode>3_cmp"
9388 [(set (reg FLAGS_REG)
9390 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9391 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9393 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9394 (ashift:SWI (match_dup 1) (match_dup 2)))]
9395 "(optimize_function_for_size_p (cfun)
9396 || !TARGET_PARTIAL_FLAG_REG_STALL
9397 || (operands[2] == const1_rtx
9399 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9400 && ix86_match_ccmode (insn, CCGOCmode)
9401 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9403 switch (get_attr_type (insn))
9406 gcc_assert (operands[2] == const1_rtx);
9407 return "add{<imodesuffix>}\t%0, %0";
9410 if (operands[2] == const1_rtx
9411 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9412 return "sal{<imodesuffix>}\t%0";
9414 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9418 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9419 (match_operand 0 "register_operand" ""))
9420 (match_operand 2 "const1_operand" ""))
9421 (const_string "alu")
9423 (const_string "ishift")))
9424 (set (attr "length_immediate")
9426 (ior (eq_attr "type" "alu")
9427 (and (eq_attr "type" "ishift")
9428 (and (match_operand 2 "const1_operand" "")
9429 (ior (match_test "TARGET_SHIFT1")
9430 (match_test "optimize_function_for_size_p (cfun)")))))
9432 (const_string "*")))
9433 (set_attr "mode" "<MODE>")])
9435 (define_insn "*ashlsi3_cmp_zext"
9436 [(set (reg FLAGS_REG)
9438 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9439 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9441 (set (match_operand:DI 0 "register_operand" "=r")
9442 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9444 && (optimize_function_for_size_p (cfun)
9445 || !TARGET_PARTIAL_FLAG_REG_STALL
9446 || (operands[2] == const1_rtx
9448 || TARGET_DOUBLE_WITH_ADD)))
9449 && ix86_match_ccmode (insn, CCGOCmode)
9450 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9452 switch (get_attr_type (insn))
9455 gcc_assert (operands[2] == const1_rtx);
9456 return "add{l}\t%k0, %k0";
9459 if (operands[2] == const1_rtx
9460 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9461 return "sal{l}\t%k0";
9463 return "sal{l}\t{%2, %k0|%k0, %2}";
9467 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9468 (match_operand 2 "const1_operand" ""))
9469 (const_string "alu")
9471 (const_string "ishift")))
9472 (set (attr "length_immediate")
9474 (ior (eq_attr "type" "alu")
9475 (and (eq_attr "type" "ishift")
9476 (and (match_operand 2 "const1_operand" "")
9477 (ior (match_test "TARGET_SHIFT1")
9478 (match_test "optimize_function_for_size_p (cfun)")))))
9480 (const_string "*")))
9481 (set_attr "mode" "SI")])
9483 (define_insn "*ashl<mode>3_cconly"
9484 [(set (reg FLAGS_REG)
9486 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9487 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9489 (clobber (match_scratch:SWI 0 "=<r>"))]
9490 "(optimize_function_for_size_p (cfun)
9491 || !TARGET_PARTIAL_FLAG_REG_STALL
9492 || (operands[2] == const1_rtx
9494 || TARGET_DOUBLE_WITH_ADD)))
9495 && ix86_match_ccmode (insn, CCGOCmode)"
9497 switch (get_attr_type (insn))
9500 gcc_assert (operands[2] == const1_rtx);
9501 return "add{<imodesuffix>}\t%0, %0";
9504 if (operands[2] == const1_rtx
9505 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9506 return "sal{<imodesuffix>}\t%0";
9508 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9512 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9513 (match_operand 0 "register_operand" ""))
9514 (match_operand 2 "const1_operand" ""))
9515 (const_string "alu")
9517 (const_string "ishift")))
9518 (set (attr "length_immediate")
9520 (ior (eq_attr "type" "alu")
9521 (and (eq_attr "type" "ishift")
9522 (and (match_operand 2 "const1_operand" "")
9523 (ior (match_test "TARGET_SHIFT1")
9524 (match_test "optimize_function_for_size_p (cfun)")))))
9526 (const_string "*")))
9527 (set_attr "mode" "<MODE>")])
9529 ;; See comment above `ashl<mode>3' about how this works.
9531 (define_expand "<shift_insn><mode>3"
9532 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9533 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9534 (match_operand:QI 2 "nonmemory_operand" "")))]
9536 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9538 ;; Avoid useless masking of count operand.
9539 (define_insn_and_split "*<shift_insn><mode>3_mask"
9540 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9542 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9545 (match_operand:SI 2 "nonimmediate_operand" "c")
9546 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9547 (clobber (reg:CC FLAGS_REG))]
9548 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9549 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9550 == GET_MODE_BITSIZE (<MODE>mode)-1"
9553 [(parallel [(set (match_dup 0)
9554 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9555 (clobber (reg:CC FLAGS_REG))])]
9557 if (can_create_pseudo_p ())
9558 operands [2] = force_reg (SImode, operands[2]);
9560 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9562 [(set_attr "type" "ishift")
9563 (set_attr "mode" "<MODE>")])
9565 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9566 [(set (match_operand:DWI 0 "register_operand" "=r")
9567 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9568 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9569 (clobber (reg:CC FLAGS_REG))]
9572 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9574 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9575 [(set_attr "type" "multi")])
9577 ;; By default we don't ask for a scratch register, because when DWImode
9578 ;; values are manipulated, registers are already at a premium. But if
9579 ;; we have one handy, we won't turn it away.
9582 [(match_scratch:DWIH 3 "r")
9583 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9585 (match_operand:<DWI> 1 "register_operand" "")
9586 (match_operand:QI 2 "nonmemory_operand" "")))
9587 (clobber (reg:CC FLAGS_REG))])
9591 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9593 (define_insn "x86_64_shrd"
9594 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9595 (ior:DI (ashiftrt:DI (match_dup 0)
9596 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9597 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9598 (minus:QI (const_int 64) (match_dup 2)))))
9599 (clobber (reg:CC FLAGS_REG))]
9601 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9602 [(set_attr "type" "ishift")
9603 (set_attr "prefix_0f" "1")
9604 (set_attr "mode" "DI")
9605 (set_attr "athlon_decode" "vector")
9606 (set_attr "amdfam10_decode" "vector")
9607 (set_attr "bdver1_decode" "vector")])
9609 (define_insn "x86_shrd"
9610 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9611 (ior:SI (ashiftrt:SI (match_dup 0)
9612 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9613 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9614 (minus:QI (const_int 32) (match_dup 2)))))
9615 (clobber (reg:CC FLAGS_REG))]
9617 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9618 [(set_attr "type" "ishift")
9619 (set_attr "prefix_0f" "1")
9620 (set_attr "mode" "SI")
9621 (set_attr "pent_pair" "np")
9622 (set_attr "athlon_decode" "vector")
9623 (set_attr "amdfam10_decode" "vector")
9624 (set_attr "bdver1_decode" "vector")])
9626 (define_insn "ashrdi3_cvt"
9627 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9628 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9629 (match_operand:QI 2 "const_int_operand" "")))
9630 (clobber (reg:CC FLAGS_REG))]
9631 "TARGET_64BIT && INTVAL (operands[2]) == 63
9632 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9633 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9636 sar{q}\t{%2, %0|%0, %2}"
9637 [(set_attr "type" "imovx,ishift")
9638 (set_attr "prefix_0f" "0,*")
9639 (set_attr "length_immediate" "0,*")
9640 (set_attr "modrm" "0,1")
9641 (set_attr "mode" "DI")])
9643 (define_insn "ashrsi3_cvt"
9644 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9645 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9646 (match_operand:QI 2 "const_int_operand" "")))
9647 (clobber (reg:CC FLAGS_REG))]
9648 "INTVAL (operands[2]) == 31
9649 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9650 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9653 sar{l}\t{%2, %0|%0, %2}"
9654 [(set_attr "type" "imovx,ishift")
9655 (set_attr "prefix_0f" "0,*")
9656 (set_attr "length_immediate" "0,*")
9657 (set_attr "modrm" "0,1")
9658 (set_attr "mode" "SI")])
9660 (define_insn "*ashrsi3_cvt_zext"
9661 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9663 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9664 (match_operand:QI 2 "const_int_operand" ""))))
9665 (clobber (reg:CC FLAGS_REG))]
9666 "TARGET_64BIT && INTVAL (operands[2]) == 31
9667 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9668 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9671 sar{l}\t{%2, %k0|%k0, %2}"
9672 [(set_attr "type" "imovx,ishift")
9673 (set_attr "prefix_0f" "0,*")
9674 (set_attr "length_immediate" "0,*")
9675 (set_attr "modrm" "0,1")
9676 (set_attr "mode" "SI")])
9678 (define_expand "x86_shift<mode>_adj_3"
9679 [(use (match_operand:SWI48 0 "register_operand" ""))
9680 (use (match_operand:SWI48 1 "register_operand" ""))
9681 (use (match_operand:QI 2 "register_operand" ""))]
9684 rtx label = gen_label_rtx ();
9687 emit_insn (gen_testqi_ccz_1 (operands[2],
9688 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9690 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9691 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9692 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9693 gen_rtx_LABEL_REF (VOIDmode, label),
9695 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9696 JUMP_LABEL (tmp) = label;
9698 emit_move_insn (operands[0], operands[1]);
9699 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9700 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9702 LABEL_NUSES (label) = 1;
9707 (define_insn "*bmi2_<shift_insn><mode>3_1"
9708 [(set (match_operand:SWI48 0 "register_operand" "=r")
9709 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9710 (match_operand:SWI48 2 "register_operand" "r")))]
9712 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9713 [(set_attr "type" "ishiftx")
9714 (set_attr "mode" "<MODE>")])
9716 (define_insn "*<shift_insn><mode>3_1"
9717 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9719 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9720 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9721 (clobber (reg:CC FLAGS_REG))]
9722 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9724 switch (get_attr_type (insn))
9730 if (operands[2] == const1_rtx
9731 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9732 return "<shift>{<imodesuffix>}\t%0";
9734 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9737 [(set_attr "isa" "*,bmi2")
9738 (set_attr "type" "ishift,ishiftx")
9739 (set (attr "length_immediate")
9741 (and (match_operand 2 "const1_operand" "")
9742 (ior (match_test "TARGET_SHIFT1")
9743 (match_test "optimize_function_for_size_p (cfun)")))
9745 (const_string "*")))
9746 (set_attr "mode" "<MODE>")])
9748 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9750 [(set (match_operand:SWI48 0 "register_operand" "")
9751 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9752 (match_operand:QI 2 "register_operand" "")))
9753 (clobber (reg:CC FLAGS_REG))]
9754 "TARGET_BMI2 && reload_completed"
9756 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9757 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9759 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9760 [(set (match_operand:DI 0 "register_operand" "=r")
9762 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9763 (match_operand:SI 2 "register_operand" "r"))))]
9764 "TARGET_64BIT && TARGET_BMI2"
9765 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9766 [(set_attr "type" "ishiftx")
9767 (set_attr "mode" "SI")])
9769 (define_insn "*<shift_insn>si3_1_zext"
9770 [(set (match_operand:DI 0 "register_operand" "=r,r")
9772 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9773 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9774 (clobber (reg:CC FLAGS_REG))]
9775 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9777 switch (get_attr_type (insn))
9783 if (operands[2] == const1_rtx
9784 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9785 return "<shift>{l}\t%k0";
9787 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9790 [(set_attr "isa" "*,bmi2")
9791 (set_attr "type" "ishift,ishiftx")
9792 (set (attr "length_immediate")
9794 (and (match_operand 2 "const1_operand" "")
9795 (ior (match_test "TARGET_SHIFT1")
9796 (match_test "optimize_function_for_size_p (cfun)")))
9798 (const_string "*")))
9799 (set_attr "mode" "SI")])
9801 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9803 [(set (match_operand:DI 0 "register_operand" "")
9805 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9806 (match_operand:QI 2 "register_operand" ""))))
9807 (clobber (reg:CC FLAGS_REG))]
9808 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9810 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9811 "operands[2] = gen_lowpart (SImode, operands[2]);")
9813 (define_insn "*<shift_insn><mode>3_1"
9814 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9816 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9817 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9818 (clobber (reg:CC FLAGS_REG))]
9819 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9821 if (operands[2] == const1_rtx
9822 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9823 return "<shift>{<imodesuffix>}\t%0";
9825 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9827 [(set_attr "type" "ishift")
9828 (set (attr "length_immediate")
9830 (and (match_operand 2 "const1_operand" "")
9831 (ior (match_test "TARGET_SHIFT1")
9832 (match_test "optimize_function_for_size_p (cfun)")))
9834 (const_string "*")))
9835 (set_attr "mode" "<MODE>")])
9837 (define_insn "*<shift_insn>qi3_1_slp"
9838 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9839 (any_shiftrt:QI (match_dup 0)
9840 (match_operand:QI 1 "nonmemory_operand" "cI")))
9841 (clobber (reg:CC FLAGS_REG))]
9842 "(optimize_function_for_size_p (cfun)
9843 || !TARGET_PARTIAL_REG_STALL
9844 || (operands[1] == const1_rtx
9847 if (operands[1] == const1_rtx
9848 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9849 return "<shift>{b}\t%0";
9851 return "<shift>{b}\t{%1, %0|%0, %1}";
9853 [(set_attr "type" "ishift1")
9854 (set (attr "length_immediate")
9856 (and (match_operand 1 "const1_operand" "")
9857 (ior (match_test "TARGET_SHIFT1")
9858 (match_test "optimize_function_for_size_p (cfun)")))
9860 (const_string "*")))
9861 (set_attr "mode" "QI")])
9863 ;; This pattern can't accept a variable shift count, since shifts by
9864 ;; zero don't affect the flags. We assume that shifts by constant
9865 ;; zero are optimized away.
9866 (define_insn "*<shift_insn><mode>3_cmp"
9867 [(set (reg FLAGS_REG)
9870 (match_operand:SWI 1 "nonimmediate_operand" "0")
9871 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9873 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9874 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9875 "(optimize_function_for_size_p (cfun)
9876 || !TARGET_PARTIAL_FLAG_REG_STALL
9877 || (operands[2] == const1_rtx
9879 && ix86_match_ccmode (insn, CCGOCmode)
9880 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9882 if (operands[2] == const1_rtx
9883 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9884 return "<shift>{<imodesuffix>}\t%0";
9886 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9888 [(set_attr "type" "ishift")
9889 (set (attr "length_immediate")
9891 (and (match_operand 2 "const1_operand" "")
9892 (ior (match_test "TARGET_SHIFT1")
9893 (match_test "optimize_function_for_size_p (cfun)")))
9895 (const_string "*")))
9896 (set_attr "mode" "<MODE>")])
9898 (define_insn "*<shift_insn>si3_cmp_zext"
9899 [(set (reg FLAGS_REG)
9901 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9902 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9904 (set (match_operand:DI 0 "register_operand" "=r")
9905 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9907 && (optimize_function_for_size_p (cfun)
9908 || !TARGET_PARTIAL_FLAG_REG_STALL
9909 || (operands[2] == const1_rtx
9911 && ix86_match_ccmode (insn, CCGOCmode)
9912 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9914 if (operands[2] == const1_rtx
9915 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9916 return "<shift>{l}\t%k0";
9918 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9920 [(set_attr "type" "ishift")
9921 (set (attr "length_immediate")
9923 (and (match_operand 2 "const1_operand" "")
9924 (ior (match_test "TARGET_SHIFT1")
9925 (match_test "optimize_function_for_size_p (cfun)")))
9927 (const_string "*")))
9928 (set_attr "mode" "SI")])
9930 (define_insn "*<shift_insn><mode>3_cconly"
9931 [(set (reg FLAGS_REG)
9934 (match_operand:SWI 1 "register_operand" "0")
9935 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9937 (clobber (match_scratch:SWI 0 "=<r>"))]
9938 "(optimize_function_for_size_p (cfun)
9939 || !TARGET_PARTIAL_FLAG_REG_STALL
9940 || (operands[2] == const1_rtx
9942 && ix86_match_ccmode (insn, CCGOCmode)"
9944 if (operands[2] == const1_rtx
9945 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9946 return "<shift>{<imodesuffix>}\t%0";
9948 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9950 [(set_attr "type" "ishift")
9951 (set (attr "length_immediate")
9953 (and (match_operand 2 "const1_operand" "")
9954 (ior (match_test "TARGET_SHIFT1")
9955 (match_test "optimize_function_for_size_p (cfun)")))
9957 (const_string "*")))
9958 (set_attr "mode" "<MODE>")])
9960 ;; Rotate instructions
9962 (define_expand "<rotate_insn>ti3"
9963 [(set (match_operand:TI 0 "register_operand" "")
9964 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9965 (match_operand:QI 2 "nonmemory_operand" "")))]
9968 if (const_1_to_63_operand (operands[2], VOIDmode))
9969 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9970 (operands[0], operands[1], operands[2]));
9977 (define_expand "<rotate_insn>di3"
9978 [(set (match_operand:DI 0 "shiftdi_operand" "")
9979 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9980 (match_operand:QI 2 "nonmemory_operand" "")))]
9984 ix86_expand_binary_operator (<CODE>, DImode, operands);
9985 else if (const_1_to_31_operand (operands[2], VOIDmode))
9986 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9987 (operands[0], operands[1], operands[2]));
9994 (define_expand "<rotate_insn><mode>3"
9995 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9996 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9997 (match_operand:QI 2 "nonmemory_operand" "")))]
9999 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10001 ;; Avoid useless masking of count operand.
10002 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10003 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10005 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10008 (match_operand:SI 2 "nonimmediate_operand" "c")
10009 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10010 (clobber (reg:CC FLAGS_REG))]
10011 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10012 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10013 == GET_MODE_BITSIZE (<MODE>mode)-1"
10016 [(parallel [(set (match_dup 0)
10017 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10018 (clobber (reg:CC FLAGS_REG))])]
10020 if (can_create_pseudo_p ())
10021 operands [2] = force_reg (SImode, operands[2]);
10023 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10025 [(set_attr "type" "rotate")
10026 (set_attr "mode" "<MODE>")])
10028 ;; Implement rotation using two double-precision
10029 ;; shift instructions and a scratch register.
10031 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10032 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10033 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10034 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10035 (clobber (reg:CC FLAGS_REG))
10036 (clobber (match_scratch:DWIH 3 "=&r"))]
10040 [(set (match_dup 3) (match_dup 4))
10042 [(set (match_dup 4)
10043 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10044 (lshiftrt:DWIH (match_dup 5)
10045 (minus:QI (match_dup 6) (match_dup 2)))))
10046 (clobber (reg:CC FLAGS_REG))])
10048 [(set (match_dup 5)
10049 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10050 (lshiftrt:DWIH (match_dup 3)
10051 (minus:QI (match_dup 6) (match_dup 2)))))
10052 (clobber (reg:CC FLAGS_REG))])]
10054 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10056 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10059 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10060 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10061 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10062 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10063 (clobber (reg:CC FLAGS_REG))
10064 (clobber (match_scratch:DWIH 3 "=&r"))]
10068 [(set (match_dup 3) (match_dup 4))
10070 [(set (match_dup 4)
10071 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10072 (ashift:DWIH (match_dup 5)
10073 (minus:QI (match_dup 6) (match_dup 2)))))
10074 (clobber (reg:CC FLAGS_REG))])
10076 [(set (match_dup 5)
10077 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10078 (ashift:DWIH (match_dup 3)
10079 (minus:QI (match_dup 6) (match_dup 2)))))
10080 (clobber (reg:CC FLAGS_REG))])]
10082 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10084 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10087 (define_insn "*bmi2_rorx<mode>3_1"
10088 [(set (match_operand:SWI48 0 "register_operand" "=r")
10089 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10090 (match_operand:QI 2 "immediate_operand" "<S>")))]
10092 "rorx\t{%2, %1, %0|%0, %1, %2}"
10093 [(set_attr "type" "rotatex")
10094 (set_attr "mode" "<MODE>")])
10096 (define_insn "*<rotate_insn><mode>3_1"
10097 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10099 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10100 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10101 (clobber (reg:CC FLAGS_REG))]
10102 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10104 switch (get_attr_type (insn))
10110 if (operands[2] == const1_rtx
10111 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10112 return "<rotate>{<imodesuffix>}\t%0";
10114 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10117 [(set_attr "isa" "*,bmi2")
10118 (set_attr "type" "rotate,rotatex")
10119 (set (attr "length_immediate")
10121 (and (eq_attr "type" "rotate")
10122 (and (match_operand 2 "const1_operand" "")
10123 (ior (match_test "TARGET_SHIFT1")
10124 (match_test "optimize_function_for_size_p (cfun)"))))
10126 (const_string "*")))
10127 (set_attr "mode" "<MODE>")])
10129 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10131 [(set (match_operand:SWI48 0 "register_operand" "")
10132 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10133 (match_operand:QI 2 "immediate_operand" "")))
10134 (clobber (reg:CC FLAGS_REG))]
10135 "TARGET_BMI2 && reload_completed"
10136 [(set (match_dup 0)
10137 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10140 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10144 [(set (match_operand:SWI48 0 "register_operand" "")
10145 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10146 (match_operand:QI 2 "immediate_operand" "")))
10147 (clobber (reg:CC FLAGS_REG))]
10148 "TARGET_BMI2 && reload_completed"
10149 [(set (match_dup 0)
10150 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10152 (define_insn "*bmi2_rorxsi3_1_zext"
10153 [(set (match_operand:DI 0 "register_operand" "=r")
10155 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10156 (match_operand:QI 2 "immediate_operand" "I"))))]
10157 "TARGET_64BIT && TARGET_BMI2"
10158 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10159 [(set_attr "type" "rotatex")
10160 (set_attr "mode" "SI")])
10162 (define_insn "*<rotate_insn>si3_1_zext"
10163 [(set (match_operand:DI 0 "register_operand" "=r,r")
10165 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10166 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10167 (clobber (reg:CC FLAGS_REG))]
10168 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10170 switch (get_attr_type (insn))
10176 if (operands[2] == const1_rtx
10177 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10178 return "<rotate>{l}\t%k0";
10180 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10183 [(set_attr "isa" "*,bmi2")
10184 (set_attr "type" "rotate,rotatex")
10185 (set (attr "length_immediate")
10187 (and (eq_attr "type" "rotate")
10188 (and (match_operand 2 "const1_operand" "")
10189 (ior (match_test "TARGET_SHIFT1")
10190 (match_test "optimize_function_for_size_p (cfun)"))))
10192 (const_string "*")))
10193 (set_attr "mode" "SI")])
10195 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10197 [(set (match_operand:DI 0 "register_operand" "")
10199 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10200 (match_operand:QI 2 "immediate_operand" ""))))
10201 (clobber (reg:CC FLAGS_REG))]
10202 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10203 [(set (match_dup 0)
10204 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10207 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10211 [(set (match_operand:DI 0 "register_operand" "")
10213 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10214 (match_operand:QI 2 "immediate_operand" ""))))
10215 (clobber (reg:CC FLAGS_REG))]
10216 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10217 [(set (match_dup 0)
10218 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10220 (define_insn "*<rotate_insn><mode>3_1"
10221 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10222 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10223 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10224 (clobber (reg:CC FLAGS_REG))]
10225 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10227 if (operands[2] == const1_rtx
10228 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10229 return "<rotate>{<imodesuffix>}\t%0";
10231 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10233 [(set_attr "type" "rotate")
10234 (set (attr "length_immediate")
10236 (and (match_operand 2 "const1_operand" "")
10237 (ior (match_test "TARGET_SHIFT1")
10238 (match_test "optimize_function_for_size_p (cfun)")))
10240 (const_string "*")))
10241 (set_attr "mode" "<MODE>")])
10243 (define_insn "*<rotate_insn>qi3_1_slp"
10244 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10245 (any_rotate:QI (match_dup 0)
10246 (match_operand:QI 1 "nonmemory_operand" "cI")))
10247 (clobber (reg:CC FLAGS_REG))]
10248 "(optimize_function_for_size_p (cfun)
10249 || !TARGET_PARTIAL_REG_STALL
10250 || (operands[1] == const1_rtx
10251 && TARGET_SHIFT1))"
10253 if (operands[1] == const1_rtx
10254 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10255 return "<rotate>{b}\t%0";
10257 return "<rotate>{b}\t{%1, %0|%0, %1}";
10259 [(set_attr "type" "rotate1")
10260 (set (attr "length_immediate")
10262 (and (match_operand 1 "const1_operand" "")
10263 (ior (match_test "TARGET_SHIFT1")
10264 (match_test "optimize_function_for_size_p (cfun)")))
10266 (const_string "*")))
10267 (set_attr "mode" "QI")])
10270 [(set (match_operand:HI 0 "register_operand" "")
10271 (any_rotate:HI (match_dup 0) (const_int 8)))
10272 (clobber (reg:CC FLAGS_REG))]
10274 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10275 [(parallel [(set (strict_low_part (match_dup 0))
10276 (bswap:HI (match_dup 0)))
10277 (clobber (reg:CC FLAGS_REG))])])
10279 ;; Bit set / bit test instructions
10281 (define_expand "extv"
10282 [(set (match_operand:SI 0 "register_operand" "")
10283 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10284 (match_operand:SI 2 "const8_operand" "")
10285 (match_operand:SI 3 "const8_operand" "")))]
10288 /* Handle extractions from %ah et al. */
10289 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10292 /* From mips.md: extract_bit_field doesn't verify that our source
10293 matches the predicate, so check it again here. */
10294 if (! ext_register_operand (operands[1], VOIDmode))
10298 (define_expand "extzv"
10299 [(set (match_operand:SI 0 "register_operand" "")
10300 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10301 (match_operand:SI 2 "const8_operand" "")
10302 (match_operand:SI 3 "const8_operand" "")))]
10305 /* Handle extractions from %ah et al. */
10306 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10309 /* From mips.md: extract_bit_field doesn't verify that our source
10310 matches the predicate, so check it again here. */
10311 if (! ext_register_operand (operands[1], VOIDmode))
10315 (define_expand "insv"
10316 [(set (zero_extract (match_operand 0 "register_operand" "")
10317 (match_operand 1 "const_int_operand" "")
10318 (match_operand 2 "const_int_operand" ""))
10319 (match_operand 3 "register_operand" ""))]
10322 rtx (*gen_mov_insv_1) (rtx, rtx);
10324 if (ix86_expand_pinsr (operands))
10327 /* Handle insertions to %ah et al. */
10328 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10331 /* From mips.md: insert_bit_field doesn't verify that our source
10332 matches the predicate, so check it again here. */
10333 if (! ext_register_operand (operands[0], VOIDmode))
10336 gen_mov_insv_1 = (TARGET_64BIT
10337 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10339 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10343 ;; %%% bts, btr, btc, bt.
10344 ;; In general these instructions are *slow* when applied to memory,
10345 ;; since they enforce atomic operation. When applied to registers,
10346 ;; it depends on the cpu implementation. They're never faster than
10347 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10348 ;; no point. But in 64-bit, we can't hold the relevant immediates
10349 ;; within the instruction itself, so operating on bits in the high
10350 ;; 32-bits of a register becomes easier.
10352 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10353 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10354 ;; negdf respectively, so they can never be disabled entirely.
10356 (define_insn "*btsq"
10357 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10359 (match_operand:DI 1 "const_0_to_63_operand" ""))
10361 (clobber (reg:CC FLAGS_REG))]
10362 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10363 "bts{q}\t{%1, %0|%0, %1}"
10364 [(set_attr "type" "alu1")
10365 (set_attr "prefix_0f" "1")
10366 (set_attr "mode" "DI")])
10368 (define_insn "*btrq"
10369 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10371 (match_operand:DI 1 "const_0_to_63_operand" ""))
10373 (clobber (reg:CC FLAGS_REG))]
10374 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10375 "btr{q}\t{%1, %0|%0, %1}"
10376 [(set_attr "type" "alu1")
10377 (set_attr "prefix_0f" "1")
10378 (set_attr "mode" "DI")])
10380 (define_insn "*btcq"
10381 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10383 (match_operand:DI 1 "const_0_to_63_operand" ""))
10384 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10385 (clobber (reg:CC FLAGS_REG))]
10386 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10387 "btc{q}\t{%1, %0|%0, %1}"
10388 [(set_attr "type" "alu1")
10389 (set_attr "prefix_0f" "1")
10390 (set_attr "mode" "DI")])
10392 ;; Allow Nocona to avoid these instructions if a register is available.
10395 [(match_scratch:DI 2 "r")
10396 (parallel [(set (zero_extract:DI
10397 (match_operand:DI 0 "register_operand" "")
10399 (match_operand:DI 1 "const_0_to_63_operand" ""))
10401 (clobber (reg:CC FLAGS_REG))])]
10402 "TARGET_64BIT && !TARGET_USE_BT"
10405 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10408 if (HOST_BITS_PER_WIDE_INT >= 64)
10409 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10410 else if (i < HOST_BITS_PER_WIDE_INT)
10411 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10413 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10415 op1 = immed_double_const (lo, hi, DImode);
10418 emit_move_insn (operands[2], op1);
10422 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10427 [(match_scratch:DI 2 "r")
10428 (parallel [(set (zero_extract:DI
10429 (match_operand:DI 0 "register_operand" "")
10431 (match_operand:DI 1 "const_0_to_63_operand" ""))
10433 (clobber (reg:CC FLAGS_REG))])]
10434 "TARGET_64BIT && !TARGET_USE_BT"
10437 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10440 if (HOST_BITS_PER_WIDE_INT >= 64)
10441 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10442 else if (i < HOST_BITS_PER_WIDE_INT)
10443 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10445 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10447 op1 = immed_double_const (~lo, ~hi, DImode);
10450 emit_move_insn (operands[2], op1);
10454 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10459 [(match_scratch:DI 2 "r")
10460 (parallel [(set (zero_extract:DI
10461 (match_operand:DI 0 "register_operand" "")
10463 (match_operand:DI 1 "const_0_to_63_operand" ""))
10464 (not:DI (zero_extract:DI
10465 (match_dup 0) (const_int 1) (match_dup 1))))
10466 (clobber (reg:CC FLAGS_REG))])]
10467 "TARGET_64BIT && !TARGET_USE_BT"
10470 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10473 if (HOST_BITS_PER_WIDE_INT >= 64)
10474 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10475 else if (i < HOST_BITS_PER_WIDE_INT)
10476 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10478 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10480 op1 = immed_double_const (lo, hi, DImode);
10483 emit_move_insn (operands[2], op1);
10487 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10491 (define_insn "*bt<mode>"
10492 [(set (reg:CCC FLAGS_REG)
10494 (zero_extract:SWI48
10495 (match_operand:SWI48 0 "register_operand" "r")
10497 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10499 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10500 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10501 [(set_attr "type" "alu1")
10502 (set_attr "prefix_0f" "1")
10503 (set_attr "mode" "<MODE>")])
10505 ;; Store-flag instructions.
10507 ;; For all sCOND expanders, also expand the compare or test insn that
10508 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10510 (define_insn_and_split "*setcc_di_1"
10511 [(set (match_operand:DI 0 "register_operand" "=q")
10512 (match_operator:DI 1 "ix86_comparison_operator"
10513 [(reg FLAGS_REG) (const_int 0)]))]
10514 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10516 "&& reload_completed"
10517 [(set (match_dup 2) (match_dup 1))
10518 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10520 PUT_MODE (operands[1], QImode);
10521 operands[2] = gen_lowpart (QImode, operands[0]);
10524 (define_insn_and_split "*setcc_si_1_and"
10525 [(set (match_operand:SI 0 "register_operand" "=q")
10526 (match_operator:SI 1 "ix86_comparison_operator"
10527 [(reg FLAGS_REG) (const_int 0)]))
10528 (clobber (reg:CC FLAGS_REG))]
10529 "!TARGET_PARTIAL_REG_STALL
10530 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10532 "&& reload_completed"
10533 [(set (match_dup 2) (match_dup 1))
10534 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10535 (clobber (reg:CC FLAGS_REG))])]
10537 PUT_MODE (operands[1], QImode);
10538 operands[2] = gen_lowpart (QImode, operands[0]);
10541 (define_insn_and_split "*setcc_si_1_movzbl"
10542 [(set (match_operand:SI 0 "register_operand" "=q")
10543 (match_operator:SI 1 "ix86_comparison_operator"
10544 [(reg FLAGS_REG) (const_int 0)]))]
10545 "!TARGET_PARTIAL_REG_STALL
10546 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10548 "&& reload_completed"
10549 [(set (match_dup 2) (match_dup 1))
10550 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10552 PUT_MODE (operands[1], QImode);
10553 operands[2] = gen_lowpart (QImode, operands[0]);
10556 (define_insn "*setcc_qi"
10557 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10558 (match_operator:QI 1 "ix86_comparison_operator"
10559 [(reg FLAGS_REG) (const_int 0)]))]
10562 [(set_attr "type" "setcc")
10563 (set_attr "mode" "QI")])
10565 (define_insn "*setcc_qi_slp"
10566 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10567 (match_operator:QI 1 "ix86_comparison_operator"
10568 [(reg FLAGS_REG) (const_int 0)]))]
10571 [(set_attr "type" "setcc")
10572 (set_attr "mode" "QI")])
10574 ;; In general it is not safe to assume too much about CCmode registers,
10575 ;; so simplify-rtx stops when it sees a second one. Under certain
10576 ;; conditions this is safe on x86, so help combine not create
10583 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10584 (ne:QI (match_operator 1 "ix86_comparison_operator"
10585 [(reg FLAGS_REG) (const_int 0)])
10588 [(set (match_dup 0) (match_dup 1))]
10589 "PUT_MODE (operands[1], QImode);")
10592 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10593 (ne:QI (match_operator 1 "ix86_comparison_operator"
10594 [(reg FLAGS_REG) (const_int 0)])
10597 [(set (match_dup 0) (match_dup 1))]
10598 "PUT_MODE (operands[1], QImode);")
10601 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10602 (eq:QI (match_operator 1 "ix86_comparison_operator"
10603 [(reg FLAGS_REG) (const_int 0)])
10606 [(set (match_dup 0) (match_dup 1))]
10608 rtx new_op1 = copy_rtx (operands[1]);
10609 operands[1] = new_op1;
10610 PUT_MODE (new_op1, QImode);
10611 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10612 GET_MODE (XEXP (new_op1, 0))));
10614 /* Make sure that (a) the CCmode we have for the flags is strong
10615 enough for the reversed compare or (b) we have a valid FP compare. */
10616 if (! ix86_comparison_operator (new_op1, VOIDmode))
10621 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10622 (eq:QI (match_operator 1 "ix86_comparison_operator"
10623 [(reg FLAGS_REG) (const_int 0)])
10626 [(set (match_dup 0) (match_dup 1))]
10628 rtx new_op1 = copy_rtx (operands[1]);
10629 operands[1] = new_op1;
10630 PUT_MODE (new_op1, QImode);
10631 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10632 GET_MODE (XEXP (new_op1, 0))));
10634 /* Make sure that (a) the CCmode we have for the flags is strong
10635 enough for the reversed compare or (b) we have a valid FP compare. */
10636 if (! ix86_comparison_operator (new_op1, VOIDmode))
10640 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10641 ;; subsequent logical operations are used to imitate conditional moves.
10642 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10645 (define_insn "setcc_<mode>_sse"
10646 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10647 (match_operator:MODEF 3 "sse_comparison_operator"
10648 [(match_operand:MODEF 1 "register_operand" "0,x")
10649 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10650 "SSE_FLOAT_MODE_P (<MODE>mode)"
10652 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10653 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10654 [(set_attr "isa" "noavx,avx")
10655 (set_attr "type" "ssecmp")
10656 (set_attr "length_immediate" "1")
10657 (set_attr "prefix" "orig,vex")
10658 (set_attr "mode" "<MODE>")])
10660 ;; Basic conditional jump instructions.
10661 ;; We ignore the overflow flag for signed branch instructions.
10663 (define_insn "*jcc_1"
10665 (if_then_else (match_operator 1 "ix86_comparison_operator"
10666 [(reg FLAGS_REG) (const_int 0)])
10667 (label_ref (match_operand 0 "" ""))
10671 [(set_attr "type" "ibr")
10672 (set_attr "modrm" "0")
10673 (set (attr "length")
10674 (if_then_else (and (ge (minus (match_dup 0) (pc))
10676 (lt (minus (match_dup 0) (pc))
10681 (define_insn "*jcc_2"
10683 (if_then_else (match_operator 1 "ix86_comparison_operator"
10684 [(reg FLAGS_REG) (const_int 0)])
10686 (label_ref (match_operand 0 "" ""))))]
10689 [(set_attr "type" "ibr")
10690 (set_attr "modrm" "0")
10691 (set (attr "length")
10692 (if_then_else (and (ge (minus (match_dup 0) (pc))
10694 (lt (minus (match_dup 0) (pc))
10699 ;; In general it is not safe to assume too much about CCmode registers,
10700 ;; so simplify-rtx stops when it sees a second one. Under certain
10701 ;; conditions this is safe on x86, so help combine not create
10709 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10710 [(reg FLAGS_REG) (const_int 0)])
10712 (label_ref (match_operand 1 "" ""))
10716 (if_then_else (match_dup 0)
10717 (label_ref (match_dup 1))
10719 "PUT_MODE (operands[0], VOIDmode);")
10723 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10724 [(reg FLAGS_REG) (const_int 0)])
10726 (label_ref (match_operand 1 "" ""))
10730 (if_then_else (match_dup 0)
10731 (label_ref (match_dup 1))
10734 rtx new_op0 = copy_rtx (operands[0]);
10735 operands[0] = new_op0;
10736 PUT_MODE (new_op0, VOIDmode);
10737 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10738 GET_MODE (XEXP (new_op0, 0))));
10740 /* Make sure that (a) the CCmode we have for the flags is strong
10741 enough for the reversed compare or (b) we have a valid FP compare. */
10742 if (! ix86_comparison_operator (new_op0, VOIDmode))
10746 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10747 ;; pass generates from shift insn with QImode operand. Actually, the mode
10748 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10749 ;; appropriate modulo of the bit offset value.
10751 (define_insn_and_split "*jcc_bt<mode>"
10753 (if_then_else (match_operator 0 "bt_comparison_operator"
10754 [(zero_extract:SWI48
10755 (match_operand:SWI48 1 "register_operand" "r")
10758 (match_operand:QI 2 "register_operand" "r")))
10760 (label_ref (match_operand 3 "" ""))
10762 (clobber (reg:CC FLAGS_REG))]
10763 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10766 [(set (reg:CCC FLAGS_REG)
10768 (zero_extract:SWI48
10774 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10775 (label_ref (match_dup 3))
10778 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10780 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10783 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10784 ;; also for DImode, this is what combine produces.
10785 (define_insn_and_split "*jcc_bt<mode>_mask"
10787 (if_then_else (match_operator 0 "bt_comparison_operator"
10788 [(zero_extract:SWI48
10789 (match_operand:SWI48 1 "register_operand" "r")
10792 (match_operand:SI 2 "register_operand" "r")
10793 (match_operand:SI 3 "const_int_operand" "n")))])
10794 (label_ref (match_operand 4 "" ""))
10796 (clobber (reg:CC FLAGS_REG))]
10797 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10798 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10799 == GET_MODE_BITSIZE (<MODE>mode)-1"
10802 [(set (reg:CCC FLAGS_REG)
10804 (zero_extract:SWI48
10810 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10811 (label_ref (match_dup 4))
10814 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10816 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10819 (define_insn_and_split "*jcc_btsi_1"
10821 (if_then_else (match_operator 0 "bt_comparison_operator"
10824 (match_operand:SI 1 "register_operand" "r")
10825 (match_operand:QI 2 "register_operand" "r"))
10828 (label_ref (match_operand 3 "" ""))
10830 (clobber (reg:CC FLAGS_REG))]
10831 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10834 [(set (reg:CCC FLAGS_REG)
10842 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10843 (label_ref (match_dup 3))
10846 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10848 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10851 ;; avoid useless masking of bit offset operand
10852 (define_insn_and_split "*jcc_btsi_mask_1"
10855 (match_operator 0 "bt_comparison_operator"
10858 (match_operand:SI 1 "register_operand" "r")
10861 (match_operand:SI 2 "register_operand" "r")
10862 (match_operand:SI 3 "const_int_operand" "n")) 0))
10865 (label_ref (match_operand 4 "" ""))
10867 (clobber (reg:CC FLAGS_REG))]
10868 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10869 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10872 [(set (reg:CCC FLAGS_REG)
10880 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10881 (label_ref (match_dup 4))
10883 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10885 ;; Define combination compare-and-branch fp compare instructions to help
10888 (define_insn "*fp_jcc_1_387"
10890 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10891 [(match_operand 1 "register_operand" "f")
10892 (match_operand 2 "nonimmediate_operand" "fm")])
10893 (label_ref (match_operand 3 "" ""))
10895 (clobber (reg:CCFP FPSR_REG))
10896 (clobber (reg:CCFP FLAGS_REG))
10897 (clobber (match_scratch:HI 4 "=a"))]
10899 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10900 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10901 && SELECT_CC_MODE (GET_CODE (operands[0]),
10902 operands[1], operands[2]) == CCFPmode
10906 (define_insn "*fp_jcc_1r_387"
10908 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10909 [(match_operand 1 "register_operand" "f")
10910 (match_operand 2 "nonimmediate_operand" "fm")])
10912 (label_ref (match_operand 3 "" ""))))
10913 (clobber (reg:CCFP FPSR_REG))
10914 (clobber (reg:CCFP FLAGS_REG))
10915 (clobber (match_scratch:HI 4 "=a"))]
10917 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10918 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10919 && SELECT_CC_MODE (GET_CODE (operands[0]),
10920 operands[1], operands[2]) == CCFPmode
10924 (define_insn "*fp_jcc_2_387"
10926 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10927 [(match_operand 1 "register_operand" "f")
10928 (match_operand 2 "register_operand" "f")])
10929 (label_ref (match_operand 3 "" ""))
10931 (clobber (reg:CCFP FPSR_REG))
10932 (clobber (reg:CCFP FLAGS_REG))
10933 (clobber (match_scratch:HI 4 "=a"))]
10934 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10935 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10939 (define_insn "*fp_jcc_2r_387"
10941 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10942 [(match_operand 1 "register_operand" "f")
10943 (match_operand 2 "register_operand" "f")])
10945 (label_ref (match_operand 3 "" ""))))
10946 (clobber (reg:CCFP FPSR_REG))
10947 (clobber (reg:CCFP FLAGS_REG))
10948 (clobber (match_scratch:HI 4 "=a"))]
10949 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10950 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10954 (define_insn "*fp_jcc_3_387"
10956 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10957 [(match_operand 1 "register_operand" "f")
10958 (match_operand 2 "const0_operand" "")])
10959 (label_ref (match_operand 3 "" ""))
10961 (clobber (reg:CCFP FPSR_REG))
10962 (clobber (reg:CCFP FLAGS_REG))
10963 (clobber (match_scratch:HI 4 "=a"))]
10964 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10965 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10966 && SELECT_CC_MODE (GET_CODE (operands[0]),
10967 operands[1], operands[2]) == CCFPmode
10973 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10974 [(match_operand 1 "register_operand" "")
10975 (match_operand 2 "nonimmediate_operand" "")])
10976 (match_operand 3 "" "")
10977 (match_operand 4 "" "")))
10978 (clobber (reg:CCFP FPSR_REG))
10979 (clobber (reg:CCFP FLAGS_REG))]
10983 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10984 operands[3], operands[4], NULL_RTX, NULL_RTX);
10990 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10991 [(match_operand 1 "register_operand" "")
10992 (match_operand 2 "general_operand" "")])
10993 (match_operand 3 "" "")
10994 (match_operand 4 "" "")))
10995 (clobber (reg:CCFP FPSR_REG))
10996 (clobber (reg:CCFP FLAGS_REG))
10997 (clobber (match_scratch:HI 5 "=a"))]
11001 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11002 operands[3], operands[4], operands[5], NULL_RTX);
11006 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11007 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11008 ;; with a precedence over other operators and is always put in the first
11009 ;; place. Swap condition and operands to match ficom instruction.
11011 (define_insn "*fp_jcc_4_<mode>_387"
11014 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11015 [(match_operator 1 "float_operator"
11016 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11017 (match_operand 3 "register_operand" "f,f")])
11018 (label_ref (match_operand 4 "" ""))
11020 (clobber (reg:CCFP FPSR_REG))
11021 (clobber (reg:CCFP FLAGS_REG))
11022 (clobber (match_scratch:HI 5 "=a,a"))]
11023 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11024 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11025 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11026 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11033 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11034 [(match_operator 1 "float_operator"
11035 [(match_operand:SWI24 2 "memory_operand" "")])
11036 (match_operand 3 "register_operand" "")])
11037 (match_operand 4 "" "")
11038 (match_operand 5 "" "")))
11039 (clobber (reg:CCFP FPSR_REG))
11040 (clobber (reg:CCFP FLAGS_REG))
11041 (clobber (match_scratch:HI 6 "=a"))]
11045 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11047 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11048 operands[3], operands[7],
11049 operands[4], operands[5], operands[6], NULL_RTX);
11053 ;; %%% Kill this when reload knows how to do it.
11057 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11058 [(match_operator 1 "float_operator"
11059 [(match_operand:SWI24 2 "register_operand" "")])
11060 (match_operand 3 "register_operand" "")])
11061 (match_operand 4 "" "")
11062 (match_operand 5 "" "")))
11063 (clobber (reg:CCFP FPSR_REG))
11064 (clobber (reg:CCFP FLAGS_REG))
11065 (clobber (match_scratch:HI 6 "=a"))]
11069 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11070 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11072 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11073 operands[3], operands[7],
11074 operands[4], operands[5], operands[6], operands[2]);
11078 ;; Unconditional and other jump instructions
11080 (define_insn "jump"
11082 (label_ref (match_operand 0 "" "")))]
11085 [(set_attr "type" "ibr")
11086 (set (attr "length")
11087 (if_then_else (and (ge (minus (match_dup 0) (pc))
11089 (lt (minus (match_dup 0) (pc))
11093 (set_attr "modrm" "0")])
11095 (define_expand "indirect_jump"
11096 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11098 (define_insn "*indirect_jump"
11099 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11102 [(set_attr "type" "ibr")
11103 (set_attr "length_immediate" "0")])
11105 (define_expand "tablejump"
11106 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11107 (use (label_ref (match_operand 1 "" "")))])]
11110 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11111 relative. Convert the relative address to an absolute address. */
11115 enum rtx_code code;
11117 /* We can't use @GOTOFF for text labels on VxWorks;
11118 see gotoff_operand. */
11119 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11123 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11125 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11129 op1 = pic_offset_table_rtx;
11134 op0 = pic_offset_table_rtx;
11138 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11141 else if (TARGET_X32)
11142 operands[0] = convert_memory_address (Pmode, operands[0]);
11145 (define_insn "*tablejump_1"
11146 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11147 (use (label_ref (match_operand 1 "" "")))]
11150 [(set_attr "type" "ibr")
11151 (set_attr "length_immediate" "0")])
11153 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11156 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11157 (set (match_operand:QI 1 "register_operand" "")
11158 (match_operator:QI 2 "ix86_comparison_operator"
11159 [(reg FLAGS_REG) (const_int 0)]))
11160 (set (match_operand 3 "q_regs_operand" "")
11161 (zero_extend (match_dup 1)))]
11162 "(peep2_reg_dead_p (3, operands[1])
11163 || operands_match_p (operands[1], operands[3]))
11164 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11165 [(set (match_dup 4) (match_dup 0))
11166 (set (strict_low_part (match_dup 5))
11169 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11170 operands[5] = gen_lowpart (QImode, operands[3]);
11171 ix86_expand_clear (operands[3]);
11174 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11177 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11178 (set (match_operand:QI 1 "register_operand" "")
11179 (match_operator:QI 2 "ix86_comparison_operator"
11180 [(reg FLAGS_REG) (const_int 0)]))
11181 (parallel [(set (match_operand 3 "q_regs_operand" "")
11182 (zero_extend (match_dup 1)))
11183 (clobber (reg:CC FLAGS_REG))])]
11184 "(peep2_reg_dead_p (3, operands[1])
11185 || operands_match_p (operands[1], operands[3]))
11186 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11187 [(set (match_dup 4) (match_dup 0))
11188 (set (strict_low_part (match_dup 5))
11191 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11192 operands[5] = gen_lowpart (QImode, operands[3]);
11193 ix86_expand_clear (operands[3]);
11196 ;; Call instructions.
11198 ;; The predicates normally associated with named expanders are not properly
11199 ;; checked for calls. This is a bug in the generic code, but it isn't that
11200 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11202 ;; P6 processors will jump to the address after the decrement when %esp
11203 ;; is used as a call operand, so they will execute return address as a code.
11204 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11206 ;; Register constraint for call instruction.
11207 (define_mode_attr c [(SI "l") (DI "r")])
11209 ;; Call subroutine returning no value.
11211 (define_expand "call"
11212 [(call (match_operand:QI 0 "" "")
11213 (match_operand 1 "" ""))
11214 (use (match_operand 2 "" ""))]
11217 ix86_expand_call (NULL, operands[0], operands[1],
11218 operands[2], NULL, false);
11222 (define_expand "sibcall"
11223 [(call (match_operand:QI 0 "" "")
11224 (match_operand 1 "" ""))
11225 (use (match_operand 2 "" ""))]
11228 ix86_expand_call (NULL, operands[0], operands[1],
11229 operands[2], NULL, true);
11233 (define_insn_and_split "*call_vzeroupper"
11234 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11235 (match_operand 1 "" ""))
11236 (unspec [(match_operand 2 "const_int_operand" "")]
11237 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11238 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11240 "&& reload_completed"
11242 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11243 [(set_attr "type" "call")])
11245 (define_insn "*call"
11246 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11247 (match_operand 1 "" ""))]
11248 "!SIBLING_CALL_P (insn)"
11249 "* return ix86_output_call_insn (insn, operands[0]);"
11250 [(set_attr "type" "call")])
11252 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11253 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11254 (match_operand 1 "" ""))
11255 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11256 (clobber (reg:TI XMM6_REG))
11257 (clobber (reg:TI XMM7_REG))
11258 (clobber (reg:TI XMM8_REG))
11259 (clobber (reg:TI XMM9_REG))
11260 (clobber (reg:TI XMM10_REG))
11261 (clobber (reg:TI XMM11_REG))
11262 (clobber (reg:TI XMM12_REG))
11263 (clobber (reg:TI XMM13_REG))
11264 (clobber (reg:TI XMM14_REG))
11265 (clobber (reg:TI XMM15_REG))
11266 (clobber (reg:DI SI_REG))
11267 (clobber (reg:DI DI_REG))
11268 (unspec [(match_operand 2 "const_int_operand" "")]
11269 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11270 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11272 "&& reload_completed"
11274 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11275 [(set_attr "type" "call")])
11277 (define_insn "*call_rex64_ms_sysv"
11278 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11279 (match_operand 1 "" ""))
11280 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11281 (clobber (reg:TI XMM6_REG))
11282 (clobber (reg:TI XMM7_REG))
11283 (clobber (reg:TI XMM8_REG))
11284 (clobber (reg:TI XMM9_REG))
11285 (clobber (reg:TI XMM10_REG))
11286 (clobber (reg:TI XMM11_REG))
11287 (clobber (reg:TI XMM12_REG))
11288 (clobber (reg:TI XMM13_REG))
11289 (clobber (reg:TI XMM14_REG))
11290 (clobber (reg:TI XMM15_REG))
11291 (clobber (reg:DI SI_REG))
11292 (clobber (reg:DI DI_REG))]
11293 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11294 "* return ix86_output_call_insn (insn, operands[0]);"
11295 [(set_attr "type" "call")])
11297 (define_insn_and_split "*sibcall_vzeroupper"
11298 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11299 (match_operand 1 "" ""))
11300 (unspec [(match_operand 2 "const_int_operand" "")]
11301 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11302 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11304 "&& reload_completed"
11306 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11307 [(set_attr "type" "call")])
11309 (define_insn "*sibcall"
11310 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11311 (match_operand 1 "" ""))]
11312 "SIBLING_CALL_P (insn)"
11313 "* return ix86_output_call_insn (insn, operands[0]);"
11314 [(set_attr "type" "call")])
11316 (define_expand "call_pop"
11317 [(parallel [(call (match_operand:QI 0 "" "")
11318 (match_operand:SI 1 "" ""))
11319 (set (reg:SI SP_REG)
11320 (plus:SI (reg:SI SP_REG)
11321 (match_operand:SI 3 "" "")))])]
11324 ix86_expand_call (NULL, operands[0], operands[1],
11325 operands[2], operands[3], false);
11329 (define_insn_and_split "*call_pop_vzeroupper"
11330 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11331 (match_operand:SI 1 "" ""))
11332 (set (reg:SI SP_REG)
11333 (plus:SI (reg:SI SP_REG)
11334 (match_operand:SI 2 "immediate_operand" "i")))
11335 (unspec [(match_operand 3 "const_int_operand" "")]
11336 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11337 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11339 "&& reload_completed"
11341 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11342 [(set_attr "type" "call")])
11344 (define_insn "*call_pop"
11345 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11346 (match_operand 1 "" ""))
11347 (set (reg:SI SP_REG)
11348 (plus:SI (reg:SI SP_REG)
11349 (match_operand:SI 2 "immediate_operand" "i")))]
11350 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11351 "* return ix86_output_call_insn (insn, operands[0]);"
11352 [(set_attr "type" "call")])
11354 (define_insn_and_split "*sibcall_pop_vzeroupper"
11355 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11356 (match_operand 1 "" ""))
11357 (set (reg:SI SP_REG)
11358 (plus:SI (reg:SI SP_REG)
11359 (match_operand:SI 2 "immediate_operand" "i")))
11360 (unspec [(match_operand 3 "const_int_operand" "")]
11361 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11362 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11364 "&& reload_completed"
11366 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11367 [(set_attr "type" "call")])
11369 (define_insn "*sibcall_pop"
11370 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11371 (match_operand 1 "" ""))
11372 (set (reg:SI SP_REG)
11373 (plus:SI (reg:SI SP_REG)
11374 (match_operand:SI 2 "immediate_operand" "i")))]
11375 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11376 "* return ix86_output_call_insn (insn, operands[0]);"
11377 [(set_attr "type" "call")])
11379 ;; Call subroutine, returning value in operand 0
11381 (define_expand "call_value"
11382 [(set (match_operand 0 "" "")
11383 (call (match_operand:QI 1 "" "")
11384 (match_operand 2 "" "")))
11385 (use (match_operand 3 "" ""))]
11388 ix86_expand_call (operands[0], operands[1], operands[2],
11389 operands[3], NULL, false);
11393 (define_expand "sibcall_value"
11394 [(set (match_operand 0 "" "")
11395 (call (match_operand:QI 1 "" "")
11396 (match_operand 2 "" "")))
11397 (use (match_operand 3 "" ""))]
11400 ix86_expand_call (operands[0], operands[1], operands[2],
11401 operands[3], NULL, true);
11405 (define_insn_and_split "*call_value_vzeroupper"
11406 [(set (match_operand 0 "" "")
11407 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11408 (match_operand 2 "" "")))
11409 (unspec [(match_operand 3 "const_int_operand" "")]
11410 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11411 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11413 "&& reload_completed"
11415 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11416 [(set_attr "type" "callv")])
11418 (define_insn "*call_value"
11419 [(set (match_operand 0 "" "")
11420 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11421 (match_operand 2 "" "")))]
11422 "!SIBLING_CALL_P (insn)"
11423 "* return ix86_output_call_insn (insn, operands[1]);"
11424 [(set_attr "type" "callv")])
11426 (define_insn_and_split "*sibcall_value_vzeroupper"
11427 [(set (match_operand 0 "" "")
11428 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11429 (match_operand 2 "" "")))
11430 (unspec [(match_operand 3 "const_int_operand" "")]
11431 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11432 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11434 "&& reload_completed"
11436 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11437 [(set_attr "type" "callv")])
11439 (define_insn "*sibcall_value"
11440 [(set (match_operand 0 "" "")
11441 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11442 (match_operand 2 "" "")))]
11443 "SIBLING_CALL_P (insn)"
11444 "* return ix86_output_call_insn (insn, operands[1]);"
11445 [(set_attr "type" "callv")])
11447 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11448 [(set (match_operand 0 "" "")
11449 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11450 (match_operand 2 "" "")))
11451 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11452 (clobber (reg:TI XMM6_REG))
11453 (clobber (reg:TI XMM7_REG))
11454 (clobber (reg:TI XMM8_REG))
11455 (clobber (reg:TI XMM9_REG))
11456 (clobber (reg:TI XMM10_REG))
11457 (clobber (reg:TI XMM11_REG))
11458 (clobber (reg:TI XMM12_REG))
11459 (clobber (reg:TI XMM13_REG))
11460 (clobber (reg:TI XMM14_REG))
11461 (clobber (reg:TI XMM15_REG))
11462 (clobber (reg:DI SI_REG))
11463 (clobber (reg:DI DI_REG))
11464 (unspec [(match_operand 3 "const_int_operand" "")]
11465 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11466 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11468 "&& reload_completed"
11470 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11471 [(set_attr "type" "callv")])
11473 (define_insn "*call_value_rex64_ms_sysv"
11474 [(set (match_operand 0 "" "")
11475 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11476 (match_operand 2 "" "")))
11477 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11478 (clobber (reg:TI XMM6_REG))
11479 (clobber (reg:TI XMM7_REG))
11480 (clobber (reg:TI XMM8_REG))
11481 (clobber (reg:TI XMM9_REG))
11482 (clobber (reg:TI XMM10_REG))
11483 (clobber (reg:TI XMM11_REG))
11484 (clobber (reg:TI XMM12_REG))
11485 (clobber (reg:TI XMM13_REG))
11486 (clobber (reg:TI XMM14_REG))
11487 (clobber (reg:TI XMM15_REG))
11488 (clobber (reg:DI SI_REG))
11489 (clobber (reg:DI DI_REG))]
11490 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11491 "* return ix86_output_call_insn (insn, operands[1]);"
11492 [(set_attr "type" "callv")])
11494 (define_expand "call_value_pop"
11495 [(parallel [(set (match_operand 0 "" "")
11496 (call (match_operand:QI 1 "" "")
11497 (match_operand:SI 2 "" "")))
11498 (set (reg:SI SP_REG)
11499 (plus:SI (reg:SI SP_REG)
11500 (match_operand:SI 4 "" "")))])]
11503 ix86_expand_call (operands[0], operands[1], operands[2],
11504 operands[3], operands[4], false);
11508 (define_insn_and_split "*call_value_pop_vzeroupper"
11509 [(set (match_operand 0 "" "")
11510 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11511 (match_operand 2 "" "")))
11512 (set (reg:SI SP_REG)
11513 (plus:SI (reg:SI SP_REG)
11514 (match_operand:SI 3 "immediate_operand" "i")))
11515 (unspec [(match_operand 4 "const_int_operand" "")]
11516 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11517 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11519 "&& reload_completed"
11521 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11522 [(set_attr "type" "callv")])
11524 (define_insn "*call_value_pop"
11525 [(set (match_operand 0 "" "")
11526 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11527 (match_operand 2 "" "")))
11528 (set (reg:SI SP_REG)
11529 (plus:SI (reg:SI SP_REG)
11530 (match_operand:SI 3 "immediate_operand" "i")))]
11531 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11532 "* return ix86_output_call_insn (insn, operands[1]);"
11533 [(set_attr "type" "callv")])
11535 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11536 [(set (match_operand 0 "" "")
11537 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11538 (match_operand 2 "" "")))
11539 (set (reg:SI SP_REG)
11540 (plus:SI (reg:SI SP_REG)
11541 (match_operand:SI 3 "immediate_operand" "i")))
11542 (unspec [(match_operand 4 "const_int_operand" "")]
11543 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11544 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11546 "&& reload_completed"
11548 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11549 [(set_attr "type" "callv")])
11551 (define_insn "*sibcall_value_pop"
11552 [(set (match_operand 0 "" "")
11553 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11554 (match_operand 2 "" "")))
11555 (set (reg:SI SP_REG)
11556 (plus:SI (reg:SI SP_REG)
11557 (match_operand:SI 3 "immediate_operand" "i")))]
11558 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11559 "* return ix86_output_call_insn (insn, operands[1]);"
11560 [(set_attr "type" "callv")])
11562 ;; Call subroutine returning any type.
11564 (define_expand "untyped_call"
11565 [(parallel [(call (match_operand 0 "" "")
11567 (match_operand 1 "" "")
11568 (match_operand 2 "" "")])]
11573 /* In order to give reg-stack an easier job in validating two
11574 coprocessor registers as containing a possible return value,
11575 simply pretend the untyped call returns a complex long double
11578 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11579 and should have the default ABI. */
11581 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11582 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11583 operands[0], const0_rtx,
11584 GEN_INT ((TARGET_64BIT
11585 ? (ix86_abi == SYSV_ABI
11586 ? X86_64_SSE_REGPARM_MAX
11587 : X86_64_MS_SSE_REGPARM_MAX)
11588 : X86_32_SSE_REGPARM_MAX)
11592 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11594 rtx set = XVECEXP (operands[2], 0, i);
11595 emit_move_insn (SET_DEST (set), SET_SRC (set));
11598 /* The optimizer does not know that the call sets the function value
11599 registers we stored in the result block. We avoid problems by
11600 claiming that all hard registers are used and clobbered at this
11602 emit_insn (gen_blockage ());
11607 ;; Prologue and epilogue instructions
11609 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11610 ;; all of memory. This blocks insns from being moved across this point.
11612 (define_insn "blockage"
11613 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11616 [(set_attr "length" "0")])
11618 ;; Do not schedule instructions accessing memory across this point.
11620 (define_expand "memory_blockage"
11621 [(set (match_dup 0)
11622 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11625 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11626 MEM_VOLATILE_P (operands[0]) = 1;
11629 (define_insn "*memory_blockage"
11630 [(set (match_operand:BLK 0 "" "")
11631 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11634 [(set_attr "length" "0")])
11636 ;; As USE insns aren't meaningful after reload, this is used instead
11637 ;; to prevent deleting instructions setting registers for PIC code
11638 (define_insn "prologue_use"
11639 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11642 [(set_attr "length" "0")])
11644 ;; Insn emitted into the body of a function to return from a function.
11645 ;; This is only done if the function's epilogue is known to be simple.
11646 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11648 (define_expand "return"
11650 "ix86_can_use_return_insn_p ()"
11652 ix86_maybe_emit_epilogue_vzeroupper ();
11653 if (crtl->args.pops_args)
11655 rtx popc = GEN_INT (crtl->args.pops_args);
11656 emit_jump_insn (gen_simple_return_pop_internal (popc));
11661 ;; We need to disable this for TARGET_SEH, as otherwise
11662 ;; shrink-wrapped prologue gets enabled too. This might exceed
11663 ;; the maximum size of prologue in unwind information.
11665 (define_expand "simple_return"
11669 ix86_maybe_emit_epilogue_vzeroupper ();
11670 if (crtl->args.pops_args)
11672 rtx popc = GEN_INT (crtl->args.pops_args);
11673 emit_jump_insn (gen_simple_return_pop_internal (popc));
11678 (define_insn "simple_return_internal"
11682 [(set_attr "length" "1")
11683 (set_attr "atom_unit" "jeu")
11684 (set_attr "length_immediate" "0")
11685 (set_attr "modrm" "0")])
11687 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11688 ;; instruction Athlon and K8 have.
11690 (define_insn "simple_return_internal_long"
11692 (unspec [(const_int 0)] UNSPEC_REP)]
11695 [(set_attr "length" "2")
11696 (set_attr "atom_unit" "jeu")
11697 (set_attr "length_immediate" "0")
11698 (set_attr "prefix_rep" "1")
11699 (set_attr "modrm" "0")])
11701 (define_insn "simple_return_pop_internal"
11703 (use (match_operand:SI 0 "const_int_operand" ""))]
11706 [(set_attr "length" "3")
11707 (set_attr "atom_unit" "jeu")
11708 (set_attr "length_immediate" "2")
11709 (set_attr "modrm" "0")])
11711 (define_insn "simple_return_indirect_internal"
11713 (use (match_operand:SI 0 "register_operand" "r"))]
11716 [(set_attr "type" "ibr")
11717 (set_attr "length_immediate" "0")])
11723 [(set_attr "length" "1")
11724 (set_attr "length_immediate" "0")
11725 (set_attr "modrm" "0")])
11727 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11728 (define_insn "nops"
11729 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11733 int num = INTVAL (operands[0]);
11735 gcc_assert (num >= 1 && num <= 8);
11738 fputs ("\tnop\n", asm_out_file);
11742 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11743 (set_attr "length_immediate" "0")
11744 (set_attr "modrm" "0")])
11746 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11747 ;; branch prediction penalty for the third jump in a 16-byte
11751 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11754 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11755 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11757 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11758 The align insn is used to avoid 3 jump instructions in the row to improve
11759 branch prediction and the benefits hardly outweigh the cost of extra 8
11760 nops on the average inserted by full alignment pseudo operation. */
11764 [(set_attr "length" "16")])
11766 (define_expand "prologue"
11769 "ix86_expand_prologue (); DONE;")
11771 (define_insn "set_got"
11772 [(set (match_operand:SI 0 "register_operand" "=r")
11773 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11774 (clobber (reg:CC FLAGS_REG))]
11776 "* return output_set_got (operands[0], NULL_RTX);"
11777 [(set_attr "type" "multi")
11778 (set_attr "length" "12")])
11780 (define_insn "set_got_labelled"
11781 [(set (match_operand:SI 0 "register_operand" "=r")
11782 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11784 (clobber (reg:CC FLAGS_REG))]
11786 "* return output_set_got (operands[0], operands[1]);"
11787 [(set_attr "type" "multi")
11788 (set_attr "length" "12")])
11790 (define_insn "set_got_rex64"
11791 [(set (match_operand:DI 0 "register_operand" "=r")
11792 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11794 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11795 [(set_attr "type" "lea")
11796 (set_attr "length_address" "4")
11797 (set_attr "mode" "DI")])
11799 (define_insn "set_rip_rex64"
11800 [(set (match_operand:DI 0 "register_operand" "=r")
11801 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11803 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11804 [(set_attr "type" "lea")
11805 (set_attr "length_address" "4")
11806 (set_attr "mode" "DI")])
11808 (define_insn "set_got_offset_rex64"
11809 [(set (match_operand:DI 0 "register_operand" "=r")
11811 [(label_ref (match_operand 1 "" ""))]
11812 UNSPEC_SET_GOT_OFFSET))]
11814 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11815 [(set_attr "type" "imov")
11816 (set_attr "length_immediate" "0")
11817 (set_attr "length_address" "8")
11818 (set_attr "mode" "DI")])
11820 (define_expand "epilogue"
11823 "ix86_expand_epilogue (1); DONE;")
11825 (define_expand "sibcall_epilogue"
11828 "ix86_expand_epilogue (0); DONE;")
11830 (define_expand "eh_return"
11831 [(use (match_operand 0 "register_operand" ""))]
11834 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11836 /* Tricky bit: we write the address of the handler to which we will
11837 be returning into someone else's stack frame, one word below the
11838 stack address we wish to restore. */
11839 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11840 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11841 tmp = gen_rtx_MEM (Pmode, tmp);
11842 emit_move_insn (tmp, ra);
11844 emit_jump_insn (gen_eh_return_internal ());
11849 (define_insn_and_split "eh_return_internal"
11853 "epilogue_completed"
11855 "ix86_expand_epilogue (2); DONE;")
11857 (define_insn "leave"
11858 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11859 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11860 (clobber (mem:BLK (scratch)))]
11863 [(set_attr "type" "leave")])
11865 (define_insn "leave_rex64"
11866 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11867 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11868 (clobber (mem:BLK (scratch)))]
11871 [(set_attr "type" "leave")])
11873 ;; Handle -fsplit-stack.
11875 (define_expand "split_stack_prologue"
11879 ix86_expand_split_stack_prologue ();
11883 ;; In order to support the call/return predictor, we use a return
11884 ;; instruction which the middle-end doesn't see.
11885 (define_insn "split_stack_return"
11886 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11887 UNSPECV_SPLIT_STACK_RETURN)]
11890 if (operands[0] == const0_rtx)
11895 [(set_attr "atom_unit" "jeu")
11896 (set_attr "modrm" "0")
11897 (set (attr "length")
11898 (if_then_else (match_operand:SI 0 "const0_operand" "")
11901 (set (attr "length_immediate")
11902 (if_then_else (match_operand:SI 0 "const0_operand" "")
11906 ;; If there are operand 0 bytes available on the stack, jump to
11909 (define_expand "split_stack_space_check"
11910 [(set (pc) (if_then_else
11911 (ltu (minus (reg SP_REG)
11912 (match_operand 0 "register_operand" ""))
11913 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11914 (label_ref (match_operand 1 "" ""))
11918 rtx reg, size, limit;
11920 reg = gen_reg_rtx (Pmode);
11921 size = force_reg (Pmode, operands[0]);
11922 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11923 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11924 UNSPEC_STACK_CHECK);
11925 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11926 ix86_expand_branch (GEU, reg, limit, operands[1]);
11931 ;; Bit manipulation instructions.
11933 (define_expand "ffs<mode>2"
11934 [(set (match_dup 2) (const_int -1))
11935 (parallel [(set (reg:CCZ FLAGS_REG)
11937 (match_operand:SWI48 1 "nonimmediate_operand" "")
11939 (set (match_operand:SWI48 0 "register_operand" "")
11940 (ctz:SWI48 (match_dup 1)))])
11941 (set (match_dup 0) (if_then_else:SWI48
11942 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11945 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11946 (clobber (reg:CC FLAGS_REG))])]
11949 if (<MODE>mode == SImode && !TARGET_CMOVE)
11951 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11954 operands[2] = gen_reg_rtx (<MODE>mode);
11957 (define_insn_and_split "ffssi2_no_cmove"
11958 [(set (match_operand:SI 0 "register_operand" "=r")
11959 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11960 (clobber (match_scratch:SI 2 "=&q"))
11961 (clobber (reg:CC FLAGS_REG))]
11964 "&& reload_completed"
11965 [(parallel [(set (reg:CCZ FLAGS_REG)
11966 (compare:CCZ (match_dup 1) (const_int 0)))
11967 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11968 (set (strict_low_part (match_dup 3))
11969 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11970 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11971 (clobber (reg:CC FLAGS_REG))])
11972 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11973 (clobber (reg:CC FLAGS_REG))])
11974 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11975 (clobber (reg:CC FLAGS_REG))])]
11977 operands[3] = gen_lowpart (QImode, operands[2]);
11978 ix86_expand_clear (operands[2]);
11981 (define_insn "*ffs<mode>_1"
11982 [(set (reg:CCZ FLAGS_REG)
11983 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11985 (set (match_operand:SWI48 0 "register_operand" "=r")
11986 (ctz:SWI48 (match_dup 1)))]
11988 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11989 [(set_attr "type" "alu1")
11990 (set_attr "prefix_0f" "1")
11991 (set_attr "mode" "<MODE>")])
11993 (define_insn "ctz<mode>2"
11994 [(set (match_operand:SWI248 0 "register_operand" "=r")
11995 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11996 (clobber (reg:CC FLAGS_REG))]
12000 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12002 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12004 [(set_attr "type" "alu1")
12005 (set_attr "prefix_0f" "1")
12006 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12007 (set_attr "mode" "<MODE>")])
12009 (define_expand "clz<mode>2"
12011 [(set (match_operand:SWI248 0 "register_operand" "")
12014 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12015 (clobber (reg:CC FLAGS_REG))])
12017 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12018 (clobber (reg:CC FLAGS_REG))])]
12023 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12026 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12029 (define_insn "clz<mode>2_lzcnt"
12030 [(set (match_operand:SWI248 0 "register_operand" "=r")
12031 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12032 (clobber (reg:CC FLAGS_REG))]
12034 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12035 [(set_attr "prefix_rep" "1")
12036 (set_attr "type" "bitmanip")
12037 (set_attr "mode" "<MODE>")])
12039 ;; BMI instructions.
12040 (define_insn "*bmi_andn_<mode>"
12041 [(set (match_operand:SWI48 0 "register_operand" "=r")
12044 (match_operand:SWI48 1 "register_operand" "r"))
12045 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12046 (clobber (reg:CC FLAGS_REG))]
12048 "andn\t{%2, %1, %0|%0, %1, %2}"
12049 [(set_attr "type" "bitmanip")
12050 (set_attr "mode" "<MODE>")])
12052 (define_insn "bmi_bextr_<mode>"
12053 [(set (match_operand:SWI48 0 "register_operand" "=r")
12054 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12055 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12057 (clobber (reg:CC FLAGS_REG))]
12059 "bextr\t{%2, %1, %0|%0, %1, %2}"
12060 [(set_attr "type" "bitmanip")
12061 (set_attr "mode" "<MODE>")])
12063 (define_insn "*bmi_blsi_<mode>"
12064 [(set (match_operand:SWI48 0 "register_operand" "=r")
12067 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12069 (clobber (reg:CC FLAGS_REG))]
12071 "blsi\t{%1, %0|%0, %1}"
12072 [(set_attr "type" "bitmanip")
12073 (set_attr "mode" "<MODE>")])
12075 (define_insn "*bmi_blsmsk_<mode>"
12076 [(set (match_operand:SWI48 0 "register_operand" "=r")
12079 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12082 (clobber (reg:CC FLAGS_REG))]
12084 "blsmsk\t{%1, %0|%0, %1}"
12085 [(set_attr "type" "bitmanip")
12086 (set_attr "mode" "<MODE>")])
12088 (define_insn "*bmi_blsr_<mode>"
12089 [(set (match_operand:SWI48 0 "register_operand" "=r")
12092 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12095 (clobber (reg:CC FLAGS_REG))]
12097 "blsr\t{%1, %0|%0, %1}"
12098 [(set_attr "type" "bitmanip")
12099 (set_attr "mode" "<MODE>")])
12101 ;; BMI2 instructions.
12102 (define_insn "bmi2_bzhi_<mode>3"
12103 [(set (match_operand:SWI48 0 "register_operand" "=r")
12104 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12105 (lshiftrt:SWI48 (const_int -1)
12106 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12107 (clobber (reg:CC FLAGS_REG))]
12109 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12110 [(set_attr "type" "bitmanip")
12111 (set_attr "prefix" "vex")
12112 (set_attr "mode" "<MODE>")])
12114 (define_insn "bmi2_pdep_<mode>3"
12115 [(set (match_operand:SWI48 0 "register_operand" "=r")
12116 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12117 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12120 "pdep\t{%2, %1, %0|%0, %1, %2}"
12121 [(set_attr "type" "bitmanip")
12122 (set_attr "prefix" "vex")
12123 (set_attr "mode" "<MODE>")])
12125 (define_insn "bmi2_pext_<mode>3"
12126 [(set (match_operand:SWI48 0 "register_operand" "=r")
12127 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12128 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12131 "pext\t{%2, %1, %0|%0, %1, %2}"
12132 [(set_attr "type" "bitmanip")
12133 (set_attr "prefix" "vex")
12134 (set_attr "mode" "<MODE>")])
12136 ;; TBM instructions.
12137 (define_insn "tbm_bextri_<mode>"
12138 [(set (match_operand:SWI48 0 "register_operand" "=r")
12139 (zero_extract:SWI48
12140 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12141 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12142 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12143 (clobber (reg:CC FLAGS_REG))]
12146 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12147 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12149 [(set_attr "type" "bitmanip")
12150 (set_attr "mode" "<MODE>")])
12152 (define_insn "*tbm_blcfill_<mode>"
12153 [(set (match_operand:SWI48 0 "register_operand" "=r")
12156 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12159 (clobber (reg:CC FLAGS_REG))]
12161 "blcfill\t{%1, %0|%0, %1}"
12162 [(set_attr "type" "bitmanip")
12163 (set_attr "mode" "<MODE>")])
12165 (define_insn "*tbm_blci_<mode>"
12166 [(set (match_operand:SWI48 0 "register_operand" "=r")
12170 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12173 (clobber (reg:CC FLAGS_REG))]
12175 "blci\t{%1, %0|%0, %1}"
12176 [(set_attr "type" "bitmanip")
12177 (set_attr "mode" "<MODE>")])
12179 (define_insn "*tbm_blcic_<mode>"
12180 [(set (match_operand:SWI48 0 "register_operand" "=r")
12183 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12187 (clobber (reg:CC FLAGS_REG))]
12189 "blcic\t{%1, %0|%0, %1}"
12190 [(set_attr "type" "bitmanip")
12191 (set_attr "mode" "<MODE>")])
12193 (define_insn "*tbm_blcmsk_<mode>"
12194 [(set (match_operand:SWI48 0 "register_operand" "=r")
12197 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12200 (clobber (reg:CC FLAGS_REG))]
12202 "blcmsk\t{%1, %0|%0, %1}"
12203 [(set_attr "type" "bitmanip")
12204 (set_attr "mode" "<MODE>")])
12206 (define_insn "*tbm_blcs_<mode>"
12207 [(set (match_operand:SWI48 0 "register_operand" "=r")
12210 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12213 (clobber (reg:CC FLAGS_REG))]
12215 "blcs\t{%1, %0|%0, %1}"
12216 [(set_attr "type" "bitmanip")
12217 (set_attr "mode" "<MODE>")])
12219 (define_insn "*tbm_blsfill_<mode>"
12220 [(set (match_operand:SWI48 0 "register_operand" "=r")
12223 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12226 (clobber (reg:CC FLAGS_REG))]
12228 "blsfill\t{%1, %0|%0, %1}"
12229 [(set_attr "type" "bitmanip")
12230 (set_attr "mode" "<MODE>")])
12232 (define_insn "*tbm_blsic_<mode>"
12233 [(set (match_operand:SWI48 0 "register_operand" "=r")
12236 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12240 (clobber (reg:CC FLAGS_REG))]
12242 "blsic\t{%1, %0|%0, %1}"
12243 [(set_attr "type" "bitmanip")
12244 (set_attr "mode" "<MODE>")])
12246 (define_insn "*tbm_t1mskc_<mode>"
12247 [(set (match_operand:SWI48 0 "register_operand" "=r")
12250 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12254 (clobber (reg:CC FLAGS_REG))]
12256 "t1mskc\t{%1, %0|%0, %1}"
12257 [(set_attr "type" "bitmanip")
12258 (set_attr "mode" "<MODE>")])
12260 (define_insn "*tbm_tzmsk_<mode>"
12261 [(set (match_operand:SWI48 0 "register_operand" "=r")
12264 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12268 (clobber (reg:CC FLAGS_REG))]
12270 "tzmsk\t{%1, %0|%0, %1}"
12271 [(set_attr "type" "bitmanip")
12272 (set_attr "mode" "<MODE>")])
12274 (define_insn "bsr_rex64"
12275 [(set (match_operand:DI 0 "register_operand" "=r")
12276 (minus:DI (const_int 63)
12277 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12278 (clobber (reg:CC FLAGS_REG))]
12280 "bsr{q}\t{%1, %0|%0, %1}"
12281 [(set_attr "type" "alu1")
12282 (set_attr "prefix_0f" "1")
12283 (set_attr "mode" "DI")])
12286 [(set (match_operand:SI 0 "register_operand" "=r")
12287 (minus:SI (const_int 31)
12288 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12289 (clobber (reg:CC FLAGS_REG))]
12291 "bsr{l}\t{%1, %0|%0, %1}"
12292 [(set_attr "type" "alu1")
12293 (set_attr "prefix_0f" "1")
12294 (set_attr "mode" "SI")])
12296 (define_insn "*bsrhi"
12297 [(set (match_operand:HI 0 "register_operand" "=r")
12298 (minus:HI (const_int 15)
12299 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12300 (clobber (reg:CC FLAGS_REG))]
12302 "bsr{w}\t{%1, %0|%0, %1}"
12303 [(set_attr "type" "alu1")
12304 (set_attr "prefix_0f" "1")
12305 (set_attr "mode" "HI")])
12307 (define_insn "popcount<mode>2"
12308 [(set (match_operand:SWI248 0 "register_operand" "=r")
12310 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12311 (clobber (reg:CC FLAGS_REG))]
12315 return "popcnt\t{%1, %0|%0, %1}";
12317 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12320 [(set_attr "prefix_rep" "1")
12321 (set_attr "type" "bitmanip")
12322 (set_attr "mode" "<MODE>")])
12324 (define_insn "*popcount<mode>2_cmp"
12325 [(set (reg FLAGS_REG)
12328 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12330 (set (match_operand:SWI248 0 "register_operand" "=r")
12331 (popcount:SWI248 (match_dup 1)))]
12332 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12335 return "popcnt\t{%1, %0|%0, %1}";
12337 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12340 [(set_attr "prefix_rep" "1")
12341 (set_attr "type" "bitmanip")
12342 (set_attr "mode" "<MODE>")])
12344 (define_insn "*popcountsi2_cmp_zext"
12345 [(set (reg FLAGS_REG)
12347 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12349 (set (match_operand:DI 0 "register_operand" "=r")
12350 (zero_extend:DI(popcount:SI (match_dup 1))))]
12351 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12354 return "popcnt\t{%1, %0|%0, %1}";
12356 return "popcnt{l}\t{%1, %0|%0, %1}";
12359 [(set_attr "prefix_rep" "1")
12360 (set_attr "type" "bitmanip")
12361 (set_attr "mode" "SI")])
12363 (define_expand "bswap<mode>2"
12364 [(set (match_operand:SWI48 0 "register_operand" "")
12365 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12368 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12370 rtx x = operands[0];
12372 emit_move_insn (x, operands[1]);
12373 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12374 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12375 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12380 (define_insn "*bswap<mode>2_movbe"
12381 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12382 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12384 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12387 movbe\t{%1, %0|%0, %1}
12388 movbe\t{%1, %0|%0, %1}"
12389 [(set_attr "type" "bitmanip,imov,imov")
12390 (set_attr "modrm" "0,1,1")
12391 (set_attr "prefix_0f" "*,1,1")
12392 (set_attr "prefix_extra" "*,1,1")
12393 (set_attr "mode" "<MODE>")])
12395 (define_insn "*bswap<mode>2_1"
12396 [(set (match_operand:SWI48 0 "register_operand" "=r")
12397 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12400 [(set_attr "type" "bitmanip")
12401 (set_attr "modrm" "0")
12402 (set_attr "mode" "<MODE>")])
12404 (define_insn "*bswaphi_lowpart_1"
12405 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12406 (bswap:HI (match_dup 0)))
12407 (clobber (reg:CC FLAGS_REG))]
12408 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12410 xchg{b}\t{%h0, %b0|%b0, %h0}
12411 rol{w}\t{$8, %0|%0, 8}"
12412 [(set_attr "length" "2,4")
12413 (set_attr "mode" "QI,HI")])
12415 (define_insn "bswaphi_lowpart"
12416 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12417 (bswap:HI (match_dup 0)))
12418 (clobber (reg:CC FLAGS_REG))]
12420 "rol{w}\t{$8, %0|%0, 8}"
12421 [(set_attr "length" "4")
12422 (set_attr "mode" "HI")])
12424 (define_expand "paritydi2"
12425 [(set (match_operand:DI 0 "register_operand" "")
12426 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12429 rtx scratch = gen_reg_rtx (QImode);
12432 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12433 NULL_RTX, operands[1]));
12435 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12436 gen_rtx_REG (CCmode, FLAGS_REG),
12438 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12441 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12444 rtx tmp = gen_reg_rtx (SImode);
12446 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12447 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12452 (define_expand "paritysi2"
12453 [(set (match_operand:SI 0 "register_operand" "")
12454 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12457 rtx scratch = gen_reg_rtx (QImode);
12460 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12462 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12463 gen_rtx_REG (CCmode, FLAGS_REG),
12465 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12467 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12471 (define_insn_and_split "paritydi2_cmp"
12472 [(set (reg:CC FLAGS_REG)
12473 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12475 (clobber (match_scratch:DI 0 "=r"))
12476 (clobber (match_scratch:SI 1 "=&r"))
12477 (clobber (match_scratch:HI 2 "=Q"))]
12480 "&& reload_completed"
12482 [(set (match_dup 1)
12483 (xor:SI (match_dup 1) (match_dup 4)))
12484 (clobber (reg:CC FLAGS_REG))])
12486 [(set (reg:CC FLAGS_REG)
12487 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12488 (clobber (match_dup 1))
12489 (clobber (match_dup 2))])]
12491 operands[4] = gen_lowpart (SImode, operands[3]);
12495 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12496 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12499 operands[1] = gen_highpart (SImode, operands[3]);
12502 (define_insn_and_split "paritysi2_cmp"
12503 [(set (reg:CC FLAGS_REG)
12504 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12506 (clobber (match_scratch:SI 0 "=r"))
12507 (clobber (match_scratch:HI 1 "=&Q"))]
12510 "&& reload_completed"
12512 [(set (match_dup 1)
12513 (xor:HI (match_dup 1) (match_dup 3)))
12514 (clobber (reg:CC FLAGS_REG))])
12516 [(set (reg:CC FLAGS_REG)
12517 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12518 (clobber (match_dup 1))])]
12520 operands[3] = gen_lowpart (HImode, operands[2]);
12522 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12523 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12526 (define_insn "*parityhi2_cmp"
12527 [(set (reg:CC FLAGS_REG)
12528 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12530 (clobber (match_scratch:HI 0 "=Q"))]
12532 "xor{b}\t{%h0, %b0|%b0, %h0}"
12533 [(set_attr "length" "2")
12534 (set_attr "mode" "HI")])
12537 ;; Thread-local storage patterns for ELF.
12539 ;; Note that these code sequences must appear exactly as shown
12540 ;; in order to allow linker relaxation.
12542 (define_insn "*tls_global_dynamic_32_gnu"
12543 [(set (match_operand:SI 0 "register_operand" "=a")
12545 [(match_operand:SI 1 "register_operand" "b")
12546 (match_operand:SI 2 "tls_symbolic_operand" "")
12547 (match_operand:SI 3 "constant_call_address_operand" "z")]
12549 (clobber (match_scratch:SI 4 "=d"))
12550 (clobber (match_scratch:SI 5 "=c"))
12551 (clobber (reg:CC FLAGS_REG))]
12552 "!TARGET_64BIT && TARGET_GNU_TLS"
12555 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12556 if (TARGET_SUN_TLS)
12557 #ifdef HAVE_AS_IX86_TLSGDPLT
12558 return "call\t%a2@tlsgdplt";
12560 return "call\t%p3@plt";
12562 return "call\t%P3";
12564 [(set_attr "type" "multi")
12565 (set_attr "length" "12")])
12567 (define_expand "tls_global_dynamic_32"
12569 [(set (match_operand:SI 0 "register_operand" "")
12570 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12571 (match_operand:SI 1 "tls_symbolic_operand" "")
12572 (match_operand:SI 3 "constant_call_address_operand" "")]
12574 (clobber (match_scratch:SI 4 ""))
12575 (clobber (match_scratch:SI 5 ""))
12576 (clobber (reg:CC FLAGS_REG))])])
12578 (define_insn "*tls_global_dynamic_64"
12579 [(set (match_operand:DI 0 "register_operand" "=a")
12581 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12582 (match_operand:DI 3 "" "")))
12583 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12588 fputs (ASM_BYTE "0x66\n", asm_out_file);
12590 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12591 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12592 fputs ("\trex64\n", asm_out_file);
12593 if (TARGET_SUN_TLS)
12594 return "call\t%p2@plt";
12595 return "call\t%P2";
12597 [(set_attr "type" "multi")
12598 (set (attr "length")
12599 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12601 (define_expand "tls_global_dynamic_64"
12603 [(set (match_operand:DI 0 "register_operand" "")
12605 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12607 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12610 (define_insn "*tls_local_dynamic_base_32_gnu"
12611 [(set (match_operand:SI 0 "register_operand" "=a")
12613 [(match_operand:SI 1 "register_operand" "b")
12614 (match_operand:SI 2 "constant_call_address_operand" "z")]
12615 UNSPEC_TLS_LD_BASE))
12616 (clobber (match_scratch:SI 3 "=d"))
12617 (clobber (match_scratch:SI 4 "=c"))
12618 (clobber (reg:CC FLAGS_REG))]
12619 "!TARGET_64BIT && TARGET_GNU_TLS"
12622 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12623 if (TARGET_SUN_TLS)
12624 #ifdef HAVE_AS_IX86_TLSLDMPLT
12625 return "call\t%&@tlsldmplt";
12627 return "call\t%p2@plt";
12629 return "call\t%P2";
12631 [(set_attr "type" "multi")
12632 (set_attr "length" "11")])
12634 (define_expand "tls_local_dynamic_base_32"
12636 [(set (match_operand:SI 0 "register_operand" "")
12638 [(match_operand:SI 1 "register_operand" "")
12639 (match_operand:SI 2 "constant_call_address_operand" "")]
12640 UNSPEC_TLS_LD_BASE))
12641 (clobber (match_scratch:SI 3 ""))
12642 (clobber (match_scratch:SI 4 ""))
12643 (clobber (reg:CC FLAGS_REG))])])
12645 (define_insn "*tls_local_dynamic_base_64"
12646 [(set (match_operand:DI 0 "register_operand" "=a")
12648 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12649 (match_operand:DI 2 "" "")))
12650 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12654 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12655 if (TARGET_SUN_TLS)
12656 return "call\t%p1@plt";
12657 return "call\t%P1";
12659 [(set_attr "type" "multi")
12660 (set_attr "length" "12")])
12662 (define_expand "tls_local_dynamic_base_64"
12664 [(set (match_operand:DI 0 "register_operand" "")
12666 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12668 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12670 ;; Local dynamic of a single variable is a lose. Show combine how
12671 ;; to convert that back to global dynamic.
12673 (define_insn_and_split "*tls_local_dynamic_32_once"
12674 [(set (match_operand:SI 0 "register_operand" "=a")
12676 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12677 (match_operand:SI 2 "constant_call_address_operand" "z")]
12678 UNSPEC_TLS_LD_BASE)
12679 (const:SI (unspec:SI
12680 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12682 (clobber (match_scratch:SI 4 "=d"))
12683 (clobber (match_scratch:SI 5 "=c"))
12684 (clobber (reg:CC FLAGS_REG))]
12689 [(set (match_dup 0)
12690 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12692 (clobber (match_dup 4))
12693 (clobber (match_dup 5))
12694 (clobber (reg:CC FLAGS_REG))])])
12696 ;; Segment register for the thread base ptr load
12697 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12699 ;; Load and add the thread base pointer from %<tp_seg>:0.
12700 (define_insn "*load_tp_x32"
12701 [(set (match_operand:SI 0 "register_operand" "=r")
12702 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12704 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12705 [(set_attr "type" "imov")
12706 (set_attr "modrm" "0")
12707 (set_attr "length" "7")
12708 (set_attr "memory" "load")
12709 (set_attr "imm_disp" "false")])
12711 (define_insn "*load_tp_x32_zext"
12712 [(set (match_operand:DI 0 "register_operand" "=r")
12713 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12715 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12716 [(set_attr "type" "imov")
12717 (set_attr "modrm" "0")
12718 (set_attr "length" "7")
12719 (set_attr "memory" "load")
12720 (set_attr "imm_disp" "false")])
12722 (define_insn "*load_tp_<mode>"
12723 [(set (match_operand:P 0 "register_operand" "=r")
12724 (unspec:P [(const_int 0)] UNSPEC_TP))]
12726 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12727 [(set_attr "type" "imov")
12728 (set_attr "modrm" "0")
12729 (set_attr "length" "7")
12730 (set_attr "memory" "load")
12731 (set_attr "imm_disp" "false")])
12733 (define_insn "*add_tp_x32"
12734 [(set (match_operand:SI 0 "register_operand" "=r")
12735 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12736 (match_operand:SI 1 "register_operand" "0")))
12737 (clobber (reg:CC FLAGS_REG))]
12739 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12740 [(set_attr "type" "alu")
12741 (set_attr "modrm" "0")
12742 (set_attr "length" "7")
12743 (set_attr "memory" "load")
12744 (set_attr "imm_disp" "false")])
12746 (define_insn "*add_tp_x32_zext"
12747 [(set (match_operand:DI 0 "register_operand" "=r")
12749 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12750 (match_operand:SI 1 "register_operand" "0"))))
12751 (clobber (reg:CC FLAGS_REG))]
12753 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12754 [(set_attr "type" "alu")
12755 (set_attr "modrm" "0")
12756 (set_attr "length" "7")
12757 (set_attr "memory" "load")
12758 (set_attr "imm_disp" "false")])
12760 (define_insn "*add_tp_<mode>"
12761 [(set (match_operand:P 0 "register_operand" "=r")
12762 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12763 (match_operand:P 1 "register_operand" "0")))
12764 (clobber (reg:CC FLAGS_REG))]
12766 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12767 [(set_attr "type" "alu")
12768 (set_attr "modrm" "0")
12769 (set_attr "length" "7")
12770 (set_attr "memory" "load")
12771 (set_attr "imm_disp" "false")])
12773 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12774 ;; %rax as destination of the initial executable code sequence.
12775 (define_insn "tls_initial_exec_64_sun"
12776 [(set (match_operand:DI 0 "register_operand" "=a")
12778 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12779 UNSPEC_TLS_IE_SUN))
12780 (clobber (reg:CC FLAGS_REG))]
12781 "TARGET_64BIT && TARGET_SUN_TLS"
12784 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12785 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12787 [(set_attr "type" "multi")])
12789 ;; GNU2 TLS patterns can be split.
12791 (define_expand "tls_dynamic_gnu2_32"
12792 [(set (match_dup 3)
12793 (plus:SI (match_operand:SI 2 "register_operand" "")
12795 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12798 [(set (match_operand:SI 0 "register_operand" "")
12799 (unspec:SI [(match_dup 1) (match_dup 3)
12800 (match_dup 2) (reg:SI SP_REG)]
12802 (clobber (reg:CC FLAGS_REG))])]
12803 "!TARGET_64BIT && TARGET_GNU2_TLS"
12805 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12806 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12809 (define_insn "*tls_dynamic_gnu2_lea_32"
12810 [(set (match_operand:SI 0 "register_operand" "=r")
12811 (plus:SI (match_operand:SI 1 "register_operand" "b")
12813 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12814 UNSPEC_TLSDESC))))]
12815 "!TARGET_64BIT && TARGET_GNU2_TLS"
12816 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12817 [(set_attr "type" "lea")
12818 (set_attr "mode" "SI")
12819 (set_attr "length" "6")
12820 (set_attr "length_address" "4")])
12822 (define_insn "*tls_dynamic_gnu2_call_32"
12823 [(set (match_operand:SI 0 "register_operand" "=a")
12824 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12825 (match_operand:SI 2 "register_operand" "0")
12826 ;; we have to make sure %ebx still points to the GOT
12827 (match_operand:SI 3 "register_operand" "b")
12830 (clobber (reg:CC FLAGS_REG))]
12831 "!TARGET_64BIT && TARGET_GNU2_TLS"
12832 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12833 [(set_attr "type" "call")
12834 (set_attr "length" "2")
12835 (set_attr "length_address" "0")])
12837 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12838 [(set (match_operand:SI 0 "register_operand" "=&a")
12840 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12841 (match_operand:SI 4 "" "")
12842 (match_operand:SI 2 "register_operand" "b")
12845 (const:SI (unspec:SI
12846 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12848 (clobber (reg:CC FLAGS_REG))]
12849 "!TARGET_64BIT && TARGET_GNU2_TLS"
12852 [(set (match_dup 0) (match_dup 5))]
12854 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12855 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12858 (define_expand "tls_dynamic_gnu2_64"
12859 [(set (match_dup 2)
12860 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12863 [(set (match_operand:DI 0 "register_operand" "")
12864 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12866 (clobber (reg:CC FLAGS_REG))])]
12867 "TARGET_64BIT && TARGET_GNU2_TLS"
12869 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12870 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12873 (define_insn "*tls_dynamic_gnu2_lea_64"
12874 [(set (match_operand:DI 0 "register_operand" "=r")
12875 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12877 "TARGET_64BIT && TARGET_GNU2_TLS"
12878 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12879 [(set_attr "type" "lea")
12880 (set_attr "mode" "DI")
12881 (set_attr "length" "7")
12882 (set_attr "length_address" "4")])
12884 (define_insn "*tls_dynamic_gnu2_call_64"
12885 [(set (match_operand:DI 0 "register_operand" "=a")
12886 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12887 (match_operand:DI 2 "register_operand" "0")
12890 (clobber (reg:CC FLAGS_REG))]
12891 "TARGET_64BIT && TARGET_GNU2_TLS"
12892 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12893 [(set_attr "type" "call")
12894 (set_attr "length" "2")
12895 (set_attr "length_address" "0")])
12897 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12898 [(set (match_operand:DI 0 "register_operand" "=&a")
12900 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12901 (match_operand:DI 3 "" "")
12904 (const:DI (unspec:DI
12905 [(match_operand 1 "tls_symbolic_operand" "")]
12907 (clobber (reg:CC FLAGS_REG))]
12908 "TARGET_64BIT && TARGET_GNU2_TLS"
12911 [(set (match_dup 0) (match_dup 4))]
12913 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12914 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12917 ;; These patterns match the binary 387 instructions for addM3, subM3,
12918 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12919 ;; SFmode. The first is the normal insn, the second the same insn but
12920 ;; with one operand a conversion, and the third the same insn but with
12921 ;; the other operand a conversion. The conversion may be SFmode or
12922 ;; SImode if the target mode DFmode, but only SImode if the target mode
12925 ;; Gcc is slightly more smart about handling normal two address instructions
12926 ;; so use special patterns for add and mull.
12928 (define_insn "*fop_<mode>_comm_mixed"
12929 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12930 (match_operator:MODEF 3 "binary_fp_operator"
12931 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12932 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12933 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12934 && COMMUTATIVE_ARITH_P (operands[3])
12935 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12936 "* return output_387_binary_op (insn, operands);"
12937 [(set (attr "type")
12938 (if_then_else (eq_attr "alternative" "1,2")
12939 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12940 (const_string "ssemul")
12941 (const_string "sseadd"))
12942 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12943 (const_string "fmul")
12944 (const_string "fop"))))
12945 (set_attr "isa" "*,noavx,avx")
12946 (set_attr "prefix" "orig,orig,vex")
12947 (set_attr "mode" "<MODE>")])
12949 (define_insn "*fop_<mode>_comm_sse"
12950 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12951 (match_operator:MODEF 3 "binary_fp_operator"
12952 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12953 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12954 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12955 && COMMUTATIVE_ARITH_P (operands[3])
12956 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12957 "* return output_387_binary_op (insn, operands);"
12958 [(set (attr "type")
12959 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12960 (const_string "ssemul")
12961 (const_string "sseadd")))
12962 (set_attr "isa" "noavx,avx")
12963 (set_attr "prefix" "orig,vex")
12964 (set_attr "mode" "<MODE>")])
12966 (define_insn "*fop_<mode>_comm_i387"
12967 [(set (match_operand:MODEF 0 "register_operand" "=f")
12968 (match_operator:MODEF 3 "binary_fp_operator"
12969 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12970 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12971 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12972 && COMMUTATIVE_ARITH_P (operands[3])
12973 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12974 "* return output_387_binary_op (insn, operands);"
12975 [(set (attr "type")
12976 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12977 (const_string "fmul")
12978 (const_string "fop")))
12979 (set_attr "mode" "<MODE>")])
12981 (define_insn "*fop_<mode>_1_mixed"
12982 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12983 (match_operator:MODEF 3 "binary_fp_operator"
12984 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12985 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12986 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12987 && !COMMUTATIVE_ARITH_P (operands[3])
12988 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12989 "* return output_387_binary_op (insn, operands);"
12990 [(set (attr "type")
12991 (cond [(and (eq_attr "alternative" "2,3")
12992 (match_operand:MODEF 3 "mult_operator" ""))
12993 (const_string "ssemul")
12994 (and (eq_attr "alternative" "2,3")
12995 (match_operand:MODEF 3 "div_operator" ""))
12996 (const_string "ssediv")
12997 (eq_attr "alternative" "2,3")
12998 (const_string "sseadd")
12999 (match_operand:MODEF 3 "mult_operator" "")
13000 (const_string "fmul")
13001 (match_operand:MODEF 3 "div_operator" "")
13002 (const_string "fdiv")
13004 (const_string "fop")))
13005 (set_attr "isa" "*,*,noavx,avx")
13006 (set_attr "prefix" "orig,orig,orig,vex")
13007 (set_attr "mode" "<MODE>")])
13009 (define_insn "*rcpsf2_sse"
13010 [(set (match_operand:SF 0 "register_operand" "=x")
13011 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13014 "%vrcpss\t{%1, %d0|%d0, %1}"
13015 [(set_attr "type" "sse")
13016 (set_attr "atom_sse_attr" "rcp")
13017 (set_attr "prefix" "maybe_vex")
13018 (set_attr "mode" "SF")])
13020 (define_insn "*fop_<mode>_1_sse"
13021 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13022 (match_operator:MODEF 3 "binary_fp_operator"
13023 [(match_operand:MODEF 1 "register_operand" "0,x")
13024 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13025 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13026 && !COMMUTATIVE_ARITH_P (operands[3])"
13027 "* return output_387_binary_op (insn, operands);"
13028 [(set (attr "type")
13029 (cond [(match_operand:MODEF 3 "mult_operator" "")
13030 (const_string "ssemul")
13031 (match_operand:MODEF 3 "div_operator" "")
13032 (const_string "ssediv")
13034 (const_string "sseadd")))
13035 (set_attr "isa" "noavx,avx")
13036 (set_attr "prefix" "orig,vex")
13037 (set_attr "mode" "<MODE>")])
13039 ;; This pattern is not fully shadowed by the pattern above.
13040 (define_insn "*fop_<mode>_1_i387"
13041 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13042 (match_operator:MODEF 3 "binary_fp_operator"
13043 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13044 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13045 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13046 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13047 && !COMMUTATIVE_ARITH_P (operands[3])
13048 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13049 "* return output_387_binary_op (insn, operands);"
13050 [(set (attr "type")
13051 (cond [(match_operand:MODEF 3 "mult_operator" "")
13052 (const_string "fmul")
13053 (match_operand:MODEF 3 "div_operator" "")
13054 (const_string "fdiv")
13056 (const_string "fop")))
13057 (set_attr "mode" "<MODE>")])
13059 ;; ??? Add SSE splitters for these!
13060 (define_insn "*fop_<MODEF:mode>_2_i387"
13061 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13062 (match_operator:MODEF 3 "binary_fp_operator"
13064 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13065 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13066 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13067 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13068 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13069 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13070 [(set (attr "type")
13071 (cond [(match_operand:MODEF 3 "mult_operator" "")
13072 (const_string "fmul")
13073 (match_operand:MODEF 3 "div_operator" "")
13074 (const_string "fdiv")
13076 (const_string "fop")))
13077 (set_attr "fp_int_src" "true")
13078 (set_attr "mode" "<SWI24:MODE>")])
13080 (define_insn "*fop_<MODEF:mode>_3_i387"
13081 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13082 (match_operator:MODEF 3 "binary_fp_operator"
13083 [(match_operand:MODEF 1 "register_operand" "0,0")
13085 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13086 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13087 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13088 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13089 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13090 [(set (attr "type")
13091 (cond [(match_operand:MODEF 3 "mult_operator" "")
13092 (const_string "fmul")
13093 (match_operand:MODEF 3 "div_operator" "")
13094 (const_string "fdiv")
13096 (const_string "fop")))
13097 (set_attr "fp_int_src" "true")
13098 (set_attr "mode" "<MODE>")])
13100 (define_insn "*fop_df_4_i387"
13101 [(set (match_operand:DF 0 "register_operand" "=f,f")
13102 (match_operator:DF 3 "binary_fp_operator"
13104 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13105 (match_operand:DF 2 "register_operand" "0,f")]))]
13106 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13107 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13108 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13109 "* return output_387_binary_op (insn, operands);"
13110 [(set (attr "type")
13111 (cond [(match_operand:DF 3 "mult_operator" "")
13112 (const_string "fmul")
13113 (match_operand:DF 3 "div_operator" "")
13114 (const_string "fdiv")
13116 (const_string "fop")))
13117 (set_attr "mode" "SF")])
13119 (define_insn "*fop_df_5_i387"
13120 [(set (match_operand:DF 0 "register_operand" "=f,f")
13121 (match_operator:DF 3 "binary_fp_operator"
13122 [(match_operand:DF 1 "register_operand" "0,f")
13124 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13125 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13126 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13127 "* return output_387_binary_op (insn, operands);"
13128 [(set (attr "type")
13129 (cond [(match_operand:DF 3 "mult_operator" "")
13130 (const_string "fmul")
13131 (match_operand:DF 3 "div_operator" "")
13132 (const_string "fdiv")
13134 (const_string "fop")))
13135 (set_attr "mode" "SF")])
13137 (define_insn "*fop_df_6_i387"
13138 [(set (match_operand:DF 0 "register_operand" "=f,f")
13139 (match_operator:DF 3 "binary_fp_operator"
13141 (match_operand:SF 1 "register_operand" "0,f"))
13143 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13144 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13145 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13146 "* return output_387_binary_op (insn, operands);"
13147 [(set (attr "type")
13148 (cond [(match_operand:DF 3 "mult_operator" "")
13149 (const_string "fmul")
13150 (match_operand:DF 3 "div_operator" "")
13151 (const_string "fdiv")
13153 (const_string "fop")))
13154 (set_attr "mode" "SF")])
13156 (define_insn "*fop_xf_comm_i387"
13157 [(set (match_operand:XF 0 "register_operand" "=f")
13158 (match_operator:XF 3 "binary_fp_operator"
13159 [(match_operand:XF 1 "register_operand" "%0")
13160 (match_operand:XF 2 "register_operand" "f")]))]
13162 && COMMUTATIVE_ARITH_P (operands[3])"
13163 "* return output_387_binary_op (insn, operands);"
13164 [(set (attr "type")
13165 (if_then_else (match_operand:XF 3 "mult_operator" "")
13166 (const_string "fmul")
13167 (const_string "fop")))
13168 (set_attr "mode" "XF")])
13170 (define_insn "*fop_xf_1_i387"
13171 [(set (match_operand:XF 0 "register_operand" "=f,f")
13172 (match_operator:XF 3 "binary_fp_operator"
13173 [(match_operand:XF 1 "register_operand" "0,f")
13174 (match_operand:XF 2 "register_operand" "f,0")]))]
13176 && !COMMUTATIVE_ARITH_P (operands[3])"
13177 "* return output_387_binary_op (insn, operands);"
13178 [(set (attr "type")
13179 (cond [(match_operand:XF 3 "mult_operator" "")
13180 (const_string "fmul")
13181 (match_operand:XF 3 "div_operator" "")
13182 (const_string "fdiv")
13184 (const_string "fop")))
13185 (set_attr "mode" "XF")])
13187 (define_insn "*fop_xf_2_i387"
13188 [(set (match_operand:XF 0 "register_operand" "=f,f")
13189 (match_operator:XF 3 "binary_fp_operator"
13191 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13192 (match_operand:XF 2 "register_operand" "0,0")]))]
13193 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13194 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13195 [(set (attr "type")
13196 (cond [(match_operand:XF 3 "mult_operator" "")
13197 (const_string "fmul")
13198 (match_operand:XF 3 "div_operator" "")
13199 (const_string "fdiv")
13201 (const_string "fop")))
13202 (set_attr "fp_int_src" "true")
13203 (set_attr "mode" "<MODE>")])
13205 (define_insn "*fop_xf_3_i387"
13206 [(set (match_operand:XF 0 "register_operand" "=f,f")
13207 (match_operator:XF 3 "binary_fp_operator"
13208 [(match_operand:XF 1 "register_operand" "0,0")
13210 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13211 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13212 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13213 [(set (attr "type")
13214 (cond [(match_operand:XF 3 "mult_operator" "")
13215 (const_string "fmul")
13216 (match_operand:XF 3 "div_operator" "")
13217 (const_string "fdiv")
13219 (const_string "fop")))
13220 (set_attr "fp_int_src" "true")
13221 (set_attr "mode" "<MODE>")])
13223 (define_insn "*fop_xf_4_i387"
13224 [(set (match_operand:XF 0 "register_operand" "=f,f")
13225 (match_operator:XF 3 "binary_fp_operator"
13227 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13228 (match_operand:XF 2 "register_operand" "0,f")]))]
13230 "* return output_387_binary_op (insn, operands);"
13231 [(set (attr "type")
13232 (cond [(match_operand:XF 3 "mult_operator" "")
13233 (const_string "fmul")
13234 (match_operand:XF 3 "div_operator" "")
13235 (const_string "fdiv")
13237 (const_string "fop")))
13238 (set_attr "mode" "<MODE>")])
13240 (define_insn "*fop_xf_5_i387"
13241 [(set (match_operand:XF 0 "register_operand" "=f,f")
13242 (match_operator:XF 3 "binary_fp_operator"
13243 [(match_operand:XF 1 "register_operand" "0,f")
13245 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13247 "* return output_387_binary_op (insn, operands);"
13248 [(set (attr "type")
13249 (cond [(match_operand:XF 3 "mult_operator" "")
13250 (const_string "fmul")
13251 (match_operand:XF 3 "div_operator" "")
13252 (const_string "fdiv")
13254 (const_string "fop")))
13255 (set_attr "mode" "<MODE>")])
13257 (define_insn "*fop_xf_6_i387"
13258 [(set (match_operand:XF 0 "register_operand" "=f,f")
13259 (match_operator:XF 3 "binary_fp_operator"
13261 (match_operand:MODEF 1 "register_operand" "0,f"))
13263 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13265 "* return output_387_binary_op (insn, operands);"
13266 [(set (attr "type")
13267 (cond [(match_operand:XF 3 "mult_operator" "")
13268 (const_string "fmul")
13269 (match_operand:XF 3 "div_operator" "")
13270 (const_string "fdiv")
13272 (const_string "fop")))
13273 (set_attr "mode" "<MODE>")])
13276 [(set (match_operand 0 "register_operand" "")
13277 (match_operator 3 "binary_fp_operator"
13278 [(float (match_operand:SWI24 1 "register_operand" ""))
13279 (match_operand 2 "register_operand" "")]))]
13281 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13282 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13285 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13286 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13287 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13288 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13289 GET_MODE (operands[3]),
13292 ix86_free_from_memory (GET_MODE (operands[1]));
13297 [(set (match_operand 0 "register_operand" "")
13298 (match_operator 3 "binary_fp_operator"
13299 [(match_operand 1 "register_operand" "")
13300 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13302 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13303 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13306 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13307 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13308 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13309 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13310 GET_MODE (operands[3]),
13313 ix86_free_from_memory (GET_MODE (operands[2]));
13317 ;; FPU special functions.
13319 ;; This pattern implements a no-op XFmode truncation for
13320 ;; all fancy i386 XFmode math functions.
13322 (define_insn "truncxf<mode>2_i387_noop_unspec"
13323 [(set (match_operand:MODEF 0 "register_operand" "=f")
13324 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13325 UNSPEC_TRUNC_NOOP))]
13326 "TARGET_USE_FANCY_MATH_387"
13327 "* return output_387_reg_move (insn, operands);"
13328 [(set_attr "type" "fmov")
13329 (set_attr "mode" "<MODE>")])
13331 (define_insn "sqrtxf2"
13332 [(set (match_operand:XF 0 "register_operand" "=f")
13333 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13334 "TARGET_USE_FANCY_MATH_387"
13336 [(set_attr "type" "fpspc")
13337 (set_attr "mode" "XF")
13338 (set_attr "athlon_decode" "direct")
13339 (set_attr "amdfam10_decode" "direct")
13340 (set_attr "bdver1_decode" "direct")])
13342 (define_insn "sqrt_extend<mode>xf2_i387"
13343 [(set (match_operand:XF 0 "register_operand" "=f")
13346 (match_operand:MODEF 1 "register_operand" "0"))))]
13347 "TARGET_USE_FANCY_MATH_387"
13349 [(set_attr "type" "fpspc")
13350 (set_attr "mode" "XF")
13351 (set_attr "athlon_decode" "direct")
13352 (set_attr "amdfam10_decode" "direct")
13353 (set_attr "bdver1_decode" "direct")])
13355 (define_insn "*rsqrtsf2_sse"
13356 [(set (match_operand:SF 0 "register_operand" "=x")
13357 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13360 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13361 [(set_attr "type" "sse")
13362 (set_attr "atom_sse_attr" "rcp")
13363 (set_attr "prefix" "maybe_vex")
13364 (set_attr "mode" "SF")])
13366 (define_expand "rsqrtsf2"
13367 [(set (match_operand:SF 0 "register_operand" "")
13368 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13372 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13376 (define_insn "*sqrt<mode>2_sse"
13377 [(set (match_operand:MODEF 0 "register_operand" "=x")
13379 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13380 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13381 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13382 [(set_attr "type" "sse")
13383 (set_attr "atom_sse_attr" "sqrt")
13384 (set_attr "prefix" "maybe_vex")
13385 (set_attr "mode" "<MODE>")
13386 (set_attr "athlon_decode" "*")
13387 (set_attr "amdfam10_decode" "*")
13388 (set_attr "bdver1_decode" "*")])
13390 (define_expand "sqrt<mode>2"
13391 [(set (match_operand:MODEF 0 "register_operand" "")
13393 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13394 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13395 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13397 if (<MODE>mode == SFmode
13399 && TARGET_RECIP_SQRT
13400 && !optimize_function_for_size_p (cfun)
13401 && flag_finite_math_only && !flag_trapping_math
13402 && flag_unsafe_math_optimizations)
13404 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13408 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13410 rtx op0 = gen_reg_rtx (XFmode);
13411 rtx op1 = force_reg (<MODE>mode, operands[1]);
13413 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13414 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13419 (define_insn "fpremxf4_i387"
13420 [(set (match_operand:XF 0 "register_operand" "=f")
13421 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13422 (match_operand:XF 3 "register_operand" "1")]
13424 (set (match_operand:XF 1 "register_operand" "=u")
13425 (unspec:XF [(match_dup 2) (match_dup 3)]
13427 (set (reg:CCFP FPSR_REG)
13428 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13430 "TARGET_USE_FANCY_MATH_387"
13432 [(set_attr "type" "fpspc")
13433 (set_attr "mode" "XF")])
13435 (define_expand "fmodxf3"
13436 [(use (match_operand:XF 0 "register_operand" ""))
13437 (use (match_operand:XF 1 "general_operand" ""))
13438 (use (match_operand:XF 2 "general_operand" ""))]
13439 "TARGET_USE_FANCY_MATH_387"
13441 rtx label = gen_label_rtx ();
13443 rtx op1 = gen_reg_rtx (XFmode);
13444 rtx op2 = gen_reg_rtx (XFmode);
13446 emit_move_insn (op2, operands[2]);
13447 emit_move_insn (op1, operands[1]);
13449 emit_label (label);
13450 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13451 ix86_emit_fp_unordered_jump (label);
13452 LABEL_NUSES (label) = 1;
13454 emit_move_insn (operands[0], op1);
13458 (define_expand "fmod<mode>3"
13459 [(use (match_operand:MODEF 0 "register_operand" ""))
13460 (use (match_operand:MODEF 1 "general_operand" ""))
13461 (use (match_operand:MODEF 2 "general_operand" ""))]
13462 "TARGET_USE_FANCY_MATH_387"
13464 rtx (*gen_truncxf) (rtx, rtx);
13466 rtx label = gen_label_rtx ();
13468 rtx op1 = gen_reg_rtx (XFmode);
13469 rtx op2 = gen_reg_rtx (XFmode);
13471 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13472 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13474 emit_label (label);
13475 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13476 ix86_emit_fp_unordered_jump (label);
13477 LABEL_NUSES (label) = 1;
13479 /* Truncate the result properly for strict SSE math. */
13480 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13481 && !TARGET_MIX_SSE_I387)
13482 gen_truncxf = gen_truncxf<mode>2;
13484 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13486 emit_insn (gen_truncxf (operands[0], op1));
13490 (define_insn "fprem1xf4_i387"
13491 [(set (match_operand:XF 0 "register_operand" "=f")
13492 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13493 (match_operand:XF 3 "register_operand" "1")]
13495 (set (match_operand:XF 1 "register_operand" "=u")
13496 (unspec:XF [(match_dup 2) (match_dup 3)]
13498 (set (reg:CCFP FPSR_REG)
13499 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13501 "TARGET_USE_FANCY_MATH_387"
13503 [(set_attr "type" "fpspc")
13504 (set_attr "mode" "XF")])
13506 (define_expand "remainderxf3"
13507 [(use (match_operand:XF 0 "register_operand" ""))
13508 (use (match_operand:XF 1 "general_operand" ""))
13509 (use (match_operand:XF 2 "general_operand" ""))]
13510 "TARGET_USE_FANCY_MATH_387"
13512 rtx label = gen_label_rtx ();
13514 rtx op1 = gen_reg_rtx (XFmode);
13515 rtx op2 = gen_reg_rtx (XFmode);
13517 emit_move_insn (op2, operands[2]);
13518 emit_move_insn (op1, operands[1]);
13520 emit_label (label);
13521 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13522 ix86_emit_fp_unordered_jump (label);
13523 LABEL_NUSES (label) = 1;
13525 emit_move_insn (operands[0], op1);
13529 (define_expand "remainder<mode>3"
13530 [(use (match_operand:MODEF 0 "register_operand" ""))
13531 (use (match_operand:MODEF 1 "general_operand" ""))
13532 (use (match_operand:MODEF 2 "general_operand" ""))]
13533 "TARGET_USE_FANCY_MATH_387"
13535 rtx (*gen_truncxf) (rtx, rtx);
13537 rtx label = gen_label_rtx ();
13539 rtx op1 = gen_reg_rtx (XFmode);
13540 rtx op2 = gen_reg_rtx (XFmode);
13542 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13543 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13545 emit_label (label);
13547 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13548 ix86_emit_fp_unordered_jump (label);
13549 LABEL_NUSES (label) = 1;
13551 /* Truncate the result properly for strict SSE math. */
13552 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13553 && !TARGET_MIX_SSE_I387)
13554 gen_truncxf = gen_truncxf<mode>2;
13556 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13558 emit_insn (gen_truncxf (operands[0], op1));
13562 (define_insn "*sinxf2_i387"
13563 [(set (match_operand:XF 0 "register_operand" "=f")
13564 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13565 "TARGET_USE_FANCY_MATH_387
13566 && flag_unsafe_math_optimizations"
13568 [(set_attr "type" "fpspc")
13569 (set_attr "mode" "XF")])
13571 (define_insn "*sin_extend<mode>xf2_i387"
13572 [(set (match_operand:XF 0 "register_operand" "=f")
13573 (unspec:XF [(float_extend:XF
13574 (match_operand:MODEF 1 "register_operand" "0"))]
13576 "TARGET_USE_FANCY_MATH_387
13577 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13578 || TARGET_MIX_SSE_I387)
13579 && flag_unsafe_math_optimizations"
13581 [(set_attr "type" "fpspc")
13582 (set_attr "mode" "XF")])
13584 (define_insn "*cosxf2_i387"
13585 [(set (match_operand:XF 0 "register_operand" "=f")
13586 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13587 "TARGET_USE_FANCY_MATH_387
13588 && flag_unsafe_math_optimizations"
13590 [(set_attr "type" "fpspc")
13591 (set_attr "mode" "XF")])
13593 (define_insn "*cos_extend<mode>xf2_i387"
13594 [(set (match_operand:XF 0 "register_operand" "=f")
13595 (unspec:XF [(float_extend:XF
13596 (match_operand:MODEF 1 "register_operand" "0"))]
13598 "TARGET_USE_FANCY_MATH_387
13599 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13600 || TARGET_MIX_SSE_I387)
13601 && flag_unsafe_math_optimizations"
13603 [(set_attr "type" "fpspc")
13604 (set_attr "mode" "XF")])
13606 ;; When sincos pattern is defined, sin and cos builtin functions will be
13607 ;; expanded to sincos pattern with one of its outputs left unused.
13608 ;; CSE pass will figure out if two sincos patterns can be combined,
13609 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13610 ;; depending on the unused output.
13612 (define_insn "sincosxf3"
13613 [(set (match_operand:XF 0 "register_operand" "=f")
13614 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13615 UNSPEC_SINCOS_COS))
13616 (set (match_operand:XF 1 "register_operand" "=u")
13617 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13618 "TARGET_USE_FANCY_MATH_387
13619 && flag_unsafe_math_optimizations"
13621 [(set_attr "type" "fpspc")
13622 (set_attr "mode" "XF")])
13625 [(set (match_operand:XF 0 "register_operand" "")
13626 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13627 UNSPEC_SINCOS_COS))
13628 (set (match_operand:XF 1 "register_operand" "")
13629 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13630 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13631 && can_create_pseudo_p ()"
13632 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13635 [(set (match_operand:XF 0 "register_operand" "")
13636 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13637 UNSPEC_SINCOS_COS))
13638 (set (match_operand:XF 1 "register_operand" "")
13639 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13640 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13641 && can_create_pseudo_p ()"
13642 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13644 (define_insn "sincos_extend<mode>xf3_i387"
13645 [(set (match_operand:XF 0 "register_operand" "=f")
13646 (unspec:XF [(float_extend:XF
13647 (match_operand:MODEF 2 "register_operand" "0"))]
13648 UNSPEC_SINCOS_COS))
13649 (set (match_operand:XF 1 "register_operand" "=u")
13650 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13651 "TARGET_USE_FANCY_MATH_387
13652 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13653 || TARGET_MIX_SSE_I387)
13654 && flag_unsafe_math_optimizations"
13656 [(set_attr "type" "fpspc")
13657 (set_attr "mode" "XF")])
13660 [(set (match_operand:XF 0 "register_operand" "")
13661 (unspec:XF [(float_extend:XF
13662 (match_operand:MODEF 2 "register_operand" ""))]
13663 UNSPEC_SINCOS_COS))
13664 (set (match_operand:XF 1 "register_operand" "")
13665 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13666 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13667 && can_create_pseudo_p ()"
13668 [(set (match_dup 1)
13669 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13672 [(set (match_operand:XF 0 "register_operand" "")
13673 (unspec:XF [(float_extend:XF
13674 (match_operand:MODEF 2 "register_operand" ""))]
13675 UNSPEC_SINCOS_COS))
13676 (set (match_operand:XF 1 "register_operand" "")
13677 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13678 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13679 && can_create_pseudo_p ()"
13680 [(set (match_dup 0)
13681 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13683 (define_expand "sincos<mode>3"
13684 [(use (match_operand:MODEF 0 "register_operand" ""))
13685 (use (match_operand:MODEF 1 "register_operand" ""))
13686 (use (match_operand:MODEF 2 "register_operand" ""))]
13687 "TARGET_USE_FANCY_MATH_387
13688 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13689 || TARGET_MIX_SSE_I387)
13690 && flag_unsafe_math_optimizations"
13692 rtx op0 = gen_reg_rtx (XFmode);
13693 rtx op1 = gen_reg_rtx (XFmode);
13695 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13696 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13697 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13701 (define_insn "fptanxf4_i387"
13702 [(set (match_operand:XF 0 "register_operand" "=f")
13703 (match_operand:XF 3 "const_double_operand" "F"))
13704 (set (match_operand:XF 1 "register_operand" "=u")
13705 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13707 "TARGET_USE_FANCY_MATH_387
13708 && flag_unsafe_math_optimizations
13709 && standard_80387_constant_p (operands[3]) == 2"
13711 [(set_attr "type" "fpspc")
13712 (set_attr "mode" "XF")])
13714 (define_insn "fptan_extend<mode>xf4_i387"
13715 [(set (match_operand:MODEF 0 "register_operand" "=f")
13716 (match_operand:MODEF 3 "const_double_operand" "F"))
13717 (set (match_operand:XF 1 "register_operand" "=u")
13718 (unspec:XF [(float_extend:XF
13719 (match_operand:MODEF 2 "register_operand" "0"))]
13721 "TARGET_USE_FANCY_MATH_387
13722 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13723 || TARGET_MIX_SSE_I387)
13724 && flag_unsafe_math_optimizations
13725 && standard_80387_constant_p (operands[3]) == 2"
13727 [(set_attr "type" "fpspc")
13728 (set_attr "mode" "XF")])
13730 (define_expand "tanxf2"
13731 [(use (match_operand:XF 0 "register_operand" ""))
13732 (use (match_operand:XF 1 "register_operand" ""))]
13733 "TARGET_USE_FANCY_MATH_387
13734 && flag_unsafe_math_optimizations"
13736 rtx one = gen_reg_rtx (XFmode);
13737 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13739 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13743 (define_expand "tan<mode>2"
13744 [(use (match_operand:MODEF 0 "register_operand" ""))
13745 (use (match_operand:MODEF 1 "register_operand" ""))]
13746 "TARGET_USE_FANCY_MATH_387
13747 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13748 || TARGET_MIX_SSE_I387)
13749 && flag_unsafe_math_optimizations"
13751 rtx op0 = gen_reg_rtx (XFmode);
13753 rtx one = gen_reg_rtx (<MODE>mode);
13754 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13756 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13757 operands[1], op2));
13758 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13762 (define_insn "*fpatanxf3_i387"
13763 [(set (match_operand:XF 0 "register_operand" "=f")
13764 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13765 (match_operand:XF 2 "register_operand" "u")]
13767 (clobber (match_scratch:XF 3 "=2"))]
13768 "TARGET_USE_FANCY_MATH_387
13769 && flag_unsafe_math_optimizations"
13771 [(set_attr "type" "fpspc")
13772 (set_attr "mode" "XF")])
13774 (define_insn "fpatan_extend<mode>xf3_i387"
13775 [(set (match_operand:XF 0 "register_operand" "=f")
13776 (unspec:XF [(float_extend:XF
13777 (match_operand:MODEF 1 "register_operand" "0"))
13779 (match_operand:MODEF 2 "register_operand" "u"))]
13781 (clobber (match_scratch:XF 3 "=2"))]
13782 "TARGET_USE_FANCY_MATH_387
13783 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13784 || TARGET_MIX_SSE_I387)
13785 && flag_unsafe_math_optimizations"
13787 [(set_attr "type" "fpspc")
13788 (set_attr "mode" "XF")])
13790 (define_expand "atan2xf3"
13791 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13792 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13793 (match_operand:XF 1 "register_operand" "")]
13795 (clobber (match_scratch:XF 3 ""))])]
13796 "TARGET_USE_FANCY_MATH_387
13797 && flag_unsafe_math_optimizations")
13799 (define_expand "atan2<mode>3"
13800 [(use (match_operand:MODEF 0 "register_operand" ""))
13801 (use (match_operand:MODEF 1 "register_operand" ""))
13802 (use (match_operand:MODEF 2 "register_operand" ""))]
13803 "TARGET_USE_FANCY_MATH_387
13804 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13805 || TARGET_MIX_SSE_I387)
13806 && flag_unsafe_math_optimizations"
13808 rtx op0 = gen_reg_rtx (XFmode);
13810 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13811 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13815 (define_expand "atanxf2"
13816 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13817 (unspec:XF [(match_dup 2)
13818 (match_operand:XF 1 "register_operand" "")]
13820 (clobber (match_scratch:XF 3 ""))])]
13821 "TARGET_USE_FANCY_MATH_387
13822 && flag_unsafe_math_optimizations"
13824 operands[2] = gen_reg_rtx (XFmode);
13825 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13828 (define_expand "atan<mode>2"
13829 [(use (match_operand:MODEF 0 "register_operand" ""))
13830 (use (match_operand:MODEF 1 "register_operand" ""))]
13831 "TARGET_USE_FANCY_MATH_387
13832 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13833 || TARGET_MIX_SSE_I387)
13834 && flag_unsafe_math_optimizations"
13836 rtx op0 = gen_reg_rtx (XFmode);
13838 rtx op2 = gen_reg_rtx (<MODE>mode);
13839 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13841 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13842 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13846 (define_expand "asinxf2"
13847 [(set (match_dup 2)
13848 (mult:XF (match_operand:XF 1 "register_operand" "")
13850 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13851 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13852 (parallel [(set (match_operand:XF 0 "register_operand" "")
13853 (unspec:XF [(match_dup 5) (match_dup 1)]
13855 (clobber (match_scratch:XF 6 ""))])]
13856 "TARGET_USE_FANCY_MATH_387
13857 && flag_unsafe_math_optimizations"
13861 if (optimize_insn_for_size_p ())
13864 for (i = 2; i < 6; i++)
13865 operands[i] = gen_reg_rtx (XFmode);
13867 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13870 (define_expand "asin<mode>2"
13871 [(use (match_operand:MODEF 0 "register_operand" ""))
13872 (use (match_operand:MODEF 1 "general_operand" ""))]
13873 "TARGET_USE_FANCY_MATH_387
13874 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13875 || TARGET_MIX_SSE_I387)
13876 && flag_unsafe_math_optimizations"
13878 rtx op0 = gen_reg_rtx (XFmode);
13879 rtx op1 = gen_reg_rtx (XFmode);
13881 if (optimize_insn_for_size_p ())
13884 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13885 emit_insn (gen_asinxf2 (op0, op1));
13886 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13890 (define_expand "acosxf2"
13891 [(set (match_dup 2)
13892 (mult:XF (match_operand:XF 1 "register_operand" "")
13894 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13895 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13896 (parallel [(set (match_operand:XF 0 "register_operand" "")
13897 (unspec:XF [(match_dup 1) (match_dup 5)]
13899 (clobber (match_scratch:XF 6 ""))])]
13900 "TARGET_USE_FANCY_MATH_387
13901 && flag_unsafe_math_optimizations"
13905 if (optimize_insn_for_size_p ())
13908 for (i = 2; i < 6; i++)
13909 operands[i] = gen_reg_rtx (XFmode);
13911 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13914 (define_expand "acos<mode>2"
13915 [(use (match_operand:MODEF 0 "register_operand" ""))
13916 (use (match_operand:MODEF 1 "general_operand" ""))]
13917 "TARGET_USE_FANCY_MATH_387
13918 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13919 || TARGET_MIX_SSE_I387)
13920 && flag_unsafe_math_optimizations"
13922 rtx op0 = gen_reg_rtx (XFmode);
13923 rtx op1 = gen_reg_rtx (XFmode);
13925 if (optimize_insn_for_size_p ())
13928 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13929 emit_insn (gen_acosxf2 (op0, op1));
13930 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13934 (define_insn "fyl2xxf3_i387"
13935 [(set (match_operand:XF 0 "register_operand" "=f")
13936 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13937 (match_operand:XF 2 "register_operand" "u")]
13939 (clobber (match_scratch:XF 3 "=2"))]
13940 "TARGET_USE_FANCY_MATH_387
13941 && flag_unsafe_math_optimizations"
13943 [(set_attr "type" "fpspc")
13944 (set_attr "mode" "XF")])
13946 (define_insn "fyl2x_extend<mode>xf3_i387"
13947 [(set (match_operand:XF 0 "register_operand" "=f")
13948 (unspec:XF [(float_extend:XF
13949 (match_operand:MODEF 1 "register_operand" "0"))
13950 (match_operand:XF 2 "register_operand" "u")]
13952 (clobber (match_scratch:XF 3 "=2"))]
13953 "TARGET_USE_FANCY_MATH_387
13954 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13955 || TARGET_MIX_SSE_I387)
13956 && flag_unsafe_math_optimizations"
13958 [(set_attr "type" "fpspc")
13959 (set_attr "mode" "XF")])
13961 (define_expand "logxf2"
13962 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13963 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13964 (match_dup 2)] UNSPEC_FYL2X))
13965 (clobber (match_scratch:XF 3 ""))])]
13966 "TARGET_USE_FANCY_MATH_387
13967 && flag_unsafe_math_optimizations"
13969 operands[2] = gen_reg_rtx (XFmode);
13970 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13973 (define_expand "log<mode>2"
13974 [(use (match_operand:MODEF 0 "register_operand" ""))
13975 (use (match_operand:MODEF 1 "register_operand" ""))]
13976 "TARGET_USE_FANCY_MATH_387
13977 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13978 || TARGET_MIX_SSE_I387)
13979 && flag_unsafe_math_optimizations"
13981 rtx op0 = gen_reg_rtx (XFmode);
13983 rtx op2 = gen_reg_rtx (XFmode);
13984 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13986 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13987 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13991 (define_expand "log10xf2"
13992 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13993 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13994 (match_dup 2)] UNSPEC_FYL2X))
13995 (clobber (match_scratch:XF 3 ""))])]
13996 "TARGET_USE_FANCY_MATH_387
13997 && flag_unsafe_math_optimizations"
13999 operands[2] = gen_reg_rtx (XFmode);
14000 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14003 (define_expand "log10<mode>2"
14004 [(use (match_operand:MODEF 0 "register_operand" ""))
14005 (use (match_operand:MODEF 1 "register_operand" ""))]
14006 "TARGET_USE_FANCY_MATH_387
14007 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14008 || TARGET_MIX_SSE_I387)
14009 && flag_unsafe_math_optimizations"
14011 rtx op0 = gen_reg_rtx (XFmode);
14013 rtx op2 = gen_reg_rtx (XFmode);
14014 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14016 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14017 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14021 (define_expand "log2xf2"
14022 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14023 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14024 (match_dup 2)] UNSPEC_FYL2X))
14025 (clobber (match_scratch:XF 3 ""))])]
14026 "TARGET_USE_FANCY_MATH_387
14027 && flag_unsafe_math_optimizations"
14029 operands[2] = gen_reg_rtx (XFmode);
14030 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14033 (define_expand "log2<mode>2"
14034 [(use (match_operand:MODEF 0 "register_operand" ""))
14035 (use (match_operand:MODEF 1 "register_operand" ""))]
14036 "TARGET_USE_FANCY_MATH_387
14037 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14038 || TARGET_MIX_SSE_I387)
14039 && flag_unsafe_math_optimizations"
14041 rtx op0 = gen_reg_rtx (XFmode);
14043 rtx op2 = gen_reg_rtx (XFmode);
14044 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14046 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14047 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14051 (define_insn "fyl2xp1xf3_i387"
14052 [(set (match_operand:XF 0 "register_operand" "=f")
14053 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14054 (match_operand:XF 2 "register_operand" "u")]
14056 (clobber (match_scratch:XF 3 "=2"))]
14057 "TARGET_USE_FANCY_MATH_387
14058 && flag_unsafe_math_optimizations"
14060 [(set_attr "type" "fpspc")
14061 (set_attr "mode" "XF")])
14063 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14064 [(set (match_operand:XF 0 "register_operand" "=f")
14065 (unspec:XF [(float_extend:XF
14066 (match_operand:MODEF 1 "register_operand" "0"))
14067 (match_operand:XF 2 "register_operand" "u")]
14069 (clobber (match_scratch:XF 3 "=2"))]
14070 "TARGET_USE_FANCY_MATH_387
14071 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14072 || TARGET_MIX_SSE_I387)
14073 && flag_unsafe_math_optimizations"
14075 [(set_attr "type" "fpspc")
14076 (set_attr "mode" "XF")])
14078 (define_expand "log1pxf2"
14079 [(use (match_operand:XF 0 "register_operand" ""))
14080 (use (match_operand:XF 1 "register_operand" ""))]
14081 "TARGET_USE_FANCY_MATH_387
14082 && flag_unsafe_math_optimizations"
14084 if (optimize_insn_for_size_p ())
14087 ix86_emit_i387_log1p (operands[0], operands[1]);
14091 (define_expand "log1p<mode>2"
14092 [(use (match_operand:MODEF 0 "register_operand" ""))
14093 (use (match_operand:MODEF 1 "register_operand" ""))]
14094 "TARGET_USE_FANCY_MATH_387
14095 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14096 || TARGET_MIX_SSE_I387)
14097 && flag_unsafe_math_optimizations"
14101 if (optimize_insn_for_size_p ())
14104 op0 = gen_reg_rtx (XFmode);
14106 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14108 ix86_emit_i387_log1p (op0, operands[1]);
14109 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14113 (define_insn "fxtractxf3_i387"
14114 [(set (match_operand:XF 0 "register_operand" "=f")
14115 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14116 UNSPEC_XTRACT_FRACT))
14117 (set (match_operand:XF 1 "register_operand" "=u")
14118 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14119 "TARGET_USE_FANCY_MATH_387
14120 && flag_unsafe_math_optimizations"
14122 [(set_attr "type" "fpspc")
14123 (set_attr "mode" "XF")])
14125 (define_insn "fxtract_extend<mode>xf3_i387"
14126 [(set (match_operand:XF 0 "register_operand" "=f")
14127 (unspec:XF [(float_extend:XF
14128 (match_operand:MODEF 2 "register_operand" "0"))]
14129 UNSPEC_XTRACT_FRACT))
14130 (set (match_operand:XF 1 "register_operand" "=u")
14131 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14132 "TARGET_USE_FANCY_MATH_387
14133 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14134 || TARGET_MIX_SSE_I387)
14135 && flag_unsafe_math_optimizations"
14137 [(set_attr "type" "fpspc")
14138 (set_attr "mode" "XF")])
14140 (define_expand "logbxf2"
14141 [(parallel [(set (match_dup 2)
14142 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14143 UNSPEC_XTRACT_FRACT))
14144 (set (match_operand:XF 0 "register_operand" "")
14145 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14146 "TARGET_USE_FANCY_MATH_387
14147 && flag_unsafe_math_optimizations"
14148 "operands[2] = gen_reg_rtx (XFmode);")
14150 (define_expand "logb<mode>2"
14151 [(use (match_operand:MODEF 0 "register_operand" ""))
14152 (use (match_operand:MODEF 1 "register_operand" ""))]
14153 "TARGET_USE_FANCY_MATH_387
14154 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14155 || TARGET_MIX_SSE_I387)
14156 && flag_unsafe_math_optimizations"
14158 rtx op0 = gen_reg_rtx (XFmode);
14159 rtx op1 = gen_reg_rtx (XFmode);
14161 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14162 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14166 (define_expand "ilogbxf2"
14167 [(use (match_operand:SI 0 "register_operand" ""))
14168 (use (match_operand:XF 1 "register_operand" ""))]
14169 "TARGET_USE_FANCY_MATH_387
14170 && flag_unsafe_math_optimizations"
14174 if (optimize_insn_for_size_p ())
14177 op0 = gen_reg_rtx (XFmode);
14178 op1 = gen_reg_rtx (XFmode);
14180 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14181 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14185 (define_expand "ilogb<mode>2"
14186 [(use (match_operand:SI 0 "register_operand" ""))
14187 (use (match_operand:MODEF 1 "register_operand" ""))]
14188 "TARGET_USE_FANCY_MATH_387
14189 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14190 || TARGET_MIX_SSE_I387)
14191 && flag_unsafe_math_optimizations"
14195 if (optimize_insn_for_size_p ())
14198 op0 = gen_reg_rtx (XFmode);
14199 op1 = gen_reg_rtx (XFmode);
14201 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14202 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14206 (define_insn "*f2xm1xf2_i387"
14207 [(set (match_operand:XF 0 "register_operand" "=f")
14208 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14210 "TARGET_USE_FANCY_MATH_387
14211 && flag_unsafe_math_optimizations"
14213 [(set_attr "type" "fpspc")
14214 (set_attr "mode" "XF")])
14216 (define_insn "*fscalexf4_i387"
14217 [(set (match_operand:XF 0 "register_operand" "=f")
14218 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14219 (match_operand:XF 3 "register_operand" "1")]
14220 UNSPEC_FSCALE_FRACT))
14221 (set (match_operand:XF 1 "register_operand" "=u")
14222 (unspec:XF [(match_dup 2) (match_dup 3)]
14223 UNSPEC_FSCALE_EXP))]
14224 "TARGET_USE_FANCY_MATH_387
14225 && flag_unsafe_math_optimizations"
14227 [(set_attr "type" "fpspc")
14228 (set_attr "mode" "XF")])
14230 (define_expand "expNcorexf3"
14231 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14232 (match_operand:XF 2 "register_operand" "")))
14233 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14234 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14235 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14236 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14237 (parallel [(set (match_operand:XF 0 "register_operand" "")
14238 (unspec:XF [(match_dup 8) (match_dup 4)]
14239 UNSPEC_FSCALE_FRACT))
14241 (unspec:XF [(match_dup 8) (match_dup 4)]
14242 UNSPEC_FSCALE_EXP))])]
14243 "TARGET_USE_FANCY_MATH_387
14244 && flag_unsafe_math_optimizations"
14248 if (optimize_insn_for_size_p ())
14251 for (i = 3; i < 10; i++)
14252 operands[i] = gen_reg_rtx (XFmode);
14254 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14257 (define_expand "expxf2"
14258 [(use (match_operand:XF 0 "register_operand" ""))
14259 (use (match_operand:XF 1 "register_operand" ""))]
14260 "TARGET_USE_FANCY_MATH_387
14261 && flag_unsafe_math_optimizations"
14265 if (optimize_insn_for_size_p ())
14268 op2 = gen_reg_rtx (XFmode);
14269 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14271 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14275 (define_expand "exp<mode>2"
14276 [(use (match_operand:MODEF 0 "register_operand" ""))
14277 (use (match_operand:MODEF 1 "general_operand" ""))]
14278 "TARGET_USE_FANCY_MATH_387
14279 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14280 || TARGET_MIX_SSE_I387)
14281 && flag_unsafe_math_optimizations"
14285 if (optimize_insn_for_size_p ())
14288 op0 = gen_reg_rtx (XFmode);
14289 op1 = gen_reg_rtx (XFmode);
14291 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14292 emit_insn (gen_expxf2 (op0, op1));
14293 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14297 (define_expand "exp10xf2"
14298 [(use (match_operand:XF 0 "register_operand" ""))
14299 (use (match_operand:XF 1 "register_operand" ""))]
14300 "TARGET_USE_FANCY_MATH_387
14301 && flag_unsafe_math_optimizations"
14305 if (optimize_insn_for_size_p ())
14308 op2 = gen_reg_rtx (XFmode);
14309 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14311 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14315 (define_expand "exp10<mode>2"
14316 [(use (match_operand:MODEF 0 "register_operand" ""))
14317 (use (match_operand:MODEF 1 "general_operand" ""))]
14318 "TARGET_USE_FANCY_MATH_387
14319 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14320 || TARGET_MIX_SSE_I387)
14321 && flag_unsafe_math_optimizations"
14325 if (optimize_insn_for_size_p ())
14328 op0 = gen_reg_rtx (XFmode);
14329 op1 = gen_reg_rtx (XFmode);
14331 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14332 emit_insn (gen_exp10xf2 (op0, op1));
14333 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14337 (define_expand "exp2xf2"
14338 [(use (match_operand:XF 0 "register_operand" ""))
14339 (use (match_operand:XF 1 "register_operand" ""))]
14340 "TARGET_USE_FANCY_MATH_387
14341 && flag_unsafe_math_optimizations"
14345 if (optimize_insn_for_size_p ())
14348 op2 = gen_reg_rtx (XFmode);
14349 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14351 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14355 (define_expand "exp2<mode>2"
14356 [(use (match_operand:MODEF 0 "register_operand" ""))
14357 (use (match_operand:MODEF 1 "general_operand" ""))]
14358 "TARGET_USE_FANCY_MATH_387
14359 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14360 || TARGET_MIX_SSE_I387)
14361 && flag_unsafe_math_optimizations"
14365 if (optimize_insn_for_size_p ())
14368 op0 = gen_reg_rtx (XFmode);
14369 op1 = gen_reg_rtx (XFmode);
14371 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14372 emit_insn (gen_exp2xf2 (op0, op1));
14373 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14377 (define_expand "expm1xf2"
14378 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14380 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14381 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14382 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14383 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14384 (parallel [(set (match_dup 7)
14385 (unspec:XF [(match_dup 6) (match_dup 4)]
14386 UNSPEC_FSCALE_FRACT))
14388 (unspec:XF [(match_dup 6) (match_dup 4)]
14389 UNSPEC_FSCALE_EXP))])
14390 (parallel [(set (match_dup 10)
14391 (unspec:XF [(match_dup 9) (match_dup 8)]
14392 UNSPEC_FSCALE_FRACT))
14393 (set (match_dup 11)
14394 (unspec:XF [(match_dup 9) (match_dup 8)]
14395 UNSPEC_FSCALE_EXP))])
14396 (set (match_dup 12) (minus:XF (match_dup 10)
14397 (float_extend:XF (match_dup 13))))
14398 (set (match_operand:XF 0 "register_operand" "")
14399 (plus:XF (match_dup 12) (match_dup 7)))]
14400 "TARGET_USE_FANCY_MATH_387
14401 && flag_unsafe_math_optimizations"
14405 if (optimize_insn_for_size_p ())
14408 for (i = 2; i < 13; i++)
14409 operands[i] = gen_reg_rtx (XFmode);
14412 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14414 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14417 (define_expand "expm1<mode>2"
14418 [(use (match_operand:MODEF 0 "register_operand" ""))
14419 (use (match_operand:MODEF 1 "general_operand" ""))]
14420 "TARGET_USE_FANCY_MATH_387
14421 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14422 || TARGET_MIX_SSE_I387)
14423 && flag_unsafe_math_optimizations"
14427 if (optimize_insn_for_size_p ())
14430 op0 = gen_reg_rtx (XFmode);
14431 op1 = gen_reg_rtx (XFmode);
14433 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14434 emit_insn (gen_expm1xf2 (op0, op1));
14435 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14439 (define_expand "ldexpxf3"
14440 [(set (match_dup 3)
14441 (float:XF (match_operand:SI 2 "register_operand" "")))
14442 (parallel [(set (match_operand:XF 0 " register_operand" "")
14443 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14445 UNSPEC_FSCALE_FRACT))
14447 (unspec:XF [(match_dup 1) (match_dup 3)]
14448 UNSPEC_FSCALE_EXP))])]
14449 "TARGET_USE_FANCY_MATH_387
14450 && flag_unsafe_math_optimizations"
14452 if (optimize_insn_for_size_p ())
14455 operands[3] = gen_reg_rtx (XFmode);
14456 operands[4] = gen_reg_rtx (XFmode);
14459 (define_expand "ldexp<mode>3"
14460 [(use (match_operand:MODEF 0 "register_operand" ""))
14461 (use (match_operand:MODEF 1 "general_operand" ""))
14462 (use (match_operand:SI 2 "register_operand" ""))]
14463 "TARGET_USE_FANCY_MATH_387
14464 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14465 || TARGET_MIX_SSE_I387)
14466 && flag_unsafe_math_optimizations"
14470 if (optimize_insn_for_size_p ())
14473 op0 = gen_reg_rtx (XFmode);
14474 op1 = gen_reg_rtx (XFmode);
14476 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14477 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14478 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14482 (define_expand "scalbxf3"
14483 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14484 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14485 (match_operand:XF 2 "register_operand" "")]
14486 UNSPEC_FSCALE_FRACT))
14488 (unspec:XF [(match_dup 1) (match_dup 2)]
14489 UNSPEC_FSCALE_EXP))])]
14490 "TARGET_USE_FANCY_MATH_387
14491 && flag_unsafe_math_optimizations"
14493 if (optimize_insn_for_size_p ())
14496 operands[3] = gen_reg_rtx (XFmode);
14499 (define_expand "scalb<mode>3"
14500 [(use (match_operand:MODEF 0 "register_operand" ""))
14501 (use (match_operand:MODEF 1 "general_operand" ""))
14502 (use (match_operand:MODEF 2 "general_operand" ""))]
14503 "TARGET_USE_FANCY_MATH_387
14504 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14505 || TARGET_MIX_SSE_I387)
14506 && flag_unsafe_math_optimizations"
14510 if (optimize_insn_for_size_p ())
14513 op0 = gen_reg_rtx (XFmode);
14514 op1 = gen_reg_rtx (XFmode);
14515 op2 = gen_reg_rtx (XFmode);
14517 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14518 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14519 emit_insn (gen_scalbxf3 (op0, op1, op2));
14520 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14524 (define_expand "significandxf2"
14525 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14526 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14527 UNSPEC_XTRACT_FRACT))
14529 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14530 "TARGET_USE_FANCY_MATH_387
14531 && flag_unsafe_math_optimizations"
14532 "operands[2] = gen_reg_rtx (XFmode);")
14534 (define_expand "significand<mode>2"
14535 [(use (match_operand:MODEF 0 "register_operand" ""))
14536 (use (match_operand:MODEF 1 "register_operand" ""))]
14537 "TARGET_USE_FANCY_MATH_387
14538 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14539 || TARGET_MIX_SSE_I387)
14540 && flag_unsafe_math_optimizations"
14542 rtx op0 = gen_reg_rtx (XFmode);
14543 rtx op1 = gen_reg_rtx (XFmode);
14545 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14546 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14551 (define_insn "sse4_1_round<mode>2"
14552 [(set (match_operand:MODEF 0 "register_operand" "=x")
14553 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14554 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14557 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14558 [(set_attr "type" "ssecvt")
14559 (set_attr "prefix_extra" "1")
14560 (set_attr "prefix" "maybe_vex")
14561 (set_attr "mode" "<MODE>")])
14563 (define_insn "rintxf2"
14564 [(set (match_operand:XF 0 "register_operand" "=f")
14565 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14567 "TARGET_USE_FANCY_MATH_387
14568 && flag_unsafe_math_optimizations"
14570 [(set_attr "type" "fpspc")
14571 (set_attr "mode" "XF")])
14573 (define_expand "rint<mode>2"
14574 [(use (match_operand:MODEF 0 "register_operand" ""))
14575 (use (match_operand:MODEF 1 "register_operand" ""))]
14576 "(TARGET_USE_FANCY_MATH_387
14577 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14578 || TARGET_MIX_SSE_I387)
14579 && flag_unsafe_math_optimizations)
14580 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14581 && !flag_trapping_math)"
14583 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14584 && !flag_trapping_math)
14587 emit_insn (gen_sse4_1_round<mode>2
14588 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14589 else if (optimize_insn_for_size_p ())
14592 ix86_expand_rint (operands[0], operands[1]);
14596 rtx op0 = gen_reg_rtx (XFmode);
14597 rtx op1 = gen_reg_rtx (XFmode);
14599 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14600 emit_insn (gen_rintxf2 (op0, op1));
14602 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14607 (define_expand "round<mode>2"
14608 [(match_operand:X87MODEF 0 "register_operand" "")
14609 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14610 "(TARGET_USE_FANCY_MATH_387
14611 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14612 || TARGET_MIX_SSE_I387)
14613 && flag_unsafe_math_optimizations)
14614 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14615 && !flag_trapping_math && !flag_rounding_math)"
14617 if (optimize_insn_for_size_p ())
14620 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14621 && !flag_trapping_math && !flag_rounding_math)
14625 operands[1] = force_reg (<MODE>mode, operands[1]);
14626 ix86_expand_round_sse4 (operands[0], operands[1]);
14628 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14629 ix86_expand_round (operands[0], operands[1]);
14631 ix86_expand_rounddf_32 (operands[0], operands[1]);
14635 operands[1] = force_reg (<MODE>mode, operands[1]);
14636 ix86_emit_i387_round (operands[0], operands[1]);
14641 (define_insn_and_split "*fistdi2_1"
14642 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14643 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14645 "TARGET_USE_FANCY_MATH_387
14646 && can_create_pseudo_p ()"
14651 if (memory_operand (operands[0], VOIDmode))
14652 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14655 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14656 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14661 [(set_attr "type" "fpspc")
14662 (set_attr "mode" "DI")])
14664 (define_insn "fistdi2"
14665 [(set (match_operand:DI 0 "memory_operand" "=m")
14666 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14668 (clobber (match_scratch:XF 2 "=&1f"))]
14669 "TARGET_USE_FANCY_MATH_387"
14670 "* return output_fix_trunc (insn, operands, false);"
14671 [(set_attr "type" "fpspc")
14672 (set_attr "mode" "DI")])
14674 (define_insn "fistdi2_with_temp"
14675 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14676 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14678 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14679 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14680 "TARGET_USE_FANCY_MATH_387"
14682 [(set_attr "type" "fpspc")
14683 (set_attr "mode" "DI")])
14686 [(set (match_operand:DI 0 "register_operand" "")
14687 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14689 (clobber (match_operand:DI 2 "memory_operand" ""))
14690 (clobber (match_scratch 3 ""))]
14692 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14693 (clobber (match_dup 3))])
14694 (set (match_dup 0) (match_dup 2))])
14697 [(set (match_operand:DI 0 "memory_operand" "")
14698 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14700 (clobber (match_operand:DI 2 "memory_operand" ""))
14701 (clobber (match_scratch 3 ""))]
14703 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14704 (clobber (match_dup 3))])])
14706 (define_insn_and_split "*fist<mode>2_1"
14707 [(set (match_operand:SWI24 0 "register_operand" "")
14708 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14710 "TARGET_USE_FANCY_MATH_387
14711 && can_create_pseudo_p ()"
14716 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14717 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14721 [(set_attr "type" "fpspc")
14722 (set_attr "mode" "<MODE>")])
14724 (define_insn "fist<mode>2"
14725 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14726 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14728 "TARGET_USE_FANCY_MATH_387"
14729 "* return output_fix_trunc (insn, operands, false);"
14730 [(set_attr "type" "fpspc")
14731 (set_attr "mode" "<MODE>")])
14733 (define_insn "fist<mode>2_with_temp"
14734 [(set (match_operand:SWI24 0 "register_operand" "=r")
14735 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14737 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14738 "TARGET_USE_FANCY_MATH_387"
14740 [(set_attr "type" "fpspc")
14741 (set_attr "mode" "<MODE>")])
14744 [(set (match_operand:SWI24 0 "register_operand" "")
14745 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14747 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14749 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14750 (set (match_dup 0) (match_dup 2))])
14753 [(set (match_operand:SWI24 0 "memory_operand" "")
14754 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14756 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14758 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14760 (define_expand "lrintxf<mode>2"
14761 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14762 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14764 "TARGET_USE_FANCY_MATH_387")
14766 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14767 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14768 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14769 UNSPEC_FIX_NOTRUNC))]
14770 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14771 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14773 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14774 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14775 (match_operand:X87MODEF 1 "register_operand" "")]
14776 "(TARGET_USE_FANCY_MATH_387
14777 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14778 || TARGET_MIX_SSE_I387)
14779 && flag_unsafe_math_optimizations)
14780 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14781 && <SWI248x:MODE>mode != HImode
14782 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14783 && !flag_trapping_math && !flag_rounding_math)"
14785 if (optimize_insn_for_size_p ())
14788 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14789 && <SWI248x:MODE>mode != HImode
14790 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14791 && !flag_trapping_math && !flag_rounding_math)
14792 ix86_expand_lround (operands[0], operands[1]);
14794 ix86_emit_i387_round (operands[0], operands[1]);
14798 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14799 (define_insn_and_split "frndintxf2_floor"
14800 [(set (match_operand:XF 0 "register_operand" "")
14801 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14802 UNSPEC_FRNDINT_FLOOR))
14803 (clobber (reg:CC FLAGS_REG))]
14804 "TARGET_USE_FANCY_MATH_387
14805 && flag_unsafe_math_optimizations
14806 && can_create_pseudo_p ()"
14811 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14813 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14814 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14816 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14817 operands[2], operands[3]));
14820 [(set_attr "type" "frndint")
14821 (set_attr "i387_cw" "floor")
14822 (set_attr "mode" "XF")])
14824 (define_insn "frndintxf2_floor_i387"
14825 [(set (match_operand:XF 0 "register_operand" "=f")
14826 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14827 UNSPEC_FRNDINT_FLOOR))
14828 (use (match_operand:HI 2 "memory_operand" "m"))
14829 (use (match_operand:HI 3 "memory_operand" "m"))]
14830 "TARGET_USE_FANCY_MATH_387
14831 && flag_unsafe_math_optimizations"
14832 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14833 [(set_attr "type" "frndint")
14834 (set_attr "i387_cw" "floor")
14835 (set_attr "mode" "XF")])
14837 (define_expand "floorxf2"
14838 [(use (match_operand:XF 0 "register_operand" ""))
14839 (use (match_operand:XF 1 "register_operand" ""))]
14840 "TARGET_USE_FANCY_MATH_387
14841 && flag_unsafe_math_optimizations"
14843 if (optimize_insn_for_size_p ())
14845 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14849 (define_expand "floor<mode>2"
14850 [(use (match_operand:MODEF 0 "register_operand" ""))
14851 (use (match_operand:MODEF 1 "register_operand" ""))]
14852 "(TARGET_USE_FANCY_MATH_387
14853 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14854 || TARGET_MIX_SSE_I387)
14855 && flag_unsafe_math_optimizations)
14856 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14857 && !flag_trapping_math)"
14859 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14860 && !flag_trapping_math)
14863 emit_insn (gen_sse4_1_round<mode>2
14864 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14865 else if (optimize_insn_for_size_p ())
14867 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14868 ix86_expand_floorceil (operands[0], operands[1], true);
14870 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14876 if (optimize_insn_for_size_p ())
14879 op0 = gen_reg_rtx (XFmode);
14880 op1 = gen_reg_rtx (XFmode);
14881 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14882 emit_insn (gen_frndintxf2_floor (op0, op1));
14884 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14889 (define_insn_and_split "*fist<mode>2_floor_1"
14890 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14891 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14892 UNSPEC_FIST_FLOOR))
14893 (clobber (reg:CC FLAGS_REG))]
14894 "TARGET_USE_FANCY_MATH_387
14895 && flag_unsafe_math_optimizations
14896 && can_create_pseudo_p ()"
14901 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14903 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14904 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14905 if (memory_operand (operands[0], VOIDmode))
14906 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14907 operands[2], operands[3]));
14910 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14911 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14912 operands[2], operands[3],
14917 [(set_attr "type" "fistp")
14918 (set_attr "i387_cw" "floor")
14919 (set_attr "mode" "<MODE>")])
14921 (define_insn "fistdi2_floor"
14922 [(set (match_operand:DI 0 "memory_operand" "=m")
14923 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14924 UNSPEC_FIST_FLOOR))
14925 (use (match_operand:HI 2 "memory_operand" "m"))
14926 (use (match_operand:HI 3 "memory_operand" "m"))
14927 (clobber (match_scratch:XF 4 "=&1f"))]
14928 "TARGET_USE_FANCY_MATH_387
14929 && flag_unsafe_math_optimizations"
14930 "* return output_fix_trunc (insn, operands, false);"
14931 [(set_attr "type" "fistp")
14932 (set_attr "i387_cw" "floor")
14933 (set_attr "mode" "DI")])
14935 (define_insn "fistdi2_floor_with_temp"
14936 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14937 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14938 UNSPEC_FIST_FLOOR))
14939 (use (match_operand:HI 2 "memory_operand" "m,m"))
14940 (use (match_operand:HI 3 "memory_operand" "m,m"))
14941 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14942 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14943 "TARGET_USE_FANCY_MATH_387
14944 && flag_unsafe_math_optimizations"
14946 [(set_attr "type" "fistp")
14947 (set_attr "i387_cw" "floor")
14948 (set_attr "mode" "DI")])
14951 [(set (match_operand:DI 0 "register_operand" "")
14952 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14953 UNSPEC_FIST_FLOOR))
14954 (use (match_operand:HI 2 "memory_operand" ""))
14955 (use (match_operand:HI 3 "memory_operand" ""))
14956 (clobber (match_operand:DI 4 "memory_operand" ""))
14957 (clobber (match_scratch 5 ""))]
14959 [(parallel [(set (match_dup 4)
14960 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14961 (use (match_dup 2))
14962 (use (match_dup 3))
14963 (clobber (match_dup 5))])
14964 (set (match_dup 0) (match_dup 4))])
14967 [(set (match_operand:DI 0 "memory_operand" "")
14968 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14969 UNSPEC_FIST_FLOOR))
14970 (use (match_operand:HI 2 "memory_operand" ""))
14971 (use (match_operand:HI 3 "memory_operand" ""))
14972 (clobber (match_operand:DI 4 "memory_operand" ""))
14973 (clobber (match_scratch 5 ""))]
14975 [(parallel [(set (match_dup 0)
14976 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14977 (use (match_dup 2))
14978 (use (match_dup 3))
14979 (clobber (match_dup 5))])])
14981 (define_insn "fist<mode>2_floor"
14982 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14983 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14984 UNSPEC_FIST_FLOOR))
14985 (use (match_operand:HI 2 "memory_operand" "m"))
14986 (use (match_operand:HI 3 "memory_operand" "m"))]
14987 "TARGET_USE_FANCY_MATH_387
14988 && flag_unsafe_math_optimizations"
14989 "* return output_fix_trunc (insn, operands, false);"
14990 [(set_attr "type" "fistp")
14991 (set_attr "i387_cw" "floor")
14992 (set_attr "mode" "<MODE>")])
14994 (define_insn "fist<mode>2_floor_with_temp"
14995 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14996 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14997 UNSPEC_FIST_FLOOR))
14998 (use (match_operand:HI 2 "memory_operand" "m,m"))
14999 (use (match_operand:HI 3 "memory_operand" "m,m"))
15000 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15001 "TARGET_USE_FANCY_MATH_387
15002 && flag_unsafe_math_optimizations"
15004 [(set_attr "type" "fistp")
15005 (set_attr "i387_cw" "floor")
15006 (set_attr "mode" "<MODE>")])
15009 [(set (match_operand:SWI24 0 "register_operand" "")
15010 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15011 UNSPEC_FIST_FLOOR))
15012 (use (match_operand:HI 2 "memory_operand" ""))
15013 (use (match_operand:HI 3 "memory_operand" ""))
15014 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15016 [(parallel [(set (match_dup 4)
15017 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15018 (use (match_dup 2))
15019 (use (match_dup 3))])
15020 (set (match_dup 0) (match_dup 4))])
15023 [(set (match_operand:SWI24 0 "memory_operand" "")
15024 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15025 UNSPEC_FIST_FLOOR))
15026 (use (match_operand:HI 2 "memory_operand" ""))
15027 (use (match_operand:HI 3 "memory_operand" ""))
15028 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15030 [(parallel [(set (match_dup 0)
15031 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15032 (use (match_dup 2))
15033 (use (match_dup 3))])])
15035 (define_expand "lfloorxf<mode>2"
15036 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15037 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15038 UNSPEC_FIST_FLOOR))
15039 (clobber (reg:CC FLAGS_REG))])]
15040 "TARGET_USE_FANCY_MATH_387
15041 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15042 && flag_unsafe_math_optimizations")
15044 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15045 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15046 (match_operand:MODEF 1 "register_operand" "")]
15047 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15048 && !flag_trapping_math"
15050 if (TARGET_64BIT && optimize_insn_for_size_p ())
15052 ix86_expand_lfloorceil (operands[0], operands[1], true);
15056 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15057 (define_insn_and_split "frndintxf2_ceil"
15058 [(set (match_operand:XF 0 "register_operand" "")
15059 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15060 UNSPEC_FRNDINT_CEIL))
15061 (clobber (reg:CC FLAGS_REG))]
15062 "TARGET_USE_FANCY_MATH_387
15063 && flag_unsafe_math_optimizations
15064 && can_create_pseudo_p ()"
15069 ix86_optimize_mode_switching[I387_CEIL] = 1;
15071 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15072 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15074 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15075 operands[2], operands[3]));
15078 [(set_attr "type" "frndint")
15079 (set_attr "i387_cw" "ceil")
15080 (set_attr "mode" "XF")])
15082 (define_insn "frndintxf2_ceil_i387"
15083 [(set (match_operand:XF 0 "register_operand" "=f")
15084 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15085 UNSPEC_FRNDINT_CEIL))
15086 (use (match_operand:HI 2 "memory_operand" "m"))
15087 (use (match_operand:HI 3 "memory_operand" "m"))]
15088 "TARGET_USE_FANCY_MATH_387
15089 && flag_unsafe_math_optimizations"
15090 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15091 [(set_attr "type" "frndint")
15092 (set_attr "i387_cw" "ceil")
15093 (set_attr "mode" "XF")])
15095 (define_expand "ceilxf2"
15096 [(use (match_operand:XF 0 "register_operand" ""))
15097 (use (match_operand:XF 1 "register_operand" ""))]
15098 "TARGET_USE_FANCY_MATH_387
15099 && flag_unsafe_math_optimizations"
15101 if (optimize_insn_for_size_p ())
15103 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15107 (define_expand "ceil<mode>2"
15108 [(use (match_operand:MODEF 0 "register_operand" ""))
15109 (use (match_operand:MODEF 1 "register_operand" ""))]
15110 "(TARGET_USE_FANCY_MATH_387
15111 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15112 || TARGET_MIX_SSE_I387)
15113 && flag_unsafe_math_optimizations)
15114 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15115 && !flag_trapping_math)"
15117 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15118 && !flag_trapping_math)
15121 emit_insn (gen_sse4_1_round<mode>2
15122 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15123 else if (optimize_insn_for_size_p ())
15125 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15126 ix86_expand_floorceil (operands[0], operands[1], false);
15128 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15134 if (optimize_insn_for_size_p ())
15137 op0 = gen_reg_rtx (XFmode);
15138 op1 = gen_reg_rtx (XFmode);
15139 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15140 emit_insn (gen_frndintxf2_ceil (op0, op1));
15142 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15147 (define_insn_and_split "*fist<mode>2_ceil_1"
15148 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15149 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15151 (clobber (reg:CC FLAGS_REG))]
15152 "TARGET_USE_FANCY_MATH_387
15153 && flag_unsafe_math_optimizations
15154 && can_create_pseudo_p ()"
15159 ix86_optimize_mode_switching[I387_CEIL] = 1;
15161 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15162 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15163 if (memory_operand (operands[0], VOIDmode))
15164 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15165 operands[2], operands[3]));
15168 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15169 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15170 operands[2], operands[3],
15175 [(set_attr "type" "fistp")
15176 (set_attr "i387_cw" "ceil")
15177 (set_attr "mode" "<MODE>")])
15179 (define_insn "fistdi2_ceil"
15180 [(set (match_operand:DI 0 "memory_operand" "=m")
15181 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15183 (use (match_operand:HI 2 "memory_operand" "m"))
15184 (use (match_operand:HI 3 "memory_operand" "m"))
15185 (clobber (match_scratch:XF 4 "=&1f"))]
15186 "TARGET_USE_FANCY_MATH_387
15187 && flag_unsafe_math_optimizations"
15188 "* return output_fix_trunc (insn, operands, false);"
15189 [(set_attr "type" "fistp")
15190 (set_attr "i387_cw" "ceil")
15191 (set_attr "mode" "DI")])
15193 (define_insn "fistdi2_ceil_with_temp"
15194 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15195 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15197 (use (match_operand:HI 2 "memory_operand" "m,m"))
15198 (use (match_operand:HI 3 "memory_operand" "m,m"))
15199 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15200 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15201 "TARGET_USE_FANCY_MATH_387
15202 && flag_unsafe_math_optimizations"
15204 [(set_attr "type" "fistp")
15205 (set_attr "i387_cw" "ceil")
15206 (set_attr "mode" "DI")])
15209 [(set (match_operand:DI 0 "register_operand" "")
15210 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15212 (use (match_operand:HI 2 "memory_operand" ""))
15213 (use (match_operand:HI 3 "memory_operand" ""))
15214 (clobber (match_operand:DI 4 "memory_operand" ""))
15215 (clobber (match_scratch 5 ""))]
15217 [(parallel [(set (match_dup 4)
15218 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15219 (use (match_dup 2))
15220 (use (match_dup 3))
15221 (clobber (match_dup 5))])
15222 (set (match_dup 0) (match_dup 4))])
15225 [(set (match_operand:DI 0 "memory_operand" "")
15226 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15228 (use (match_operand:HI 2 "memory_operand" ""))
15229 (use (match_operand:HI 3 "memory_operand" ""))
15230 (clobber (match_operand:DI 4 "memory_operand" ""))
15231 (clobber (match_scratch 5 ""))]
15233 [(parallel [(set (match_dup 0)
15234 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15235 (use (match_dup 2))
15236 (use (match_dup 3))
15237 (clobber (match_dup 5))])])
15239 (define_insn "fist<mode>2_ceil"
15240 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15241 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15243 (use (match_operand:HI 2 "memory_operand" "m"))
15244 (use (match_operand:HI 3 "memory_operand" "m"))]
15245 "TARGET_USE_FANCY_MATH_387
15246 && flag_unsafe_math_optimizations"
15247 "* return output_fix_trunc (insn, operands, false);"
15248 [(set_attr "type" "fistp")
15249 (set_attr "i387_cw" "ceil")
15250 (set_attr "mode" "<MODE>")])
15252 (define_insn "fist<mode>2_ceil_with_temp"
15253 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15254 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15256 (use (match_operand:HI 2 "memory_operand" "m,m"))
15257 (use (match_operand:HI 3 "memory_operand" "m,m"))
15258 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15259 "TARGET_USE_FANCY_MATH_387
15260 && flag_unsafe_math_optimizations"
15262 [(set_attr "type" "fistp")
15263 (set_attr "i387_cw" "ceil")
15264 (set_attr "mode" "<MODE>")])
15267 [(set (match_operand:SWI24 0 "register_operand" "")
15268 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15270 (use (match_operand:HI 2 "memory_operand" ""))
15271 (use (match_operand:HI 3 "memory_operand" ""))
15272 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15274 [(parallel [(set (match_dup 4)
15275 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15276 (use (match_dup 2))
15277 (use (match_dup 3))])
15278 (set (match_dup 0) (match_dup 4))])
15281 [(set (match_operand:SWI24 0 "memory_operand" "")
15282 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15284 (use (match_operand:HI 2 "memory_operand" ""))
15285 (use (match_operand:HI 3 "memory_operand" ""))
15286 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15288 [(parallel [(set (match_dup 0)
15289 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15290 (use (match_dup 2))
15291 (use (match_dup 3))])])
15293 (define_expand "lceilxf<mode>2"
15294 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15295 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15297 (clobber (reg:CC FLAGS_REG))])]
15298 "TARGET_USE_FANCY_MATH_387
15299 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15300 && flag_unsafe_math_optimizations")
15302 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15303 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15304 (match_operand:MODEF 1 "register_operand" "")]
15305 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15306 && !flag_trapping_math"
15308 ix86_expand_lfloorceil (operands[0], operands[1], false);
15312 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15313 (define_insn_and_split "frndintxf2_trunc"
15314 [(set (match_operand:XF 0 "register_operand" "")
15315 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15316 UNSPEC_FRNDINT_TRUNC))
15317 (clobber (reg:CC FLAGS_REG))]
15318 "TARGET_USE_FANCY_MATH_387
15319 && flag_unsafe_math_optimizations
15320 && can_create_pseudo_p ()"
15325 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15327 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15328 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15330 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15331 operands[2], operands[3]));
15334 [(set_attr "type" "frndint")
15335 (set_attr "i387_cw" "trunc")
15336 (set_attr "mode" "XF")])
15338 (define_insn "frndintxf2_trunc_i387"
15339 [(set (match_operand:XF 0 "register_operand" "=f")
15340 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15341 UNSPEC_FRNDINT_TRUNC))
15342 (use (match_operand:HI 2 "memory_operand" "m"))
15343 (use (match_operand:HI 3 "memory_operand" "m"))]
15344 "TARGET_USE_FANCY_MATH_387
15345 && flag_unsafe_math_optimizations"
15346 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15347 [(set_attr "type" "frndint")
15348 (set_attr "i387_cw" "trunc")
15349 (set_attr "mode" "XF")])
15351 (define_expand "btruncxf2"
15352 [(use (match_operand:XF 0 "register_operand" ""))
15353 (use (match_operand:XF 1 "register_operand" ""))]
15354 "TARGET_USE_FANCY_MATH_387
15355 && flag_unsafe_math_optimizations"
15357 if (optimize_insn_for_size_p ())
15359 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15363 (define_expand "btrunc<mode>2"
15364 [(use (match_operand:MODEF 0 "register_operand" ""))
15365 (use (match_operand:MODEF 1 "register_operand" ""))]
15366 "(TARGET_USE_FANCY_MATH_387
15367 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15368 || TARGET_MIX_SSE_I387)
15369 && flag_unsafe_math_optimizations)
15370 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15371 && !flag_trapping_math)"
15373 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15374 && !flag_trapping_math)
15377 emit_insn (gen_sse4_1_round<mode>2
15378 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15379 else if (optimize_insn_for_size_p ())
15381 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15382 ix86_expand_trunc (operands[0], operands[1]);
15384 ix86_expand_truncdf_32 (operands[0], operands[1]);
15390 if (optimize_insn_for_size_p ())
15393 op0 = gen_reg_rtx (XFmode);
15394 op1 = gen_reg_rtx (XFmode);
15395 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15396 emit_insn (gen_frndintxf2_trunc (op0, op1));
15398 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15403 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15404 (define_insn_and_split "frndintxf2_mask_pm"
15405 [(set (match_operand:XF 0 "register_operand" "")
15406 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15407 UNSPEC_FRNDINT_MASK_PM))
15408 (clobber (reg:CC FLAGS_REG))]
15409 "TARGET_USE_FANCY_MATH_387
15410 && flag_unsafe_math_optimizations
15411 && can_create_pseudo_p ()"
15416 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15418 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15419 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15421 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15422 operands[2], operands[3]));
15425 [(set_attr "type" "frndint")
15426 (set_attr "i387_cw" "mask_pm")
15427 (set_attr "mode" "XF")])
15429 (define_insn "frndintxf2_mask_pm_i387"
15430 [(set (match_operand:XF 0 "register_operand" "=f")
15431 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15432 UNSPEC_FRNDINT_MASK_PM))
15433 (use (match_operand:HI 2 "memory_operand" "m"))
15434 (use (match_operand:HI 3 "memory_operand" "m"))]
15435 "TARGET_USE_FANCY_MATH_387
15436 && flag_unsafe_math_optimizations"
15437 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15438 [(set_attr "type" "frndint")
15439 (set_attr "i387_cw" "mask_pm")
15440 (set_attr "mode" "XF")])
15442 (define_expand "nearbyintxf2"
15443 [(use (match_operand:XF 0 "register_operand" ""))
15444 (use (match_operand:XF 1 "register_operand" ""))]
15445 "TARGET_USE_FANCY_MATH_387
15446 && flag_unsafe_math_optimizations"
15448 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15452 (define_expand "nearbyint<mode>2"
15453 [(use (match_operand:MODEF 0 "register_operand" ""))
15454 (use (match_operand:MODEF 1 "register_operand" ""))]
15455 "TARGET_USE_FANCY_MATH_387
15456 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15457 || TARGET_MIX_SSE_I387)
15458 && flag_unsafe_math_optimizations"
15460 rtx op0 = gen_reg_rtx (XFmode);
15461 rtx op1 = gen_reg_rtx (XFmode);
15463 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15464 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15466 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15470 (define_insn "fxam<mode>2_i387"
15471 [(set (match_operand:HI 0 "register_operand" "=a")
15473 [(match_operand:X87MODEF 1 "register_operand" "f")]
15475 "TARGET_USE_FANCY_MATH_387"
15476 "fxam\n\tfnstsw\t%0"
15477 [(set_attr "type" "multi")
15478 (set_attr "length" "4")
15479 (set_attr "unit" "i387")
15480 (set_attr "mode" "<MODE>")])
15482 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15483 [(set (match_operand:HI 0 "register_operand" "")
15485 [(match_operand:MODEF 1 "memory_operand" "")]
15487 "TARGET_USE_FANCY_MATH_387
15488 && can_create_pseudo_p ()"
15491 [(set (match_dup 2)(match_dup 1))
15493 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15495 operands[2] = gen_reg_rtx (<MODE>mode);
15497 MEM_VOLATILE_P (operands[1]) = 1;
15499 [(set_attr "type" "multi")
15500 (set_attr "unit" "i387")
15501 (set_attr "mode" "<MODE>")])
15503 (define_expand "isinfxf2"
15504 [(use (match_operand:SI 0 "register_operand" ""))
15505 (use (match_operand:XF 1 "register_operand" ""))]
15506 "TARGET_USE_FANCY_MATH_387
15507 && TARGET_C99_FUNCTIONS"
15509 rtx mask = GEN_INT (0x45);
15510 rtx val = GEN_INT (0x05);
15514 rtx scratch = gen_reg_rtx (HImode);
15515 rtx res = gen_reg_rtx (QImode);
15517 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15519 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15520 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15521 cond = gen_rtx_fmt_ee (EQ, QImode,
15522 gen_rtx_REG (CCmode, FLAGS_REG),
15524 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15525 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15529 (define_expand "isinf<mode>2"
15530 [(use (match_operand:SI 0 "register_operand" ""))
15531 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15532 "TARGET_USE_FANCY_MATH_387
15533 && TARGET_C99_FUNCTIONS
15534 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15536 rtx mask = GEN_INT (0x45);
15537 rtx val = GEN_INT (0x05);
15541 rtx scratch = gen_reg_rtx (HImode);
15542 rtx res = gen_reg_rtx (QImode);
15544 /* Remove excess precision by forcing value through memory. */
15545 if (memory_operand (operands[1], VOIDmode))
15546 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15549 enum ix86_stack_slot slot = (virtuals_instantiated
15552 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15554 emit_move_insn (temp, operands[1]);
15555 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15558 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15559 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15560 cond = gen_rtx_fmt_ee (EQ, QImode,
15561 gen_rtx_REG (CCmode, FLAGS_REG),
15563 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15564 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15568 (define_expand "signbitxf2"
15569 [(use (match_operand:SI 0 "register_operand" ""))
15570 (use (match_operand:XF 1 "register_operand" ""))]
15571 "TARGET_USE_FANCY_MATH_387"
15573 rtx scratch = gen_reg_rtx (HImode);
15575 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15576 emit_insn (gen_andsi3 (operands[0],
15577 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15581 (define_insn "movmsk_df"
15582 [(set (match_operand:SI 0 "register_operand" "=r")
15584 [(match_operand:DF 1 "register_operand" "x")]
15586 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15587 "%vmovmskpd\t{%1, %0|%0, %1}"
15588 [(set_attr "type" "ssemov")
15589 (set_attr "prefix" "maybe_vex")
15590 (set_attr "mode" "DF")])
15592 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15593 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15594 (define_expand "signbitdf2"
15595 [(use (match_operand:SI 0 "register_operand" ""))
15596 (use (match_operand:DF 1 "register_operand" ""))]
15597 "TARGET_USE_FANCY_MATH_387
15598 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15600 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15602 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15603 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15607 rtx scratch = gen_reg_rtx (HImode);
15609 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15610 emit_insn (gen_andsi3 (operands[0],
15611 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15616 (define_expand "signbitsf2"
15617 [(use (match_operand:SI 0 "register_operand" ""))
15618 (use (match_operand:SF 1 "register_operand" ""))]
15619 "TARGET_USE_FANCY_MATH_387
15620 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15622 rtx scratch = gen_reg_rtx (HImode);
15624 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15625 emit_insn (gen_andsi3 (operands[0],
15626 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15630 ;; Block operation instructions
15633 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15636 [(set_attr "length" "1")
15637 (set_attr "length_immediate" "0")
15638 (set_attr "modrm" "0")])
15640 (define_expand "movmem<mode>"
15641 [(use (match_operand:BLK 0 "memory_operand" ""))
15642 (use (match_operand:BLK 1 "memory_operand" ""))
15643 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15644 (use (match_operand:SWI48 3 "const_int_operand" ""))
15645 (use (match_operand:SI 4 "const_int_operand" ""))
15646 (use (match_operand:SI 5 "const_int_operand" ""))]
15649 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15650 operands[4], operands[5]))
15656 ;; Most CPUs don't like single string operations
15657 ;; Handle this case here to simplify previous expander.
15659 (define_expand "strmov"
15660 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15661 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15662 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15663 (clobber (reg:CC FLAGS_REG))])
15664 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15665 (clobber (reg:CC FLAGS_REG))])]
15668 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15670 /* If .md ever supports :P for Pmode, these can be directly
15671 in the pattern above. */
15672 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15673 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15675 /* Can't use this if the user has appropriated esi or edi. */
15676 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15677 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15679 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15680 operands[2], operands[3],
15681 operands[5], operands[6]));
15685 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15688 (define_expand "strmov_singleop"
15689 [(parallel [(set (match_operand 1 "memory_operand" "")
15690 (match_operand 3 "memory_operand" ""))
15691 (set (match_operand 0 "register_operand" "")
15692 (match_operand 4 "" ""))
15693 (set (match_operand 2 "register_operand" "")
15694 (match_operand 5 "" ""))])]
15696 "ix86_current_function_needs_cld = 1;")
15698 (define_insn "*strmovdi_rex_1"
15699 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15700 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15701 (set (match_operand:DI 0 "register_operand" "=D")
15702 (plus:DI (match_dup 2)
15704 (set (match_operand:DI 1 "register_operand" "=S")
15705 (plus:DI (match_dup 3)
15708 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15710 [(set_attr "type" "str")
15711 (set_attr "memory" "both")
15712 (set_attr "mode" "DI")])
15714 (define_insn "*strmovsi_1"
15715 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15716 (mem:SI (match_operand:P 3 "register_operand" "1")))
15717 (set (match_operand:P 0 "register_operand" "=D")
15718 (plus:P (match_dup 2)
15720 (set (match_operand:P 1 "register_operand" "=S")
15721 (plus:P (match_dup 3)
15723 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15725 [(set_attr "type" "str")
15726 (set_attr "memory" "both")
15727 (set_attr "mode" "SI")])
15729 (define_insn "*strmovhi_1"
15730 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15731 (mem:HI (match_operand:P 3 "register_operand" "1")))
15732 (set (match_operand:P 0 "register_operand" "=D")
15733 (plus:P (match_dup 2)
15735 (set (match_operand:P 1 "register_operand" "=S")
15736 (plus:P (match_dup 3)
15738 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15740 [(set_attr "type" "str")
15741 (set_attr "memory" "both")
15742 (set_attr "mode" "HI")])
15744 (define_insn "*strmovqi_1"
15745 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15746 (mem:QI (match_operand:P 3 "register_operand" "1")))
15747 (set (match_operand:P 0 "register_operand" "=D")
15748 (plus:P (match_dup 2)
15750 (set (match_operand:P 1 "register_operand" "=S")
15751 (plus:P (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 "prefix_rex")
15759 (match_test "<P:MODE>mode == DImode")
15761 (const_string "*")))
15762 (set_attr "mode" "QI")])
15764 (define_expand "rep_mov"
15765 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15766 (set (match_operand 0 "register_operand" "")
15767 (match_operand 5 "" ""))
15768 (set (match_operand 2 "register_operand" "")
15769 (match_operand 6 "" ""))
15770 (set (match_operand 1 "memory_operand" "")
15771 (match_operand 3 "memory_operand" ""))
15772 (use (match_dup 4))])]
15774 "ix86_current_function_needs_cld = 1;")
15776 (define_insn "*rep_movdi_rex64"
15777 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15778 (set (match_operand:DI 0 "register_operand" "=D")
15779 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15781 (match_operand:DI 3 "register_operand" "0")))
15782 (set (match_operand:DI 1 "register_operand" "=S")
15783 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15784 (match_operand:DI 4 "register_operand" "1")))
15785 (set (mem:BLK (match_dup 3))
15786 (mem:BLK (match_dup 4)))
15787 (use (match_dup 5))]
15789 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15791 [(set_attr "type" "str")
15792 (set_attr "prefix_rep" "1")
15793 (set_attr "memory" "both")
15794 (set_attr "mode" "DI")])
15796 (define_insn "*rep_movsi"
15797 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15798 (set (match_operand:P 0 "register_operand" "=D")
15799 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15801 (match_operand:P 3 "register_operand" "0")))
15802 (set (match_operand:P 1 "register_operand" "=S")
15803 (plus:P (ashift:P (match_dup 5) (const_int 2))
15804 (match_operand:P 4 "register_operand" "1")))
15805 (set (mem:BLK (match_dup 3))
15806 (mem:BLK (match_dup 4)))
15807 (use (match_dup 5))]
15808 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15809 "rep{%;} movs{l|d}"
15810 [(set_attr "type" "str")
15811 (set_attr "prefix_rep" "1")
15812 (set_attr "memory" "both")
15813 (set_attr "mode" "SI")])
15815 (define_insn "*rep_movqi"
15816 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15817 (set (match_operand:P 0 "register_operand" "=D")
15818 (plus:P (match_operand:P 3 "register_operand" "0")
15819 (match_operand:P 5 "register_operand" "2")))
15820 (set (match_operand:P 1 "register_operand" "=S")
15821 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15822 (set (mem:BLK (match_dup 3))
15823 (mem:BLK (match_dup 4)))
15824 (use (match_dup 5))]
15825 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15827 [(set_attr "type" "str")
15828 (set_attr "prefix_rep" "1")
15829 (set_attr "memory" "both")
15830 (set_attr "mode" "QI")])
15832 (define_expand "setmem<mode>"
15833 [(use (match_operand:BLK 0 "memory_operand" ""))
15834 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15835 (use (match_operand:QI 2 "nonmemory_operand" ""))
15836 (use (match_operand 3 "const_int_operand" ""))
15837 (use (match_operand:SI 4 "const_int_operand" ""))
15838 (use (match_operand:SI 5 "const_int_operand" ""))]
15841 if (ix86_expand_setmem (operands[0], operands[1],
15842 operands[2], operands[3],
15843 operands[4], operands[5]))
15849 ;; Most CPUs don't like single string operations
15850 ;; Handle this case here to simplify previous expander.
15852 (define_expand "strset"
15853 [(set (match_operand 1 "memory_operand" "")
15854 (match_operand 2 "register_operand" ""))
15855 (parallel [(set (match_operand 0 "register_operand" "")
15857 (clobber (reg:CC FLAGS_REG))])]
15860 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15861 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15863 /* If .md ever supports :P for Pmode, this can be directly
15864 in the pattern above. */
15865 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15866 GEN_INT (GET_MODE_SIZE (GET_MODE
15868 /* Can't use this if the user has appropriated eax or edi. */
15869 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15870 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15872 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15878 (define_expand "strset_singleop"
15879 [(parallel [(set (match_operand 1 "memory_operand" "")
15880 (match_operand 2 "register_operand" ""))
15881 (set (match_operand 0 "register_operand" "")
15882 (match_operand 3 "" ""))])]
15884 "ix86_current_function_needs_cld = 1;")
15886 (define_insn "*strsetdi_rex_1"
15887 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15888 (match_operand:DI 2 "register_operand" "a"))
15889 (set (match_operand:DI 0 "register_operand" "=D")
15890 (plus:DI (match_dup 1)
15893 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15895 [(set_attr "type" "str")
15896 (set_attr "memory" "store")
15897 (set_attr "mode" "DI")])
15899 (define_insn "*strsetsi_1"
15900 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15901 (match_operand:SI 2 "register_operand" "a"))
15902 (set (match_operand:P 0 "register_operand" "=D")
15903 (plus:P (match_dup 1)
15905 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15907 [(set_attr "type" "str")
15908 (set_attr "memory" "store")
15909 (set_attr "mode" "SI")])
15911 (define_insn "*strsethi_1"
15912 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15913 (match_operand:HI 2 "register_operand" "a"))
15914 (set (match_operand:P 0 "register_operand" "=D")
15915 (plus:P (match_dup 1)
15917 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15919 [(set_attr "type" "str")
15920 (set_attr "memory" "store")
15921 (set_attr "mode" "HI")])
15923 (define_insn "*strsetqi_1"
15924 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15925 (match_operand:QI 2 "register_operand" "a"))
15926 (set (match_operand:P 0 "register_operand" "=D")
15927 (plus:P (match_dup 1)
15929 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15931 [(set_attr "type" "str")
15932 (set_attr "memory" "store")
15933 (set (attr "prefix_rex")
15935 (match_test "<P:MODE>mode == DImode")
15937 (const_string "*")))
15938 (set_attr "mode" "QI")])
15940 (define_expand "rep_stos"
15941 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15942 (set (match_operand 0 "register_operand" "")
15943 (match_operand 4 "" ""))
15944 (set (match_operand 2 "memory_operand" "") (const_int 0))
15945 (use (match_operand 3 "register_operand" ""))
15946 (use (match_dup 1))])]
15948 "ix86_current_function_needs_cld = 1;")
15950 (define_insn "*rep_stosdi_rex64"
15951 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15952 (set (match_operand:DI 0 "register_operand" "=D")
15953 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15955 (match_operand:DI 3 "register_operand" "0")))
15956 (set (mem:BLK (match_dup 3))
15958 (use (match_operand:DI 2 "register_operand" "a"))
15959 (use (match_dup 4))]
15961 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15963 [(set_attr "type" "str")
15964 (set_attr "prefix_rep" "1")
15965 (set_attr "memory" "store")
15966 (set_attr "mode" "DI")])
15968 (define_insn "*rep_stossi"
15969 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15970 (set (match_operand:P 0 "register_operand" "=D")
15971 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15973 (match_operand:P 3 "register_operand" "0")))
15974 (set (mem:BLK (match_dup 3))
15976 (use (match_operand:SI 2 "register_operand" "a"))
15977 (use (match_dup 4))]
15978 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15979 "rep{%;} stos{l|d}"
15980 [(set_attr "type" "str")
15981 (set_attr "prefix_rep" "1")
15982 (set_attr "memory" "store")
15983 (set_attr "mode" "SI")])
15985 (define_insn "*rep_stosqi"
15986 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15987 (set (match_operand:P 0 "register_operand" "=D")
15988 (plus:P (match_operand:P 3 "register_operand" "0")
15989 (match_operand:P 4 "register_operand" "1")))
15990 (set (mem:BLK (match_dup 3))
15992 (use (match_operand:QI 2 "register_operand" "a"))
15993 (use (match_dup 4))]
15994 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15996 [(set_attr "type" "str")
15997 (set_attr "prefix_rep" "1")
15998 (set_attr "memory" "store")
15999 (set (attr "prefix_rex")
16001 (match_test "<P:MODE>mode == DImode")
16003 (const_string "*")))
16004 (set_attr "mode" "QI")])
16006 (define_expand "cmpstrnsi"
16007 [(set (match_operand:SI 0 "register_operand" "")
16008 (compare:SI (match_operand:BLK 1 "general_operand" "")
16009 (match_operand:BLK 2 "general_operand" "")))
16010 (use (match_operand 3 "general_operand" ""))
16011 (use (match_operand 4 "immediate_operand" ""))]
16014 rtx addr1, addr2, out, outlow, count, countreg, align;
16016 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16019 /* Can't use this if the user has appropriated ecx, esi or edi. */
16020 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16025 out = gen_reg_rtx (SImode);
16027 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16028 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16029 if (addr1 != XEXP (operands[1], 0))
16030 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16031 if (addr2 != XEXP (operands[2], 0))
16032 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16034 count = operands[3];
16035 countreg = ix86_zero_extend_to_Pmode (count);
16037 /* %%% Iff we are testing strict equality, we can use known alignment
16038 to good advantage. This may be possible with combine, particularly
16039 once cc0 is dead. */
16040 align = operands[4];
16042 if (CONST_INT_P (count))
16044 if (INTVAL (count) == 0)
16046 emit_move_insn (operands[0], const0_rtx);
16049 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16050 operands[1], operands[2]));
16054 rtx (*gen_cmp) (rtx, rtx);
16056 gen_cmp = (TARGET_64BIT
16057 ? gen_cmpdi_1 : gen_cmpsi_1);
16059 emit_insn (gen_cmp (countreg, countreg));
16060 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16061 operands[1], operands[2]));
16064 outlow = gen_lowpart (QImode, out);
16065 emit_insn (gen_cmpintqi (outlow));
16066 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16068 if (operands[0] != out)
16069 emit_move_insn (operands[0], out);
16074 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16076 (define_expand "cmpintqi"
16077 [(set (match_dup 1)
16078 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16080 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16081 (parallel [(set (match_operand:QI 0 "register_operand" "")
16082 (minus:QI (match_dup 1)
16084 (clobber (reg:CC FLAGS_REG))])]
16087 operands[1] = gen_reg_rtx (QImode);
16088 operands[2] = gen_reg_rtx (QImode);
16091 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16092 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16094 (define_expand "cmpstrnqi_nz_1"
16095 [(parallel [(set (reg:CC FLAGS_REG)
16096 (compare:CC (match_operand 4 "memory_operand" "")
16097 (match_operand 5 "memory_operand" "")))
16098 (use (match_operand 2 "register_operand" ""))
16099 (use (match_operand:SI 3 "immediate_operand" ""))
16100 (clobber (match_operand 0 "register_operand" ""))
16101 (clobber (match_operand 1 "register_operand" ""))
16102 (clobber (match_dup 2))])]
16104 "ix86_current_function_needs_cld = 1;")
16106 (define_insn "*cmpstrnqi_nz_1"
16107 [(set (reg:CC FLAGS_REG)
16108 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16109 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16110 (use (match_operand:P 6 "register_operand" "2"))
16111 (use (match_operand:SI 3 "immediate_operand" "i"))
16112 (clobber (match_operand:P 0 "register_operand" "=S"))
16113 (clobber (match_operand:P 1 "register_operand" "=D"))
16114 (clobber (match_operand:P 2 "register_operand" "=c"))]
16115 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16117 [(set_attr "type" "str")
16118 (set_attr "mode" "QI")
16119 (set (attr "prefix_rex")
16121 (match_test "<P:MODE>mode == DImode")
16123 (const_string "*")))
16124 (set_attr "prefix_rep" "1")])
16126 ;; The same, but the count is not known to not be zero.
16128 (define_expand "cmpstrnqi_1"
16129 [(parallel [(set (reg:CC FLAGS_REG)
16130 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16132 (compare:CC (match_operand 4 "memory_operand" "")
16133 (match_operand 5 "memory_operand" ""))
16135 (use (match_operand:SI 3 "immediate_operand" ""))
16136 (use (reg:CC FLAGS_REG))
16137 (clobber (match_operand 0 "register_operand" ""))
16138 (clobber (match_operand 1 "register_operand" ""))
16139 (clobber (match_dup 2))])]
16141 "ix86_current_function_needs_cld = 1;")
16143 (define_insn "*cmpstrnqi_1"
16144 [(set (reg:CC FLAGS_REG)
16145 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16147 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16148 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16150 (use (match_operand:SI 3 "immediate_operand" "i"))
16151 (use (reg:CC FLAGS_REG))
16152 (clobber (match_operand:P 0 "register_operand" "=S"))
16153 (clobber (match_operand:P 1 "register_operand" "=D"))
16154 (clobber (match_operand:P 2 "register_operand" "=c"))]
16155 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16157 [(set_attr "type" "str")
16158 (set_attr "mode" "QI")
16159 (set (attr "prefix_rex")
16161 (match_test "<P:MODE>mode == DImode")
16163 (const_string "*")))
16164 (set_attr "prefix_rep" "1")])
16166 (define_expand "strlen<mode>"
16167 [(set (match_operand:P 0 "register_operand" "")
16168 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16169 (match_operand:QI 2 "immediate_operand" "")
16170 (match_operand 3 "immediate_operand" "")]
16174 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16180 (define_expand "strlenqi_1"
16181 [(parallel [(set (match_operand 0 "register_operand" "")
16182 (match_operand 2 "" ""))
16183 (clobber (match_operand 1 "register_operand" ""))
16184 (clobber (reg:CC FLAGS_REG))])]
16186 "ix86_current_function_needs_cld = 1;")
16188 (define_insn "*strlenqi_1"
16189 [(set (match_operand:P 0 "register_operand" "=&c")
16190 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16191 (match_operand:QI 2 "register_operand" "a")
16192 (match_operand:P 3 "immediate_operand" "i")
16193 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16194 (clobber (match_operand:P 1 "register_operand" "=D"))
16195 (clobber (reg:CC FLAGS_REG))]
16196 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16198 [(set_attr "type" "str")
16199 (set_attr "mode" "QI")
16200 (set (attr "prefix_rex")
16202 (match_test "<P:MODE>mode == DImode")
16204 (const_string "*")))
16205 (set_attr "prefix_rep" "1")])
16207 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16208 ;; handled in combine, but it is not currently up to the task.
16209 ;; When used for their truth value, the cmpstrn* expanders generate
16218 ;; The intermediate three instructions are unnecessary.
16220 ;; This one handles cmpstrn*_nz_1...
16223 (set (reg:CC FLAGS_REG)
16224 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16225 (mem:BLK (match_operand 5 "register_operand" ""))))
16226 (use (match_operand 6 "register_operand" ""))
16227 (use (match_operand:SI 3 "immediate_operand" ""))
16228 (clobber (match_operand 0 "register_operand" ""))
16229 (clobber (match_operand 1 "register_operand" ""))
16230 (clobber (match_operand 2 "register_operand" ""))])
16231 (set (match_operand:QI 7 "register_operand" "")
16232 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16233 (set (match_operand:QI 8 "register_operand" "")
16234 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16235 (set (reg FLAGS_REG)
16236 (compare (match_dup 7) (match_dup 8)))
16238 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16240 (set (reg:CC FLAGS_REG)
16241 (compare:CC (mem:BLK (match_dup 4))
16242 (mem:BLK (match_dup 5))))
16243 (use (match_dup 6))
16244 (use (match_dup 3))
16245 (clobber (match_dup 0))
16246 (clobber (match_dup 1))
16247 (clobber (match_dup 2))])])
16249 ;; ...and this one handles cmpstrn*_1.
16252 (set (reg:CC FLAGS_REG)
16253 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16255 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16256 (mem:BLK (match_operand 5 "register_operand" "")))
16258 (use (match_operand:SI 3 "immediate_operand" ""))
16259 (use (reg:CC FLAGS_REG))
16260 (clobber (match_operand 0 "register_operand" ""))
16261 (clobber (match_operand 1 "register_operand" ""))
16262 (clobber (match_operand 2 "register_operand" ""))])
16263 (set (match_operand:QI 7 "register_operand" "")
16264 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16265 (set (match_operand:QI 8 "register_operand" "")
16266 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16267 (set (reg FLAGS_REG)
16268 (compare (match_dup 7) (match_dup 8)))
16270 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16272 (set (reg:CC FLAGS_REG)
16273 (if_then_else:CC (ne (match_dup 6)
16275 (compare:CC (mem:BLK (match_dup 4))
16276 (mem:BLK (match_dup 5)))
16278 (use (match_dup 3))
16279 (use (reg:CC FLAGS_REG))
16280 (clobber (match_dup 0))
16281 (clobber (match_dup 1))
16282 (clobber (match_dup 2))])])
16284 ;; Conditional move instructions.
16286 (define_expand "mov<mode>cc"
16287 [(set (match_operand:SWIM 0 "register_operand" "")
16288 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16289 (match_operand:SWIM 2 "<general_operand>" "")
16290 (match_operand:SWIM 3 "<general_operand>" "")))]
16292 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16294 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16295 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16296 ;; So just document what we're doing explicitly.
16298 (define_expand "x86_mov<mode>cc_0_m1"
16300 [(set (match_operand:SWI48 0 "register_operand" "")
16301 (if_then_else:SWI48
16302 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16303 [(match_operand 1 "flags_reg_operand" "")
16307 (clobber (reg:CC FLAGS_REG))])])
16309 (define_insn "*x86_mov<mode>cc_0_m1"
16310 [(set (match_operand:SWI48 0 "register_operand" "=r")
16311 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16312 [(reg FLAGS_REG) (const_int 0)])
16315 (clobber (reg:CC FLAGS_REG))]
16317 "sbb{<imodesuffix>}\t%0, %0"
16318 ; Since we don't have the proper number of operands for an alu insn,
16319 ; fill in all the blanks.
16320 [(set_attr "type" "alu")
16321 (set_attr "use_carry" "1")
16322 (set_attr "pent_pair" "pu")
16323 (set_attr "memory" "none")
16324 (set_attr "imm_disp" "false")
16325 (set_attr "mode" "<MODE>")
16326 (set_attr "length_immediate" "0")])
16328 (define_insn "*x86_mov<mode>cc_0_m1_se"
16329 [(set (match_operand:SWI48 0 "register_operand" "=r")
16330 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16331 [(reg FLAGS_REG) (const_int 0)])
16334 (clobber (reg:CC FLAGS_REG))]
16336 "sbb{<imodesuffix>}\t%0, %0"
16337 [(set_attr "type" "alu")
16338 (set_attr "use_carry" "1")
16339 (set_attr "pent_pair" "pu")
16340 (set_attr "memory" "none")
16341 (set_attr "imm_disp" "false")
16342 (set_attr "mode" "<MODE>")
16343 (set_attr "length_immediate" "0")])
16345 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16346 [(set (match_operand:SWI48 0 "register_operand" "=r")
16347 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16348 [(reg FLAGS_REG) (const_int 0)])))]
16350 "sbb{<imodesuffix>}\t%0, %0"
16351 [(set_attr "type" "alu")
16352 (set_attr "use_carry" "1")
16353 (set_attr "pent_pair" "pu")
16354 (set_attr "memory" "none")
16355 (set_attr "imm_disp" "false")
16356 (set_attr "mode" "<MODE>")
16357 (set_attr "length_immediate" "0")])
16359 (define_insn "*mov<mode>cc_noc"
16360 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16361 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16362 [(reg FLAGS_REG) (const_int 0)])
16363 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16364 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16365 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16367 cmov%O2%C1\t{%2, %0|%0, %2}
16368 cmov%O2%c1\t{%3, %0|%0, %3}"
16369 [(set_attr "type" "icmov")
16370 (set_attr "mode" "<MODE>")])
16372 (define_insn_and_split "*movqicc_noc"
16373 [(set (match_operand:QI 0 "register_operand" "=r,r")
16374 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16375 [(match_operand 4 "flags_reg_operand" "")
16377 (match_operand:QI 2 "register_operand" "r,0")
16378 (match_operand:QI 3 "register_operand" "0,r")))]
16379 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16381 "&& reload_completed"
16382 [(set (match_dup 0)
16383 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16386 "operands[0] = gen_lowpart (SImode, operands[0]);
16387 operands[2] = gen_lowpart (SImode, operands[2]);
16388 operands[3] = gen_lowpart (SImode, operands[3]);"
16389 [(set_attr "type" "icmov")
16390 (set_attr "mode" "SI")])
16392 (define_expand "mov<mode>cc"
16393 [(set (match_operand:X87MODEF 0 "register_operand" "")
16394 (if_then_else:X87MODEF
16395 (match_operand 1 "ix86_fp_comparison_operator" "")
16396 (match_operand:X87MODEF 2 "register_operand" "")
16397 (match_operand:X87MODEF 3 "register_operand" "")))]
16398 "(TARGET_80387 && TARGET_CMOVE)
16399 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16400 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16402 (define_insn "*movxfcc_1"
16403 [(set (match_operand:XF 0 "register_operand" "=f,f")
16404 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16405 [(reg FLAGS_REG) (const_int 0)])
16406 (match_operand:XF 2 "register_operand" "f,0")
16407 (match_operand:XF 3 "register_operand" "0,f")))]
16408 "TARGET_80387 && TARGET_CMOVE"
16410 fcmov%F1\t{%2, %0|%0, %2}
16411 fcmov%f1\t{%3, %0|%0, %3}"
16412 [(set_attr "type" "fcmov")
16413 (set_attr "mode" "XF")])
16415 (define_insn "*movdfcc_1_rex64"
16416 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16417 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16418 [(reg FLAGS_REG) (const_int 0)])
16419 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16420 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16421 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16422 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16424 fcmov%F1\t{%2, %0|%0, %2}
16425 fcmov%f1\t{%3, %0|%0, %3}
16426 cmov%O2%C1\t{%2, %0|%0, %2}
16427 cmov%O2%c1\t{%3, %0|%0, %3}"
16428 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16429 (set_attr "mode" "DF,DF,DI,DI")])
16431 (define_insn "*movdfcc_1"
16432 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16433 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16434 [(reg FLAGS_REG) (const_int 0)])
16435 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16436 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16437 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16438 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16440 fcmov%F1\t{%2, %0|%0, %2}
16441 fcmov%f1\t{%3, %0|%0, %3}
16444 [(set_attr "type" "fcmov,fcmov,multi,multi")
16445 (set_attr "mode" "DF,DF,DI,DI")])
16448 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16449 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16450 [(match_operand 4 "flags_reg_operand" "")
16452 (match_operand:DF 2 "nonimmediate_operand" "")
16453 (match_operand:DF 3 "nonimmediate_operand" "")))]
16454 "!TARGET_64BIT && reload_completed"
16455 [(set (match_dup 2)
16456 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16460 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16464 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16465 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16468 (define_insn "*movsfcc_1_387"
16469 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16470 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16471 [(reg FLAGS_REG) (const_int 0)])
16472 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16473 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16474 "TARGET_80387 && TARGET_CMOVE
16475 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16477 fcmov%F1\t{%2, %0|%0, %2}
16478 fcmov%f1\t{%3, %0|%0, %3}
16479 cmov%O2%C1\t{%2, %0|%0, %2}
16480 cmov%O2%c1\t{%3, %0|%0, %3}"
16481 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16482 (set_attr "mode" "SF,SF,SI,SI")])
16484 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16485 ;; the scalar versions to have only XMM registers as operands.
16487 ;; XOP conditional move
16488 (define_insn "*xop_pcmov_<mode>"
16489 [(set (match_operand:MODEF 0 "register_operand" "=x")
16490 (if_then_else:MODEF
16491 (match_operand:MODEF 1 "register_operand" "x")
16492 (match_operand:MODEF 2 "register_operand" "x")
16493 (match_operand:MODEF 3 "register_operand" "x")))]
16495 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16496 [(set_attr "type" "sse4arg")])
16498 ;; These versions of the min/max patterns are intentionally ignorant of
16499 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16500 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16501 ;; are undefined in this condition, we're certain this is correct.
16503 (define_insn "<code><mode>3"
16504 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16506 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16507 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16508 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16510 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16511 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16512 [(set_attr "isa" "noavx,avx")
16513 (set_attr "prefix" "orig,vex")
16514 (set_attr "type" "sseadd")
16515 (set_attr "mode" "<MODE>")])
16517 ;; These versions of the min/max patterns implement exactly the operations
16518 ;; min = (op1 < op2 ? op1 : op2)
16519 ;; max = (!(op1 < op2) ? op1 : op2)
16520 ;; Their operands are not commutative, and thus they may be used in the
16521 ;; presence of -0.0 and NaN.
16523 (define_insn "*ieee_smin<mode>3"
16524 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16526 [(match_operand:MODEF 1 "register_operand" "0,x")
16527 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16529 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16531 min<ssemodesuffix>\t{%2, %0|%0, %2}
16532 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16533 [(set_attr "isa" "noavx,avx")
16534 (set_attr "prefix" "orig,vex")
16535 (set_attr "type" "sseadd")
16536 (set_attr "mode" "<MODE>")])
16538 (define_insn "*ieee_smax<mode>3"
16539 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16541 [(match_operand:MODEF 1 "register_operand" "0,x")
16542 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16544 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16546 max<ssemodesuffix>\t{%2, %0|%0, %2}
16547 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16548 [(set_attr "isa" "noavx,avx")
16549 (set_attr "prefix" "orig,vex")
16550 (set_attr "type" "sseadd")
16551 (set_attr "mode" "<MODE>")])
16553 ;; Make two stack loads independent:
16555 ;; fld %st(0) -> fld bb
16556 ;; fmul bb fmul %st(1), %st
16558 ;; Actually we only match the last two instructions for simplicity.
16560 [(set (match_operand 0 "fp_register_operand" "")
16561 (match_operand 1 "fp_register_operand" ""))
16563 (match_operator 2 "binary_fp_operator"
16565 (match_operand 3 "memory_operand" "")]))]
16566 "REGNO (operands[0]) != REGNO (operands[1])"
16567 [(set (match_dup 0) (match_dup 3))
16568 (set (match_dup 0) (match_dup 4))]
16570 ;; The % modifier is not operational anymore in peephole2's, so we have to
16571 ;; swap the operands manually in the case of addition and multiplication.
16575 if (COMMUTATIVE_ARITH_P (operands[2]))
16576 op0 = operands[0], op1 = operands[1];
16578 op0 = operands[1], op1 = operands[0];
16580 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16581 GET_MODE (operands[2]),
16585 ;; Conditional addition patterns
16586 (define_expand "add<mode>cc"
16587 [(match_operand:SWI 0 "register_operand" "")
16588 (match_operand 1 "ordered_comparison_operator" "")
16589 (match_operand:SWI 2 "register_operand" "")
16590 (match_operand:SWI 3 "const_int_operand" "")]
16592 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16594 ;; Misc patterns (?)
16596 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16597 ;; Otherwise there will be nothing to keep
16599 ;; [(set (reg ebp) (reg esp))]
16600 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16601 ;; (clobber (eflags)]
16602 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16604 ;; in proper program order.
16606 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16607 [(set (match_operand:P 0 "register_operand" "=r,r")
16608 (plus:P (match_operand:P 1 "register_operand" "0,r")
16609 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16610 (clobber (reg:CC FLAGS_REG))
16611 (clobber (mem:BLK (scratch)))]
16614 switch (get_attr_type (insn))
16617 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16620 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16621 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16622 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16624 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16627 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16628 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16631 [(set (attr "type")
16632 (cond [(and (eq_attr "alternative" "0")
16633 (not (match_test "TARGET_OPT_AGU")))
16634 (const_string "alu")
16635 (match_operand:<MODE> 2 "const0_operand" "")
16636 (const_string "imov")
16638 (const_string "lea")))
16639 (set (attr "length_immediate")
16640 (cond [(eq_attr "type" "imov")
16642 (and (eq_attr "type" "alu")
16643 (match_operand 2 "const128_operand" ""))
16646 (const_string "*")))
16647 (set_attr "mode" "<MODE>")])
16649 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16650 [(set (match_operand:P 0 "register_operand" "=r")
16651 (minus:P (match_operand:P 1 "register_operand" "0")
16652 (match_operand:P 2 "register_operand" "r")))
16653 (clobber (reg:CC FLAGS_REG))
16654 (clobber (mem:BLK (scratch)))]
16656 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16657 [(set_attr "type" "alu")
16658 (set_attr "mode" "<MODE>")])
16660 (define_insn "allocate_stack_worker_probe_<mode>"
16661 [(set (match_operand:P 0 "register_operand" "=a")
16662 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16663 UNSPECV_STACK_PROBE))
16664 (clobber (reg:CC FLAGS_REG))]
16665 "ix86_target_stack_probe ()"
16666 "call\t___chkstk_ms"
16667 [(set_attr "type" "multi")
16668 (set_attr "length" "5")])
16670 (define_expand "allocate_stack"
16671 [(match_operand 0 "register_operand" "")
16672 (match_operand 1 "general_operand" "")]
16673 "ix86_target_stack_probe ()"
16677 #ifndef CHECK_STACK_LIMIT
16678 #define CHECK_STACK_LIMIT 0
16681 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16682 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16684 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16685 stack_pointer_rtx, 0, OPTAB_DIRECT);
16686 if (x != stack_pointer_rtx)
16687 emit_move_insn (stack_pointer_rtx, x);
16691 x = copy_to_mode_reg (Pmode, operands[1]);
16693 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16695 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16696 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16697 stack_pointer_rtx, 0, OPTAB_DIRECT);
16698 if (x != stack_pointer_rtx)
16699 emit_move_insn (stack_pointer_rtx, x);
16702 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16706 ;; Use IOR for stack probes, this is shorter.
16707 (define_expand "probe_stack"
16708 [(match_operand 0 "memory_operand" "")]
16711 rtx (*gen_ior3) (rtx, rtx, rtx);
16713 gen_ior3 = (GET_MODE (operands[0]) == DImode
16714 ? gen_iordi3 : gen_iorsi3);
16716 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16720 (define_insn "adjust_stack_and_probe<mode>"
16721 [(set (match_operand:P 0 "register_operand" "=r")
16722 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16723 UNSPECV_PROBE_STACK_RANGE))
16724 (set (reg:P SP_REG)
16725 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16726 (clobber (reg:CC FLAGS_REG))
16727 (clobber (mem:BLK (scratch)))]
16729 "* return output_adjust_stack_and_probe (operands[0]);"
16730 [(set_attr "type" "multi")])
16732 (define_insn "probe_stack_range<mode>"
16733 [(set (match_operand:P 0 "register_operand" "=r")
16734 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16735 (match_operand:P 2 "const_int_operand" "n")]
16736 UNSPECV_PROBE_STACK_RANGE))
16737 (clobber (reg:CC FLAGS_REG))]
16739 "* return output_probe_stack_range (operands[0], operands[2]);"
16740 [(set_attr "type" "multi")])
16742 (define_expand "builtin_setjmp_receiver"
16743 [(label_ref (match_operand 0 "" ""))]
16744 "!TARGET_64BIT && flag_pic"
16750 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16751 rtx label_rtx = gen_label_rtx ();
16752 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16753 xops[0] = xops[1] = picreg;
16754 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16755 ix86_expand_binary_operator (MINUS, SImode, xops);
16759 emit_insn (gen_set_got (pic_offset_table_rtx));
16763 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16766 [(set (match_operand 0 "register_operand" "")
16767 (match_operator 3 "promotable_binary_operator"
16768 [(match_operand 1 "register_operand" "")
16769 (match_operand 2 "aligned_operand" "")]))
16770 (clobber (reg:CC FLAGS_REG))]
16771 "! TARGET_PARTIAL_REG_STALL && reload_completed
16772 && ((GET_MODE (operands[0]) == HImode
16773 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16774 /* ??? next two lines just !satisfies_constraint_K (...) */
16775 || !CONST_INT_P (operands[2])
16776 || satisfies_constraint_K (operands[2])))
16777 || (GET_MODE (operands[0]) == QImode
16778 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16779 [(parallel [(set (match_dup 0)
16780 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16781 (clobber (reg:CC FLAGS_REG))])]
16783 operands[0] = gen_lowpart (SImode, operands[0]);
16784 operands[1] = gen_lowpart (SImode, operands[1]);
16785 if (GET_CODE (operands[3]) != ASHIFT)
16786 operands[2] = gen_lowpart (SImode, operands[2]);
16787 PUT_MODE (operands[3], SImode);
16790 ; Promote the QImode tests, as i386 has encoding of the AND
16791 ; instruction with 32-bit sign-extended immediate and thus the
16792 ; instruction size is unchanged, except in the %eax case for
16793 ; which it is increased by one byte, hence the ! optimize_size.
16795 [(set (match_operand 0 "flags_reg_operand" "")
16796 (match_operator 2 "compare_operator"
16797 [(and (match_operand 3 "aligned_operand" "")
16798 (match_operand 4 "const_int_operand" ""))
16800 (set (match_operand 1 "register_operand" "")
16801 (and (match_dup 3) (match_dup 4)))]
16802 "! TARGET_PARTIAL_REG_STALL && reload_completed
16803 && optimize_insn_for_speed_p ()
16804 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16805 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16806 /* Ensure that the operand will remain sign-extended immediate. */
16807 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16808 [(parallel [(set (match_dup 0)
16809 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16812 (and:SI (match_dup 3) (match_dup 4)))])]
16815 = gen_int_mode (INTVAL (operands[4])
16816 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16817 operands[1] = gen_lowpart (SImode, operands[1]);
16818 operands[3] = gen_lowpart (SImode, operands[3]);
16821 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16822 ; the TEST instruction with 32-bit sign-extended immediate and thus
16823 ; the instruction size would at least double, which is not what we
16824 ; want even with ! optimize_size.
16826 [(set (match_operand 0 "flags_reg_operand" "")
16827 (match_operator 1 "compare_operator"
16828 [(and (match_operand:HI 2 "aligned_operand" "")
16829 (match_operand:HI 3 "const_int_operand" ""))
16831 "! TARGET_PARTIAL_REG_STALL && reload_completed
16832 && ! TARGET_FAST_PREFIX
16833 && optimize_insn_for_speed_p ()
16834 /* Ensure that the operand will remain sign-extended immediate. */
16835 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16836 [(set (match_dup 0)
16837 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16841 = gen_int_mode (INTVAL (operands[3])
16842 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16843 operands[2] = gen_lowpart (SImode, operands[2]);
16847 [(set (match_operand 0 "register_operand" "")
16848 (neg (match_operand 1 "register_operand" "")))
16849 (clobber (reg:CC FLAGS_REG))]
16850 "! TARGET_PARTIAL_REG_STALL && reload_completed
16851 && (GET_MODE (operands[0]) == HImode
16852 || (GET_MODE (operands[0]) == QImode
16853 && (TARGET_PROMOTE_QImode
16854 || optimize_insn_for_size_p ())))"
16855 [(parallel [(set (match_dup 0)
16856 (neg:SI (match_dup 1)))
16857 (clobber (reg:CC FLAGS_REG))])]
16859 operands[0] = gen_lowpart (SImode, operands[0]);
16860 operands[1] = gen_lowpart (SImode, operands[1]);
16864 [(set (match_operand 0 "register_operand" "")
16865 (not (match_operand 1 "register_operand" "")))]
16866 "! TARGET_PARTIAL_REG_STALL && reload_completed
16867 && (GET_MODE (operands[0]) == HImode
16868 || (GET_MODE (operands[0]) == QImode
16869 && (TARGET_PROMOTE_QImode
16870 || optimize_insn_for_size_p ())))"
16871 [(set (match_dup 0)
16872 (not:SI (match_dup 1)))]
16874 operands[0] = gen_lowpart (SImode, operands[0]);
16875 operands[1] = gen_lowpart (SImode, operands[1]);
16879 [(set (match_operand 0 "register_operand" "")
16880 (if_then_else (match_operator 1 "ordered_comparison_operator"
16881 [(reg FLAGS_REG) (const_int 0)])
16882 (match_operand 2 "register_operand" "")
16883 (match_operand 3 "register_operand" "")))]
16884 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16885 && (GET_MODE (operands[0]) == HImode
16886 || (GET_MODE (operands[0]) == QImode
16887 && (TARGET_PROMOTE_QImode
16888 || optimize_insn_for_size_p ())))"
16889 [(set (match_dup 0)
16890 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16892 operands[0] = gen_lowpart (SImode, operands[0]);
16893 operands[2] = gen_lowpart (SImode, operands[2]);
16894 operands[3] = gen_lowpart (SImode, operands[3]);
16897 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16898 ;; transform a complex memory operation into two memory to register operations.
16900 ;; Don't push memory operands
16902 [(set (match_operand:SWI 0 "push_operand" "")
16903 (match_operand:SWI 1 "memory_operand" ""))
16904 (match_scratch:SWI 2 "<r>")]
16905 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16906 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16907 [(set (match_dup 2) (match_dup 1))
16908 (set (match_dup 0) (match_dup 2))])
16910 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16913 [(set (match_operand:SF 0 "push_operand" "")
16914 (match_operand:SF 1 "memory_operand" ""))
16915 (match_scratch:SF 2 "r")]
16916 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16917 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16918 [(set (match_dup 2) (match_dup 1))
16919 (set (match_dup 0) (match_dup 2))])
16921 ;; Don't move an immediate directly to memory when the instruction
16924 [(match_scratch:SWI124 1 "<r>")
16925 (set (match_operand:SWI124 0 "memory_operand" "")
16927 "optimize_insn_for_speed_p ()
16928 && !TARGET_USE_MOV0
16929 && TARGET_SPLIT_LONG_MOVES
16930 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16931 && peep2_regno_dead_p (0, FLAGS_REG)"
16932 [(parallel [(set (match_dup 2) (const_int 0))
16933 (clobber (reg:CC FLAGS_REG))])
16934 (set (match_dup 0) (match_dup 1))]
16935 "operands[2] = gen_lowpart (SImode, operands[1]);")
16938 [(match_scratch:SWI124 2 "<r>")
16939 (set (match_operand:SWI124 0 "memory_operand" "")
16940 (match_operand:SWI124 1 "immediate_operand" ""))]
16941 "optimize_insn_for_speed_p ()
16942 && TARGET_SPLIT_LONG_MOVES
16943 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16944 [(set (match_dup 2) (match_dup 1))
16945 (set (match_dup 0) (match_dup 2))])
16947 ;; Don't compare memory with zero, load and use a test instead.
16949 [(set (match_operand 0 "flags_reg_operand" "")
16950 (match_operator 1 "compare_operator"
16951 [(match_operand:SI 2 "memory_operand" "")
16953 (match_scratch:SI 3 "r")]
16954 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16955 [(set (match_dup 3) (match_dup 2))
16956 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16958 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16959 ;; Don't split NOTs with a displacement operand, because resulting XOR
16960 ;; will not be pairable anyway.
16962 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16963 ;; represented using a modRM byte. The XOR replacement is long decoded,
16964 ;; so this split helps here as well.
16966 ;; Note: Can't do this as a regular split because we can't get proper
16967 ;; lifetime information then.
16970 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16971 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16972 "optimize_insn_for_speed_p ()
16973 && ((TARGET_NOT_UNPAIRABLE
16974 && (!MEM_P (operands[0])
16975 || !memory_displacement_operand (operands[0], <MODE>mode)))
16976 || (TARGET_NOT_VECTORMODE
16977 && long_memory_operand (operands[0], <MODE>mode)))
16978 && peep2_regno_dead_p (0, FLAGS_REG)"
16979 [(parallel [(set (match_dup 0)
16980 (xor:SWI124 (match_dup 1) (const_int -1)))
16981 (clobber (reg:CC FLAGS_REG))])])
16983 ;; Non pairable "test imm, reg" instructions can be translated to
16984 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16985 ;; byte opcode instead of two, have a short form for byte operands),
16986 ;; so do it for other CPUs as well. Given that the value was dead,
16987 ;; this should not create any new dependencies. Pass on the sub-word
16988 ;; versions if we're concerned about partial register stalls.
16991 [(set (match_operand 0 "flags_reg_operand" "")
16992 (match_operator 1 "compare_operator"
16993 [(and:SI (match_operand:SI 2 "register_operand" "")
16994 (match_operand:SI 3 "immediate_operand" ""))
16996 "ix86_match_ccmode (insn, CCNOmode)
16997 && (true_regnum (operands[2]) != AX_REG
16998 || satisfies_constraint_K (operands[3]))
16999 && peep2_reg_dead_p (1, operands[2])"
17001 [(set (match_dup 0)
17002 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17005 (and:SI (match_dup 2) (match_dup 3)))])])
17007 ;; We don't need to handle HImode case, because it will be promoted to SImode
17008 ;; on ! TARGET_PARTIAL_REG_STALL
17011 [(set (match_operand 0 "flags_reg_operand" "")
17012 (match_operator 1 "compare_operator"
17013 [(and:QI (match_operand:QI 2 "register_operand" "")
17014 (match_operand:QI 3 "immediate_operand" ""))
17016 "! TARGET_PARTIAL_REG_STALL
17017 && ix86_match_ccmode (insn, CCNOmode)
17018 && true_regnum (operands[2]) != AX_REG
17019 && peep2_reg_dead_p (1, operands[2])"
17021 [(set (match_dup 0)
17022 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17025 (and:QI (match_dup 2) (match_dup 3)))])])
17028 [(set (match_operand 0 "flags_reg_operand" "")
17029 (match_operator 1 "compare_operator"
17032 (match_operand 2 "ext_register_operand" "")
17035 (match_operand 3 "const_int_operand" ""))
17037 "! TARGET_PARTIAL_REG_STALL
17038 && ix86_match_ccmode (insn, CCNOmode)
17039 && true_regnum (operands[2]) != AX_REG
17040 && peep2_reg_dead_p (1, operands[2])"
17041 [(parallel [(set (match_dup 0)
17050 (set (zero_extract:SI (match_dup 2)
17058 (match_dup 3)))])])
17060 ;; Don't do logical operations with memory inputs.
17062 [(match_scratch:SI 2 "r")
17063 (parallel [(set (match_operand:SI 0 "register_operand" "")
17064 (match_operator:SI 3 "arith_or_logical_operator"
17066 (match_operand:SI 1 "memory_operand" "")]))
17067 (clobber (reg:CC FLAGS_REG))])]
17068 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17069 [(set (match_dup 2) (match_dup 1))
17070 (parallel [(set (match_dup 0)
17071 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17072 (clobber (reg:CC FLAGS_REG))])])
17075 [(match_scratch:SI 2 "r")
17076 (parallel [(set (match_operand:SI 0 "register_operand" "")
17077 (match_operator:SI 3 "arith_or_logical_operator"
17078 [(match_operand:SI 1 "memory_operand" "")
17080 (clobber (reg:CC FLAGS_REG))])]
17081 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17082 [(set (match_dup 2) (match_dup 1))
17083 (parallel [(set (match_dup 0)
17084 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17085 (clobber (reg:CC FLAGS_REG))])])
17087 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17088 ;; refers to the destination of the load!
17091 [(set (match_operand:SI 0 "register_operand" "")
17092 (match_operand:SI 1 "register_operand" ""))
17093 (parallel [(set (match_dup 0)
17094 (match_operator:SI 3 "commutative_operator"
17096 (match_operand:SI 2 "memory_operand" "")]))
17097 (clobber (reg:CC FLAGS_REG))])]
17098 "REGNO (operands[0]) != REGNO (operands[1])
17099 && GENERAL_REGNO_P (REGNO (operands[0]))
17100 && GENERAL_REGNO_P (REGNO (operands[1]))"
17101 [(set (match_dup 0) (match_dup 4))
17102 (parallel [(set (match_dup 0)
17103 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17104 (clobber (reg:CC FLAGS_REG))])]
17105 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17108 [(set (match_operand 0 "register_operand" "")
17109 (match_operand 1 "register_operand" ""))
17111 (match_operator 3 "commutative_operator"
17113 (match_operand 2 "memory_operand" "")]))]
17114 "REGNO (operands[0]) != REGNO (operands[1])
17115 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17116 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17117 [(set (match_dup 0) (match_dup 2))
17119 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17121 ; Don't do logical operations with memory outputs
17123 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17124 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17125 ; the same decoder scheduling characteristics as the original.
17128 [(match_scratch:SI 2 "r")
17129 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17130 (match_operator:SI 3 "arith_or_logical_operator"
17132 (match_operand:SI 1 "nonmemory_operand" "")]))
17133 (clobber (reg:CC FLAGS_REG))])]
17134 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17135 /* Do not split stack checking probes. */
17136 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17137 [(set (match_dup 2) (match_dup 0))
17138 (parallel [(set (match_dup 2)
17139 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17140 (clobber (reg:CC FLAGS_REG))])
17141 (set (match_dup 0) (match_dup 2))])
17144 [(match_scratch:SI 2 "r")
17145 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17146 (match_operator:SI 3 "arith_or_logical_operator"
17147 [(match_operand:SI 1 "nonmemory_operand" "")
17149 (clobber (reg:CC FLAGS_REG))])]
17150 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17151 /* Do not split stack checking probes. */
17152 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17153 [(set (match_dup 2) (match_dup 0))
17154 (parallel [(set (match_dup 2)
17155 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17156 (clobber (reg:CC FLAGS_REG))])
17157 (set (match_dup 0) (match_dup 2))])
17159 ;; Attempt to use arith or logical operations with memory outputs with
17160 ;; setting of flags.
17162 [(set (match_operand:SWI 0 "register_operand" "")
17163 (match_operand:SWI 1 "memory_operand" ""))
17164 (parallel [(set (match_dup 0)
17165 (match_operator:SWI 3 "plusminuslogic_operator"
17167 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17168 (clobber (reg:CC FLAGS_REG))])
17169 (set (match_dup 1) (match_dup 0))
17170 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17171 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17172 && peep2_reg_dead_p (4, operands[0])
17173 && !reg_overlap_mentioned_p (operands[0], operands[1])
17174 && ix86_match_ccmode (peep2_next_insn (3),
17175 (GET_CODE (operands[3]) == PLUS
17176 || GET_CODE (operands[3]) == MINUS)
17177 ? CCGOCmode : CCNOmode)"
17178 [(parallel [(set (match_dup 4) (match_dup 5))
17179 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17180 (match_dup 2)]))])]
17182 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17183 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17184 copy_rtx (operands[1]),
17185 copy_rtx (operands[2]));
17186 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17187 operands[5], const0_rtx);
17191 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17192 (match_operator:SWI 2 "plusminuslogic_operator"
17194 (match_operand:SWI 1 "memory_operand" "")]))
17195 (clobber (reg:CC FLAGS_REG))])
17196 (set (match_dup 1) (match_dup 0))
17197 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17198 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17199 && GET_CODE (operands[2]) != MINUS
17200 && peep2_reg_dead_p (3, operands[0])
17201 && !reg_overlap_mentioned_p (operands[0], operands[1])
17202 && ix86_match_ccmode (peep2_next_insn (2),
17203 GET_CODE (operands[2]) == PLUS
17204 ? CCGOCmode : CCNOmode)"
17205 [(parallel [(set (match_dup 3) (match_dup 4))
17206 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17207 (match_dup 0)]))])]
17209 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17210 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17211 copy_rtx (operands[1]),
17212 copy_rtx (operands[0]));
17213 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17214 operands[4], const0_rtx);
17218 [(set (match_operand:SWI12 0 "register_operand" "")
17219 (match_operand:SWI12 1 "memory_operand" ""))
17220 (parallel [(set (match_operand:SI 4 "register_operand" "")
17221 (match_operator:SI 3 "plusminuslogic_operator"
17223 (match_operand:SI 2 "nonmemory_operand" "")]))
17224 (clobber (reg:CC FLAGS_REG))])
17225 (set (match_dup 1) (match_dup 0))
17226 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17227 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17228 && REG_P (operands[0]) && REG_P (operands[4])
17229 && REGNO (operands[0]) == REGNO (operands[4])
17230 && peep2_reg_dead_p (4, operands[0])
17231 && !reg_overlap_mentioned_p (operands[0], operands[1])
17232 && ix86_match_ccmode (peep2_next_insn (3),
17233 (GET_CODE (operands[3]) == PLUS
17234 || GET_CODE (operands[3]) == MINUS)
17235 ? CCGOCmode : CCNOmode)"
17236 [(parallel [(set (match_dup 4) (match_dup 5))
17237 (set (match_dup 1) (match_dup 6))])]
17239 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17240 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17241 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17242 copy_rtx (operands[1]), operands[2]);
17243 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17244 operands[5], const0_rtx);
17245 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17246 copy_rtx (operands[1]),
17247 copy_rtx (operands[2]));
17250 ;; Attempt to always use XOR for zeroing registers.
17252 [(set (match_operand 0 "register_operand" "")
17253 (match_operand 1 "const0_operand" ""))]
17254 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17255 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17256 && GENERAL_REG_P (operands[0])
17257 && peep2_regno_dead_p (0, FLAGS_REG)"
17258 [(parallel [(set (match_dup 0) (const_int 0))
17259 (clobber (reg:CC FLAGS_REG))])]
17260 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17263 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17265 "(GET_MODE (operands[0]) == QImode
17266 || GET_MODE (operands[0]) == HImode)
17267 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17268 && peep2_regno_dead_p (0, FLAGS_REG)"
17269 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17270 (clobber (reg:CC FLAGS_REG))])])
17272 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17274 [(set (match_operand:SWI248 0 "register_operand" "")
17276 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17277 && peep2_regno_dead_p (0, FLAGS_REG)"
17278 [(parallel [(set (match_dup 0) (const_int -1))
17279 (clobber (reg:CC FLAGS_REG))])]
17281 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17282 operands[0] = gen_lowpart (SImode, operands[0]);
17285 ;; Attempt to convert simple lea to add/shift.
17286 ;; These can be created by move expanders.
17289 [(set (match_operand:SWI48 0 "register_operand" "")
17290 (plus:SWI48 (match_dup 0)
17291 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17292 "peep2_regno_dead_p (0, FLAGS_REG)"
17293 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17294 (clobber (reg:CC FLAGS_REG))])])
17297 [(set (match_operand:SI 0 "register_operand" "")
17298 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17299 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17301 && peep2_regno_dead_p (0, FLAGS_REG)
17302 && REGNO (operands[0]) == REGNO (operands[1])"
17303 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17304 (clobber (reg:CC FLAGS_REG))])]
17305 "operands[2] = gen_lowpart (SImode, operands[2]);")
17308 [(set (match_operand:SWI48 0 "register_operand" "")
17309 (mult:SWI48 (match_dup 0)
17310 (match_operand:SWI48 1 "const_int_operand" "")))]
17311 "exact_log2 (INTVAL (operands[1])) >= 0
17312 && peep2_regno_dead_p (0, FLAGS_REG)"
17313 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17314 (clobber (reg:CC FLAGS_REG))])]
17315 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17318 [(set (match_operand:SI 0 "register_operand" "")
17319 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17320 (match_operand:DI 2 "const_int_operand" "")) 0))]
17322 && exact_log2 (INTVAL (operands[2])) >= 0
17323 && REGNO (operands[0]) == REGNO (operands[1])
17324 && peep2_regno_dead_p (0, FLAGS_REG)"
17325 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17326 (clobber (reg:CC FLAGS_REG))])]
17327 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17329 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17330 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17331 ;; On many CPUs it is also faster, since special hardware to avoid esp
17332 ;; dependencies is present.
17334 ;; While some of these conversions may be done using splitters, we use
17335 ;; peepholes in order to allow combine_stack_adjustments pass to see
17336 ;; nonobfuscated RTL.
17338 ;; Convert prologue esp subtractions to push.
17339 ;; We need register to push. In order to keep verify_flow_info happy we have
17341 ;; - use scratch and clobber it in order to avoid dependencies
17342 ;; - use already live register
17343 ;; We can't use the second way right now, since there is no reliable way how to
17344 ;; verify that given register is live. First choice will also most likely in
17345 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17346 ;; call clobbered registers are dead. We may want to use base pointer as an
17347 ;; alternative when no register is available later.
17350 [(match_scratch:P 1 "r")
17351 (parallel [(set (reg:P SP_REG)
17352 (plus:P (reg:P SP_REG)
17353 (match_operand:P 0 "const_int_operand" "")))
17354 (clobber (reg:CC FLAGS_REG))
17355 (clobber (mem:BLK (scratch)))])]
17356 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17357 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17358 [(clobber (match_dup 1))
17359 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17360 (clobber (mem:BLK (scratch)))])])
17363 [(match_scratch:P 1 "r")
17364 (parallel [(set (reg:P SP_REG)
17365 (plus:P (reg:P SP_REG)
17366 (match_operand:P 0 "const_int_operand" "")))
17367 (clobber (reg:CC FLAGS_REG))
17368 (clobber (mem:BLK (scratch)))])]
17369 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17370 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17371 [(clobber (match_dup 1))
17372 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17373 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17374 (clobber (mem:BLK (scratch)))])])
17376 ;; Convert esp subtractions to push.
17378 [(match_scratch:P 1 "r")
17379 (parallel [(set (reg:P SP_REG)
17380 (plus:P (reg:P SP_REG)
17381 (match_operand:P 0 "const_int_operand" "")))
17382 (clobber (reg:CC FLAGS_REG))])]
17383 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17384 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17385 [(clobber (match_dup 1))
17386 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17389 [(match_scratch:P 1 "r")
17390 (parallel [(set (reg:P SP_REG)
17391 (plus:P (reg:P SP_REG)
17392 (match_operand:P 0 "const_int_operand" "")))
17393 (clobber (reg:CC FLAGS_REG))])]
17394 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17395 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17396 [(clobber (match_dup 1))
17397 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17398 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17400 ;; Convert epilogue deallocator to pop.
17402 [(match_scratch:P 1 "r")
17403 (parallel [(set (reg:P SP_REG)
17404 (plus:P (reg:P SP_REG)
17405 (match_operand:P 0 "const_int_operand" "")))
17406 (clobber (reg:CC FLAGS_REG))
17407 (clobber (mem:BLK (scratch)))])]
17408 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17409 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17410 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17411 (clobber (mem:BLK (scratch)))])])
17413 ;; Two pops case is tricky, since pop causes dependency
17414 ;; on destination register. We use two registers if available.
17416 [(match_scratch:P 1 "r")
17417 (match_scratch:P 2 "r")
17418 (parallel [(set (reg:P SP_REG)
17419 (plus:P (reg:P SP_REG)
17420 (match_operand:P 0 "const_int_operand" "")))
17421 (clobber (reg:CC FLAGS_REG))
17422 (clobber (mem:BLK (scratch)))])]
17423 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17424 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17425 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17426 (clobber (mem:BLK (scratch)))])
17427 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17430 [(match_scratch:P 1 "r")
17431 (parallel [(set (reg:P SP_REG)
17432 (plus:P (reg:P SP_REG)
17433 (match_operand:P 0 "const_int_operand" "")))
17434 (clobber (reg:CC FLAGS_REG))
17435 (clobber (mem:BLK (scratch)))])]
17436 "optimize_insn_for_size_p ()
17437 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17438 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17439 (clobber (mem:BLK (scratch)))])
17440 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17442 ;; Convert esp additions to pop.
17444 [(match_scratch:P 1 "r")
17445 (parallel [(set (reg:P SP_REG)
17446 (plus:P (reg:P SP_REG)
17447 (match_operand:P 0 "const_int_operand" "")))
17448 (clobber (reg:CC FLAGS_REG))])]
17449 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17450 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17452 ;; Two pops case is tricky, since pop causes dependency
17453 ;; on destination register. We use two registers if available.
17455 [(match_scratch:P 1 "r")
17456 (match_scratch:P 2 "r")
17457 (parallel [(set (reg:P SP_REG)
17458 (plus:P (reg:P SP_REG)
17459 (match_operand:P 0 "const_int_operand" "")))
17460 (clobber (reg:CC FLAGS_REG))])]
17461 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17462 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17463 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17466 [(match_scratch:P 1 "r")
17467 (parallel [(set (reg:P SP_REG)
17468 (plus:P (reg:P SP_REG)
17469 (match_operand:P 0 "const_int_operand" "")))
17470 (clobber (reg:CC FLAGS_REG))])]
17471 "optimize_insn_for_size_p ()
17472 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17473 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17474 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17476 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17477 ;; required and register dies. Similarly for 128 to -128.
17479 [(set (match_operand 0 "flags_reg_operand" "")
17480 (match_operator 1 "compare_operator"
17481 [(match_operand 2 "register_operand" "")
17482 (match_operand 3 "const_int_operand" "")]))]
17483 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17484 && incdec_operand (operands[3], GET_MODE (operands[3])))
17485 || (!TARGET_FUSE_CMP_AND_BRANCH
17486 && INTVAL (operands[3]) == 128))
17487 && ix86_match_ccmode (insn, CCGCmode)
17488 && peep2_reg_dead_p (1, operands[2])"
17489 [(parallel [(set (match_dup 0)
17490 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17491 (clobber (match_dup 2))])])
17493 ;; Convert imul by three, five and nine into lea
17496 [(set (match_operand:SWI48 0 "register_operand" "")
17497 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17498 (match_operand:SWI48 2 "const359_operand" "")))
17499 (clobber (reg:CC FLAGS_REG))])]
17500 "!TARGET_PARTIAL_REG_STALL
17501 || <MODE>mode == SImode
17502 || optimize_function_for_size_p (cfun)"
17503 [(set (match_dup 0)
17504 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17506 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17510 [(set (match_operand:SWI48 0 "register_operand" "")
17511 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17512 (match_operand:SWI48 2 "const359_operand" "")))
17513 (clobber (reg:CC FLAGS_REG))])]
17514 "optimize_insn_for_speed_p ()
17515 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17516 [(set (match_dup 0) (match_dup 1))
17518 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17520 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17522 ;; imul $32bit_imm, mem, reg is vector decoded, while
17523 ;; imul $32bit_imm, reg, reg is direct decoded.
17525 [(match_scratch:SWI48 3 "r")
17526 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17527 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17528 (match_operand:SWI48 2 "immediate_operand" "")))
17529 (clobber (reg:CC FLAGS_REG))])]
17530 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17531 && !satisfies_constraint_K (operands[2])"
17532 [(set (match_dup 3) (match_dup 1))
17533 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17534 (clobber (reg:CC FLAGS_REG))])])
17537 [(match_scratch:SI 3 "r")
17538 (parallel [(set (match_operand:DI 0 "register_operand" "")
17540 (mult:SI (match_operand:SI 1 "memory_operand" "")
17541 (match_operand:SI 2 "immediate_operand" ""))))
17542 (clobber (reg:CC FLAGS_REG))])]
17544 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17545 && !satisfies_constraint_K (operands[2])"
17546 [(set (match_dup 3) (match_dup 1))
17547 (parallel [(set (match_dup 0)
17548 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17549 (clobber (reg:CC FLAGS_REG))])])
17551 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17552 ;; Convert it into imul reg, reg
17553 ;; It would be better to force assembler to encode instruction using long
17554 ;; immediate, but there is apparently no way to do so.
17556 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17558 (match_operand:SWI248 1 "nonimmediate_operand" "")
17559 (match_operand:SWI248 2 "const_int_operand" "")))
17560 (clobber (reg:CC FLAGS_REG))])
17561 (match_scratch:SWI248 3 "r")]
17562 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17563 && satisfies_constraint_K (operands[2])"
17564 [(set (match_dup 3) (match_dup 2))
17565 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17566 (clobber (reg:CC FLAGS_REG))])]
17568 if (!rtx_equal_p (operands[0], operands[1]))
17569 emit_move_insn (operands[0], operands[1]);
17572 ;; After splitting up read-modify operations, array accesses with memory
17573 ;; operands might end up in form:
17575 ;; movl 4(%esp), %edx
17577 ;; instead of pre-splitting:
17579 ;; addl 4(%esp), %eax
17581 ;; movl 4(%esp), %edx
17582 ;; leal (%edx,%eax,4), %eax
17585 [(match_scratch:P 5 "r")
17586 (parallel [(set (match_operand 0 "register_operand" "")
17587 (ashift (match_operand 1 "register_operand" "")
17588 (match_operand 2 "const_int_operand" "")))
17589 (clobber (reg:CC FLAGS_REG))])
17590 (parallel [(set (match_operand 3 "register_operand" "")
17591 (plus (match_dup 0)
17592 (match_operand 4 "x86_64_general_operand" "")))
17593 (clobber (reg:CC FLAGS_REG))])]
17594 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17595 /* Validate MODE for lea. */
17596 && ((!TARGET_PARTIAL_REG_STALL
17597 && (GET_MODE (operands[0]) == QImode
17598 || GET_MODE (operands[0]) == HImode))
17599 || GET_MODE (operands[0]) == SImode
17600 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17601 && (rtx_equal_p (operands[0], operands[3])
17602 || peep2_reg_dead_p (2, operands[0]))
17603 /* We reorder load and the shift. */
17604 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17605 [(set (match_dup 5) (match_dup 4))
17606 (set (match_dup 0) (match_dup 1))]
17608 enum machine_mode op1mode = GET_MODE (operands[1]);
17609 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17610 int scale = 1 << INTVAL (operands[2]);
17611 rtx index = gen_lowpart (Pmode, operands[1]);
17612 rtx base = gen_lowpart (Pmode, operands[5]);
17613 rtx dest = gen_lowpart (mode, operands[3]);
17615 operands[1] = gen_rtx_PLUS (Pmode, base,
17616 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17617 operands[5] = base;
17619 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17620 if (op1mode != Pmode)
17621 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17622 operands[0] = dest;
17625 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17626 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17627 ;; caught for use by garbage collectors and the like. Using an insn that
17628 ;; maps to SIGILL makes it more likely the program will rightfully die.
17629 ;; Keeping with tradition, "6" is in honor of #UD.
17630 (define_insn "trap"
17631 [(trap_if (const_int 1) (const_int 6))]
17633 { return ASM_SHORT "0x0b0f"; }
17634 [(set_attr "length" "2")])
17636 (define_expand "prefetch"
17637 [(prefetch (match_operand 0 "address_operand" "")
17638 (match_operand:SI 1 "const_int_operand" "")
17639 (match_operand:SI 2 "const_int_operand" ""))]
17640 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17642 int rw = INTVAL (operands[1]);
17643 int locality = INTVAL (operands[2]);
17645 gcc_assert (rw == 0 || rw == 1);
17646 gcc_assert (locality >= 0 && locality <= 3);
17647 gcc_assert (GET_MODE (operands[0]) == Pmode
17648 || GET_MODE (operands[0]) == VOIDmode);
17650 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17651 supported by SSE counterpart or the SSE prefetch is not available
17652 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17654 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17655 operands[2] = GEN_INT (3);
17657 operands[1] = const0_rtx;
17660 (define_insn "*prefetch_sse_<mode>"
17661 [(prefetch (match_operand:P 0 "address_operand" "p")
17663 (match_operand:SI 1 "const_int_operand" ""))]
17664 "TARGET_PREFETCH_SSE"
17666 static const char * const patterns[4] = {
17667 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17670 int locality = INTVAL (operands[1]);
17671 gcc_assert (locality >= 0 && locality <= 3);
17673 return patterns[locality];
17675 [(set_attr "type" "sse")
17676 (set_attr "atom_sse_attr" "prefetch")
17677 (set (attr "length_address")
17678 (symbol_ref "memory_address_length (operands[0])"))
17679 (set_attr "memory" "none")])
17681 (define_insn "*prefetch_3dnow_<mode>"
17682 [(prefetch (match_operand:P 0 "address_operand" "p")
17683 (match_operand:SI 1 "const_int_operand" "n")
17687 if (INTVAL (operands[1]) == 0)
17688 return "prefetch\t%a0";
17690 return "prefetchw\t%a0";
17692 [(set_attr "type" "mmx")
17693 (set (attr "length_address")
17694 (symbol_ref "memory_address_length (operands[0])"))
17695 (set_attr "memory" "none")])
17697 (define_expand "stack_protect_set"
17698 [(match_operand 0 "memory_operand" "")
17699 (match_operand 1 "memory_operand" "")]
17702 rtx (*insn)(rtx, rtx);
17704 #ifdef TARGET_THREAD_SSP_OFFSET
17705 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17706 insn = (TARGET_LP64
17707 ? gen_stack_tls_protect_set_di
17708 : gen_stack_tls_protect_set_si);
17710 insn = (TARGET_LP64
17711 ? gen_stack_protect_set_di
17712 : gen_stack_protect_set_si);
17715 emit_insn (insn (operands[0], operands[1]));
17719 (define_insn "stack_protect_set_<mode>"
17720 [(set (match_operand:PTR 0 "memory_operand" "=m")
17721 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17723 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17724 (clobber (reg:CC FLAGS_REG))]
17726 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17727 [(set_attr "type" "multi")])
17729 (define_insn "stack_tls_protect_set_<mode>"
17730 [(set (match_operand:PTR 0 "memory_operand" "=m")
17731 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17732 UNSPEC_SP_TLS_SET))
17733 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17734 (clobber (reg:CC FLAGS_REG))]
17736 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17737 [(set_attr "type" "multi")])
17739 (define_expand "stack_protect_test"
17740 [(match_operand 0 "memory_operand" "")
17741 (match_operand 1 "memory_operand" "")
17742 (match_operand 2 "" "")]
17745 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17747 rtx (*insn)(rtx, rtx, rtx);
17749 #ifdef TARGET_THREAD_SSP_OFFSET
17750 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17751 insn = (TARGET_LP64
17752 ? gen_stack_tls_protect_test_di
17753 : gen_stack_tls_protect_test_si);
17755 insn = (TARGET_LP64
17756 ? gen_stack_protect_test_di
17757 : gen_stack_protect_test_si);
17760 emit_insn (insn (flags, operands[0], operands[1]));
17762 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17763 flags, const0_rtx, operands[2]));
17767 (define_insn "stack_protect_test_<mode>"
17768 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17769 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17770 (match_operand:PTR 2 "memory_operand" "m")]
17772 (clobber (match_scratch:PTR 3 "=&r"))]
17774 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17775 [(set_attr "type" "multi")])
17777 (define_insn "stack_tls_protect_test_<mode>"
17778 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17779 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17780 (match_operand:PTR 2 "const_int_operand" "i")]
17781 UNSPEC_SP_TLS_TEST))
17782 (clobber (match_scratch:PTR 3 "=r"))]
17784 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17785 [(set_attr "type" "multi")])
17787 (define_insn "sse4_2_crc32<mode>"
17788 [(set (match_operand:SI 0 "register_operand" "=r")
17790 [(match_operand:SI 1 "register_operand" "0")
17791 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17793 "TARGET_SSE4_2 || TARGET_CRC32"
17794 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17795 [(set_attr "type" "sselog1")
17796 (set_attr "prefix_rep" "1")
17797 (set_attr "prefix_extra" "1")
17798 (set (attr "prefix_data16")
17799 (if_then_else (match_operand:HI 2 "" "")
17801 (const_string "*")))
17802 (set (attr "prefix_rex")
17803 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17805 (const_string "*")))
17806 (set_attr "mode" "SI")])
17808 (define_insn "sse4_2_crc32di"
17809 [(set (match_operand:DI 0 "register_operand" "=r")
17811 [(match_operand:DI 1 "register_operand" "0")
17812 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17814 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17815 "crc32{q}\t{%2, %0|%0, %2}"
17816 [(set_attr "type" "sselog1")
17817 (set_attr "prefix_rep" "1")
17818 (set_attr "prefix_extra" "1")
17819 (set_attr "mode" "DI")])
17821 (define_expand "rdpmc"
17822 [(match_operand:DI 0 "register_operand" "")
17823 (match_operand:SI 1 "register_operand" "")]
17826 rtx reg = gen_reg_rtx (DImode);
17829 /* Force operand 1 into ECX. */
17830 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17831 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17832 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17837 rtvec vec = rtvec_alloc (2);
17838 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17839 rtx upper = gen_reg_rtx (DImode);
17840 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17841 gen_rtvec (1, const0_rtx),
17843 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17844 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17846 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17847 NULL, 1, OPTAB_DIRECT);
17848 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17852 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17853 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17857 (define_insn "*rdpmc"
17858 [(set (match_operand:DI 0 "register_operand" "=A")
17859 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17863 [(set_attr "type" "other")
17864 (set_attr "length" "2")])
17866 (define_insn "*rdpmc_rex64"
17867 [(set (match_operand:DI 0 "register_operand" "=a")
17868 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17870 (set (match_operand:DI 1 "register_operand" "=d")
17871 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17874 [(set_attr "type" "other")
17875 (set_attr "length" "2")])
17877 (define_expand "rdtsc"
17878 [(set (match_operand:DI 0 "register_operand" "")
17879 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17884 rtvec vec = rtvec_alloc (2);
17885 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17886 rtx upper = gen_reg_rtx (DImode);
17887 rtx lower = gen_reg_rtx (DImode);
17888 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17889 gen_rtvec (1, const0_rtx),
17891 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17892 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17894 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17895 NULL, 1, OPTAB_DIRECT);
17896 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17898 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17903 (define_insn "*rdtsc"
17904 [(set (match_operand:DI 0 "register_operand" "=A")
17905 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17908 [(set_attr "type" "other")
17909 (set_attr "length" "2")])
17911 (define_insn "*rdtsc_rex64"
17912 [(set (match_operand:DI 0 "register_operand" "=a")
17913 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17914 (set (match_operand:DI 1 "register_operand" "=d")
17915 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17918 [(set_attr "type" "other")
17919 (set_attr "length" "2")])
17921 (define_expand "rdtscp"
17922 [(match_operand:DI 0 "register_operand" "")
17923 (match_operand:SI 1 "memory_operand" "")]
17926 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17927 gen_rtvec (1, const0_rtx),
17929 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17930 gen_rtvec (1, const0_rtx),
17932 rtx reg = gen_reg_rtx (DImode);
17933 rtx tmp = gen_reg_rtx (SImode);
17937 rtvec vec = rtvec_alloc (3);
17938 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17939 rtx upper = gen_reg_rtx (DImode);
17940 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17941 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17942 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17944 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17945 NULL, 1, OPTAB_DIRECT);
17946 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17951 rtvec vec = rtvec_alloc (2);
17952 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17953 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17954 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17957 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17958 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17962 (define_insn "*rdtscp"
17963 [(set (match_operand:DI 0 "register_operand" "=A")
17964 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17965 (set (match_operand:SI 1 "register_operand" "=c")
17966 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17969 [(set_attr "type" "other")
17970 (set_attr "length" "3")])
17972 (define_insn "*rdtscp_rex64"
17973 [(set (match_operand:DI 0 "register_operand" "=a")
17974 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17975 (set (match_operand:DI 1 "register_operand" "=d")
17976 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17977 (set (match_operand:SI 2 "register_operand" "=c")
17978 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17981 [(set_attr "type" "other")
17982 (set_attr "length" "3")])
17984 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17986 ;; LWP instructions
17988 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17990 (define_expand "lwp_llwpcb"
17991 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17992 UNSPECV_LLWP_INTRINSIC)]
17995 (define_insn "*lwp_llwpcb<mode>1"
17996 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17997 UNSPECV_LLWP_INTRINSIC)]
18000 [(set_attr "type" "lwp")
18001 (set_attr "mode" "<MODE>")
18002 (set_attr "length" "5")])
18004 (define_expand "lwp_slwpcb"
18005 [(set (match_operand 0 "register_operand" "=r")
18006 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18011 insn = (TARGET_64BIT
18013 : gen_lwp_slwpcbsi);
18015 emit_insn (insn (operands[0]));
18019 (define_insn "lwp_slwpcb<mode>"
18020 [(set (match_operand:P 0 "register_operand" "=r")
18021 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18024 [(set_attr "type" "lwp")
18025 (set_attr "mode" "<MODE>")
18026 (set_attr "length" "5")])
18028 (define_expand "lwp_lwpval<mode>3"
18029 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18030 (match_operand:SI 2 "nonimmediate_operand" "rm")
18031 (match_operand:SI 3 "const_int_operand" "i")]
18032 UNSPECV_LWPVAL_INTRINSIC)]
18034 ;; Avoid unused variable warning.
18035 "(void) operands[0];")
18037 (define_insn "*lwp_lwpval<mode>3_1"
18038 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18039 (match_operand:SI 1 "nonimmediate_operand" "rm")
18040 (match_operand:SI 2 "const_int_operand" "i")]
18041 UNSPECV_LWPVAL_INTRINSIC)]
18043 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18044 [(set_attr "type" "lwp")
18045 (set_attr "mode" "<MODE>")
18046 (set (attr "length")
18047 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18049 (define_expand "lwp_lwpins<mode>3"
18050 [(set (reg:CCC FLAGS_REG)
18051 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18052 (match_operand:SI 2 "nonimmediate_operand" "rm")
18053 (match_operand:SI 3 "const_int_operand" "i")]
18054 UNSPECV_LWPINS_INTRINSIC))
18055 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18056 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18059 (define_insn "*lwp_lwpins<mode>3_1"
18060 [(set (reg:CCC FLAGS_REG)
18061 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18062 (match_operand:SI 1 "nonimmediate_operand" "rm")
18063 (match_operand:SI 2 "const_int_operand" "i")]
18064 UNSPECV_LWPINS_INTRINSIC))]
18066 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18067 [(set_attr "type" "lwp")
18068 (set_attr "mode" "<MODE>")
18069 (set (attr "length")
18070 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18072 (define_insn "rdfsbase<mode>"
18073 [(set (match_operand:SWI48 0 "register_operand" "=r")
18074 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18075 "TARGET_64BIT && TARGET_FSGSBASE"
18077 [(set_attr "type" "other")
18078 (set_attr "prefix_extra" "2")])
18080 (define_insn "rdgsbase<mode>"
18081 [(set (match_operand:SWI48 0 "register_operand" "=r")
18082 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18083 "TARGET_64BIT && TARGET_FSGSBASE"
18085 [(set_attr "type" "other")
18086 (set_attr "prefix_extra" "2")])
18088 (define_insn "wrfsbase<mode>"
18089 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18091 "TARGET_64BIT && TARGET_FSGSBASE"
18093 [(set_attr "type" "other")
18094 (set_attr "prefix_extra" "2")])
18096 (define_insn "wrgsbase<mode>"
18097 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18099 "TARGET_64BIT && TARGET_FSGSBASE"
18101 [(set_attr "type" "other")
18102 (set_attr "prefix_extra" "2")])
18104 (define_insn "rdrand<mode>_1"
18105 [(set (match_operand:SWI248 0 "register_operand" "=r")
18106 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18107 (set (reg:CCC FLAGS_REG)
18108 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18111 [(set_attr "type" "other")
18112 (set_attr "prefix_extra" "1")])
18114 (define_expand "pause"
18115 [(set (match_dup 0)
18116 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18119 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18120 MEM_VOLATILE_P (operands[0]) = 1;
18123 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18124 ;; They have the same encoding.
18125 (define_insn "*pause"
18126 [(set (match_operand:BLK 0 "" "")
18127 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18130 [(set_attr "length" "2")
18131 (set_attr "memory" "unknown")])
18135 (include "sync.md")