1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; @ -- print a segment register of thread base pointer load
65 (define_c_enum "unspec" [
66 ;; Relocation specifiers
77 UNSPEC_MACHOPIC_OFFSET
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{l}\t{%1, %k0|%k0, %1}
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" "=X,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]) == (HOST_WIDE_INT) 0xffffffff)
7683 else if (INTVAL (operands[2]) == 0xffff)
7687 gcc_assert (INTVAL (operands[2]) == 0xff);
7691 operands[1] = gen_lowpart (mode, operands[1]);
7693 return "mov{l}\t{%1, %k0|%k0, %1}";
7694 else if (mode == HImode)
7695 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7697 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7701 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7702 if (get_attr_mode (insn) == MODE_SI)
7703 return "and{l}\t{%k2, %k0|%k0, %k2}";
7705 return "and{q}\t{%2, %0|%0, %2}";
7708 [(set_attr "type" "alu,alu,alu,imovx")
7709 (set_attr "length_immediate" "*,*,*,0")
7710 (set (attr "prefix_rex")
7712 (and (eq_attr "type" "imovx")
7713 (and (match_test "INTVAL (operands[2]) == 0xff")
7714 (match_operand 1 "ext_QIreg_operand" "")))
7716 (const_string "*")))
7717 (set_attr "mode" "SI,DI,DI,SI")])
7719 (define_insn "*andsi_1"
7720 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7721 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7722 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7723 (clobber (reg:CC FLAGS_REG))]
7724 "ix86_binary_operator_ok (AND, SImode, operands)"
7726 switch (get_attr_type (insn))
7730 enum machine_mode mode;
7732 gcc_assert (CONST_INT_P (operands[2]));
7733 if (INTVAL (operands[2]) == 0xffff)
7737 gcc_assert (INTVAL (operands[2]) == 0xff);
7741 operands[1] = gen_lowpart (mode, operands[1]);
7743 return "movz{wl|x}\t{%1, %0|%0, %1}";
7745 return "movz{bl|x}\t{%1, %0|%0, %1}";
7749 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7750 return "and{l}\t{%2, %0|%0, %2}";
7753 [(set_attr "type" "alu,alu,imovx")
7754 (set (attr "prefix_rex")
7756 (and (eq_attr "type" "imovx")
7757 (and (match_test "INTVAL (operands[2]) == 0xff")
7758 (match_operand 1 "ext_QIreg_operand" "")))
7760 (const_string "*")))
7761 (set_attr "length_immediate" "*,*,0")
7762 (set_attr "mode" "SI")])
7764 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7765 (define_insn "*andsi_1_zext"
7766 [(set (match_operand:DI 0 "register_operand" "=r")
7768 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7769 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7770 (clobber (reg:CC FLAGS_REG))]
7771 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7772 "and{l}\t{%2, %k0|%k0, %2}"
7773 [(set_attr "type" "alu")
7774 (set_attr "mode" "SI")])
7776 (define_insn "*andhi_1"
7777 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7778 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7779 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7780 (clobber (reg:CC FLAGS_REG))]
7781 "ix86_binary_operator_ok (AND, HImode, operands)"
7783 switch (get_attr_type (insn))
7786 gcc_assert (CONST_INT_P (operands[2]));
7787 gcc_assert (INTVAL (operands[2]) == 0xff);
7788 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7791 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7793 return "and{w}\t{%2, %0|%0, %2}";
7796 [(set_attr "type" "alu,alu,imovx")
7797 (set_attr "length_immediate" "*,*,0")
7798 (set (attr "prefix_rex")
7800 (and (eq_attr "type" "imovx")
7801 (match_operand 1 "ext_QIreg_operand" ""))
7803 (const_string "*")))
7804 (set_attr "mode" "HI,HI,SI")])
7806 ;; %%% Potential partial reg stall on alternative 2. What to do?
7807 (define_insn "*andqi_1"
7808 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7809 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7810 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7811 (clobber (reg:CC FLAGS_REG))]
7812 "ix86_binary_operator_ok (AND, QImode, operands)"
7814 and{b}\t{%2, %0|%0, %2}
7815 and{b}\t{%2, %0|%0, %2}
7816 and{l}\t{%k2, %k0|%k0, %k2}"
7817 [(set_attr "type" "alu")
7818 (set_attr "mode" "QI,QI,SI")])
7820 (define_insn "*andqi_1_slp"
7821 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7822 (and:QI (match_dup 0)
7823 (match_operand:QI 1 "general_operand" "qn,qmn")))
7824 (clobber (reg:CC FLAGS_REG))]
7825 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7826 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7827 "and{b}\t{%1, %0|%0, %1}"
7828 [(set_attr "type" "alu1")
7829 (set_attr "mode" "QI")])
7832 [(set (match_operand 0 "register_operand" "")
7834 (const_int -65536)))
7835 (clobber (reg:CC FLAGS_REG))]
7836 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7837 || optimize_function_for_size_p (cfun)"
7838 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7839 "operands[1] = gen_lowpart (HImode, operands[0]);")
7842 [(set (match_operand 0 "ext_register_operand" "")
7845 (clobber (reg:CC FLAGS_REG))]
7846 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7847 && reload_completed"
7848 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7849 "operands[1] = gen_lowpart (QImode, operands[0]);")
7852 [(set (match_operand 0 "ext_register_operand" "")
7854 (const_int -65281)))
7855 (clobber (reg:CC FLAGS_REG))]
7856 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7857 && reload_completed"
7858 [(parallel [(set (zero_extract:SI (match_dup 0)
7862 (zero_extract:SI (match_dup 0)
7865 (zero_extract:SI (match_dup 0)
7868 (clobber (reg:CC FLAGS_REG))])]
7869 "operands[0] = gen_lowpart (SImode, operands[0]);")
7871 (define_insn "*anddi_2"
7872 [(set (reg FLAGS_REG)
7875 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7876 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7878 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7879 (and:DI (match_dup 1) (match_dup 2)))]
7880 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7881 && ix86_binary_operator_ok (AND, DImode, operands)"
7883 and{l}\t{%k2, %k0|%k0, %k2}
7884 and{q}\t{%2, %0|%0, %2}
7885 and{q}\t{%2, %0|%0, %2}"
7886 [(set_attr "type" "alu")
7887 (set_attr "mode" "SI,DI,DI")])
7889 (define_insn "*andqi_2_maybe_si"
7890 [(set (reg FLAGS_REG)
7892 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7893 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7895 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7896 (and:QI (match_dup 1) (match_dup 2)))]
7897 "ix86_binary_operator_ok (AND, QImode, operands)
7898 && ix86_match_ccmode (insn,
7899 CONST_INT_P (operands[2])
7900 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7902 if (which_alternative == 2)
7904 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7905 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7906 return "and{l}\t{%2, %k0|%k0, %2}";
7908 return "and{b}\t{%2, %0|%0, %2}";
7910 [(set_attr "type" "alu")
7911 (set_attr "mode" "QI,QI,SI")])
7913 (define_insn "*and<mode>_2"
7914 [(set (reg FLAGS_REG)
7915 (compare (and:SWI124
7916 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7917 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7919 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7920 (and:SWI124 (match_dup 1) (match_dup 2)))]
7921 "ix86_match_ccmode (insn, CCNOmode)
7922 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7923 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7924 [(set_attr "type" "alu")
7925 (set_attr "mode" "<MODE>")])
7927 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7928 (define_insn "*andsi_2_zext"
7929 [(set (reg FLAGS_REG)
7931 (match_operand:SI 1 "nonimmediate_operand" "%0")
7932 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7934 (set (match_operand:DI 0 "register_operand" "=r")
7935 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7936 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7937 && ix86_binary_operator_ok (AND, SImode, operands)"
7938 "and{l}\t{%2, %k0|%k0, %2}"
7939 [(set_attr "type" "alu")
7940 (set_attr "mode" "SI")])
7942 (define_insn "*andqi_2_slp"
7943 [(set (reg FLAGS_REG)
7945 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7946 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7948 (set (strict_low_part (match_dup 0))
7949 (and:QI (match_dup 0) (match_dup 1)))]
7950 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7951 && ix86_match_ccmode (insn, CCNOmode)
7952 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7953 "and{b}\t{%1, %0|%0, %1}"
7954 [(set_attr "type" "alu1")
7955 (set_attr "mode" "QI")])
7957 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7958 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7959 ;; for a QImode operand, which of course failed.
7960 (define_insn "andqi_ext_0"
7961 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7966 (match_operand 1 "ext_register_operand" "0")
7969 (match_operand 2 "const_int_operand" "n")))
7970 (clobber (reg:CC FLAGS_REG))]
7972 "and{b}\t{%2, %h0|%h0, %2}"
7973 [(set_attr "type" "alu")
7974 (set_attr "length_immediate" "1")
7975 (set_attr "modrm" "1")
7976 (set_attr "mode" "QI")])
7978 ;; Generated by peephole translating test to and. This shows up
7979 ;; often in fp comparisons.
7980 (define_insn "*andqi_ext_0_cc"
7981 [(set (reg FLAGS_REG)
7985 (match_operand 1 "ext_register_operand" "0")
7988 (match_operand 2 "const_int_operand" "n"))
7990 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7999 "ix86_match_ccmode (insn, CCNOmode)"
8000 "and{b}\t{%2, %h0|%h0, %2}"
8001 [(set_attr "type" "alu")
8002 (set_attr "length_immediate" "1")
8003 (set_attr "modrm" "1")
8004 (set_attr "mode" "QI")])
8006 (define_insn "*andqi_ext_1_rex64"
8007 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8012 (match_operand 1 "ext_register_operand" "0")
8016 (match_operand 2 "ext_register_operand" "Q"))))
8017 (clobber (reg:CC FLAGS_REG))]
8019 "and{b}\t{%2, %h0|%h0, %2}"
8020 [(set_attr "type" "alu")
8021 (set_attr "length_immediate" "0")
8022 (set_attr "mode" "QI")])
8024 (define_insn "*andqi_ext_1"
8025 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8030 (match_operand 1 "ext_register_operand" "0")
8034 (match_operand:QI 2 "general_operand" "Qm"))))
8035 (clobber (reg:CC FLAGS_REG))]
8037 "and{b}\t{%2, %h0|%h0, %2}"
8038 [(set_attr "type" "alu")
8039 (set_attr "length_immediate" "0")
8040 (set_attr "mode" "QI")])
8042 (define_insn "*andqi_ext_2"
8043 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8048 (match_operand 1 "ext_register_operand" "%0")
8052 (match_operand 2 "ext_register_operand" "Q")
8055 (clobber (reg:CC FLAGS_REG))]
8057 "and{b}\t{%h2, %h0|%h0, %h2}"
8058 [(set_attr "type" "alu")
8059 (set_attr "length_immediate" "0")
8060 (set_attr "mode" "QI")])
8062 ;; Convert wide AND instructions with immediate operand to shorter QImode
8063 ;; equivalents when possible.
8064 ;; Don't do the splitting with memory operands, since it introduces risk
8065 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8066 ;; for size, but that can (should?) be handled by generic code instead.
8068 [(set (match_operand 0 "register_operand" "")
8069 (and (match_operand 1 "register_operand" "")
8070 (match_operand 2 "const_int_operand" "")))
8071 (clobber (reg:CC FLAGS_REG))]
8073 && QI_REG_P (operands[0])
8074 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8075 && !(~INTVAL (operands[2]) & ~(255 << 8))
8076 && GET_MODE (operands[0]) != QImode"
8077 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8078 (and:SI (zero_extract:SI (match_dup 1)
8079 (const_int 8) (const_int 8))
8081 (clobber (reg:CC FLAGS_REG))])]
8083 operands[0] = gen_lowpart (SImode, operands[0]);
8084 operands[1] = gen_lowpart (SImode, operands[1]);
8085 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8088 ;; Since AND can be encoded with sign extended immediate, this is only
8089 ;; profitable when 7th bit is not set.
8091 [(set (match_operand 0 "register_operand" "")
8092 (and (match_operand 1 "general_operand" "")
8093 (match_operand 2 "const_int_operand" "")))
8094 (clobber (reg:CC FLAGS_REG))]
8096 && ANY_QI_REG_P (operands[0])
8097 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8098 && !(~INTVAL (operands[2]) & ~255)
8099 && !(INTVAL (operands[2]) & 128)
8100 && GET_MODE (operands[0]) != QImode"
8101 [(parallel [(set (strict_low_part (match_dup 0))
8102 (and:QI (match_dup 1)
8104 (clobber (reg:CC FLAGS_REG))])]
8106 operands[0] = gen_lowpart (QImode, operands[0]);
8107 operands[1] = gen_lowpart (QImode, operands[1]);
8108 operands[2] = gen_lowpart (QImode, operands[2]);
8111 ;; Logical inclusive and exclusive OR instructions
8113 ;; %%% This used to optimize known byte-wide and operations to memory.
8114 ;; If this is considered useful, it should be done with splitters.
8116 (define_expand "<code><mode>3"
8117 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8118 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8119 (match_operand:SWIM 2 "<general_operand>" "")))]
8121 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8123 (define_insn "*<code><mode>_1"
8124 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8126 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8127 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8128 (clobber (reg:CC FLAGS_REG))]
8129 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8130 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8131 [(set_attr "type" "alu")
8132 (set_attr "mode" "<MODE>")])
8134 ;; %%% Potential partial reg stall on alternative 2. What to do?
8135 (define_insn "*<code>qi_1"
8136 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8137 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8138 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8139 (clobber (reg:CC FLAGS_REG))]
8140 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8142 <logic>{b}\t{%2, %0|%0, %2}
8143 <logic>{b}\t{%2, %0|%0, %2}
8144 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8145 [(set_attr "type" "alu")
8146 (set_attr "mode" "QI,QI,SI")])
8148 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8149 (define_insn "*<code>si_1_zext"
8150 [(set (match_operand:DI 0 "register_operand" "=r")
8152 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8153 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8154 (clobber (reg:CC FLAGS_REG))]
8155 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8156 "<logic>{l}\t{%2, %k0|%k0, %2}"
8157 [(set_attr "type" "alu")
8158 (set_attr "mode" "SI")])
8160 (define_insn "*<code>si_1_zext_imm"
8161 [(set (match_operand:DI 0 "register_operand" "=r")
8163 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8164 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8165 (clobber (reg:CC FLAGS_REG))]
8166 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8167 "<logic>{l}\t{%2, %k0|%k0, %2}"
8168 [(set_attr "type" "alu")
8169 (set_attr "mode" "SI")])
8171 (define_insn "*<code>qi_1_slp"
8172 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8173 (any_or:QI (match_dup 0)
8174 (match_operand:QI 1 "general_operand" "qmn,qn")))
8175 (clobber (reg:CC FLAGS_REG))]
8176 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8177 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8178 "<logic>{b}\t{%1, %0|%0, %1}"
8179 [(set_attr "type" "alu1")
8180 (set_attr "mode" "QI")])
8182 (define_insn "*<code><mode>_2"
8183 [(set (reg FLAGS_REG)
8184 (compare (any_or:SWI
8185 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8186 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8188 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8189 (any_or:SWI (match_dup 1) (match_dup 2)))]
8190 "ix86_match_ccmode (insn, CCNOmode)
8191 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8192 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8193 [(set_attr "type" "alu")
8194 (set_attr "mode" "<MODE>")])
8196 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8197 ;; ??? Special case for immediate operand is missing - it is tricky.
8198 (define_insn "*<code>si_2_zext"
8199 [(set (reg FLAGS_REG)
8200 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8201 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8203 (set (match_operand:DI 0 "register_operand" "=r")
8204 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8205 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8206 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8207 "<logic>{l}\t{%2, %k0|%k0, %2}"
8208 [(set_attr "type" "alu")
8209 (set_attr "mode" "SI")])
8211 (define_insn "*<code>si_2_zext_imm"
8212 [(set (reg FLAGS_REG)
8214 (match_operand:SI 1 "nonimmediate_operand" "%0")
8215 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8217 (set (match_operand:DI 0 "register_operand" "=r")
8218 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8219 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8220 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8221 "<logic>{l}\t{%2, %k0|%k0, %2}"
8222 [(set_attr "type" "alu")
8223 (set_attr "mode" "SI")])
8225 (define_insn "*<code>qi_2_slp"
8226 [(set (reg FLAGS_REG)
8227 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8228 (match_operand:QI 1 "general_operand" "qmn,qn"))
8230 (set (strict_low_part (match_dup 0))
8231 (any_or:QI (match_dup 0) (match_dup 1)))]
8232 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8233 && ix86_match_ccmode (insn, CCNOmode)
8234 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8235 "<logic>{b}\t{%1, %0|%0, %1}"
8236 [(set_attr "type" "alu1")
8237 (set_attr "mode" "QI")])
8239 (define_insn "*<code><mode>_3"
8240 [(set (reg FLAGS_REG)
8241 (compare (any_or:SWI
8242 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8243 (match_operand:SWI 2 "<general_operand>" "<g>"))
8245 (clobber (match_scratch:SWI 0 "=<r>"))]
8246 "ix86_match_ccmode (insn, CCNOmode)
8247 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8248 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8249 [(set_attr "type" "alu")
8250 (set_attr "mode" "<MODE>")])
8252 (define_insn "*<code>qi_ext_0"
8253 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8258 (match_operand 1 "ext_register_operand" "0")
8261 (match_operand 2 "const_int_operand" "n")))
8262 (clobber (reg:CC FLAGS_REG))]
8263 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8264 "<logic>{b}\t{%2, %h0|%h0, %2}"
8265 [(set_attr "type" "alu")
8266 (set_attr "length_immediate" "1")
8267 (set_attr "modrm" "1")
8268 (set_attr "mode" "QI")])
8270 (define_insn "*<code>qi_ext_1_rex64"
8271 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8276 (match_operand 1 "ext_register_operand" "0")
8280 (match_operand 2 "ext_register_operand" "Q"))))
8281 (clobber (reg:CC FLAGS_REG))]
8283 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8284 "<logic>{b}\t{%2, %h0|%h0, %2}"
8285 [(set_attr "type" "alu")
8286 (set_attr "length_immediate" "0")
8287 (set_attr "mode" "QI")])
8289 (define_insn "*<code>qi_ext_1"
8290 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8295 (match_operand 1 "ext_register_operand" "0")
8299 (match_operand:QI 2 "general_operand" "Qm"))))
8300 (clobber (reg:CC FLAGS_REG))]
8302 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8303 "<logic>{b}\t{%2, %h0|%h0, %2}"
8304 [(set_attr "type" "alu")
8305 (set_attr "length_immediate" "0")
8306 (set_attr "mode" "QI")])
8308 (define_insn "*<code>qi_ext_2"
8309 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8313 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8316 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8319 (clobber (reg:CC FLAGS_REG))]
8320 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8321 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8322 [(set_attr "type" "alu")
8323 (set_attr "length_immediate" "0")
8324 (set_attr "mode" "QI")])
8327 [(set (match_operand 0 "register_operand" "")
8328 (any_or (match_operand 1 "register_operand" "")
8329 (match_operand 2 "const_int_operand" "")))
8330 (clobber (reg:CC FLAGS_REG))]
8332 && QI_REG_P (operands[0])
8333 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8334 && !(INTVAL (operands[2]) & ~(255 << 8))
8335 && GET_MODE (operands[0]) != QImode"
8336 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8337 (any_or:SI (zero_extract:SI (match_dup 1)
8338 (const_int 8) (const_int 8))
8340 (clobber (reg:CC FLAGS_REG))])]
8342 operands[0] = gen_lowpart (SImode, operands[0]);
8343 operands[1] = gen_lowpart (SImode, operands[1]);
8344 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8347 ;; Since OR can be encoded with sign extended immediate, this is only
8348 ;; profitable when 7th bit is set.
8350 [(set (match_operand 0 "register_operand" "")
8351 (any_or (match_operand 1 "general_operand" "")
8352 (match_operand 2 "const_int_operand" "")))
8353 (clobber (reg:CC FLAGS_REG))]
8355 && ANY_QI_REG_P (operands[0])
8356 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8357 && !(INTVAL (operands[2]) & ~255)
8358 && (INTVAL (operands[2]) & 128)
8359 && GET_MODE (operands[0]) != QImode"
8360 [(parallel [(set (strict_low_part (match_dup 0))
8361 (any_or:QI (match_dup 1)
8363 (clobber (reg:CC FLAGS_REG))])]
8365 operands[0] = gen_lowpart (QImode, operands[0]);
8366 operands[1] = gen_lowpart (QImode, operands[1]);
8367 operands[2] = gen_lowpart (QImode, operands[2]);
8370 (define_expand "xorqi_cc_ext_1"
8372 (set (reg:CCNO FLAGS_REG)
8376 (match_operand 1 "ext_register_operand" "")
8379 (match_operand:QI 2 "general_operand" ""))
8381 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8391 (define_insn "*xorqi_cc_ext_1_rex64"
8392 [(set (reg FLAGS_REG)
8396 (match_operand 1 "ext_register_operand" "0")
8399 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8401 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8410 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8411 "xor{b}\t{%2, %h0|%h0, %2}"
8412 [(set_attr "type" "alu")
8413 (set_attr "modrm" "1")
8414 (set_attr "mode" "QI")])
8416 (define_insn "*xorqi_cc_ext_1"
8417 [(set (reg FLAGS_REG)
8421 (match_operand 1 "ext_register_operand" "0")
8424 (match_operand:QI 2 "general_operand" "qmn"))
8426 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8435 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8436 "xor{b}\t{%2, %h0|%h0, %2}"
8437 [(set_attr "type" "alu")
8438 (set_attr "modrm" "1")
8439 (set_attr "mode" "QI")])
8441 ;; Negation instructions
8443 (define_expand "neg<mode>2"
8444 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8445 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8447 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8449 (define_insn_and_split "*neg<dwi>2_doubleword"
8450 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8451 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8452 (clobber (reg:CC FLAGS_REG))]
8453 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8457 [(set (reg:CCZ FLAGS_REG)
8458 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8459 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8462 (plus:DWIH (match_dup 3)
8463 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8465 (clobber (reg:CC FLAGS_REG))])
8468 (neg:DWIH (match_dup 2)))
8469 (clobber (reg:CC FLAGS_REG))])]
8470 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8472 (define_insn "*neg<mode>2_1"
8473 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8474 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8475 (clobber (reg:CC FLAGS_REG))]
8476 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8477 "neg{<imodesuffix>}\t%0"
8478 [(set_attr "type" "negnot")
8479 (set_attr "mode" "<MODE>")])
8481 ;; Combine is quite creative about this pattern.
8482 (define_insn "*negsi2_1_zext"
8483 [(set (match_operand:DI 0 "register_operand" "=r")
8485 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8488 (clobber (reg:CC FLAGS_REG))]
8489 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8491 [(set_attr "type" "negnot")
8492 (set_attr "mode" "SI")])
8494 ;; The problem with neg is that it does not perform (compare x 0),
8495 ;; it really performs (compare 0 x), which leaves us with the zero
8496 ;; flag being the only useful item.
8498 (define_insn "*neg<mode>2_cmpz"
8499 [(set (reg:CCZ FLAGS_REG)
8501 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8503 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8504 (neg:SWI (match_dup 1)))]
8505 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8506 "neg{<imodesuffix>}\t%0"
8507 [(set_attr "type" "negnot")
8508 (set_attr "mode" "<MODE>")])
8510 (define_insn "*negsi2_cmpz_zext"
8511 [(set (reg:CCZ FLAGS_REG)
8515 (match_operand:DI 1 "register_operand" "0")
8519 (set (match_operand:DI 0 "register_operand" "=r")
8520 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8523 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8525 [(set_attr "type" "negnot")
8526 (set_attr "mode" "SI")])
8528 ;; Changing of sign for FP values is doable using integer unit too.
8530 (define_expand "<code><mode>2"
8531 [(set (match_operand:X87MODEF 0 "register_operand" "")
8532 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8533 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8534 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8536 (define_insn "*absneg<mode>2_mixed"
8537 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8538 (match_operator:MODEF 3 "absneg_operator"
8539 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8540 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8541 (clobber (reg:CC FLAGS_REG))]
8542 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8545 (define_insn "*absneg<mode>2_sse"
8546 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8547 (match_operator:MODEF 3 "absneg_operator"
8548 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8549 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8550 (clobber (reg:CC FLAGS_REG))]
8551 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8554 (define_insn "*absneg<mode>2_i387"
8555 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8556 (match_operator:X87MODEF 3 "absneg_operator"
8557 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8558 (use (match_operand 2 "" ""))
8559 (clobber (reg:CC FLAGS_REG))]
8560 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8563 (define_expand "<code>tf2"
8564 [(set (match_operand:TF 0 "register_operand" "")
8565 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8567 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8569 (define_insn "*absnegtf2_sse"
8570 [(set (match_operand:TF 0 "register_operand" "=x,x")
8571 (match_operator:TF 3 "absneg_operator"
8572 [(match_operand:TF 1 "register_operand" "0,x")]))
8573 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8574 (clobber (reg:CC FLAGS_REG))]
8578 ;; Splitters for fp abs and neg.
8581 [(set (match_operand 0 "fp_register_operand" "")
8582 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8583 (use (match_operand 2 "" ""))
8584 (clobber (reg:CC FLAGS_REG))]
8586 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8589 [(set (match_operand 0 "register_operand" "")
8590 (match_operator 3 "absneg_operator"
8591 [(match_operand 1 "register_operand" "")]))
8592 (use (match_operand 2 "nonimmediate_operand" ""))
8593 (clobber (reg:CC FLAGS_REG))]
8594 "reload_completed && SSE_REG_P (operands[0])"
8595 [(set (match_dup 0) (match_dup 3))]
8597 enum machine_mode mode = GET_MODE (operands[0]);
8598 enum machine_mode vmode = GET_MODE (operands[2]);
8601 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8602 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8603 if (operands_match_p (operands[0], operands[2]))
8606 operands[1] = operands[2];
8609 if (GET_CODE (operands[3]) == ABS)
8610 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8612 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8617 [(set (match_operand:SF 0 "register_operand" "")
8618 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8619 (use (match_operand:V4SF 2 "" ""))
8620 (clobber (reg:CC FLAGS_REG))]
8622 [(parallel [(set (match_dup 0) (match_dup 1))
8623 (clobber (reg:CC FLAGS_REG))])]
8626 operands[0] = gen_lowpart (SImode, operands[0]);
8627 if (GET_CODE (operands[1]) == ABS)
8629 tmp = gen_int_mode (0x7fffffff, SImode);
8630 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8634 tmp = gen_int_mode (0x80000000, SImode);
8635 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8641 [(set (match_operand:DF 0 "register_operand" "")
8642 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8643 (use (match_operand 2 "" ""))
8644 (clobber (reg:CC FLAGS_REG))]
8646 [(parallel [(set (match_dup 0) (match_dup 1))
8647 (clobber (reg:CC FLAGS_REG))])]
8652 tmp = gen_lowpart (DImode, operands[0]);
8653 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8656 if (GET_CODE (operands[1]) == ABS)
8659 tmp = gen_rtx_NOT (DImode, tmp);
8663 operands[0] = gen_highpart (SImode, operands[0]);
8664 if (GET_CODE (operands[1]) == ABS)
8666 tmp = gen_int_mode (0x7fffffff, SImode);
8667 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8671 tmp = gen_int_mode (0x80000000, SImode);
8672 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8679 [(set (match_operand:XF 0 "register_operand" "")
8680 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8681 (use (match_operand 2 "" ""))
8682 (clobber (reg:CC FLAGS_REG))]
8684 [(parallel [(set (match_dup 0) (match_dup 1))
8685 (clobber (reg:CC FLAGS_REG))])]
8688 operands[0] = gen_rtx_REG (SImode,
8689 true_regnum (operands[0])
8690 + (TARGET_64BIT ? 1 : 2));
8691 if (GET_CODE (operands[1]) == ABS)
8693 tmp = GEN_INT (0x7fff);
8694 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8698 tmp = GEN_INT (0x8000);
8699 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8704 ;; Conditionalize these after reload. If they match before reload, we
8705 ;; lose the clobber and ability to use integer instructions.
8707 (define_insn "*<code><mode>2_1"
8708 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8709 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8711 && (reload_completed
8712 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8713 "f<absneg_mnemonic>"
8714 [(set_attr "type" "fsgn")
8715 (set_attr "mode" "<MODE>")])
8717 (define_insn "*<code>extendsfdf2"
8718 [(set (match_operand:DF 0 "register_operand" "=f")
8719 (absneg:DF (float_extend:DF
8720 (match_operand:SF 1 "register_operand" "0"))))]
8721 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8722 "f<absneg_mnemonic>"
8723 [(set_attr "type" "fsgn")
8724 (set_attr "mode" "DF")])
8726 (define_insn "*<code>extendsfxf2"
8727 [(set (match_operand:XF 0 "register_operand" "=f")
8728 (absneg:XF (float_extend:XF
8729 (match_operand:SF 1 "register_operand" "0"))))]
8731 "f<absneg_mnemonic>"
8732 [(set_attr "type" "fsgn")
8733 (set_attr "mode" "XF")])
8735 (define_insn "*<code>extenddfxf2"
8736 [(set (match_operand:XF 0 "register_operand" "=f")
8737 (absneg:XF (float_extend:XF
8738 (match_operand:DF 1 "register_operand" "0"))))]
8740 "f<absneg_mnemonic>"
8741 [(set_attr "type" "fsgn")
8742 (set_attr "mode" "XF")])
8744 ;; Copysign instructions
8746 (define_mode_iterator CSGNMODE [SF DF TF])
8747 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8749 (define_expand "copysign<mode>3"
8750 [(match_operand:CSGNMODE 0 "register_operand" "")
8751 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8752 (match_operand:CSGNMODE 2 "register_operand" "")]
8753 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8754 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8755 "ix86_expand_copysign (operands); DONE;")
8757 (define_insn_and_split "copysign<mode>3_const"
8758 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8760 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8761 (match_operand:CSGNMODE 2 "register_operand" "0")
8762 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8764 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8765 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8767 "&& reload_completed"
8769 "ix86_split_copysign_const (operands); DONE;")
8771 (define_insn "copysign<mode>3_var"
8772 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8774 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8775 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8776 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8777 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8779 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8780 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8781 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8785 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8787 [(match_operand:CSGNMODE 2 "register_operand" "")
8788 (match_operand:CSGNMODE 3 "register_operand" "")
8789 (match_operand:<CSGNVMODE> 4 "" "")
8790 (match_operand:<CSGNVMODE> 5 "" "")]
8792 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8793 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8794 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8795 && reload_completed"
8797 "ix86_split_copysign_var (operands); DONE;")
8799 ;; One complement instructions
8801 (define_expand "one_cmpl<mode>2"
8802 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8803 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8805 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8807 (define_insn "*one_cmpl<mode>2_1"
8808 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8809 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8810 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8811 "not{<imodesuffix>}\t%0"
8812 [(set_attr "type" "negnot")
8813 (set_attr "mode" "<MODE>")])
8815 ;; %%% Potential partial reg stall on alternative 1. What to do?
8816 (define_insn "*one_cmplqi2_1"
8817 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8818 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8819 "ix86_unary_operator_ok (NOT, QImode, operands)"
8823 [(set_attr "type" "negnot")
8824 (set_attr "mode" "QI,SI")])
8826 ;; ??? Currently never generated - xor is used instead.
8827 (define_insn "*one_cmplsi2_1_zext"
8828 [(set (match_operand:DI 0 "register_operand" "=r")
8830 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8831 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8833 [(set_attr "type" "negnot")
8834 (set_attr "mode" "SI")])
8836 (define_insn "*one_cmpl<mode>2_2"
8837 [(set (reg FLAGS_REG)
8838 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8840 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8841 (not:SWI (match_dup 1)))]
8842 "ix86_match_ccmode (insn, CCNOmode)
8843 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8845 [(set_attr "type" "alu1")
8846 (set_attr "mode" "<MODE>")])
8849 [(set (match_operand 0 "flags_reg_operand" "")
8850 (match_operator 2 "compare_operator"
8851 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8853 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8854 (not:SWI (match_dup 3)))]
8855 "ix86_match_ccmode (insn, CCNOmode)"
8856 [(parallel [(set (match_dup 0)
8857 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8860 (xor:SWI (match_dup 3) (const_int -1)))])])
8862 ;; ??? Currently never generated - xor is used instead.
8863 (define_insn "*one_cmplsi2_2_zext"
8864 [(set (reg FLAGS_REG)
8865 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8867 (set (match_operand:DI 0 "register_operand" "=r")
8868 (zero_extend:DI (not:SI (match_dup 1))))]
8869 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8870 && ix86_unary_operator_ok (NOT, SImode, operands)"
8872 [(set_attr "type" "alu1")
8873 (set_attr "mode" "SI")])
8876 [(set (match_operand 0 "flags_reg_operand" "")
8877 (match_operator 2 "compare_operator"
8878 [(not:SI (match_operand:SI 3 "register_operand" ""))
8880 (set (match_operand:DI 1 "register_operand" "")
8881 (zero_extend:DI (not:SI (match_dup 3))))]
8882 "ix86_match_ccmode (insn, CCNOmode)"
8883 [(parallel [(set (match_dup 0)
8884 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8887 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8889 ;; Shift instructions
8891 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8892 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8893 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8894 ;; from the assembler input.
8896 ;; This instruction shifts the target reg/mem as usual, but instead of
8897 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8898 ;; is a left shift double, bits are taken from the high order bits of
8899 ;; reg, else if the insn is a shift right double, bits are taken from the
8900 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8901 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8903 ;; Since sh[lr]d does not change the `reg' operand, that is done
8904 ;; separately, making all shifts emit pairs of shift double and normal
8905 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8906 ;; support a 63 bit shift, each shift where the count is in a reg expands
8907 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8909 ;; If the shift count is a constant, we need never emit more than one
8910 ;; shift pair, instead using moves and sign extension for counts greater
8913 (define_expand "ashl<mode>3"
8914 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8915 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8916 (match_operand:QI 2 "nonmemory_operand" "")))]
8918 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8920 (define_insn "*ashl<mode>3_doubleword"
8921 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8922 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8923 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8924 (clobber (reg:CC FLAGS_REG))]
8927 [(set_attr "type" "multi")])
8930 [(set (match_operand:DWI 0 "register_operand" "")
8931 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8932 (match_operand:QI 2 "nonmemory_operand" "")))
8933 (clobber (reg:CC FLAGS_REG))]
8934 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8936 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8938 ;; By default we don't ask for a scratch register, because when DWImode
8939 ;; values are manipulated, registers are already at a premium. But if
8940 ;; we have one handy, we won't turn it away.
8943 [(match_scratch:DWIH 3 "r")
8944 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8946 (match_operand:<DWI> 1 "nonmemory_operand" "")
8947 (match_operand:QI 2 "nonmemory_operand" "")))
8948 (clobber (reg:CC FLAGS_REG))])
8952 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8954 (define_insn "x86_64_shld"
8955 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8956 (ior:DI (ashift:DI (match_dup 0)
8957 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8958 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8959 (minus:QI (const_int 64) (match_dup 2)))))
8960 (clobber (reg:CC FLAGS_REG))]
8962 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8963 [(set_attr "type" "ishift")
8964 (set_attr "prefix_0f" "1")
8965 (set_attr "mode" "DI")
8966 (set_attr "athlon_decode" "vector")
8967 (set_attr "amdfam10_decode" "vector")
8968 (set_attr "bdver1_decode" "vector")])
8970 (define_insn "x86_shld"
8971 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8972 (ior:SI (ashift:SI (match_dup 0)
8973 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8974 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8975 (minus:QI (const_int 32) (match_dup 2)))))
8976 (clobber (reg:CC FLAGS_REG))]
8978 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8979 [(set_attr "type" "ishift")
8980 (set_attr "prefix_0f" "1")
8981 (set_attr "mode" "SI")
8982 (set_attr "pent_pair" "np")
8983 (set_attr "athlon_decode" "vector")
8984 (set_attr "amdfam10_decode" "vector")
8985 (set_attr "bdver1_decode" "vector")])
8987 (define_expand "x86_shift<mode>_adj_1"
8988 [(set (reg:CCZ FLAGS_REG)
8989 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8992 (set (match_operand:SWI48 0 "register_operand" "")
8993 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8994 (match_operand:SWI48 1 "register_operand" "")
8997 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8998 (match_operand:SWI48 3 "register_operand" "")
9001 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9003 (define_expand "x86_shift<mode>_adj_2"
9004 [(use (match_operand:SWI48 0 "register_operand" ""))
9005 (use (match_operand:SWI48 1 "register_operand" ""))
9006 (use (match_operand:QI 2 "register_operand" ""))]
9009 rtx label = gen_label_rtx ();
9012 emit_insn (gen_testqi_ccz_1 (operands[2],
9013 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9015 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9016 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9017 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9018 gen_rtx_LABEL_REF (VOIDmode, label),
9020 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9021 JUMP_LABEL (tmp) = label;
9023 emit_move_insn (operands[0], operands[1]);
9024 ix86_expand_clear (operands[1]);
9027 LABEL_NUSES (label) = 1;
9032 ;; Avoid useless masking of count operand.
9033 (define_insn_and_split "*ashl<mode>3_mask"
9034 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9036 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9039 (match_operand:SI 2 "nonimmediate_operand" "c")
9040 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9041 (clobber (reg:CC FLAGS_REG))]
9042 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9043 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9044 == GET_MODE_BITSIZE (<MODE>mode)-1"
9047 [(parallel [(set (match_dup 0)
9048 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9049 (clobber (reg:CC FLAGS_REG))])]
9051 if (can_create_pseudo_p ())
9052 operands [2] = force_reg (SImode, operands[2]);
9054 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9056 [(set_attr "type" "ishift")
9057 (set_attr "mode" "<MODE>")])
9059 (define_insn "*bmi2_ashl<mode>3_1"
9060 [(set (match_operand:SWI48 0 "register_operand" "=r")
9061 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9062 (match_operand:SWI48 2 "register_operand" "r")))]
9064 "shlx\t{%2, %1, %0|%0, %1, %2}"
9065 [(set_attr "type" "ishiftx")
9066 (set_attr "mode" "<MODE>")])
9068 (define_insn "*ashl<mode>3_1"
9069 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9070 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9071 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9072 (clobber (reg:CC FLAGS_REG))]
9073 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9075 switch (get_attr_type (insn))
9082 gcc_assert (operands[2] == const1_rtx);
9083 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9084 return "add{<imodesuffix>}\t%0, %0";
9087 if (operands[2] == const1_rtx
9088 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9089 return "sal{<imodesuffix>}\t%0";
9091 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9094 [(set_attr "isa" "*,*,bmi2")
9096 (cond [(eq_attr "alternative" "1")
9097 (const_string "lea")
9098 (eq_attr "alternative" "2")
9099 (const_string "ishiftx")
9100 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9101 (match_operand 0 "register_operand" ""))
9102 (match_operand 2 "const1_operand" ""))
9103 (const_string "alu")
9105 (const_string "ishift")))
9106 (set (attr "length_immediate")
9108 (ior (eq_attr "type" "alu")
9109 (and (eq_attr "type" "ishift")
9110 (and (match_operand 2 "const1_operand" "")
9111 (ior (match_test "TARGET_SHIFT1")
9112 (match_test "optimize_function_for_size_p (cfun)")))))
9114 (const_string "*")))
9115 (set_attr "mode" "<MODE>")])
9117 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9119 [(set (match_operand:SWI48 0 "register_operand" "")
9120 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9121 (match_operand:QI 2 "register_operand" "")))
9122 (clobber (reg:CC FLAGS_REG))]
9123 "TARGET_BMI2 && reload_completed"
9125 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9126 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9128 (define_insn "*bmi2_ashlsi3_1_zext"
9129 [(set (match_operand:DI 0 "register_operand" "=r")
9131 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9132 (match_operand:SI 2 "register_operand" "r"))))]
9133 "TARGET_64BIT && TARGET_BMI2"
9134 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9135 [(set_attr "type" "ishiftx")
9136 (set_attr "mode" "SI")])
9138 (define_insn "*ashlsi3_1_zext"
9139 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9141 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9142 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9143 (clobber (reg:CC FLAGS_REG))]
9144 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9146 switch (get_attr_type (insn))
9153 gcc_assert (operands[2] == const1_rtx);
9154 return "add{l}\t%k0, %k0";
9157 if (operands[2] == const1_rtx
9158 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9159 return "sal{l}\t%k0";
9161 return "sal{l}\t{%2, %k0|%k0, %2}";
9164 [(set_attr "isa" "*,*,bmi2")
9166 (cond [(eq_attr "alternative" "1")
9167 (const_string "lea")
9168 (eq_attr "alternative" "2")
9169 (const_string "ishiftx")
9170 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9171 (match_operand 2 "const1_operand" ""))
9172 (const_string "alu")
9174 (const_string "ishift")))
9175 (set (attr "length_immediate")
9177 (ior (eq_attr "type" "alu")
9178 (and (eq_attr "type" "ishift")
9179 (and (match_operand 2 "const1_operand" "")
9180 (ior (match_test "TARGET_SHIFT1")
9181 (match_test "optimize_function_for_size_p (cfun)")))))
9183 (const_string "*")))
9184 (set_attr "mode" "SI")])
9186 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9188 [(set (match_operand:DI 0 "register_operand" "")
9190 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9191 (match_operand:QI 2 "register_operand" ""))))
9192 (clobber (reg:CC FLAGS_REG))]
9193 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9195 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9196 "operands[2] = gen_lowpart (SImode, operands[2]);")
9198 (define_insn "*ashlhi3_1"
9199 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9200 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9201 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9202 (clobber (reg:CC FLAGS_REG))]
9203 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9205 switch (get_attr_type (insn))
9211 gcc_assert (operands[2] == const1_rtx);
9212 return "add{w}\t%0, %0";
9215 if (operands[2] == const1_rtx
9216 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9217 return "sal{w}\t%0";
9219 return "sal{w}\t{%2, %0|%0, %2}";
9223 (cond [(eq_attr "alternative" "1")
9224 (const_string "lea")
9225 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9226 (match_operand 0 "register_operand" ""))
9227 (match_operand 2 "const1_operand" ""))
9228 (const_string "alu")
9230 (const_string "ishift")))
9231 (set (attr "length_immediate")
9233 (ior (eq_attr "type" "alu")
9234 (and (eq_attr "type" "ishift")
9235 (and (match_operand 2 "const1_operand" "")
9236 (ior (match_test "TARGET_SHIFT1")
9237 (match_test "optimize_function_for_size_p (cfun)")))))
9239 (const_string "*")))
9240 (set_attr "mode" "HI,SI")])
9242 ;; %%% Potential partial reg stall on alternative 1. What to do?
9243 (define_insn "*ashlqi3_1"
9244 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9245 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9246 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9247 (clobber (reg:CC FLAGS_REG))]
9248 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9250 switch (get_attr_type (insn))
9256 gcc_assert (operands[2] == const1_rtx);
9257 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9258 return "add{l}\t%k0, %k0";
9260 return "add{b}\t%0, %0";
9263 if (operands[2] == const1_rtx
9264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9266 if (get_attr_mode (insn) == MODE_SI)
9267 return "sal{l}\t%k0";
9269 return "sal{b}\t%0";
9273 if (get_attr_mode (insn) == MODE_SI)
9274 return "sal{l}\t{%2, %k0|%k0, %2}";
9276 return "sal{b}\t{%2, %0|%0, %2}";
9281 (cond [(eq_attr "alternative" "2")
9282 (const_string "lea")
9283 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9284 (match_operand 0 "register_operand" ""))
9285 (match_operand 2 "const1_operand" ""))
9286 (const_string "alu")
9288 (const_string "ishift")))
9289 (set (attr "length_immediate")
9291 (ior (eq_attr "type" "alu")
9292 (and (eq_attr "type" "ishift")
9293 (and (match_operand 2 "const1_operand" "")
9294 (ior (match_test "TARGET_SHIFT1")
9295 (match_test "optimize_function_for_size_p (cfun)")))))
9297 (const_string "*")))
9298 (set_attr "mode" "QI,SI,SI")])
9300 (define_insn "*ashlqi3_1_slp"
9301 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9302 (ashift:QI (match_dup 0)
9303 (match_operand:QI 1 "nonmemory_operand" "cI")))
9304 (clobber (reg:CC FLAGS_REG))]
9305 "(optimize_function_for_size_p (cfun)
9306 || !TARGET_PARTIAL_FLAG_REG_STALL
9307 || (operands[1] == const1_rtx
9309 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9311 switch (get_attr_type (insn))
9314 gcc_assert (operands[1] == const1_rtx);
9315 return "add{b}\t%0, %0";
9318 if (operands[1] == const1_rtx
9319 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9320 return "sal{b}\t%0";
9322 return "sal{b}\t{%1, %0|%0, %1}";
9326 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9327 (match_operand 0 "register_operand" ""))
9328 (match_operand 1 "const1_operand" ""))
9329 (const_string "alu")
9331 (const_string "ishift1")))
9332 (set (attr "length_immediate")
9334 (ior (eq_attr "type" "alu")
9335 (and (eq_attr "type" "ishift1")
9336 (and (match_operand 1 "const1_operand" "")
9337 (ior (match_test "TARGET_SHIFT1")
9338 (match_test "optimize_function_for_size_p (cfun)")))))
9340 (const_string "*")))
9341 (set_attr "mode" "QI")])
9343 ;; Convert ashift to the lea pattern to avoid flags dependency.
9345 [(set (match_operand 0 "register_operand" "")
9346 (ashift (match_operand 1 "index_register_operand" "")
9347 (match_operand:QI 2 "const_int_operand" "")))
9348 (clobber (reg:CC FLAGS_REG))]
9349 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9351 && true_regnum (operands[0]) != true_regnum (operands[1])"
9354 enum machine_mode mode = GET_MODE (operands[0]);
9357 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9360 operands[0] = gen_lowpart (mode, operands[0]);
9361 operands[1] = gen_lowpart (mode, operands[1]);
9364 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9366 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9368 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9372 ;; Convert ashift to the lea pattern to avoid flags dependency.
9374 [(set (match_operand:DI 0 "register_operand" "")
9376 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9377 (match_operand:QI 2 "const_int_operand" ""))))
9378 (clobber (reg:CC FLAGS_REG))]
9379 "TARGET_64BIT && reload_completed
9380 && true_regnum (operands[0]) != true_regnum (operands[1])"
9382 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9384 operands[1] = gen_lowpart (DImode, operands[1]);
9385 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9388 ;; This pattern can't accept a variable shift count, since shifts by
9389 ;; zero don't affect the flags. We assume that shifts by constant
9390 ;; zero are optimized away.
9391 (define_insn "*ashl<mode>3_cmp"
9392 [(set (reg FLAGS_REG)
9394 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9395 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9397 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9398 (ashift:SWI (match_dup 1) (match_dup 2)))]
9399 "(optimize_function_for_size_p (cfun)
9400 || !TARGET_PARTIAL_FLAG_REG_STALL
9401 || (operands[2] == const1_rtx
9403 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9404 && ix86_match_ccmode (insn, CCGOCmode)
9405 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9407 switch (get_attr_type (insn))
9410 gcc_assert (operands[2] == const1_rtx);
9411 return "add{<imodesuffix>}\t%0, %0";
9414 if (operands[2] == const1_rtx
9415 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9416 return "sal{<imodesuffix>}\t%0";
9418 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9422 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9423 (match_operand 0 "register_operand" ""))
9424 (match_operand 2 "const1_operand" ""))
9425 (const_string "alu")
9427 (const_string "ishift")))
9428 (set (attr "length_immediate")
9430 (ior (eq_attr "type" "alu")
9431 (and (eq_attr "type" "ishift")
9432 (and (match_operand 2 "const1_operand" "")
9433 (ior (match_test "TARGET_SHIFT1")
9434 (match_test "optimize_function_for_size_p (cfun)")))))
9436 (const_string "*")))
9437 (set_attr "mode" "<MODE>")])
9439 (define_insn "*ashlsi3_cmp_zext"
9440 [(set (reg FLAGS_REG)
9442 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9443 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9445 (set (match_operand:DI 0 "register_operand" "=r")
9446 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9448 && (optimize_function_for_size_p (cfun)
9449 || !TARGET_PARTIAL_FLAG_REG_STALL
9450 || (operands[2] == const1_rtx
9452 || TARGET_DOUBLE_WITH_ADD)))
9453 && ix86_match_ccmode (insn, CCGOCmode)
9454 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9456 switch (get_attr_type (insn))
9459 gcc_assert (operands[2] == const1_rtx);
9460 return "add{l}\t%k0, %k0";
9463 if (operands[2] == const1_rtx
9464 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9465 return "sal{l}\t%k0";
9467 return "sal{l}\t{%2, %k0|%k0, %2}";
9471 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9472 (match_operand 2 "const1_operand" ""))
9473 (const_string "alu")
9475 (const_string "ishift")))
9476 (set (attr "length_immediate")
9478 (ior (eq_attr "type" "alu")
9479 (and (eq_attr "type" "ishift")
9480 (and (match_operand 2 "const1_operand" "")
9481 (ior (match_test "TARGET_SHIFT1")
9482 (match_test "optimize_function_for_size_p (cfun)")))))
9484 (const_string "*")))
9485 (set_attr "mode" "SI")])
9487 (define_insn "*ashl<mode>3_cconly"
9488 [(set (reg FLAGS_REG)
9490 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9491 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9493 (clobber (match_scratch:SWI 0 "=<r>"))]
9494 "(optimize_function_for_size_p (cfun)
9495 || !TARGET_PARTIAL_FLAG_REG_STALL
9496 || (operands[2] == const1_rtx
9498 || TARGET_DOUBLE_WITH_ADD)))
9499 && ix86_match_ccmode (insn, CCGOCmode)"
9501 switch (get_attr_type (insn))
9504 gcc_assert (operands[2] == const1_rtx);
9505 return "add{<imodesuffix>}\t%0, %0";
9508 if (operands[2] == const1_rtx
9509 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9510 return "sal{<imodesuffix>}\t%0";
9512 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9516 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9517 (match_operand 0 "register_operand" ""))
9518 (match_operand 2 "const1_operand" ""))
9519 (const_string "alu")
9521 (const_string "ishift")))
9522 (set (attr "length_immediate")
9524 (ior (eq_attr "type" "alu")
9525 (and (eq_attr "type" "ishift")
9526 (and (match_operand 2 "const1_operand" "")
9527 (ior (match_test "TARGET_SHIFT1")
9528 (match_test "optimize_function_for_size_p (cfun)")))))
9530 (const_string "*")))
9531 (set_attr "mode" "<MODE>")])
9533 ;; See comment above `ashl<mode>3' about how this works.
9535 (define_expand "<shift_insn><mode>3"
9536 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9537 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9538 (match_operand:QI 2 "nonmemory_operand" "")))]
9540 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9542 ;; Avoid useless masking of count operand.
9543 (define_insn_and_split "*<shift_insn><mode>3_mask"
9544 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9546 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9549 (match_operand:SI 2 "nonimmediate_operand" "c")
9550 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9551 (clobber (reg:CC FLAGS_REG))]
9552 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9553 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9554 == GET_MODE_BITSIZE (<MODE>mode)-1"
9557 [(parallel [(set (match_dup 0)
9558 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9559 (clobber (reg:CC FLAGS_REG))])]
9561 if (can_create_pseudo_p ())
9562 operands [2] = force_reg (SImode, operands[2]);
9564 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9566 [(set_attr "type" "ishift")
9567 (set_attr "mode" "<MODE>")])
9569 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9570 [(set (match_operand:DWI 0 "register_operand" "=r")
9571 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9572 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9573 (clobber (reg:CC FLAGS_REG))]
9576 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9578 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9579 [(set_attr "type" "multi")])
9581 ;; By default we don't ask for a scratch register, because when DWImode
9582 ;; values are manipulated, registers are already at a premium. But if
9583 ;; we have one handy, we won't turn it away.
9586 [(match_scratch:DWIH 3 "r")
9587 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9589 (match_operand:<DWI> 1 "register_operand" "")
9590 (match_operand:QI 2 "nonmemory_operand" "")))
9591 (clobber (reg:CC FLAGS_REG))])
9595 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9597 (define_insn "x86_64_shrd"
9598 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9599 (ior:DI (ashiftrt:DI (match_dup 0)
9600 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9601 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9602 (minus:QI (const_int 64) (match_dup 2)))))
9603 (clobber (reg:CC FLAGS_REG))]
9605 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9606 [(set_attr "type" "ishift")
9607 (set_attr "prefix_0f" "1")
9608 (set_attr "mode" "DI")
9609 (set_attr "athlon_decode" "vector")
9610 (set_attr "amdfam10_decode" "vector")
9611 (set_attr "bdver1_decode" "vector")])
9613 (define_insn "x86_shrd"
9614 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9615 (ior:SI (ashiftrt:SI (match_dup 0)
9616 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9617 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9618 (minus:QI (const_int 32) (match_dup 2)))))
9619 (clobber (reg:CC FLAGS_REG))]
9621 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9622 [(set_attr "type" "ishift")
9623 (set_attr "prefix_0f" "1")
9624 (set_attr "mode" "SI")
9625 (set_attr "pent_pair" "np")
9626 (set_attr "athlon_decode" "vector")
9627 (set_attr "amdfam10_decode" "vector")
9628 (set_attr "bdver1_decode" "vector")])
9630 (define_insn "ashrdi3_cvt"
9631 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9632 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9633 (match_operand:QI 2 "const_int_operand" "")))
9634 (clobber (reg:CC FLAGS_REG))]
9635 "TARGET_64BIT && INTVAL (operands[2]) == 63
9636 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9637 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9640 sar{q}\t{%2, %0|%0, %2}"
9641 [(set_attr "type" "imovx,ishift")
9642 (set_attr "prefix_0f" "0,*")
9643 (set_attr "length_immediate" "0,*")
9644 (set_attr "modrm" "0,1")
9645 (set_attr "mode" "DI")])
9647 (define_insn "ashrsi3_cvt"
9648 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9649 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9650 (match_operand:QI 2 "const_int_operand" "")))
9651 (clobber (reg:CC FLAGS_REG))]
9652 "INTVAL (operands[2]) == 31
9653 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9654 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9657 sar{l}\t{%2, %0|%0, %2}"
9658 [(set_attr "type" "imovx,ishift")
9659 (set_attr "prefix_0f" "0,*")
9660 (set_attr "length_immediate" "0,*")
9661 (set_attr "modrm" "0,1")
9662 (set_attr "mode" "SI")])
9664 (define_insn "*ashrsi3_cvt_zext"
9665 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9667 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9668 (match_operand:QI 2 "const_int_operand" ""))))
9669 (clobber (reg:CC FLAGS_REG))]
9670 "TARGET_64BIT && INTVAL (operands[2]) == 31
9671 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9672 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9675 sar{l}\t{%2, %k0|%k0, %2}"
9676 [(set_attr "type" "imovx,ishift")
9677 (set_attr "prefix_0f" "0,*")
9678 (set_attr "length_immediate" "0,*")
9679 (set_attr "modrm" "0,1")
9680 (set_attr "mode" "SI")])
9682 (define_expand "x86_shift<mode>_adj_3"
9683 [(use (match_operand:SWI48 0 "register_operand" ""))
9684 (use (match_operand:SWI48 1 "register_operand" ""))
9685 (use (match_operand:QI 2 "register_operand" ""))]
9688 rtx label = gen_label_rtx ();
9691 emit_insn (gen_testqi_ccz_1 (operands[2],
9692 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9694 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9695 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9696 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9697 gen_rtx_LABEL_REF (VOIDmode, label),
9699 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9700 JUMP_LABEL (tmp) = label;
9702 emit_move_insn (operands[0], operands[1]);
9703 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9704 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9706 LABEL_NUSES (label) = 1;
9711 (define_insn "*bmi2_<shift_insn><mode>3_1"
9712 [(set (match_operand:SWI48 0 "register_operand" "=r")
9713 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9714 (match_operand:SWI48 2 "register_operand" "r")))]
9716 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9717 [(set_attr "type" "ishiftx")
9718 (set_attr "mode" "<MODE>")])
9720 (define_insn "*<shift_insn><mode>3_1"
9721 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9723 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9724 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9725 (clobber (reg:CC FLAGS_REG))]
9726 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9728 switch (get_attr_type (insn))
9734 if (operands[2] == const1_rtx
9735 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9736 return "<shift>{<imodesuffix>}\t%0";
9738 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9741 [(set_attr "isa" "*,bmi2")
9742 (set_attr "type" "ishift,ishiftx")
9743 (set (attr "length_immediate")
9745 (and (match_operand 2 "const1_operand" "")
9746 (ior (match_test "TARGET_SHIFT1")
9747 (match_test "optimize_function_for_size_p (cfun)")))
9749 (const_string "*")))
9750 (set_attr "mode" "<MODE>")])
9752 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9754 [(set (match_operand:SWI48 0 "register_operand" "")
9755 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9756 (match_operand:QI 2 "register_operand" "")))
9757 (clobber (reg:CC FLAGS_REG))]
9758 "TARGET_BMI2 && reload_completed"
9760 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9761 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9763 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9764 [(set (match_operand:DI 0 "register_operand" "=r")
9766 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9767 (match_operand:SI 2 "register_operand" "r"))))]
9768 "TARGET_64BIT && TARGET_BMI2"
9769 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9770 [(set_attr "type" "ishiftx")
9771 (set_attr "mode" "SI")])
9773 (define_insn "*<shift_insn>si3_1_zext"
9774 [(set (match_operand:DI 0 "register_operand" "=r,r")
9776 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9777 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9778 (clobber (reg:CC FLAGS_REG))]
9779 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9781 switch (get_attr_type (insn))
9787 if (operands[2] == const1_rtx
9788 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9789 return "<shift>{l}\t%k0";
9791 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9794 [(set_attr "isa" "*,bmi2")
9795 (set_attr "type" "ishift,ishiftx")
9796 (set (attr "length_immediate")
9798 (and (match_operand 2 "const1_operand" "")
9799 (ior (match_test "TARGET_SHIFT1")
9800 (match_test "optimize_function_for_size_p (cfun)")))
9802 (const_string "*")))
9803 (set_attr "mode" "SI")])
9805 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9807 [(set (match_operand:DI 0 "register_operand" "")
9809 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9810 (match_operand:QI 2 "register_operand" ""))))
9811 (clobber (reg:CC FLAGS_REG))]
9812 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9814 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9815 "operands[2] = gen_lowpart (SImode, operands[2]);")
9817 (define_insn "*<shift_insn><mode>3_1"
9818 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9820 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9821 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9822 (clobber (reg:CC FLAGS_REG))]
9823 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9825 if (operands[2] == const1_rtx
9826 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9827 return "<shift>{<imodesuffix>}\t%0";
9829 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9831 [(set_attr "type" "ishift")
9832 (set (attr "length_immediate")
9834 (and (match_operand 2 "const1_operand" "")
9835 (ior (match_test "TARGET_SHIFT1")
9836 (match_test "optimize_function_for_size_p (cfun)")))
9838 (const_string "*")))
9839 (set_attr "mode" "<MODE>")])
9841 (define_insn "*<shift_insn>qi3_1_slp"
9842 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9843 (any_shiftrt:QI (match_dup 0)
9844 (match_operand:QI 1 "nonmemory_operand" "cI")))
9845 (clobber (reg:CC FLAGS_REG))]
9846 "(optimize_function_for_size_p (cfun)
9847 || !TARGET_PARTIAL_REG_STALL
9848 || (operands[1] == const1_rtx
9851 if (operands[1] == const1_rtx
9852 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9853 return "<shift>{b}\t%0";
9855 return "<shift>{b}\t{%1, %0|%0, %1}";
9857 [(set_attr "type" "ishift1")
9858 (set (attr "length_immediate")
9860 (and (match_operand 1 "const1_operand" "")
9861 (ior (match_test "TARGET_SHIFT1")
9862 (match_test "optimize_function_for_size_p (cfun)")))
9864 (const_string "*")))
9865 (set_attr "mode" "QI")])
9867 ;; This pattern can't accept a variable shift count, since shifts by
9868 ;; zero don't affect the flags. We assume that shifts by constant
9869 ;; zero are optimized away.
9870 (define_insn "*<shift_insn><mode>3_cmp"
9871 [(set (reg FLAGS_REG)
9874 (match_operand:SWI 1 "nonimmediate_operand" "0")
9875 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9877 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9878 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9879 "(optimize_function_for_size_p (cfun)
9880 || !TARGET_PARTIAL_FLAG_REG_STALL
9881 || (operands[2] == const1_rtx
9883 && ix86_match_ccmode (insn, CCGOCmode)
9884 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9886 if (operands[2] == const1_rtx
9887 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9888 return "<shift>{<imodesuffix>}\t%0";
9890 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9892 [(set_attr "type" "ishift")
9893 (set (attr "length_immediate")
9895 (and (match_operand 2 "const1_operand" "")
9896 (ior (match_test "TARGET_SHIFT1")
9897 (match_test "optimize_function_for_size_p (cfun)")))
9899 (const_string "*")))
9900 (set_attr "mode" "<MODE>")])
9902 (define_insn "*<shift_insn>si3_cmp_zext"
9903 [(set (reg FLAGS_REG)
9905 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9906 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9908 (set (match_operand:DI 0 "register_operand" "=r")
9909 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9911 && (optimize_function_for_size_p (cfun)
9912 || !TARGET_PARTIAL_FLAG_REG_STALL
9913 || (operands[2] == const1_rtx
9915 && ix86_match_ccmode (insn, CCGOCmode)
9916 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9918 if (operands[2] == const1_rtx
9919 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9920 return "<shift>{l}\t%k0";
9922 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9924 [(set_attr "type" "ishift")
9925 (set (attr "length_immediate")
9927 (and (match_operand 2 "const1_operand" "")
9928 (ior (match_test "TARGET_SHIFT1")
9929 (match_test "optimize_function_for_size_p (cfun)")))
9931 (const_string "*")))
9932 (set_attr "mode" "SI")])
9934 (define_insn "*<shift_insn><mode>3_cconly"
9935 [(set (reg FLAGS_REG)
9938 (match_operand:SWI 1 "register_operand" "0")
9939 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9941 (clobber (match_scratch:SWI 0 "=<r>"))]
9942 "(optimize_function_for_size_p (cfun)
9943 || !TARGET_PARTIAL_FLAG_REG_STALL
9944 || (operands[2] == const1_rtx
9946 && ix86_match_ccmode (insn, CCGOCmode)"
9948 if (operands[2] == const1_rtx
9949 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9950 return "<shift>{<imodesuffix>}\t%0";
9952 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9954 [(set_attr "type" "ishift")
9955 (set (attr "length_immediate")
9957 (and (match_operand 2 "const1_operand" "")
9958 (ior (match_test "TARGET_SHIFT1")
9959 (match_test "optimize_function_for_size_p (cfun)")))
9961 (const_string "*")))
9962 (set_attr "mode" "<MODE>")])
9964 ;; Rotate instructions
9966 (define_expand "<rotate_insn>ti3"
9967 [(set (match_operand:TI 0 "register_operand" "")
9968 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9969 (match_operand:QI 2 "nonmemory_operand" "")))]
9972 if (const_1_to_63_operand (operands[2], VOIDmode))
9973 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9974 (operands[0], operands[1], operands[2]));
9981 (define_expand "<rotate_insn>di3"
9982 [(set (match_operand:DI 0 "shiftdi_operand" "")
9983 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9984 (match_operand:QI 2 "nonmemory_operand" "")))]
9988 ix86_expand_binary_operator (<CODE>, DImode, operands);
9989 else if (const_1_to_31_operand (operands[2], VOIDmode))
9990 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9991 (operands[0], operands[1], operands[2]));
9998 (define_expand "<rotate_insn><mode>3"
9999 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10000 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10001 (match_operand:QI 2 "nonmemory_operand" "")))]
10003 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10005 ;; Avoid useless masking of count operand.
10006 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10007 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10009 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10012 (match_operand:SI 2 "nonimmediate_operand" "c")
10013 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10014 (clobber (reg:CC FLAGS_REG))]
10015 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10016 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10017 == GET_MODE_BITSIZE (<MODE>mode)-1"
10020 [(parallel [(set (match_dup 0)
10021 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10022 (clobber (reg:CC FLAGS_REG))])]
10024 if (can_create_pseudo_p ())
10025 operands [2] = force_reg (SImode, operands[2]);
10027 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10029 [(set_attr "type" "rotate")
10030 (set_attr "mode" "<MODE>")])
10032 ;; Implement rotation using two double-precision
10033 ;; shift instructions and a scratch register.
10035 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10036 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10037 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10038 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10039 (clobber (reg:CC FLAGS_REG))
10040 (clobber (match_scratch:DWIH 3 "=&r"))]
10044 [(set (match_dup 3) (match_dup 4))
10046 [(set (match_dup 4)
10047 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10048 (lshiftrt:DWIH (match_dup 5)
10049 (minus:QI (match_dup 6) (match_dup 2)))))
10050 (clobber (reg:CC FLAGS_REG))])
10052 [(set (match_dup 5)
10053 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10054 (lshiftrt:DWIH (match_dup 3)
10055 (minus:QI (match_dup 6) (match_dup 2)))))
10056 (clobber (reg:CC FLAGS_REG))])]
10058 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10060 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10063 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10064 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10065 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10066 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10067 (clobber (reg:CC FLAGS_REG))
10068 (clobber (match_scratch:DWIH 3 "=&r"))]
10072 [(set (match_dup 3) (match_dup 4))
10074 [(set (match_dup 4)
10075 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10076 (ashift:DWIH (match_dup 5)
10077 (minus:QI (match_dup 6) (match_dup 2)))))
10078 (clobber (reg:CC FLAGS_REG))])
10080 [(set (match_dup 5)
10081 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10082 (ashift:DWIH (match_dup 3)
10083 (minus:QI (match_dup 6) (match_dup 2)))))
10084 (clobber (reg:CC FLAGS_REG))])]
10086 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10088 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10091 (define_insn "*bmi2_rorx<mode>3_1"
10092 [(set (match_operand:SWI48 0 "register_operand" "=r")
10093 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10094 (match_operand:QI 2 "immediate_operand" "<S>")))]
10096 "rorx\t{%2, %1, %0|%0, %1, %2}"
10097 [(set_attr "type" "rotatex")
10098 (set_attr "mode" "<MODE>")])
10100 (define_insn "*<rotate_insn><mode>3_1"
10101 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10103 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10104 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10105 (clobber (reg:CC FLAGS_REG))]
10106 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10108 switch (get_attr_type (insn))
10114 if (operands[2] == const1_rtx
10115 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10116 return "<rotate>{<imodesuffix>}\t%0";
10118 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10121 [(set_attr "isa" "*,bmi2")
10122 (set_attr "type" "rotate,rotatex")
10123 (set (attr "length_immediate")
10125 (and (eq_attr "type" "rotate")
10126 (and (match_operand 2 "const1_operand" "")
10127 (ior (match_test "TARGET_SHIFT1")
10128 (match_test "optimize_function_for_size_p (cfun)"))))
10130 (const_string "*")))
10131 (set_attr "mode" "<MODE>")])
10133 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10135 [(set (match_operand:SWI48 0 "register_operand" "")
10136 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10137 (match_operand:QI 2 "immediate_operand" "")))
10138 (clobber (reg:CC FLAGS_REG))]
10139 "TARGET_BMI2 && reload_completed"
10140 [(set (match_dup 0)
10141 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10144 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10148 [(set (match_operand:SWI48 0 "register_operand" "")
10149 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10150 (match_operand:QI 2 "immediate_operand" "")))
10151 (clobber (reg:CC FLAGS_REG))]
10152 "TARGET_BMI2 && reload_completed"
10153 [(set (match_dup 0)
10154 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10156 (define_insn "*bmi2_rorxsi3_1_zext"
10157 [(set (match_operand:DI 0 "register_operand" "=r")
10159 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10160 (match_operand:QI 2 "immediate_operand" "I"))))]
10161 "TARGET_64BIT && TARGET_BMI2"
10162 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10163 [(set_attr "type" "rotatex")
10164 (set_attr "mode" "SI")])
10166 (define_insn "*<rotate_insn>si3_1_zext"
10167 [(set (match_operand:DI 0 "register_operand" "=r,r")
10169 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10170 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10171 (clobber (reg:CC FLAGS_REG))]
10172 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10174 switch (get_attr_type (insn))
10180 if (operands[2] == const1_rtx
10181 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10182 return "<rotate>{l}\t%k0";
10184 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10187 [(set_attr "isa" "*,bmi2")
10188 (set_attr "type" "rotate,rotatex")
10189 (set (attr "length_immediate")
10191 (and (eq_attr "type" "rotate")
10192 (and (match_operand 2 "const1_operand" "")
10193 (ior (match_test "TARGET_SHIFT1")
10194 (match_test "optimize_function_for_size_p (cfun)"))))
10196 (const_string "*")))
10197 (set_attr "mode" "SI")])
10199 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10201 [(set (match_operand:DI 0 "register_operand" "")
10203 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10204 (match_operand:QI 2 "immediate_operand" ""))))
10205 (clobber (reg:CC FLAGS_REG))]
10206 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10207 [(set (match_dup 0)
10208 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10211 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10215 [(set (match_operand:DI 0 "register_operand" "")
10217 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10218 (match_operand:QI 2 "immediate_operand" ""))))
10219 (clobber (reg:CC FLAGS_REG))]
10220 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10221 [(set (match_dup 0)
10222 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10224 (define_insn "*<rotate_insn><mode>3_1"
10225 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10226 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10227 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10228 (clobber (reg:CC FLAGS_REG))]
10229 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10231 if (operands[2] == const1_rtx
10232 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10233 return "<rotate>{<imodesuffix>}\t%0";
10235 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10237 [(set_attr "type" "rotate")
10238 (set (attr "length_immediate")
10240 (and (match_operand 2 "const1_operand" "")
10241 (ior (match_test "TARGET_SHIFT1")
10242 (match_test "optimize_function_for_size_p (cfun)")))
10244 (const_string "*")))
10245 (set_attr "mode" "<MODE>")])
10247 (define_insn "*<rotate_insn>qi3_1_slp"
10248 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10249 (any_rotate:QI (match_dup 0)
10250 (match_operand:QI 1 "nonmemory_operand" "cI")))
10251 (clobber (reg:CC FLAGS_REG))]
10252 "(optimize_function_for_size_p (cfun)
10253 || !TARGET_PARTIAL_REG_STALL
10254 || (operands[1] == const1_rtx
10255 && TARGET_SHIFT1))"
10257 if (operands[1] == const1_rtx
10258 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10259 return "<rotate>{b}\t%0";
10261 return "<rotate>{b}\t{%1, %0|%0, %1}";
10263 [(set_attr "type" "rotate1")
10264 (set (attr "length_immediate")
10266 (and (match_operand 1 "const1_operand" "")
10267 (ior (match_test "TARGET_SHIFT1")
10268 (match_test "optimize_function_for_size_p (cfun)")))
10270 (const_string "*")))
10271 (set_attr "mode" "QI")])
10274 [(set (match_operand:HI 0 "register_operand" "")
10275 (any_rotate:HI (match_dup 0) (const_int 8)))
10276 (clobber (reg:CC FLAGS_REG))]
10278 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10279 [(parallel [(set (strict_low_part (match_dup 0))
10280 (bswap:HI (match_dup 0)))
10281 (clobber (reg:CC FLAGS_REG))])])
10283 ;; Bit set / bit test instructions
10285 (define_expand "extv"
10286 [(set (match_operand:SI 0 "register_operand" "")
10287 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10288 (match_operand:SI 2 "const8_operand" "")
10289 (match_operand:SI 3 "const8_operand" "")))]
10292 /* Handle extractions from %ah et al. */
10293 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10296 /* From mips.md: extract_bit_field doesn't verify that our source
10297 matches the predicate, so check it again here. */
10298 if (! ext_register_operand (operands[1], VOIDmode))
10302 (define_expand "extzv"
10303 [(set (match_operand:SI 0 "register_operand" "")
10304 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10305 (match_operand:SI 2 "const8_operand" "")
10306 (match_operand:SI 3 "const8_operand" "")))]
10309 /* Handle extractions from %ah et al. */
10310 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10313 /* From mips.md: extract_bit_field doesn't verify that our source
10314 matches the predicate, so check it again here. */
10315 if (! ext_register_operand (operands[1], VOIDmode))
10319 (define_expand "insv"
10320 [(set (zero_extract (match_operand 0 "register_operand" "")
10321 (match_operand 1 "const_int_operand" "")
10322 (match_operand 2 "const_int_operand" ""))
10323 (match_operand 3 "register_operand" ""))]
10326 rtx (*gen_mov_insv_1) (rtx, rtx);
10328 if (ix86_expand_pinsr (operands))
10331 /* Handle insertions to %ah et al. */
10332 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10335 /* From mips.md: insert_bit_field doesn't verify that our source
10336 matches the predicate, so check it again here. */
10337 if (! ext_register_operand (operands[0], VOIDmode))
10340 gen_mov_insv_1 = (TARGET_64BIT
10341 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10343 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10347 ;; %%% bts, btr, btc, bt.
10348 ;; In general these instructions are *slow* when applied to memory,
10349 ;; since they enforce atomic operation. When applied to registers,
10350 ;; it depends on the cpu implementation. They're never faster than
10351 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10352 ;; no point. But in 64-bit, we can't hold the relevant immediates
10353 ;; within the instruction itself, so operating on bits in the high
10354 ;; 32-bits of a register becomes easier.
10356 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10357 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10358 ;; negdf respectively, so they can never be disabled entirely.
10360 (define_insn "*btsq"
10361 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10363 (match_operand:DI 1 "const_0_to_63_operand" ""))
10365 (clobber (reg:CC FLAGS_REG))]
10366 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10367 "bts{q}\t{%1, %0|%0, %1}"
10368 [(set_attr "type" "alu1")
10369 (set_attr "prefix_0f" "1")
10370 (set_attr "mode" "DI")])
10372 (define_insn "*btrq"
10373 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10375 (match_operand:DI 1 "const_0_to_63_operand" ""))
10377 (clobber (reg:CC FLAGS_REG))]
10378 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10379 "btr{q}\t{%1, %0|%0, %1}"
10380 [(set_attr "type" "alu1")
10381 (set_attr "prefix_0f" "1")
10382 (set_attr "mode" "DI")])
10384 (define_insn "*btcq"
10385 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10387 (match_operand:DI 1 "const_0_to_63_operand" ""))
10388 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10389 (clobber (reg:CC FLAGS_REG))]
10390 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10391 "btc{q}\t{%1, %0|%0, %1}"
10392 [(set_attr "type" "alu1")
10393 (set_attr "prefix_0f" "1")
10394 (set_attr "mode" "DI")])
10396 ;; Allow Nocona to avoid these instructions if a register is available.
10399 [(match_scratch:DI 2 "r")
10400 (parallel [(set (zero_extract:DI
10401 (match_operand:DI 0 "register_operand" "")
10403 (match_operand:DI 1 "const_0_to_63_operand" ""))
10405 (clobber (reg:CC FLAGS_REG))])]
10406 "TARGET_64BIT && !TARGET_USE_BT"
10409 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10412 if (HOST_BITS_PER_WIDE_INT >= 64)
10413 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10414 else if (i < HOST_BITS_PER_WIDE_INT)
10415 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10417 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10419 op1 = immed_double_const (lo, hi, DImode);
10422 emit_move_insn (operands[2], op1);
10426 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10431 [(match_scratch:DI 2 "r")
10432 (parallel [(set (zero_extract:DI
10433 (match_operand:DI 0 "register_operand" "")
10435 (match_operand:DI 1 "const_0_to_63_operand" ""))
10437 (clobber (reg:CC FLAGS_REG))])]
10438 "TARGET_64BIT && !TARGET_USE_BT"
10441 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10444 if (HOST_BITS_PER_WIDE_INT >= 64)
10445 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10446 else if (i < HOST_BITS_PER_WIDE_INT)
10447 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10449 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10451 op1 = immed_double_const (~lo, ~hi, DImode);
10454 emit_move_insn (operands[2], op1);
10458 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10463 [(match_scratch:DI 2 "r")
10464 (parallel [(set (zero_extract:DI
10465 (match_operand:DI 0 "register_operand" "")
10467 (match_operand:DI 1 "const_0_to_63_operand" ""))
10468 (not:DI (zero_extract:DI
10469 (match_dup 0) (const_int 1) (match_dup 1))))
10470 (clobber (reg:CC FLAGS_REG))])]
10471 "TARGET_64BIT && !TARGET_USE_BT"
10474 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10477 if (HOST_BITS_PER_WIDE_INT >= 64)
10478 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10479 else if (i < HOST_BITS_PER_WIDE_INT)
10480 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10482 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10484 op1 = immed_double_const (lo, hi, DImode);
10487 emit_move_insn (operands[2], op1);
10491 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10495 (define_insn "*bt<mode>"
10496 [(set (reg:CCC FLAGS_REG)
10498 (zero_extract:SWI48
10499 (match_operand:SWI48 0 "register_operand" "r")
10501 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10503 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10504 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10505 [(set_attr "type" "alu1")
10506 (set_attr "prefix_0f" "1")
10507 (set_attr "mode" "<MODE>")])
10509 ;; Store-flag instructions.
10511 ;; For all sCOND expanders, also expand the compare or test insn that
10512 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10514 (define_insn_and_split "*setcc_di_1"
10515 [(set (match_operand:DI 0 "register_operand" "=q")
10516 (match_operator:DI 1 "ix86_comparison_operator"
10517 [(reg FLAGS_REG) (const_int 0)]))]
10518 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10520 "&& reload_completed"
10521 [(set (match_dup 2) (match_dup 1))
10522 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10524 PUT_MODE (operands[1], QImode);
10525 operands[2] = gen_lowpart (QImode, operands[0]);
10528 (define_insn_and_split "*setcc_si_1_and"
10529 [(set (match_operand:SI 0 "register_operand" "=q")
10530 (match_operator:SI 1 "ix86_comparison_operator"
10531 [(reg FLAGS_REG) (const_int 0)]))
10532 (clobber (reg:CC FLAGS_REG))]
10533 "!TARGET_PARTIAL_REG_STALL
10534 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10536 "&& reload_completed"
10537 [(set (match_dup 2) (match_dup 1))
10538 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10539 (clobber (reg:CC FLAGS_REG))])]
10541 PUT_MODE (operands[1], QImode);
10542 operands[2] = gen_lowpart (QImode, operands[0]);
10545 (define_insn_and_split "*setcc_si_1_movzbl"
10546 [(set (match_operand:SI 0 "register_operand" "=q")
10547 (match_operator:SI 1 "ix86_comparison_operator"
10548 [(reg FLAGS_REG) (const_int 0)]))]
10549 "!TARGET_PARTIAL_REG_STALL
10550 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10552 "&& reload_completed"
10553 [(set (match_dup 2) (match_dup 1))
10554 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10556 PUT_MODE (operands[1], QImode);
10557 operands[2] = gen_lowpart (QImode, operands[0]);
10560 (define_insn "*setcc_qi"
10561 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10562 (match_operator:QI 1 "ix86_comparison_operator"
10563 [(reg FLAGS_REG) (const_int 0)]))]
10566 [(set_attr "type" "setcc")
10567 (set_attr "mode" "QI")])
10569 (define_insn "*setcc_qi_slp"
10570 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10571 (match_operator:QI 1 "ix86_comparison_operator"
10572 [(reg FLAGS_REG) (const_int 0)]))]
10575 [(set_attr "type" "setcc")
10576 (set_attr "mode" "QI")])
10578 ;; In general it is not safe to assume too much about CCmode registers,
10579 ;; so simplify-rtx stops when it sees a second one. Under certain
10580 ;; conditions this is safe on x86, so help combine not create
10587 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10588 (ne:QI (match_operator 1 "ix86_comparison_operator"
10589 [(reg FLAGS_REG) (const_int 0)])
10592 [(set (match_dup 0) (match_dup 1))]
10593 "PUT_MODE (operands[1], QImode);")
10596 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10597 (ne:QI (match_operator 1 "ix86_comparison_operator"
10598 [(reg FLAGS_REG) (const_int 0)])
10601 [(set (match_dup 0) (match_dup 1))]
10602 "PUT_MODE (operands[1], QImode);")
10605 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10606 (eq:QI (match_operator 1 "ix86_comparison_operator"
10607 [(reg FLAGS_REG) (const_int 0)])
10610 [(set (match_dup 0) (match_dup 1))]
10612 rtx new_op1 = copy_rtx (operands[1]);
10613 operands[1] = new_op1;
10614 PUT_MODE (new_op1, QImode);
10615 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10616 GET_MODE (XEXP (new_op1, 0))));
10618 /* Make sure that (a) the CCmode we have for the flags is strong
10619 enough for the reversed compare or (b) we have a valid FP compare. */
10620 if (! ix86_comparison_operator (new_op1, VOIDmode))
10625 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10626 (eq:QI (match_operator 1 "ix86_comparison_operator"
10627 [(reg FLAGS_REG) (const_int 0)])
10630 [(set (match_dup 0) (match_dup 1))]
10632 rtx new_op1 = copy_rtx (operands[1]);
10633 operands[1] = new_op1;
10634 PUT_MODE (new_op1, QImode);
10635 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10636 GET_MODE (XEXP (new_op1, 0))));
10638 /* Make sure that (a) the CCmode we have for the flags is strong
10639 enough for the reversed compare or (b) we have a valid FP compare. */
10640 if (! ix86_comparison_operator (new_op1, VOIDmode))
10644 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10645 ;; subsequent logical operations are used to imitate conditional moves.
10646 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10649 (define_insn "setcc_<mode>_sse"
10650 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10651 (match_operator:MODEF 3 "sse_comparison_operator"
10652 [(match_operand:MODEF 1 "register_operand" "0,x")
10653 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10654 "SSE_FLOAT_MODE_P (<MODE>mode)"
10656 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10657 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10658 [(set_attr "isa" "noavx,avx")
10659 (set_attr "type" "ssecmp")
10660 (set_attr "length_immediate" "1")
10661 (set_attr "prefix" "orig,vex")
10662 (set_attr "mode" "<MODE>")])
10664 ;; Basic conditional jump instructions.
10665 ;; We ignore the overflow flag for signed branch instructions.
10667 (define_insn "*jcc_1"
10669 (if_then_else (match_operator 1 "ix86_comparison_operator"
10670 [(reg FLAGS_REG) (const_int 0)])
10671 (label_ref (match_operand 0 "" ""))
10675 [(set_attr "type" "ibr")
10676 (set_attr "modrm" "0")
10677 (set (attr "length")
10678 (if_then_else (and (ge (minus (match_dup 0) (pc))
10680 (lt (minus (match_dup 0) (pc))
10685 (define_insn "*jcc_2"
10687 (if_then_else (match_operator 1 "ix86_comparison_operator"
10688 [(reg FLAGS_REG) (const_int 0)])
10690 (label_ref (match_operand 0 "" ""))))]
10693 [(set_attr "type" "ibr")
10694 (set_attr "modrm" "0")
10695 (set (attr "length")
10696 (if_then_else (and (ge (minus (match_dup 0) (pc))
10698 (lt (minus (match_dup 0) (pc))
10703 ;; In general it is not safe to assume too much about CCmode registers,
10704 ;; so simplify-rtx stops when it sees a second one. Under certain
10705 ;; conditions this is safe on x86, so help combine not create
10713 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10714 [(reg FLAGS_REG) (const_int 0)])
10716 (label_ref (match_operand 1 "" ""))
10720 (if_then_else (match_dup 0)
10721 (label_ref (match_dup 1))
10723 "PUT_MODE (operands[0], VOIDmode);")
10727 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10728 [(reg FLAGS_REG) (const_int 0)])
10730 (label_ref (match_operand 1 "" ""))
10734 (if_then_else (match_dup 0)
10735 (label_ref (match_dup 1))
10738 rtx new_op0 = copy_rtx (operands[0]);
10739 operands[0] = new_op0;
10740 PUT_MODE (new_op0, VOIDmode);
10741 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10742 GET_MODE (XEXP (new_op0, 0))));
10744 /* Make sure that (a) the CCmode we have for the flags is strong
10745 enough for the reversed compare or (b) we have a valid FP compare. */
10746 if (! ix86_comparison_operator (new_op0, VOIDmode))
10750 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10751 ;; pass generates from shift insn with QImode operand. Actually, the mode
10752 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10753 ;; appropriate modulo of the bit offset value.
10755 (define_insn_and_split "*jcc_bt<mode>"
10757 (if_then_else (match_operator 0 "bt_comparison_operator"
10758 [(zero_extract:SWI48
10759 (match_operand:SWI48 1 "register_operand" "r")
10762 (match_operand:QI 2 "register_operand" "r")))
10764 (label_ref (match_operand 3 "" ""))
10766 (clobber (reg:CC FLAGS_REG))]
10767 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10770 [(set (reg:CCC FLAGS_REG)
10772 (zero_extract:SWI48
10778 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10779 (label_ref (match_dup 3))
10782 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10784 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10787 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10788 ;; also for DImode, this is what combine produces.
10789 (define_insn_and_split "*jcc_bt<mode>_mask"
10791 (if_then_else (match_operator 0 "bt_comparison_operator"
10792 [(zero_extract:SWI48
10793 (match_operand:SWI48 1 "register_operand" "r")
10796 (match_operand:SI 2 "register_operand" "r")
10797 (match_operand:SI 3 "const_int_operand" "n")))])
10798 (label_ref (match_operand 4 "" ""))
10800 (clobber (reg:CC FLAGS_REG))]
10801 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10802 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10803 == GET_MODE_BITSIZE (<MODE>mode)-1"
10806 [(set (reg:CCC FLAGS_REG)
10808 (zero_extract:SWI48
10814 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10815 (label_ref (match_dup 4))
10818 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10820 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10823 (define_insn_and_split "*jcc_btsi_1"
10825 (if_then_else (match_operator 0 "bt_comparison_operator"
10828 (match_operand:SI 1 "register_operand" "r")
10829 (match_operand:QI 2 "register_operand" "r"))
10832 (label_ref (match_operand 3 "" ""))
10834 (clobber (reg:CC FLAGS_REG))]
10835 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10838 [(set (reg:CCC FLAGS_REG)
10846 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10847 (label_ref (match_dup 3))
10850 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10852 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10855 ;; avoid useless masking of bit offset operand
10856 (define_insn_and_split "*jcc_btsi_mask_1"
10859 (match_operator 0 "bt_comparison_operator"
10862 (match_operand:SI 1 "register_operand" "r")
10865 (match_operand:SI 2 "register_operand" "r")
10866 (match_operand:SI 3 "const_int_operand" "n")) 0))
10869 (label_ref (match_operand 4 "" ""))
10871 (clobber (reg:CC FLAGS_REG))]
10872 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10873 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10876 [(set (reg:CCC FLAGS_REG)
10884 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10885 (label_ref (match_dup 4))
10887 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10889 ;; Define combination compare-and-branch fp compare instructions to help
10892 (define_insn "*fp_jcc_1_387"
10894 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10895 [(match_operand 1 "register_operand" "f")
10896 (match_operand 2 "nonimmediate_operand" "fm")])
10897 (label_ref (match_operand 3 "" ""))
10899 (clobber (reg:CCFP FPSR_REG))
10900 (clobber (reg:CCFP FLAGS_REG))
10901 (clobber (match_scratch:HI 4 "=a"))]
10903 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10904 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10905 && SELECT_CC_MODE (GET_CODE (operands[0]),
10906 operands[1], operands[2]) == CCFPmode
10910 (define_insn "*fp_jcc_1r_387"
10912 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10913 [(match_operand 1 "register_operand" "f")
10914 (match_operand 2 "nonimmediate_operand" "fm")])
10916 (label_ref (match_operand 3 "" ""))))
10917 (clobber (reg:CCFP FPSR_REG))
10918 (clobber (reg:CCFP FLAGS_REG))
10919 (clobber (match_scratch:HI 4 "=a"))]
10921 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10922 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10923 && SELECT_CC_MODE (GET_CODE (operands[0]),
10924 operands[1], operands[2]) == CCFPmode
10928 (define_insn "*fp_jcc_2_387"
10930 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10931 [(match_operand 1 "register_operand" "f")
10932 (match_operand 2 "register_operand" "f")])
10933 (label_ref (match_operand 3 "" ""))
10935 (clobber (reg:CCFP FPSR_REG))
10936 (clobber (reg:CCFP FLAGS_REG))
10937 (clobber (match_scratch:HI 4 "=a"))]
10938 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10939 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10943 (define_insn "*fp_jcc_2r_387"
10945 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10946 [(match_operand 1 "register_operand" "f")
10947 (match_operand 2 "register_operand" "f")])
10949 (label_ref (match_operand 3 "" ""))))
10950 (clobber (reg:CCFP FPSR_REG))
10951 (clobber (reg:CCFP FLAGS_REG))
10952 (clobber (match_scratch:HI 4 "=a"))]
10953 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10954 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10958 (define_insn "*fp_jcc_3_387"
10960 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10961 [(match_operand 1 "register_operand" "f")
10962 (match_operand 2 "const0_operand" "")])
10963 (label_ref (match_operand 3 "" ""))
10965 (clobber (reg:CCFP FPSR_REG))
10966 (clobber (reg:CCFP FLAGS_REG))
10967 (clobber (match_scratch:HI 4 "=a"))]
10968 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10969 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10970 && SELECT_CC_MODE (GET_CODE (operands[0]),
10971 operands[1], operands[2]) == CCFPmode
10977 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10978 [(match_operand 1 "register_operand" "")
10979 (match_operand 2 "nonimmediate_operand" "")])
10980 (match_operand 3 "" "")
10981 (match_operand 4 "" "")))
10982 (clobber (reg:CCFP FPSR_REG))
10983 (clobber (reg:CCFP FLAGS_REG))]
10987 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10988 operands[3], operands[4], NULL_RTX, NULL_RTX);
10994 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10995 [(match_operand 1 "register_operand" "")
10996 (match_operand 2 "general_operand" "")])
10997 (match_operand 3 "" "")
10998 (match_operand 4 "" "")))
10999 (clobber (reg:CCFP FPSR_REG))
11000 (clobber (reg:CCFP FLAGS_REG))
11001 (clobber (match_scratch:HI 5 "=a"))]
11005 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11006 operands[3], operands[4], operands[5], NULL_RTX);
11010 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11011 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11012 ;; with a precedence over other operators and is always put in the first
11013 ;; place. Swap condition and operands to match ficom instruction.
11015 (define_insn "*fp_jcc_4_<mode>_387"
11018 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11019 [(match_operator 1 "float_operator"
11020 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11021 (match_operand 3 "register_operand" "f,f")])
11022 (label_ref (match_operand 4 "" ""))
11024 (clobber (reg:CCFP FPSR_REG))
11025 (clobber (reg:CCFP FLAGS_REG))
11026 (clobber (match_scratch:HI 5 "=a,a"))]
11027 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11028 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11029 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11030 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11037 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11038 [(match_operator 1 "float_operator"
11039 [(match_operand:SWI24 2 "memory_operand" "")])
11040 (match_operand 3 "register_operand" "")])
11041 (match_operand 4 "" "")
11042 (match_operand 5 "" "")))
11043 (clobber (reg:CCFP FPSR_REG))
11044 (clobber (reg:CCFP FLAGS_REG))
11045 (clobber (match_scratch:HI 6 "=a"))]
11049 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11051 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11052 operands[3], operands[7],
11053 operands[4], operands[5], operands[6], NULL_RTX);
11057 ;; %%% Kill this when reload knows how to do it.
11061 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11062 [(match_operator 1 "float_operator"
11063 [(match_operand:SWI24 2 "register_operand" "")])
11064 (match_operand 3 "register_operand" "")])
11065 (match_operand 4 "" "")
11066 (match_operand 5 "" "")))
11067 (clobber (reg:CCFP FPSR_REG))
11068 (clobber (reg:CCFP FLAGS_REG))
11069 (clobber (match_scratch:HI 6 "=a"))]
11073 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11074 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11076 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11077 operands[3], operands[7],
11078 operands[4], operands[5], operands[6], operands[2]);
11082 ;; Unconditional and other jump instructions
11084 (define_insn "jump"
11086 (label_ref (match_operand 0 "" "")))]
11089 [(set_attr "type" "ibr")
11090 (set (attr "length")
11091 (if_then_else (and (ge (minus (match_dup 0) (pc))
11093 (lt (minus (match_dup 0) (pc))
11097 (set_attr "modrm" "0")])
11099 (define_expand "indirect_jump"
11100 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11102 (define_insn "*indirect_jump"
11103 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11106 [(set_attr "type" "ibr")
11107 (set_attr "length_immediate" "0")])
11109 (define_expand "tablejump"
11110 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11111 (use (label_ref (match_operand 1 "" "")))])]
11114 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11115 relative. Convert the relative address to an absolute address. */
11119 enum rtx_code code;
11121 /* We can't use @GOTOFF for text labels on VxWorks;
11122 see gotoff_operand. */
11123 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11127 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11129 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11133 op1 = pic_offset_table_rtx;
11138 op0 = pic_offset_table_rtx;
11142 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11145 else if (TARGET_X32)
11146 operands[0] = convert_memory_address (Pmode, operands[0]);
11149 (define_insn "*tablejump_1"
11150 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11151 (use (label_ref (match_operand 1 "" "")))]
11154 [(set_attr "type" "ibr")
11155 (set_attr "length_immediate" "0")])
11157 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11160 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11161 (set (match_operand:QI 1 "register_operand" "")
11162 (match_operator:QI 2 "ix86_comparison_operator"
11163 [(reg FLAGS_REG) (const_int 0)]))
11164 (set (match_operand 3 "q_regs_operand" "")
11165 (zero_extend (match_dup 1)))]
11166 "(peep2_reg_dead_p (3, operands[1])
11167 || operands_match_p (operands[1], operands[3]))
11168 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11169 [(set (match_dup 4) (match_dup 0))
11170 (set (strict_low_part (match_dup 5))
11173 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11174 operands[5] = gen_lowpart (QImode, operands[3]);
11175 ix86_expand_clear (operands[3]);
11178 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11181 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11182 (set (match_operand:QI 1 "register_operand" "")
11183 (match_operator:QI 2 "ix86_comparison_operator"
11184 [(reg FLAGS_REG) (const_int 0)]))
11185 (parallel [(set (match_operand 3 "q_regs_operand" "")
11186 (zero_extend (match_dup 1)))
11187 (clobber (reg:CC FLAGS_REG))])]
11188 "(peep2_reg_dead_p (3, operands[1])
11189 || operands_match_p (operands[1], operands[3]))
11190 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11191 [(set (match_dup 4) (match_dup 0))
11192 (set (strict_low_part (match_dup 5))
11195 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11196 operands[5] = gen_lowpart (QImode, operands[3]);
11197 ix86_expand_clear (operands[3]);
11200 ;; Call instructions.
11202 ;; The predicates normally associated with named expanders are not properly
11203 ;; checked for calls. This is a bug in the generic code, but it isn't that
11204 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11206 ;; P6 processors will jump to the address after the decrement when %esp
11207 ;; is used as a call operand, so they will execute return address as a code.
11208 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11210 ;; Register constraint for call instruction.
11211 (define_mode_attr c [(SI "l") (DI "r")])
11213 ;; Call subroutine returning no value.
11215 (define_expand "call"
11216 [(call (match_operand:QI 0 "" "")
11217 (match_operand 1 "" ""))
11218 (use (match_operand 2 "" ""))]
11221 ix86_expand_call (NULL, operands[0], operands[1],
11222 operands[2], NULL, false);
11226 (define_expand "sibcall"
11227 [(call (match_operand:QI 0 "" "")
11228 (match_operand 1 "" ""))
11229 (use (match_operand 2 "" ""))]
11232 ix86_expand_call (NULL, operands[0], operands[1],
11233 operands[2], NULL, true);
11237 (define_insn_and_split "*call_vzeroupper"
11238 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11239 (match_operand 1 "" ""))
11240 (unspec [(match_operand 2 "const_int_operand" "")]
11241 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11242 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11244 "&& reload_completed"
11246 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11247 [(set_attr "type" "call")])
11249 (define_insn "*call"
11250 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11251 (match_operand 1 "" ""))]
11252 "!SIBLING_CALL_P (insn)"
11253 "* return ix86_output_call_insn (insn, operands[0]);"
11254 [(set_attr "type" "call")])
11256 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11257 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11258 (match_operand 1 "" ""))
11259 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11260 (clobber (reg:TI XMM6_REG))
11261 (clobber (reg:TI XMM7_REG))
11262 (clobber (reg:TI XMM8_REG))
11263 (clobber (reg:TI XMM9_REG))
11264 (clobber (reg:TI XMM10_REG))
11265 (clobber (reg:TI XMM11_REG))
11266 (clobber (reg:TI XMM12_REG))
11267 (clobber (reg:TI XMM13_REG))
11268 (clobber (reg:TI XMM14_REG))
11269 (clobber (reg:TI XMM15_REG))
11270 (clobber (reg:DI SI_REG))
11271 (clobber (reg:DI DI_REG))
11272 (unspec [(match_operand 2 "const_int_operand" "")]
11273 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11274 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11276 "&& reload_completed"
11278 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11279 [(set_attr "type" "call")])
11281 (define_insn "*call_rex64_ms_sysv"
11282 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11283 (match_operand 1 "" ""))
11284 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11285 (clobber (reg:TI XMM6_REG))
11286 (clobber (reg:TI XMM7_REG))
11287 (clobber (reg:TI XMM8_REG))
11288 (clobber (reg:TI XMM9_REG))
11289 (clobber (reg:TI XMM10_REG))
11290 (clobber (reg:TI XMM11_REG))
11291 (clobber (reg:TI XMM12_REG))
11292 (clobber (reg:TI XMM13_REG))
11293 (clobber (reg:TI XMM14_REG))
11294 (clobber (reg:TI XMM15_REG))
11295 (clobber (reg:DI SI_REG))
11296 (clobber (reg:DI DI_REG))]
11297 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11298 "* return ix86_output_call_insn (insn, operands[0]);"
11299 [(set_attr "type" "call")])
11301 (define_insn_and_split "*sibcall_vzeroupper"
11302 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11303 (match_operand 1 "" ""))
11304 (unspec [(match_operand 2 "const_int_operand" "")]
11305 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11306 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11308 "&& reload_completed"
11310 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11311 [(set_attr "type" "call")])
11313 (define_insn "*sibcall"
11314 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11315 (match_operand 1 "" ""))]
11316 "SIBLING_CALL_P (insn)"
11317 "* return ix86_output_call_insn (insn, operands[0]);"
11318 [(set_attr "type" "call")])
11320 (define_expand "call_pop"
11321 [(parallel [(call (match_operand:QI 0 "" "")
11322 (match_operand:SI 1 "" ""))
11323 (set (reg:SI SP_REG)
11324 (plus:SI (reg:SI SP_REG)
11325 (match_operand:SI 3 "" "")))])]
11328 ix86_expand_call (NULL, operands[0], operands[1],
11329 operands[2], operands[3], false);
11333 (define_insn_and_split "*call_pop_vzeroupper"
11334 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11335 (match_operand:SI 1 "" ""))
11336 (set (reg:SI SP_REG)
11337 (plus:SI (reg:SI SP_REG)
11338 (match_operand:SI 2 "immediate_operand" "i")))
11339 (unspec [(match_operand 3 "const_int_operand" "")]
11340 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11341 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11343 "&& reload_completed"
11345 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11346 [(set_attr "type" "call")])
11348 (define_insn "*call_pop"
11349 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11350 (match_operand 1 "" ""))
11351 (set (reg:SI SP_REG)
11352 (plus:SI (reg:SI SP_REG)
11353 (match_operand:SI 2 "immediate_operand" "i")))]
11354 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11355 "* return ix86_output_call_insn (insn, operands[0]);"
11356 [(set_attr "type" "call")])
11358 (define_insn_and_split "*sibcall_pop_vzeroupper"
11359 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11360 (match_operand 1 "" ""))
11361 (set (reg:SI SP_REG)
11362 (plus:SI (reg:SI SP_REG)
11363 (match_operand:SI 2 "immediate_operand" "i")))
11364 (unspec [(match_operand 3 "const_int_operand" "")]
11365 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11366 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11368 "&& reload_completed"
11370 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11371 [(set_attr "type" "call")])
11373 (define_insn "*sibcall_pop"
11374 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11375 (match_operand 1 "" ""))
11376 (set (reg:SI SP_REG)
11377 (plus:SI (reg:SI SP_REG)
11378 (match_operand:SI 2 "immediate_operand" "i")))]
11379 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11380 "* return ix86_output_call_insn (insn, operands[0]);"
11381 [(set_attr "type" "call")])
11383 ;; Call subroutine, returning value in operand 0
11385 (define_expand "call_value"
11386 [(set (match_operand 0 "" "")
11387 (call (match_operand:QI 1 "" "")
11388 (match_operand 2 "" "")))
11389 (use (match_operand 3 "" ""))]
11392 ix86_expand_call (operands[0], operands[1], operands[2],
11393 operands[3], NULL, false);
11397 (define_expand "sibcall_value"
11398 [(set (match_operand 0 "" "")
11399 (call (match_operand:QI 1 "" "")
11400 (match_operand 2 "" "")))
11401 (use (match_operand 3 "" ""))]
11404 ix86_expand_call (operands[0], operands[1], operands[2],
11405 operands[3], NULL, true);
11409 (define_insn_and_split "*call_value_vzeroupper"
11410 [(set (match_operand 0 "" "")
11411 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11412 (match_operand 2 "" "")))
11413 (unspec [(match_operand 3 "const_int_operand" "")]
11414 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11415 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11417 "&& reload_completed"
11419 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11420 [(set_attr "type" "callv")])
11422 (define_insn "*call_value"
11423 [(set (match_operand 0 "" "")
11424 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11425 (match_operand 2 "" "")))]
11426 "!SIBLING_CALL_P (insn)"
11427 "* return ix86_output_call_insn (insn, operands[1]);"
11428 [(set_attr "type" "callv")])
11430 (define_insn_and_split "*sibcall_value_vzeroupper"
11431 [(set (match_operand 0 "" "")
11432 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11433 (match_operand 2 "" "")))
11434 (unspec [(match_operand 3 "const_int_operand" "")]
11435 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11436 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11438 "&& reload_completed"
11440 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11441 [(set_attr "type" "callv")])
11443 (define_insn "*sibcall_value"
11444 [(set (match_operand 0 "" "")
11445 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11446 (match_operand 2 "" "")))]
11447 "SIBLING_CALL_P (insn)"
11448 "* return ix86_output_call_insn (insn, operands[1]);"
11449 [(set_attr "type" "callv")])
11451 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11452 [(set (match_operand 0 "" "")
11453 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11454 (match_operand 2 "" "")))
11455 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11456 (clobber (reg:TI XMM6_REG))
11457 (clobber (reg:TI XMM7_REG))
11458 (clobber (reg:TI XMM8_REG))
11459 (clobber (reg:TI XMM9_REG))
11460 (clobber (reg:TI XMM10_REG))
11461 (clobber (reg:TI XMM11_REG))
11462 (clobber (reg:TI XMM12_REG))
11463 (clobber (reg:TI XMM13_REG))
11464 (clobber (reg:TI XMM14_REG))
11465 (clobber (reg:TI XMM15_REG))
11466 (clobber (reg:DI SI_REG))
11467 (clobber (reg:DI DI_REG))
11468 (unspec [(match_operand 3 "const_int_operand" "")]
11469 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11470 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11472 "&& reload_completed"
11474 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11475 [(set_attr "type" "callv")])
11477 (define_insn "*call_value_rex64_ms_sysv"
11478 [(set (match_operand 0 "" "")
11479 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11480 (match_operand 2 "" "")))
11481 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11482 (clobber (reg:TI XMM6_REG))
11483 (clobber (reg:TI XMM7_REG))
11484 (clobber (reg:TI XMM8_REG))
11485 (clobber (reg:TI XMM9_REG))
11486 (clobber (reg:TI XMM10_REG))
11487 (clobber (reg:TI XMM11_REG))
11488 (clobber (reg:TI XMM12_REG))
11489 (clobber (reg:TI XMM13_REG))
11490 (clobber (reg:TI XMM14_REG))
11491 (clobber (reg:TI XMM15_REG))
11492 (clobber (reg:DI SI_REG))
11493 (clobber (reg:DI DI_REG))]
11494 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11495 "* return ix86_output_call_insn (insn, operands[1]);"
11496 [(set_attr "type" "callv")])
11498 (define_expand "call_value_pop"
11499 [(parallel [(set (match_operand 0 "" "")
11500 (call (match_operand:QI 1 "" "")
11501 (match_operand:SI 2 "" "")))
11502 (set (reg:SI SP_REG)
11503 (plus:SI (reg:SI SP_REG)
11504 (match_operand:SI 4 "" "")))])]
11507 ix86_expand_call (operands[0], operands[1], operands[2],
11508 operands[3], operands[4], false);
11512 (define_insn_and_split "*call_value_pop_vzeroupper"
11513 [(set (match_operand 0 "" "")
11514 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11515 (match_operand 2 "" "")))
11516 (set (reg:SI SP_REG)
11517 (plus:SI (reg:SI SP_REG)
11518 (match_operand:SI 3 "immediate_operand" "i")))
11519 (unspec [(match_operand 4 "const_int_operand" "")]
11520 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11521 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11523 "&& reload_completed"
11525 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11526 [(set_attr "type" "callv")])
11528 (define_insn "*call_value_pop"
11529 [(set (match_operand 0 "" "")
11530 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11531 (match_operand 2 "" "")))
11532 (set (reg:SI SP_REG)
11533 (plus:SI (reg:SI SP_REG)
11534 (match_operand:SI 3 "immediate_operand" "i")))]
11535 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11536 "* return ix86_output_call_insn (insn, operands[1]);"
11537 [(set_attr "type" "callv")])
11539 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11540 [(set (match_operand 0 "" "")
11541 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11542 (match_operand 2 "" "")))
11543 (set (reg:SI SP_REG)
11544 (plus:SI (reg:SI SP_REG)
11545 (match_operand:SI 3 "immediate_operand" "i")))
11546 (unspec [(match_operand 4 "const_int_operand" "")]
11547 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11548 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11550 "&& reload_completed"
11552 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11553 [(set_attr "type" "callv")])
11555 (define_insn "*sibcall_value_pop"
11556 [(set (match_operand 0 "" "")
11557 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11558 (match_operand 2 "" "")))
11559 (set (reg:SI SP_REG)
11560 (plus:SI (reg:SI SP_REG)
11561 (match_operand:SI 3 "immediate_operand" "i")))]
11562 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11563 "* return ix86_output_call_insn (insn, operands[1]);"
11564 [(set_attr "type" "callv")])
11566 ;; Call subroutine returning any type.
11568 (define_expand "untyped_call"
11569 [(parallel [(call (match_operand 0 "" "")
11571 (match_operand 1 "" "")
11572 (match_operand 2 "" "")])]
11577 /* In order to give reg-stack an easier job in validating two
11578 coprocessor registers as containing a possible return value,
11579 simply pretend the untyped call returns a complex long double
11582 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11583 and should have the default ABI. */
11585 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11586 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11587 operands[0], const0_rtx,
11588 GEN_INT ((TARGET_64BIT
11589 ? (ix86_abi == SYSV_ABI
11590 ? X86_64_SSE_REGPARM_MAX
11591 : X86_64_MS_SSE_REGPARM_MAX)
11592 : X86_32_SSE_REGPARM_MAX)
11596 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11598 rtx set = XVECEXP (operands[2], 0, i);
11599 emit_move_insn (SET_DEST (set), SET_SRC (set));
11602 /* The optimizer does not know that the call sets the function value
11603 registers we stored in the result block. We avoid problems by
11604 claiming that all hard registers are used and clobbered at this
11606 emit_insn (gen_blockage ());
11611 ;; Prologue and epilogue instructions
11613 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11614 ;; all of memory. This blocks insns from being moved across this point.
11616 (define_insn "blockage"
11617 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11620 [(set_attr "length" "0")])
11622 ;; Do not schedule instructions accessing memory across this point.
11624 (define_expand "memory_blockage"
11625 [(set (match_dup 0)
11626 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11629 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11630 MEM_VOLATILE_P (operands[0]) = 1;
11633 (define_insn "*memory_blockage"
11634 [(set (match_operand:BLK 0 "" "")
11635 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11638 [(set_attr "length" "0")])
11640 ;; As USE insns aren't meaningful after reload, this is used instead
11641 ;; to prevent deleting instructions setting registers for PIC code
11642 (define_insn "prologue_use"
11643 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11646 [(set_attr "length" "0")])
11648 ;; Insn emitted into the body of a function to return from a function.
11649 ;; This is only done if the function's epilogue is known to be simple.
11650 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11652 (define_expand "return"
11654 "ix86_can_use_return_insn_p ()"
11656 ix86_maybe_emit_epilogue_vzeroupper ();
11657 if (crtl->args.pops_args)
11659 rtx popc = GEN_INT (crtl->args.pops_args);
11660 emit_jump_insn (gen_simple_return_pop_internal (popc));
11665 ;; We need to disable this for TARGET_SEH, as otherwise
11666 ;; shrink-wrapped prologue gets enabled too. This might exceed
11667 ;; the maximum size of prologue in unwind information.
11669 (define_expand "simple_return"
11673 ix86_maybe_emit_epilogue_vzeroupper ();
11674 if (crtl->args.pops_args)
11676 rtx popc = GEN_INT (crtl->args.pops_args);
11677 emit_jump_insn (gen_simple_return_pop_internal (popc));
11682 (define_insn "simple_return_internal"
11686 [(set_attr "length" "1")
11687 (set_attr "atom_unit" "jeu")
11688 (set_attr "length_immediate" "0")
11689 (set_attr "modrm" "0")])
11691 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11692 ;; instruction Athlon and K8 have.
11694 (define_insn "simple_return_internal_long"
11696 (unspec [(const_int 0)] UNSPEC_REP)]
11699 [(set_attr "length" "2")
11700 (set_attr "atom_unit" "jeu")
11701 (set_attr "length_immediate" "0")
11702 (set_attr "prefix_rep" "1")
11703 (set_attr "modrm" "0")])
11705 (define_insn "simple_return_pop_internal"
11707 (use (match_operand:SI 0 "const_int_operand" ""))]
11710 [(set_attr "length" "3")
11711 (set_attr "atom_unit" "jeu")
11712 (set_attr "length_immediate" "2")
11713 (set_attr "modrm" "0")])
11715 (define_insn "simple_return_indirect_internal"
11717 (use (match_operand:SI 0 "register_operand" "r"))]
11720 [(set_attr "type" "ibr")
11721 (set_attr "length_immediate" "0")])
11727 [(set_attr "length" "1")
11728 (set_attr "length_immediate" "0")
11729 (set_attr "modrm" "0")])
11731 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11732 (define_insn "nops"
11733 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11737 int num = INTVAL (operands[0]);
11739 gcc_assert (num >= 1 && num <= 8);
11742 fputs ("\tnop\n", asm_out_file);
11746 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11747 (set_attr "length_immediate" "0")
11748 (set_attr "modrm" "0")])
11750 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11751 ;; branch prediction penalty for the third jump in a 16-byte
11755 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11758 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11759 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11761 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11762 The align insn is used to avoid 3 jump instructions in the row to improve
11763 branch prediction and the benefits hardly outweigh the cost of extra 8
11764 nops on the average inserted by full alignment pseudo operation. */
11768 [(set_attr "length" "16")])
11770 (define_expand "prologue"
11773 "ix86_expand_prologue (); DONE;")
11775 (define_insn "set_got"
11776 [(set (match_operand:SI 0 "register_operand" "=r")
11777 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11778 (clobber (reg:CC FLAGS_REG))]
11780 "* return output_set_got (operands[0], NULL_RTX);"
11781 [(set_attr "type" "multi")
11782 (set_attr "length" "12")])
11784 (define_insn "set_got_labelled"
11785 [(set (match_operand:SI 0 "register_operand" "=r")
11786 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11788 (clobber (reg:CC FLAGS_REG))]
11790 "* return output_set_got (operands[0], operands[1]);"
11791 [(set_attr "type" "multi")
11792 (set_attr "length" "12")])
11794 (define_insn "set_got_rex64"
11795 [(set (match_operand:DI 0 "register_operand" "=r")
11796 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11798 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11799 [(set_attr "type" "lea")
11800 (set_attr "length_address" "4")
11801 (set_attr "mode" "DI")])
11803 (define_insn "set_rip_rex64"
11804 [(set (match_operand:DI 0 "register_operand" "=r")
11805 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11807 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11808 [(set_attr "type" "lea")
11809 (set_attr "length_address" "4")
11810 (set_attr "mode" "DI")])
11812 (define_insn "set_got_offset_rex64"
11813 [(set (match_operand:DI 0 "register_operand" "=r")
11815 [(label_ref (match_operand 1 "" ""))]
11816 UNSPEC_SET_GOT_OFFSET))]
11818 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11819 [(set_attr "type" "imov")
11820 (set_attr "length_immediate" "0")
11821 (set_attr "length_address" "8")
11822 (set_attr "mode" "DI")])
11824 (define_expand "epilogue"
11827 "ix86_expand_epilogue (1); DONE;")
11829 (define_expand "sibcall_epilogue"
11832 "ix86_expand_epilogue (0); DONE;")
11834 (define_expand "eh_return"
11835 [(use (match_operand 0 "register_operand" ""))]
11838 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11840 /* Tricky bit: we write the address of the handler to which we will
11841 be returning into someone else's stack frame, one word below the
11842 stack address we wish to restore. */
11843 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11844 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11845 tmp = gen_rtx_MEM (Pmode, tmp);
11846 emit_move_insn (tmp, ra);
11848 emit_jump_insn (gen_eh_return_internal ());
11853 (define_insn_and_split "eh_return_internal"
11857 "epilogue_completed"
11859 "ix86_expand_epilogue (2); DONE;")
11861 (define_insn "leave"
11862 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11863 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11864 (clobber (mem:BLK (scratch)))]
11867 [(set_attr "type" "leave")])
11869 (define_insn "leave_rex64"
11870 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11871 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11872 (clobber (mem:BLK (scratch)))]
11875 [(set_attr "type" "leave")])
11877 ;; Handle -fsplit-stack.
11879 (define_expand "split_stack_prologue"
11883 ix86_expand_split_stack_prologue ();
11887 ;; In order to support the call/return predictor, we use a return
11888 ;; instruction which the middle-end doesn't see.
11889 (define_insn "split_stack_return"
11890 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11891 UNSPECV_SPLIT_STACK_RETURN)]
11894 if (operands[0] == const0_rtx)
11899 [(set_attr "atom_unit" "jeu")
11900 (set_attr "modrm" "0")
11901 (set (attr "length")
11902 (if_then_else (match_operand:SI 0 "const0_operand" "")
11905 (set (attr "length_immediate")
11906 (if_then_else (match_operand:SI 0 "const0_operand" "")
11910 ;; If there are operand 0 bytes available on the stack, jump to
11913 (define_expand "split_stack_space_check"
11914 [(set (pc) (if_then_else
11915 (ltu (minus (reg SP_REG)
11916 (match_operand 0 "register_operand" ""))
11917 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11918 (label_ref (match_operand 1 "" ""))
11922 rtx reg, size, limit;
11924 reg = gen_reg_rtx (Pmode);
11925 size = force_reg (Pmode, operands[0]);
11926 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11927 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11928 UNSPEC_STACK_CHECK);
11929 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11930 ix86_expand_branch (GEU, reg, limit, operands[1]);
11935 ;; Bit manipulation instructions.
11937 (define_expand "ffs<mode>2"
11938 [(set (match_dup 2) (const_int -1))
11939 (parallel [(set (reg:CCZ FLAGS_REG)
11941 (match_operand:SWI48 1 "nonimmediate_operand" "")
11943 (set (match_operand:SWI48 0 "register_operand" "")
11944 (ctz:SWI48 (match_dup 1)))])
11945 (set (match_dup 0) (if_then_else:SWI48
11946 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11949 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11950 (clobber (reg:CC FLAGS_REG))])]
11953 if (<MODE>mode == SImode && !TARGET_CMOVE)
11955 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11958 operands[2] = gen_reg_rtx (<MODE>mode);
11961 (define_insn_and_split "ffssi2_no_cmove"
11962 [(set (match_operand:SI 0 "register_operand" "=r")
11963 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11964 (clobber (match_scratch:SI 2 "=&q"))
11965 (clobber (reg:CC FLAGS_REG))]
11968 "&& reload_completed"
11969 [(parallel [(set (reg:CCZ FLAGS_REG)
11970 (compare:CCZ (match_dup 1) (const_int 0)))
11971 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11972 (set (strict_low_part (match_dup 3))
11973 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11974 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11975 (clobber (reg:CC FLAGS_REG))])
11976 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11977 (clobber (reg:CC FLAGS_REG))])
11978 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11979 (clobber (reg:CC FLAGS_REG))])]
11981 operands[3] = gen_lowpart (QImode, operands[2]);
11982 ix86_expand_clear (operands[2]);
11985 (define_insn "*ffs<mode>_1"
11986 [(set (reg:CCZ FLAGS_REG)
11987 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11989 (set (match_operand:SWI48 0 "register_operand" "=r")
11990 (ctz:SWI48 (match_dup 1)))]
11992 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11993 [(set_attr "type" "alu1")
11994 (set_attr "prefix_0f" "1")
11995 (set_attr "mode" "<MODE>")])
11997 (define_insn "ctz<mode>2"
11998 [(set (match_operand:SWI248 0 "register_operand" "=r")
11999 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12000 (clobber (reg:CC FLAGS_REG))]
12004 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12006 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12008 [(set_attr "type" "alu1")
12009 (set_attr "prefix_0f" "1")
12010 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12011 (set_attr "mode" "<MODE>")])
12013 (define_expand "clz<mode>2"
12015 [(set (match_operand:SWI248 0 "register_operand" "")
12018 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12019 (clobber (reg:CC FLAGS_REG))])
12021 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12022 (clobber (reg:CC FLAGS_REG))])]
12027 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12030 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12033 (define_insn "clz<mode>2_lzcnt"
12034 [(set (match_operand:SWI248 0 "register_operand" "=r")
12035 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12036 (clobber (reg:CC FLAGS_REG))]
12038 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12039 [(set_attr "prefix_rep" "1")
12040 (set_attr "type" "bitmanip")
12041 (set_attr "mode" "<MODE>")])
12043 ;; BMI instructions.
12044 (define_insn "*bmi_andn_<mode>"
12045 [(set (match_operand:SWI48 0 "register_operand" "=r")
12048 (match_operand:SWI48 1 "register_operand" "r"))
12049 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12050 (clobber (reg:CC FLAGS_REG))]
12052 "andn\t{%2, %1, %0|%0, %1, %2}"
12053 [(set_attr "type" "bitmanip")
12054 (set_attr "mode" "<MODE>")])
12056 (define_insn "bmi_bextr_<mode>"
12057 [(set (match_operand:SWI48 0 "register_operand" "=r")
12058 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12059 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12061 (clobber (reg:CC FLAGS_REG))]
12063 "bextr\t{%2, %1, %0|%0, %1, %2}"
12064 [(set_attr "type" "bitmanip")
12065 (set_attr "mode" "<MODE>")])
12067 (define_insn "*bmi_blsi_<mode>"
12068 [(set (match_operand:SWI48 0 "register_operand" "=r")
12071 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12073 (clobber (reg:CC FLAGS_REG))]
12075 "blsi\t{%1, %0|%0, %1}"
12076 [(set_attr "type" "bitmanip")
12077 (set_attr "mode" "<MODE>")])
12079 (define_insn "*bmi_blsmsk_<mode>"
12080 [(set (match_operand:SWI48 0 "register_operand" "=r")
12083 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12086 (clobber (reg:CC FLAGS_REG))]
12088 "blsmsk\t{%1, %0|%0, %1}"
12089 [(set_attr "type" "bitmanip")
12090 (set_attr "mode" "<MODE>")])
12092 (define_insn "*bmi_blsr_<mode>"
12093 [(set (match_operand:SWI48 0 "register_operand" "=r")
12096 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12099 (clobber (reg:CC FLAGS_REG))]
12101 "blsr\t{%1, %0|%0, %1}"
12102 [(set_attr "type" "bitmanip")
12103 (set_attr "mode" "<MODE>")])
12105 ;; BMI2 instructions.
12106 (define_insn "bmi2_bzhi_<mode>3"
12107 [(set (match_operand:SWI48 0 "register_operand" "=r")
12108 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12109 (lshiftrt:SWI48 (const_int -1)
12110 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12111 (clobber (reg:CC FLAGS_REG))]
12113 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12114 [(set_attr "type" "bitmanip")
12115 (set_attr "prefix" "vex")
12116 (set_attr "mode" "<MODE>")])
12118 (define_insn "bmi2_pdep_<mode>3"
12119 [(set (match_operand:SWI48 0 "register_operand" "=r")
12120 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12121 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12124 "pdep\t{%2, %1, %0|%0, %1, %2}"
12125 [(set_attr "type" "bitmanip")
12126 (set_attr "prefix" "vex")
12127 (set_attr "mode" "<MODE>")])
12129 (define_insn "bmi2_pext_<mode>3"
12130 [(set (match_operand:SWI48 0 "register_operand" "=r")
12131 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12132 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12135 "pext\t{%2, %1, %0|%0, %1, %2}"
12136 [(set_attr "type" "bitmanip")
12137 (set_attr "prefix" "vex")
12138 (set_attr "mode" "<MODE>")])
12140 ;; TBM instructions.
12141 (define_insn "tbm_bextri_<mode>"
12142 [(set (match_operand:SWI48 0 "register_operand" "=r")
12143 (zero_extract:SWI48
12144 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12145 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12146 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12147 (clobber (reg:CC FLAGS_REG))]
12150 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12151 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12153 [(set_attr "type" "bitmanip")
12154 (set_attr "mode" "<MODE>")])
12156 (define_insn "*tbm_blcfill_<mode>"
12157 [(set (match_operand:SWI48 0 "register_operand" "=r")
12160 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12163 (clobber (reg:CC FLAGS_REG))]
12165 "blcfill\t{%1, %0|%0, %1}"
12166 [(set_attr "type" "bitmanip")
12167 (set_attr "mode" "<MODE>")])
12169 (define_insn "*tbm_blci_<mode>"
12170 [(set (match_operand:SWI48 0 "register_operand" "=r")
12174 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12177 (clobber (reg:CC FLAGS_REG))]
12179 "blci\t{%1, %0|%0, %1}"
12180 [(set_attr "type" "bitmanip")
12181 (set_attr "mode" "<MODE>")])
12183 (define_insn "*tbm_blcic_<mode>"
12184 [(set (match_operand:SWI48 0 "register_operand" "=r")
12187 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12191 (clobber (reg:CC FLAGS_REG))]
12193 "blcic\t{%1, %0|%0, %1}"
12194 [(set_attr "type" "bitmanip")
12195 (set_attr "mode" "<MODE>")])
12197 (define_insn "*tbm_blcmsk_<mode>"
12198 [(set (match_operand:SWI48 0 "register_operand" "=r")
12201 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12204 (clobber (reg:CC FLAGS_REG))]
12206 "blcmsk\t{%1, %0|%0, %1}"
12207 [(set_attr "type" "bitmanip")
12208 (set_attr "mode" "<MODE>")])
12210 (define_insn "*tbm_blcs_<mode>"
12211 [(set (match_operand:SWI48 0 "register_operand" "=r")
12214 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12217 (clobber (reg:CC FLAGS_REG))]
12219 "blcs\t{%1, %0|%0, %1}"
12220 [(set_attr "type" "bitmanip")
12221 (set_attr "mode" "<MODE>")])
12223 (define_insn "*tbm_blsfill_<mode>"
12224 [(set (match_operand:SWI48 0 "register_operand" "=r")
12227 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12230 (clobber (reg:CC FLAGS_REG))]
12232 "blsfill\t{%1, %0|%0, %1}"
12233 [(set_attr "type" "bitmanip")
12234 (set_attr "mode" "<MODE>")])
12236 (define_insn "*tbm_blsic_<mode>"
12237 [(set (match_operand:SWI48 0 "register_operand" "=r")
12240 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12244 (clobber (reg:CC FLAGS_REG))]
12246 "blsic\t{%1, %0|%0, %1}"
12247 [(set_attr "type" "bitmanip")
12248 (set_attr "mode" "<MODE>")])
12250 (define_insn "*tbm_t1mskc_<mode>"
12251 [(set (match_operand:SWI48 0 "register_operand" "=r")
12254 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12258 (clobber (reg:CC FLAGS_REG))]
12260 "t1mskc\t{%1, %0|%0, %1}"
12261 [(set_attr "type" "bitmanip")
12262 (set_attr "mode" "<MODE>")])
12264 (define_insn "*tbm_tzmsk_<mode>"
12265 [(set (match_operand:SWI48 0 "register_operand" "=r")
12268 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12272 (clobber (reg:CC FLAGS_REG))]
12274 "tzmsk\t{%1, %0|%0, %1}"
12275 [(set_attr "type" "bitmanip")
12276 (set_attr "mode" "<MODE>")])
12278 (define_insn "bsr_rex64"
12279 [(set (match_operand:DI 0 "register_operand" "=r")
12280 (minus:DI (const_int 63)
12281 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12282 (clobber (reg:CC FLAGS_REG))]
12284 "bsr{q}\t{%1, %0|%0, %1}"
12285 [(set_attr "type" "alu1")
12286 (set_attr "prefix_0f" "1")
12287 (set_attr "mode" "DI")])
12290 [(set (match_operand:SI 0 "register_operand" "=r")
12291 (minus:SI (const_int 31)
12292 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12293 (clobber (reg:CC FLAGS_REG))]
12295 "bsr{l}\t{%1, %0|%0, %1}"
12296 [(set_attr "type" "alu1")
12297 (set_attr "prefix_0f" "1")
12298 (set_attr "mode" "SI")])
12300 (define_insn "*bsrhi"
12301 [(set (match_operand:HI 0 "register_operand" "=r")
12302 (minus:HI (const_int 15)
12303 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12304 (clobber (reg:CC FLAGS_REG))]
12306 "bsr{w}\t{%1, %0|%0, %1}"
12307 [(set_attr "type" "alu1")
12308 (set_attr "prefix_0f" "1")
12309 (set_attr "mode" "HI")])
12311 (define_insn "popcount<mode>2"
12312 [(set (match_operand:SWI248 0 "register_operand" "=r")
12314 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12315 (clobber (reg:CC FLAGS_REG))]
12319 return "popcnt\t{%1, %0|%0, %1}";
12321 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12324 [(set_attr "prefix_rep" "1")
12325 (set_attr "type" "bitmanip")
12326 (set_attr "mode" "<MODE>")])
12328 (define_insn "*popcount<mode>2_cmp"
12329 [(set (reg FLAGS_REG)
12332 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12334 (set (match_operand:SWI248 0 "register_operand" "=r")
12335 (popcount:SWI248 (match_dup 1)))]
12336 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12339 return "popcnt\t{%1, %0|%0, %1}";
12341 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12344 [(set_attr "prefix_rep" "1")
12345 (set_attr "type" "bitmanip")
12346 (set_attr "mode" "<MODE>")])
12348 (define_insn "*popcountsi2_cmp_zext"
12349 [(set (reg FLAGS_REG)
12351 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12353 (set (match_operand:DI 0 "register_operand" "=r")
12354 (zero_extend:DI(popcount:SI (match_dup 1))))]
12355 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12358 return "popcnt\t{%1, %0|%0, %1}";
12360 return "popcnt{l}\t{%1, %0|%0, %1}";
12363 [(set_attr "prefix_rep" "1")
12364 (set_attr "type" "bitmanip")
12365 (set_attr "mode" "SI")])
12367 (define_expand "bswap<mode>2"
12368 [(set (match_operand:SWI48 0 "register_operand" "")
12369 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12372 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12374 rtx x = operands[0];
12376 emit_move_insn (x, operands[1]);
12377 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12378 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12379 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12384 (define_insn "*bswap<mode>2_movbe"
12385 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12386 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12388 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12391 movbe\t{%1, %0|%0, %1}
12392 movbe\t{%1, %0|%0, %1}"
12393 [(set_attr "type" "bitmanip,imov,imov")
12394 (set_attr "modrm" "0,1,1")
12395 (set_attr "prefix_0f" "*,1,1")
12396 (set_attr "prefix_extra" "*,1,1")
12397 (set_attr "mode" "<MODE>")])
12399 (define_insn "*bswap<mode>2_1"
12400 [(set (match_operand:SWI48 0 "register_operand" "=r")
12401 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12404 [(set_attr "type" "bitmanip")
12405 (set_attr "modrm" "0")
12406 (set_attr "mode" "<MODE>")])
12408 (define_insn "*bswaphi_lowpart_1"
12409 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12410 (bswap:HI (match_dup 0)))
12411 (clobber (reg:CC FLAGS_REG))]
12412 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12414 xchg{b}\t{%h0, %b0|%b0, %h0}
12415 rol{w}\t{$8, %0|%0, 8}"
12416 [(set_attr "length" "2,4")
12417 (set_attr "mode" "QI,HI")])
12419 (define_insn "bswaphi_lowpart"
12420 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12421 (bswap:HI (match_dup 0)))
12422 (clobber (reg:CC FLAGS_REG))]
12424 "rol{w}\t{$8, %0|%0, 8}"
12425 [(set_attr "length" "4")
12426 (set_attr "mode" "HI")])
12428 (define_expand "paritydi2"
12429 [(set (match_operand:DI 0 "register_operand" "")
12430 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12433 rtx scratch = gen_reg_rtx (QImode);
12436 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12437 NULL_RTX, operands[1]));
12439 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12440 gen_rtx_REG (CCmode, FLAGS_REG),
12442 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12445 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12448 rtx tmp = gen_reg_rtx (SImode);
12450 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12451 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12456 (define_expand "paritysi2"
12457 [(set (match_operand:SI 0 "register_operand" "")
12458 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12461 rtx scratch = gen_reg_rtx (QImode);
12464 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12466 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12467 gen_rtx_REG (CCmode, FLAGS_REG),
12469 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12471 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12475 (define_insn_and_split "paritydi2_cmp"
12476 [(set (reg:CC FLAGS_REG)
12477 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12479 (clobber (match_scratch:DI 0 "=r"))
12480 (clobber (match_scratch:SI 1 "=&r"))
12481 (clobber (match_scratch:HI 2 "=Q"))]
12484 "&& reload_completed"
12486 [(set (match_dup 1)
12487 (xor:SI (match_dup 1) (match_dup 4)))
12488 (clobber (reg:CC FLAGS_REG))])
12490 [(set (reg:CC FLAGS_REG)
12491 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12492 (clobber (match_dup 1))
12493 (clobber (match_dup 2))])]
12495 operands[4] = gen_lowpart (SImode, operands[3]);
12499 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12500 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12503 operands[1] = gen_highpart (SImode, operands[3]);
12506 (define_insn_and_split "paritysi2_cmp"
12507 [(set (reg:CC FLAGS_REG)
12508 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12510 (clobber (match_scratch:SI 0 "=r"))
12511 (clobber (match_scratch:HI 1 "=&Q"))]
12514 "&& reload_completed"
12516 [(set (match_dup 1)
12517 (xor:HI (match_dup 1) (match_dup 3)))
12518 (clobber (reg:CC FLAGS_REG))])
12520 [(set (reg:CC FLAGS_REG)
12521 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12522 (clobber (match_dup 1))])]
12524 operands[3] = gen_lowpart (HImode, operands[2]);
12526 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12527 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12530 (define_insn "*parityhi2_cmp"
12531 [(set (reg:CC FLAGS_REG)
12532 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12534 (clobber (match_scratch:HI 0 "=Q"))]
12536 "xor{b}\t{%h0, %b0|%b0, %h0}"
12537 [(set_attr "length" "2")
12538 (set_attr "mode" "HI")])
12541 ;; Thread-local storage patterns for ELF.
12543 ;; Note that these code sequences must appear exactly as shown
12544 ;; in order to allow linker relaxation.
12546 (define_insn "*tls_global_dynamic_32_gnu"
12547 [(set (match_operand:SI 0 "register_operand" "=a")
12549 [(match_operand:SI 1 "register_operand" "b")
12550 (match_operand:SI 2 "tls_symbolic_operand" "")
12551 (match_operand:SI 3 "constant_call_address_operand" "z")]
12553 (clobber (match_scratch:SI 4 "=d"))
12554 (clobber (match_scratch:SI 5 "=c"))
12555 (clobber (reg:CC FLAGS_REG))]
12556 "!TARGET_64BIT && TARGET_GNU_TLS"
12559 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12560 if (TARGET_SUN_TLS)
12561 #ifdef HAVE_AS_IX86_TLSGDPLT
12562 return "call\t%a2@tlsgdplt";
12564 return "call\t%p3@plt";
12566 return "call\t%P3";
12568 [(set_attr "type" "multi")
12569 (set_attr "length" "12")])
12571 (define_expand "tls_global_dynamic_32"
12573 [(set (match_operand:SI 0 "register_operand" "")
12574 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12575 (match_operand:SI 1 "tls_symbolic_operand" "")
12576 (match_operand:SI 3 "constant_call_address_operand" "")]
12578 (clobber (match_scratch:SI 4 ""))
12579 (clobber (match_scratch:SI 5 ""))
12580 (clobber (reg:CC FLAGS_REG))])])
12582 (define_insn "*tls_global_dynamic_64"
12583 [(set (match_operand:DI 0 "register_operand" "=a")
12585 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12586 (match_operand:DI 3 "" "")))
12587 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12592 fputs (ASM_BYTE "0x66\n", asm_out_file);
12594 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12595 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12596 fputs ("\trex64\n", asm_out_file);
12597 if (TARGET_SUN_TLS)
12598 return "call\t%p2@plt";
12599 return "call\t%P2";
12601 [(set_attr "type" "multi")
12602 (set (attr "length")
12603 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12605 (define_expand "tls_global_dynamic_64"
12607 [(set (match_operand:DI 0 "register_operand" "")
12609 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12611 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12614 (define_insn "*tls_local_dynamic_base_32_gnu"
12615 [(set (match_operand:SI 0 "register_operand" "=a")
12617 [(match_operand:SI 1 "register_operand" "b")
12618 (match_operand:SI 2 "constant_call_address_operand" "z")]
12619 UNSPEC_TLS_LD_BASE))
12620 (clobber (match_scratch:SI 3 "=d"))
12621 (clobber (match_scratch:SI 4 "=c"))
12622 (clobber (reg:CC FLAGS_REG))]
12623 "!TARGET_64BIT && TARGET_GNU_TLS"
12626 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12627 if (TARGET_SUN_TLS)
12628 #ifdef HAVE_AS_IX86_TLSLDMPLT
12629 return "call\t%&@tlsldmplt";
12631 return "call\t%p2@plt";
12633 return "call\t%P2";
12635 [(set_attr "type" "multi")
12636 (set_attr "length" "11")])
12638 (define_expand "tls_local_dynamic_base_32"
12640 [(set (match_operand:SI 0 "register_operand" "")
12642 [(match_operand:SI 1 "register_operand" "")
12643 (match_operand:SI 2 "constant_call_address_operand" "")]
12644 UNSPEC_TLS_LD_BASE))
12645 (clobber (match_scratch:SI 3 ""))
12646 (clobber (match_scratch:SI 4 ""))
12647 (clobber (reg:CC FLAGS_REG))])])
12649 (define_insn "*tls_local_dynamic_base_64"
12650 [(set (match_operand:DI 0 "register_operand" "=a")
12652 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12653 (match_operand:DI 2 "" "")))
12654 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12658 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12659 if (TARGET_SUN_TLS)
12660 return "call\t%p1@plt";
12661 return "call\t%P1";
12663 [(set_attr "type" "multi")
12664 (set_attr "length" "12")])
12666 (define_expand "tls_local_dynamic_base_64"
12668 [(set (match_operand:DI 0 "register_operand" "")
12670 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12672 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12674 ;; Local dynamic of a single variable is a lose. Show combine how
12675 ;; to convert that back to global dynamic.
12677 (define_insn_and_split "*tls_local_dynamic_32_once"
12678 [(set (match_operand:SI 0 "register_operand" "=a")
12680 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12681 (match_operand:SI 2 "constant_call_address_operand" "z")]
12682 UNSPEC_TLS_LD_BASE)
12683 (const:SI (unspec:SI
12684 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12686 (clobber (match_scratch:SI 4 "=d"))
12687 (clobber (match_scratch:SI 5 "=c"))
12688 (clobber (reg:CC FLAGS_REG))]
12693 [(set (match_dup 0)
12694 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12696 (clobber (match_dup 4))
12697 (clobber (match_dup 5))
12698 (clobber (reg:CC FLAGS_REG))])])
12700 ;; Segment register for the thread base ptr load
12701 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12703 ;; Load and add the thread base pointer from %<tp_seg>:0.
12704 (define_insn "*load_tp_x32"
12705 [(set (match_operand:SI 0 "register_operand" "=r")
12706 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12708 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12709 [(set_attr "type" "imov")
12710 (set_attr "modrm" "0")
12711 (set_attr "length" "7")
12712 (set_attr "memory" "load")
12713 (set_attr "imm_disp" "false")])
12715 (define_insn "*load_tp_x32_zext"
12716 [(set (match_operand:DI 0 "register_operand" "=r")
12717 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12719 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12720 [(set_attr "type" "imov")
12721 (set_attr "modrm" "0")
12722 (set_attr "length" "7")
12723 (set_attr "memory" "load")
12724 (set_attr "imm_disp" "false")])
12726 (define_insn "*load_tp_<mode>"
12727 [(set (match_operand:P 0 "register_operand" "=r")
12728 (unspec:P [(const_int 0)] UNSPEC_TP))]
12730 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12731 [(set_attr "type" "imov")
12732 (set_attr "modrm" "0")
12733 (set_attr "length" "7")
12734 (set_attr "memory" "load")
12735 (set_attr "imm_disp" "false")])
12737 (define_insn "*add_tp_x32"
12738 [(set (match_operand:SI 0 "register_operand" "=r")
12739 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12740 (match_operand:SI 1 "register_operand" "0")))
12741 (clobber (reg:CC FLAGS_REG))]
12743 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12744 [(set_attr "type" "alu")
12745 (set_attr "modrm" "0")
12746 (set_attr "length" "7")
12747 (set_attr "memory" "load")
12748 (set_attr "imm_disp" "false")])
12750 (define_insn "*add_tp_x32_zext"
12751 [(set (match_operand:DI 0 "register_operand" "=r")
12753 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12754 (match_operand:SI 1 "register_operand" "0"))))
12755 (clobber (reg:CC FLAGS_REG))]
12757 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12758 [(set_attr "type" "alu")
12759 (set_attr "modrm" "0")
12760 (set_attr "length" "7")
12761 (set_attr "memory" "load")
12762 (set_attr "imm_disp" "false")])
12764 (define_insn "*add_tp_<mode>"
12765 [(set (match_operand:P 0 "register_operand" "=r")
12766 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12767 (match_operand:P 1 "register_operand" "0")))
12768 (clobber (reg:CC FLAGS_REG))]
12770 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12771 [(set_attr "type" "alu")
12772 (set_attr "modrm" "0")
12773 (set_attr "length" "7")
12774 (set_attr "memory" "load")
12775 (set_attr "imm_disp" "false")])
12777 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12778 ;; %rax as destination of the initial executable code sequence.
12779 (define_insn "tls_initial_exec_64_sun"
12780 [(set (match_operand:DI 0 "register_operand" "=a")
12782 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12783 UNSPEC_TLS_IE_SUN))
12784 (clobber (reg:CC FLAGS_REG))]
12785 "TARGET_64BIT && TARGET_SUN_TLS"
12788 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12789 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12791 [(set_attr "type" "multi")])
12793 ;; GNU2 TLS patterns can be split.
12795 (define_expand "tls_dynamic_gnu2_32"
12796 [(set (match_dup 3)
12797 (plus:SI (match_operand:SI 2 "register_operand" "")
12799 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12802 [(set (match_operand:SI 0 "register_operand" "")
12803 (unspec:SI [(match_dup 1) (match_dup 3)
12804 (match_dup 2) (reg:SI SP_REG)]
12806 (clobber (reg:CC FLAGS_REG))])]
12807 "!TARGET_64BIT && TARGET_GNU2_TLS"
12809 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12810 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12813 (define_insn "*tls_dynamic_gnu2_lea_32"
12814 [(set (match_operand:SI 0 "register_operand" "=r")
12815 (plus:SI (match_operand:SI 1 "register_operand" "b")
12817 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12818 UNSPEC_TLSDESC))))]
12819 "!TARGET_64BIT && TARGET_GNU2_TLS"
12820 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12821 [(set_attr "type" "lea")
12822 (set_attr "mode" "SI")
12823 (set_attr "length" "6")
12824 (set_attr "length_address" "4")])
12826 (define_insn "*tls_dynamic_gnu2_call_32"
12827 [(set (match_operand:SI 0 "register_operand" "=a")
12828 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12829 (match_operand:SI 2 "register_operand" "0")
12830 ;; we have to make sure %ebx still points to the GOT
12831 (match_operand:SI 3 "register_operand" "b")
12834 (clobber (reg:CC FLAGS_REG))]
12835 "!TARGET_64BIT && TARGET_GNU2_TLS"
12836 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12837 [(set_attr "type" "call")
12838 (set_attr "length" "2")
12839 (set_attr "length_address" "0")])
12841 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12842 [(set (match_operand:SI 0 "register_operand" "=&a")
12844 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12845 (match_operand:SI 4 "" "")
12846 (match_operand:SI 2 "register_operand" "b")
12849 (const:SI (unspec:SI
12850 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12852 (clobber (reg:CC FLAGS_REG))]
12853 "!TARGET_64BIT && TARGET_GNU2_TLS"
12856 [(set (match_dup 0) (match_dup 5))]
12858 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12859 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12862 (define_expand "tls_dynamic_gnu2_64"
12863 [(set (match_dup 2)
12864 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12867 [(set (match_operand:DI 0 "register_operand" "")
12868 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12870 (clobber (reg:CC FLAGS_REG))])]
12871 "TARGET_64BIT && TARGET_GNU2_TLS"
12873 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12874 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12877 (define_insn "*tls_dynamic_gnu2_lea_64"
12878 [(set (match_operand:DI 0 "register_operand" "=r")
12879 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12881 "TARGET_64BIT && TARGET_GNU2_TLS"
12882 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12883 [(set_attr "type" "lea")
12884 (set_attr "mode" "DI")
12885 (set_attr "length" "7")
12886 (set_attr "length_address" "4")])
12888 (define_insn "*tls_dynamic_gnu2_call_64"
12889 [(set (match_operand:DI 0 "register_operand" "=a")
12890 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12891 (match_operand:DI 2 "register_operand" "0")
12894 (clobber (reg:CC FLAGS_REG))]
12895 "TARGET_64BIT && TARGET_GNU2_TLS"
12896 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12897 [(set_attr "type" "call")
12898 (set_attr "length" "2")
12899 (set_attr "length_address" "0")])
12901 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12902 [(set (match_operand:DI 0 "register_operand" "=&a")
12904 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12905 (match_operand:DI 3 "" "")
12908 (const:DI (unspec:DI
12909 [(match_operand 1 "tls_symbolic_operand" "")]
12911 (clobber (reg:CC FLAGS_REG))]
12912 "TARGET_64BIT && TARGET_GNU2_TLS"
12915 [(set (match_dup 0) (match_dup 4))]
12917 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12918 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12921 ;; These patterns match the binary 387 instructions for addM3, subM3,
12922 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12923 ;; SFmode. The first is the normal insn, the second the same insn but
12924 ;; with one operand a conversion, and the third the same insn but with
12925 ;; the other operand a conversion. The conversion may be SFmode or
12926 ;; SImode if the target mode DFmode, but only SImode if the target mode
12929 ;; Gcc is slightly more smart about handling normal two address instructions
12930 ;; so use special patterns for add and mull.
12932 (define_insn "*fop_<mode>_comm_mixed"
12933 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12934 (match_operator:MODEF 3 "binary_fp_operator"
12935 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12936 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12937 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12938 && COMMUTATIVE_ARITH_P (operands[3])
12939 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12940 "* return output_387_binary_op (insn, operands);"
12941 [(set (attr "type")
12942 (if_then_else (eq_attr "alternative" "1,2")
12943 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12944 (const_string "ssemul")
12945 (const_string "sseadd"))
12946 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12947 (const_string "fmul")
12948 (const_string "fop"))))
12949 (set_attr "isa" "*,noavx,avx")
12950 (set_attr "prefix" "orig,orig,vex")
12951 (set_attr "mode" "<MODE>")])
12953 (define_insn "*fop_<mode>_comm_sse"
12954 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12955 (match_operator:MODEF 3 "binary_fp_operator"
12956 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12957 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12958 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12959 && COMMUTATIVE_ARITH_P (operands[3])
12960 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12961 "* return output_387_binary_op (insn, operands);"
12962 [(set (attr "type")
12963 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12964 (const_string "ssemul")
12965 (const_string "sseadd")))
12966 (set_attr "isa" "noavx,avx")
12967 (set_attr "prefix" "orig,vex")
12968 (set_attr "mode" "<MODE>")])
12970 (define_insn "*fop_<mode>_comm_i387"
12971 [(set (match_operand:MODEF 0 "register_operand" "=f")
12972 (match_operator:MODEF 3 "binary_fp_operator"
12973 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12974 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12975 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12976 && COMMUTATIVE_ARITH_P (operands[3])
12977 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12978 "* return output_387_binary_op (insn, operands);"
12979 [(set (attr "type")
12980 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12981 (const_string "fmul")
12982 (const_string "fop")))
12983 (set_attr "mode" "<MODE>")])
12985 (define_insn "*fop_<mode>_1_mixed"
12986 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12987 (match_operator:MODEF 3 "binary_fp_operator"
12988 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12989 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12990 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12991 && !COMMUTATIVE_ARITH_P (operands[3])
12992 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12993 "* return output_387_binary_op (insn, operands);"
12994 [(set (attr "type")
12995 (cond [(and (eq_attr "alternative" "2,3")
12996 (match_operand:MODEF 3 "mult_operator" ""))
12997 (const_string "ssemul")
12998 (and (eq_attr "alternative" "2,3")
12999 (match_operand:MODEF 3 "div_operator" ""))
13000 (const_string "ssediv")
13001 (eq_attr "alternative" "2,3")
13002 (const_string "sseadd")
13003 (match_operand:MODEF 3 "mult_operator" "")
13004 (const_string "fmul")
13005 (match_operand:MODEF 3 "div_operator" "")
13006 (const_string "fdiv")
13008 (const_string "fop")))
13009 (set_attr "isa" "*,*,noavx,avx")
13010 (set_attr "prefix" "orig,orig,orig,vex")
13011 (set_attr "mode" "<MODE>")])
13013 (define_insn "*rcpsf2_sse"
13014 [(set (match_operand:SF 0 "register_operand" "=x")
13015 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13018 "%vrcpss\t{%1, %d0|%d0, %1}"
13019 [(set_attr "type" "sse")
13020 (set_attr "atom_sse_attr" "rcp")
13021 (set_attr "prefix" "maybe_vex")
13022 (set_attr "mode" "SF")])
13024 (define_insn "*fop_<mode>_1_sse"
13025 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13026 (match_operator:MODEF 3 "binary_fp_operator"
13027 [(match_operand:MODEF 1 "register_operand" "0,x")
13028 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13029 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13030 && !COMMUTATIVE_ARITH_P (operands[3])"
13031 "* return output_387_binary_op (insn, operands);"
13032 [(set (attr "type")
13033 (cond [(match_operand:MODEF 3 "mult_operator" "")
13034 (const_string "ssemul")
13035 (match_operand:MODEF 3 "div_operator" "")
13036 (const_string "ssediv")
13038 (const_string "sseadd")))
13039 (set_attr "isa" "noavx,avx")
13040 (set_attr "prefix" "orig,vex")
13041 (set_attr "mode" "<MODE>")])
13043 ;; This pattern is not fully shadowed by the pattern above.
13044 (define_insn "*fop_<mode>_1_i387"
13045 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13046 (match_operator:MODEF 3 "binary_fp_operator"
13047 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13048 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13049 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13050 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13051 && !COMMUTATIVE_ARITH_P (operands[3])
13052 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13053 "* return output_387_binary_op (insn, operands);"
13054 [(set (attr "type")
13055 (cond [(match_operand:MODEF 3 "mult_operator" "")
13056 (const_string "fmul")
13057 (match_operand:MODEF 3 "div_operator" "")
13058 (const_string "fdiv")
13060 (const_string "fop")))
13061 (set_attr "mode" "<MODE>")])
13063 ;; ??? Add SSE splitters for these!
13064 (define_insn "*fop_<MODEF:mode>_2_i387"
13065 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13066 (match_operator:MODEF 3 "binary_fp_operator"
13068 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13069 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13070 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13071 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13072 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13073 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13074 [(set (attr "type")
13075 (cond [(match_operand:MODEF 3 "mult_operator" "")
13076 (const_string "fmul")
13077 (match_operand:MODEF 3 "div_operator" "")
13078 (const_string "fdiv")
13080 (const_string "fop")))
13081 (set_attr "fp_int_src" "true")
13082 (set_attr "mode" "<SWI24:MODE>")])
13084 (define_insn "*fop_<MODEF:mode>_3_i387"
13085 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13086 (match_operator:MODEF 3 "binary_fp_operator"
13087 [(match_operand:MODEF 1 "register_operand" "0,0")
13089 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13090 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13091 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13092 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13093 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13094 [(set (attr "type")
13095 (cond [(match_operand:MODEF 3 "mult_operator" "")
13096 (const_string "fmul")
13097 (match_operand:MODEF 3 "div_operator" "")
13098 (const_string "fdiv")
13100 (const_string "fop")))
13101 (set_attr "fp_int_src" "true")
13102 (set_attr "mode" "<MODE>")])
13104 (define_insn "*fop_df_4_i387"
13105 [(set (match_operand:DF 0 "register_operand" "=f,f")
13106 (match_operator:DF 3 "binary_fp_operator"
13108 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13109 (match_operand:DF 2 "register_operand" "0,f")]))]
13110 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13111 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13112 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13113 "* return output_387_binary_op (insn, operands);"
13114 [(set (attr "type")
13115 (cond [(match_operand:DF 3 "mult_operator" "")
13116 (const_string "fmul")
13117 (match_operand:DF 3 "div_operator" "")
13118 (const_string "fdiv")
13120 (const_string "fop")))
13121 (set_attr "mode" "SF")])
13123 (define_insn "*fop_df_5_i387"
13124 [(set (match_operand:DF 0 "register_operand" "=f,f")
13125 (match_operator:DF 3 "binary_fp_operator"
13126 [(match_operand:DF 1 "register_operand" "0,f")
13128 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13129 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13130 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13131 "* return output_387_binary_op (insn, operands);"
13132 [(set (attr "type")
13133 (cond [(match_operand:DF 3 "mult_operator" "")
13134 (const_string "fmul")
13135 (match_operand:DF 3 "div_operator" "")
13136 (const_string "fdiv")
13138 (const_string "fop")))
13139 (set_attr "mode" "SF")])
13141 (define_insn "*fop_df_6_i387"
13142 [(set (match_operand:DF 0 "register_operand" "=f,f")
13143 (match_operator:DF 3 "binary_fp_operator"
13145 (match_operand:SF 1 "register_operand" "0,f"))
13147 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13148 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13149 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13150 "* return output_387_binary_op (insn, operands);"
13151 [(set (attr "type")
13152 (cond [(match_operand:DF 3 "mult_operator" "")
13153 (const_string "fmul")
13154 (match_operand:DF 3 "div_operator" "")
13155 (const_string "fdiv")
13157 (const_string "fop")))
13158 (set_attr "mode" "SF")])
13160 (define_insn "*fop_xf_comm_i387"
13161 [(set (match_operand:XF 0 "register_operand" "=f")
13162 (match_operator:XF 3 "binary_fp_operator"
13163 [(match_operand:XF 1 "register_operand" "%0")
13164 (match_operand:XF 2 "register_operand" "f")]))]
13166 && COMMUTATIVE_ARITH_P (operands[3])"
13167 "* return output_387_binary_op (insn, operands);"
13168 [(set (attr "type")
13169 (if_then_else (match_operand:XF 3 "mult_operator" "")
13170 (const_string "fmul")
13171 (const_string "fop")))
13172 (set_attr "mode" "XF")])
13174 (define_insn "*fop_xf_1_i387"
13175 [(set (match_operand:XF 0 "register_operand" "=f,f")
13176 (match_operator:XF 3 "binary_fp_operator"
13177 [(match_operand:XF 1 "register_operand" "0,f")
13178 (match_operand:XF 2 "register_operand" "f,0")]))]
13180 && !COMMUTATIVE_ARITH_P (operands[3])"
13181 "* return output_387_binary_op (insn, operands);"
13182 [(set (attr "type")
13183 (cond [(match_operand:XF 3 "mult_operator" "")
13184 (const_string "fmul")
13185 (match_operand:XF 3 "div_operator" "")
13186 (const_string "fdiv")
13188 (const_string "fop")))
13189 (set_attr "mode" "XF")])
13191 (define_insn "*fop_xf_2_i387"
13192 [(set (match_operand:XF 0 "register_operand" "=f,f")
13193 (match_operator:XF 3 "binary_fp_operator"
13195 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13196 (match_operand:XF 2 "register_operand" "0,0")]))]
13197 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13198 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13199 [(set (attr "type")
13200 (cond [(match_operand:XF 3 "mult_operator" "")
13201 (const_string "fmul")
13202 (match_operand:XF 3 "div_operator" "")
13203 (const_string "fdiv")
13205 (const_string "fop")))
13206 (set_attr "fp_int_src" "true")
13207 (set_attr "mode" "<MODE>")])
13209 (define_insn "*fop_xf_3_i387"
13210 [(set (match_operand:XF 0 "register_operand" "=f,f")
13211 (match_operator:XF 3 "binary_fp_operator"
13212 [(match_operand:XF 1 "register_operand" "0,0")
13214 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13215 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13216 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13217 [(set (attr "type")
13218 (cond [(match_operand:XF 3 "mult_operator" "")
13219 (const_string "fmul")
13220 (match_operand:XF 3 "div_operator" "")
13221 (const_string "fdiv")
13223 (const_string "fop")))
13224 (set_attr "fp_int_src" "true")
13225 (set_attr "mode" "<MODE>")])
13227 (define_insn "*fop_xf_4_i387"
13228 [(set (match_operand:XF 0 "register_operand" "=f,f")
13229 (match_operator:XF 3 "binary_fp_operator"
13231 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13232 (match_operand:XF 2 "register_operand" "0,f")]))]
13234 "* return output_387_binary_op (insn, operands);"
13235 [(set (attr "type")
13236 (cond [(match_operand:XF 3 "mult_operator" "")
13237 (const_string "fmul")
13238 (match_operand:XF 3 "div_operator" "")
13239 (const_string "fdiv")
13241 (const_string "fop")))
13242 (set_attr "mode" "<MODE>")])
13244 (define_insn "*fop_xf_5_i387"
13245 [(set (match_operand:XF 0 "register_operand" "=f,f")
13246 (match_operator:XF 3 "binary_fp_operator"
13247 [(match_operand:XF 1 "register_operand" "0,f")
13249 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13251 "* return output_387_binary_op (insn, operands);"
13252 [(set (attr "type")
13253 (cond [(match_operand:XF 3 "mult_operator" "")
13254 (const_string "fmul")
13255 (match_operand:XF 3 "div_operator" "")
13256 (const_string "fdiv")
13258 (const_string "fop")))
13259 (set_attr "mode" "<MODE>")])
13261 (define_insn "*fop_xf_6_i387"
13262 [(set (match_operand:XF 0 "register_operand" "=f,f")
13263 (match_operator:XF 3 "binary_fp_operator"
13265 (match_operand:MODEF 1 "register_operand" "0,f"))
13267 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13269 "* return output_387_binary_op (insn, operands);"
13270 [(set (attr "type")
13271 (cond [(match_operand:XF 3 "mult_operator" "")
13272 (const_string "fmul")
13273 (match_operand:XF 3 "div_operator" "")
13274 (const_string "fdiv")
13276 (const_string "fop")))
13277 (set_attr "mode" "<MODE>")])
13280 [(set (match_operand 0 "register_operand" "")
13281 (match_operator 3 "binary_fp_operator"
13282 [(float (match_operand:SWI24 1 "register_operand" ""))
13283 (match_operand 2 "register_operand" "")]))]
13285 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13286 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13289 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13290 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13291 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13292 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13293 GET_MODE (operands[3]),
13296 ix86_free_from_memory (GET_MODE (operands[1]));
13301 [(set (match_operand 0 "register_operand" "")
13302 (match_operator 3 "binary_fp_operator"
13303 [(match_operand 1 "register_operand" "")
13304 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13306 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13307 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13310 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13311 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13312 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13313 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13314 GET_MODE (operands[3]),
13317 ix86_free_from_memory (GET_MODE (operands[2]));
13321 ;; FPU special functions.
13323 ;; This pattern implements a no-op XFmode truncation for
13324 ;; all fancy i386 XFmode math functions.
13326 (define_insn "truncxf<mode>2_i387_noop_unspec"
13327 [(set (match_operand:MODEF 0 "register_operand" "=f")
13328 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13329 UNSPEC_TRUNC_NOOP))]
13330 "TARGET_USE_FANCY_MATH_387"
13331 "* return output_387_reg_move (insn, operands);"
13332 [(set_attr "type" "fmov")
13333 (set_attr "mode" "<MODE>")])
13335 (define_insn "sqrtxf2"
13336 [(set (match_operand:XF 0 "register_operand" "=f")
13337 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13338 "TARGET_USE_FANCY_MATH_387"
13340 [(set_attr "type" "fpspc")
13341 (set_attr "mode" "XF")
13342 (set_attr "athlon_decode" "direct")
13343 (set_attr "amdfam10_decode" "direct")
13344 (set_attr "bdver1_decode" "direct")])
13346 (define_insn "sqrt_extend<mode>xf2_i387"
13347 [(set (match_operand:XF 0 "register_operand" "=f")
13350 (match_operand:MODEF 1 "register_operand" "0"))))]
13351 "TARGET_USE_FANCY_MATH_387"
13353 [(set_attr "type" "fpspc")
13354 (set_attr "mode" "XF")
13355 (set_attr "athlon_decode" "direct")
13356 (set_attr "amdfam10_decode" "direct")
13357 (set_attr "bdver1_decode" "direct")])
13359 (define_insn "*rsqrtsf2_sse"
13360 [(set (match_operand:SF 0 "register_operand" "=x")
13361 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13364 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13365 [(set_attr "type" "sse")
13366 (set_attr "atom_sse_attr" "rcp")
13367 (set_attr "prefix" "maybe_vex")
13368 (set_attr "mode" "SF")])
13370 (define_expand "rsqrtsf2"
13371 [(set (match_operand:SF 0 "register_operand" "")
13372 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13376 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13380 (define_insn "*sqrt<mode>2_sse"
13381 [(set (match_operand:MODEF 0 "register_operand" "=x")
13383 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13384 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13385 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13386 [(set_attr "type" "sse")
13387 (set_attr "atom_sse_attr" "sqrt")
13388 (set_attr "prefix" "maybe_vex")
13389 (set_attr "mode" "<MODE>")
13390 (set_attr "athlon_decode" "*")
13391 (set_attr "amdfam10_decode" "*")
13392 (set_attr "bdver1_decode" "*")])
13394 (define_expand "sqrt<mode>2"
13395 [(set (match_operand:MODEF 0 "register_operand" "")
13397 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13398 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13399 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13401 if (<MODE>mode == SFmode
13403 && TARGET_RECIP_SQRT
13404 && !optimize_function_for_size_p (cfun)
13405 && flag_finite_math_only && !flag_trapping_math
13406 && flag_unsafe_math_optimizations)
13408 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13412 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13414 rtx op0 = gen_reg_rtx (XFmode);
13415 rtx op1 = force_reg (<MODE>mode, operands[1]);
13417 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13418 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13423 (define_insn "fpremxf4_i387"
13424 [(set (match_operand:XF 0 "register_operand" "=f")
13425 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13426 (match_operand:XF 3 "register_operand" "1")]
13428 (set (match_operand:XF 1 "register_operand" "=u")
13429 (unspec:XF [(match_dup 2) (match_dup 3)]
13431 (set (reg:CCFP FPSR_REG)
13432 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13434 "TARGET_USE_FANCY_MATH_387"
13436 [(set_attr "type" "fpspc")
13437 (set_attr "mode" "XF")])
13439 (define_expand "fmodxf3"
13440 [(use (match_operand:XF 0 "register_operand" ""))
13441 (use (match_operand:XF 1 "general_operand" ""))
13442 (use (match_operand:XF 2 "general_operand" ""))]
13443 "TARGET_USE_FANCY_MATH_387"
13445 rtx label = gen_label_rtx ();
13447 rtx op1 = gen_reg_rtx (XFmode);
13448 rtx op2 = gen_reg_rtx (XFmode);
13450 emit_move_insn (op2, operands[2]);
13451 emit_move_insn (op1, operands[1]);
13453 emit_label (label);
13454 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13455 ix86_emit_fp_unordered_jump (label);
13456 LABEL_NUSES (label) = 1;
13458 emit_move_insn (operands[0], op1);
13462 (define_expand "fmod<mode>3"
13463 [(use (match_operand:MODEF 0 "register_operand" ""))
13464 (use (match_operand:MODEF 1 "general_operand" ""))
13465 (use (match_operand:MODEF 2 "general_operand" ""))]
13466 "TARGET_USE_FANCY_MATH_387"
13468 rtx (*gen_truncxf) (rtx, rtx);
13470 rtx label = gen_label_rtx ();
13472 rtx op1 = gen_reg_rtx (XFmode);
13473 rtx op2 = gen_reg_rtx (XFmode);
13475 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13476 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13478 emit_label (label);
13479 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13480 ix86_emit_fp_unordered_jump (label);
13481 LABEL_NUSES (label) = 1;
13483 /* Truncate the result properly for strict SSE math. */
13484 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13485 && !TARGET_MIX_SSE_I387)
13486 gen_truncxf = gen_truncxf<mode>2;
13488 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13490 emit_insn (gen_truncxf (operands[0], op1));
13494 (define_insn "fprem1xf4_i387"
13495 [(set (match_operand:XF 0 "register_operand" "=f")
13496 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13497 (match_operand:XF 3 "register_operand" "1")]
13499 (set (match_operand:XF 1 "register_operand" "=u")
13500 (unspec:XF [(match_dup 2) (match_dup 3)]
13502 (set (reg:CCFP FPSR_REG)
13503 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13505 "TARGET_USE_FANCY_MATH_387"
13507 [(set_attr "type" "fpspc")
13508 (set_attr "mode" "XF")])
13510 (define_expand "remainderxf3"
13511 [(use (match_operand:XF 0 "register_operand" ""))
13512 (use (match_operand:XF 1 "general_operand" ""))
13513 (use (match_operand:XF 2 "general_operand" ""))]
13514 "TARGET_USE_FANCY_MATH_387"
13516 rtx label = gen_label_rtx ();
13518 rtx op1 = gen_reg_rtx (XFmode);
13519 rtx op2 = gen_reg_rtx (XFmode);
13521 emit_move_insn (op2, operands[2]);
13522 emit_move_insn (op1, operands[1]);
13524 emit_label (label);
13525 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13526 ix86_emit_fp_unordered_jump (label);
13527 LABEL_NUSES (label) = 1;
13529 emit_move_insn (operands[0], op1);
13533 (define_expand "remainder<mode>3"
13534 [(use (match_operand:MODEF 0 "register_operand" ""))
13535 (use (match_operand:MODEF 1 "general_operand" ""))
13536 (use (match_operand:MODEF 2 "general_operand" ""))]
13537 "TARGET_USE_FANCY_MATH_387"
13539 rtx (*gen_truncxf) (rtx, rtx);
13541 rtx label = gen_label_rtx ();
13543 rtx op1 = gen_reg_rtx (XFmode);
13544 rtx op2 = gen_reg_rtx (XFmode);
13546 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13547 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13549 emit_label (label);
13551 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13552 ix86_emit_fp_unordered_jump (label);
13553 LABEL_NUSES (label) = 1;
13555 /* Truncate the result properly for strict SSE math. */
13556 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13557 && !TARGET_MIX_SSE_I387)
13558 gen_truncxf = gen_truncxf<mode>2;
13560 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13562 emit_insn (gen_truncxf (operands[0], op1));
13566 (define_insn "*sinxf2_i387"
13567 [(set (match_operand:XF 0 "register_operand" "=f")
13568 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13569 "TARGET_USE_FANCY_MATH_387
13570 && flag_unsafe_math_optimizations"
13572 [(set_attr "type" "fpspc")
13573 (set_attr "mode" "XF")])
13575 (define_insn "*sin_extend<mode>xf2_i387"
13576 [(set (match_operand:XF 0 "register_operand" "=f")
13577 (unspec:XF [(float_extend:XF
13578 (match_operand:MODEF 1 "register_operand" "0"))]
13580 "TARGET_USE_FANCY_MATH_387
13581 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13582 || TARGET_MIX_SSE_I387)
13583 && flag_unsafe_math_optimizations"
13585 [(set_attr "type" "fpspc")
13586 (set_attr "mode" "XF")])
13588 (define_insn "*cosxf2_i387"
13589 [(set (match_operand:XF 0 "register_operand" "=f")
13590 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13591 "TARGET_USE_FANCY_MATH_387
13592 && flag_unsafe_math_optimizations"
13594 [(set_attr "type" "fpspc")
13595 (set_attr "mode" "XF")])
13597 (define_insn "*cos_extend<mode>xf2_i387"
13598 [(set (match_operand:XF 0 "register_operand" "=f")
13599 (unspec:XF [(float_extend:XF
13600 (match_operand:MODEF 1 "register_operand" "0"))]
13602 "TARGET_USE_FANCY_MATH_387
13603 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13604 || TARGET_MIX_SSE_I387)
13605 && flag_unsafe_math_optimizations"
13607 [(set_attr "type" "fpspc")
13608 (set_attr "mode" "XF")])
13610 ;; When sincos pattern is defined, sin and cos builtin functions will be
13611 ;; expanded to sincos pattern with one of its outputs left unused.
13612 ;; CSE pass will figure out if two sincos patterns can be combined,
13613 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13614 ;; depending on the unused output.
13616 (define_insn "sincosxf3"
13617 [(set (match_operand:XF 0 "register_operand" "=f")
13618 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13619 UNSPEC_SINCOS_COS))
13620 (set (match_operand:XF 1 "register_operand" "=u")
13621 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13622 "TARGET_USE_FANCY_MATH_387
13623 && flag_unsafe_math_optimizations"
13625 [(set_attr "type" "fpspc")
13626 (set_attr "mode" "XF")])
13629 [(set (match_operand:XF 0 "register_operand" "")
13630 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13631 UNSPEC_SINCOS_COS))
13632 (set (match_operand:XF 1 "register_operand" "")
13633 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13634 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13635 && can_create_pseudo_p ()"
13636 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13639 [(set (match_operand:XF 0 "register_operand" "")
13640 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13641 UNSPEC_SINCOS_COS))
13642 (set (match_operand:XF 1 "register_operand" "")
13643 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13644 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13645 && can_create_pseudo_p ()"
13646 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13648 (define_insn "sincos_extend<mode>xf3_i387"
13649 [(set (match_operand:XF 0 "register_operand" "=f")
13650 (unspec:XF [(float_extend:XF
13651 (match_operand:MODEF 2 "register_operand" "0"))]
13652 UNSPEC_SINCOS_COS))
13653 (set (match_operand:XF 1 "register_operand" "=u")
13654 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13655 "TARGET_USE_FANCY_MATH_387
13656 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13657 || TARGET_MIX_SSE_I387)
13658 && flag_unsafe_math_optimizations"
13660 [(set_attr "type" "fpspc")
13661 (set_attr "mode" "XF")])
13664 [(set (match_operand:XF 0 "register_operand" "")
13665 (unspec:XF [(float_extend:XF
13666 (match_operand:MODEF 2 "register_operand" ""))]
13667 UNSPEC_SINCOS_COS))
13668 (set (match_operand:XF 1 "register_operand" "")
13669 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13670 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13671 && can_create_pseudo_p ()"
13672 [(set (match_dup 1)
13673 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13676 [(set (match_operand:XF 0 "register_operand" "")
13677 (unspec:XF [(float_extend:XF
13678 (match_operand:MODEF 2 "register_operand" ""))]
13679 UNSPEC_SINCOS_COS))
13680 (set (match_operand:XF 1 "register_operand" "")
13681 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13682 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13683 && can_create_pseudo_p ()"
13684 [(set (match_dup 0)
13685 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13687 (define_expand "sincos<mode>3"
13688 [(use (match_operand:MODEF 0 "register_operand" ""))
13689 (use (match_operand:MODEF 1 "register_operand" ""))
13690 (use (match_operand:MODEF 2 "register_operand" ""))]
13691 "TARGET_USE_FANCY_MATH_387
13692 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13693 || TARGET_MIX_SSE_I387)
13694 && flag_unsafe_math_optimizations"
13696 rtx op0 = gen_reg_rtx (XFmode);
13697 rtx op1 = gen_reg_rtx (XFmode);
13699 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13700 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13701 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13705 (define_insn "fptanxf4_i387"
13706 [(set (match_operand:XF 0 "register_operand" "=f")
13707 (match_operand:XF 3 "const_double_operand" "F"))
13708 (set (match_operand:XF 1 "register_operand" "=u")
13709 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13711 "TARGET_USE_FANCY_MATH_387
13712 && flag_unsafe_math_optimizations
13713 && standard_80387_constant_p (operands[3]) == 2"
13715 [(set_attr "type" "fpspc")
13716 (set_attr "mode" "XF")])
13718 (define_insn "fptan_extend<mode>xf4_i387"
13719 [(set (match_operand:MODEF 0 "register_operand" "=f")
13720 (match_operand:MODEF 3 "const_double_operand" "F"))
13721 (set (match_operand:XF 1 "register_operand" "=u")
13722 (unspec:XF [(float_extend:XF
13723 (match_operand:MODEF 2 "register_operand" "0"))]
13725 "TARGET_USE_FANCY_MATH_387
13726 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13727 || TARGET_MIX_SSE_I387)
13728 && flag_unsafe_math_optimizations
13729 && standard_80387_constant_p (operands[3]) == 2"
13731 [(set_attr "type" "fpspc")
13732 (set_attr "mode" "XF")])
13734 (define_expand "tanxf2"
13735 [(use (match_operand:XF 0 "register_operand" ""))
13736 (use (match_operand:XF 1 "register_operand" ""))]
13737 "TARGET_USE_FANCY_MATH_387
13738 && flag_unsafe_math_optimizations"
13740 rtx one = gen_reg_rtx (XFmode);
13741 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13743 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13747 (define_expand "tan<mode>2"
13748 [(use (match_operand:MODEF 0 "register_operand" ""))
13749 (use (match_operand:MODEF 1 "register_operand" ""))]
13750 "TARGET_USE_FANCY_MATH_387
13751 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13752 || TARGET_MIX_SSE_I387)
13753 && flag_unsafe_math_optimizations"
13755 rtx op0 = gen_reg_rtx (XFmode);
13757 rtx one = gen_reg_rtx (<MODE>mode);
13758 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13760 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13761 operands[1], op2));
13762 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13766 (define_insn "*fpatanxf3_i387"
13767 [(set (match_operand:XF 0 "register_operand" "=f")
13768 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13769 (match_operand:XF 2 "register_operand" "u")]
13771 (clobber (match_scratch:XF 3 "=2"))]
13772 "TARGET_USE_FANCY_MATH_387
13773 && flag_unsafe_math_optimizations"
13775 [(set_attr "type" "fpspc")
13776 (set_attr "mode" "XF")])
13778 (define_insn "fpatan_extend<mode>xf3_i387"
13779 [(set (match_operand:XF 0 "register_operand" "=f")
13780 (unspec:XF [(float_extend:XF
13781 (match_operand:MODEF 1 "register_operand" "0"))
13783 (match_operand:MODEF 2 "register_operand" "u"))]
13785 (clobber (match_scratch:XF 3 "=2"))]
13786 "TARGET_USE_FANCY_MATH_387
13787 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13788 || TARGET_MIX_SSE_I387)
13789 && flag_unsafe_math_optimizations"
13791 [(set_attr "type" "fpspc")
13792 (set_attr "mode" "XF")])
13794 (define_expand "atan2xf3"
13795 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13796 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13797 (match_operand:XF 1 "register_operand" "")]
13799 (clobber (match_scratch:XF 3 ""))])]
13800 "TARGET_USE_FANCY_MATH_387
13801 && flag_unsafe_math_optimizations")
13803 (define_expand "atan2<mode>3"
13804 [(use (match_operand:MODEF 0 "register_operand" ""))
13805 (use (match_operand:MODEF 1 "register_operand" ""))
13806 (use (match_operand:MODEF 2 "register_operand" ""))]
13807 "TARGET_USE_FANCY_MATH_387
13808 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13809 || TARGET_MIX_SSE_I387)
13810 && flag_unsafe_math_optimizations"
13812 rtx op0 = gen_reg_rtx (XFmode);
13814 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13815 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13819 (define_expand "atanxf2"
13820 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13821 (unspec:XF [(match_dup 2)
13822 (match_operand:XF 1 "register_operand" "")]
13824 (clobber (match_scratch:XF 3 ""))])]
13825 "TARGET_USE_FANCY_MATH_387
13826 && flag_unsafe_math_optimizations"
13828 operands[2] = gen_reg_rtx (XFmode);
13829 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13832 (define_expand "atan<mode>2"
13833 [(use (match_operand:MODEF 0 "register_operand" ""))
13834 (use (match_operand:MODEF 1 "register_operand" ""))]
13835 "TARGET_USE_FANCY_MATH_387
13836 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13837 || TARGET_MIX_SSE_I387)
13838 && flag_unsafe_math_optimizations"
13840 rtx op0 = gen_reg_rtx (XFmode);
13842 rtx op2 = gen_reg_rtx (<MODE>mode);
13843 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13845 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13846 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13850 (define_expand "asinxf2"
13851 [(set (match_dup 2)
13852 (mult:XF (match_operand:XF 1 "register_operand" "")
13854 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13855 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13856 (parallel [(set (match_operand:XF 0 "register_operand" "")
13857 (unspec:XF [(match_dup 5) (match_dup 1)]
13859 (clobber (match_scratch:XF 6 ""))])]
13860 "TARGET_USE_FANCY_MATH_387
13861 && flag_unsafe_math_optimizations"
13865 if (optimize_insn_for_size_p ())
13868 for (i = 2; i < 6; i++)
13869 operands[i] = gen_reg_rtx (XFmode);
13871 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13874 (define_expand "asin<mode>2"
13875 [(use (match_operand:MODEF 0 "register_operand" ""))
13876 (use (match_operand:MODEF 1 "general_operand" ""))]
13877 "TARGET_USE_FANCY_MATH_387
13878 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13879 || TARGET_MIX_SSE_I387)
13880 && flag_unsafe_math_optimizations"
13882 rtx op0 = gen_reg_rtx (XFmode);
13883 rtx op1 = gen_reg_rtx (XFmode);
13885 if (optimize_insn_for_size_p ())
13888 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13889 emit_insn (gen_asinxf2 (op0, op1));
13890 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13894 (define_expand "acosxf2"
13895 [(set (match_dup 2)
13896 (mult:XF (match_operand:XF 1 "register_operand" "")
13898 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13899 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13900 (parallel [(set (match_operand:XF 0 "register_operand" "")
13901 (unspec:XF [(match_dup 1) (match_dup 5)]
13903 (clobber (match_scratch:XF 6 ""))])]
13904 "TARGET_USE_FANCY_MATH_387
13905 && flag_unsafe_math_optimizations"
13909 if (optimize_insn_for_size_p ())
13912 for (i = 2; i < 6; i++)
13913 operands[i] = gen_reg_rtx (XFmode);
13915 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13918 (define_expand "acos<mode>2"
13919 [(use (match_operand:MODEF 0 "register_operand" ""))
13920 (use (match_operand:MODEF 1 "general_operand" ""))]
13921 "TARGET_USE_FANCY_MATH_387
13922 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13923 || TARGET_MIX_SSE_I387)
13924 && flag_unsafe_math_optimizations"
13926 rtx op0 = gen_reg_rtx (XFmode);
13927 rtx op1 = gen_reg_rtx (XFmode);
13929 if (optimize_insn_for_size_p ())
13932 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13933 emit_insn (gen_acosxf2 (op0, op1));
13934 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13938 (define_insn "fyl2xxf3_i387"
13939 [(set (match_operand:XF 0 "register_operand" "=f")
13940 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13941 (match_operand:XF 2 "register_operand" "u")]
13943 (clobber (match_scratch:XF 3 "=2"))]
13944 "TARGET_USE_FANCY_MATH_387
13945 && flag_unsafe_math_optimizations"
13947 [(set_attr "type" "fpspc")
13948 (set_attr "mode" "XF")])
13950 (define_insn "fyl2x_extend<mode>xf3_i387"
13951 [(set (match_operand:XF 0 "register_operand" "=f")
13952 (unspec:XF [(float_extend:XF
13953 (match_operand:MODEF 1 "register_operand" "0"))
13954 (match_operand:XF 2 "register_operand" "u")]
13956 (clobber (match_scratch:XF 3 "=2"))]
13957 "TARGET_USE_FANCY_MATH_387
13958 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13959 || TARGET_MIX_SSE_I387)
13960 && flag_unsafe_math_optimizations"
13962 [(set_attr "type" "fpspc")
13963 (set_attr "mode" "XF")])
13965 (define_expand "logxf2"
13966 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13967 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13968 (match_dup 2)] UNSPEC_FYL2X))
13969 (clobber (match_scratch:XF 3 ""))])]
13970 "TARGET_USE_FANCY_MATH_387
13971 && flag_unsafe_math_optimizations"
13973 operands[2] = gen_reg_rtx (XFmode);
13974 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13977 (define_expand "log<mode>2"
13978 [(use (match_operand:MODEF 0 "register_operand" ""))
13979 (use (match_operand:MODEF 1 "register_operand" ""))]
13980 "TARGET_USE_FANCY_MATH_387
13981 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13982 || TARGET_MIX_SSE_I387)
13983 && flag_unsafe_math_optimizations"
13985 rtx op0 = gen_reg_rtx (XFmode);
13987 rtx op2 = gen_reg_rtx (XFmode);
13988 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13990 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13991 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13995 (define_expand "log10xf2"
13996 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13997 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13998 (match_dup 2)] UNSPEC_FYL2X))
13999 (clobber (match_scratch:XF 3 ""))])]
14000 "TARGET_USE_FANCY_MATH_387
14001 && flag_unsafe_math_optimizations"
14003 operands[2] = gen_reg_rtx (XFmode);
14004 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14007 (define_expand "log10<mode>2"
14008 [(use (match_operand:MODEF 0 "register_operand" ""))
14009 (use (match_operand:MODEF 1 "register_operand" ""))]
14010 "TARGET_USE_FANCY_MATH_387
14011 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14012 || TARGET_MIX_SSE_I387)
14013 && flag_unsafe_math_optimizations"
14015 rtx op0 = gen_reg_rtx (XFmode);
14017 rtx op2 = gen_reg_rtx (XFmode);
14018 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14020 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14021 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14025 (define_expand "log2xf2"
14026 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14027 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14028 (match_dup 2)] UNSPEC_FYL2X))
14029 (clobber (match_scratch:XF 3 ""))])]
14030 "TARGET_USE_FANCY_MATH_387
14031 && flag_unsafe_math_optimizations"
14033 operands[2] = gen_reg_rtx (XFmode);
14034 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14037 (define_expand "log2<mode>2"
14038 [(use (match_operand:MODEF 0 "register_operand" ""))
14039 (use (match_operand:MODEF 1 "register_operand" ""))]
14040 "TARGET_USE_FANCY_MATH_387
14041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14042 || TARGET_MIX_SSE_I387)
14043 && flag_unsafe_math_optimizations"
14045 rtx op0 = gen_reg_rtx (XFmode);
14047 rtx op2 = gen_reg_rtx (XFmode);
14048 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14050 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14051 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14055 (define_insn "fyl2xp1xf3_i387"
14056 [(set (match_operand:XF 0 "register_operand" "=f")
14057 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14058 (match_operand:XF 2 "register_operand" "u")]
14060 (clobber (match_scratch:XF 3 "=2"))]
14061 "TARGET_USE_FANCY_MATH_387
14062 && flag_unsafe_math_optimizations"
14064 [(set_attr "type" "fpspc")
14065 (set_attr "mode" "XF")])
14067 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14068 [(set (match_operand:XF 0 "register_operand" "=f")
14069 (unspec:XF [(float_extend:XF
14070 (match_operand:MODEF 1 "register_operand" "0"))
14071 (match_operand:XF 2 "register_operand" "u")]
14073 (clobber (match_scratch:XF 3 "=2"))]
14074 "TARGET_USE_FANCY_MATH_387
14075 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14076 || TARGET_MIX_SSE_I387)
14077 && flag_unsafe_math_optimizations"
14079 [(set_attr "type" "fpspc")
14080 (set_attr "mode" "XF")])
14082 (define_expand "log1pxf2"
14083 [(use (match_operand:XF 0 "register_operand" ""))
14084 (use (match_operand:XF 1 "register_operand" ""))]
14085 "TARGET_USE_FANCY_MATH_387
14086 && flag_unsafe_math_optimizations"
14088 if (optimize_insn_for_size_p ())
14091 ix86_emit_i387_log1p (operands[0], operands[1]);
14095 (define_expand "log1p<mode>2"
14096 [(use (match_operand:MODEF 0 "register_operand" ""))
14097 (use (match_operand:MODEF 1 "register_operand" ""))]
14098 "TARGET_USE_FANCY_MATH_387
14099 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14100 || TARGET_MIX_SSE_I387)
14101 && flag_unsafe_math_optimizations"
14105 if (optimize_insn_for_size_p ())
14108 op0 = gen_reg_rtx (XFmode);
14110 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14112 ix86_emit_i387_log1p (op0, operands[1]);
14113 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14117 (define_insn "fxtractxf3_i387"
14118 [(set (match_operand:XF 0 "register_operand" "=f")
14119 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14120 UNSPEC_XTRACT_FRACT))
14121 (set (match_operand:XF 1 "register_operand" "=u")
14122 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14123 "TARGET_USE_FANCY_MATH_387
14124 && flag_unsafe_math_optimizations"
14126 [(set_attr "type" "fpspc")
14127 (set_attr "mode" "XF")])
14129 (define_insn "fxtract_extend<mode>xf3_i387"
14130 [(set (match_operand:XF 0 "register_operand" "=f")
14131 (unspec:XF [(float_extend:XF
14132 (match_operand:MODEF 2 "register_operand" "0"))]
14133 UNSPEC_XTRACT_FRACT))
14134 (set (match_operand:XF 1 "register_operand" "=u")
14135 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14136 "TARGET_USE_FANCY_MATH_387
14137 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14138 || TARGET_MIX_SSE_I387)
14139 && flag_unsafe_math_optimizations"
14141 [(set_attr "type" "fpspc")
14142 (set_attr "mode" "XF")])
14144 (define_expand "logbxf2"
14145 [(parallel [(set (match_dup 2)
14146 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14147 UNSPEC_XTRACT_FRACT))
14148 (set (match_operand:XF 0 "register_operand" "")
14149 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14150 "TARGET_USE_FANCY_MATH_387
14151 && flag_unsafe_math_optimizations"
14152 "operands[2] = gen_reg_rtx (XFmode);")
14154 (define_expand "logb<mode>2"
14155 [(use (match_operand:MODEF 0 "register_operand" ""))
14156 (use (match_operand:MODEF 1 "register_operand" ""))]
14157 "TARGET_USE_FANCY_MATH_387
14158 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14159 || TARGET_MIX_SSE_I387)
14160 && flag_unsafe_math_optimizations"
14162 rtx op0 = gen_reg_rtx (XFmode);
14163 rtx op1 = gen_reg_rtx (XFmode);
14165 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14166 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14170 (define_expand "ilogbxf2"
14171 [(use (match_operand:SI 0 "register_operand" ""))
14172 (use (match_operand:XF 1 "register_operand" ""))]
14173 "TARGET_USE_FANCY_MATH_387
14174 && flag_unsafe_math_optimizations"
14178 if (optimize_insn_for_size_p ())
14181 op0 = gen_reg_rtx (XFmode);
14182 op1 = gen_reg_rtx (XFmode);
14184 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14185 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14189 (define_expand "ilogb<mode>2"
14190 [(use (match_operand:SI 0 "register_operand" ""))
14191 (use (match_operand:MODEF 1 "register_operand" ""))]
14192 "TARGET_USE_FANCY_MATH_387
14193 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14194 || TARGET_MIX_SSE_I387)
14195 && flag_unsafe_math_optimizations"
14199 if (optimize_insn_for_size_p ())
14202 op0 = gen_reg_rtx (XFmode);
14203 op1 = gen_reg_rtx (XFmode);
14205 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14206 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14210 (define_insn "*f2xm1xf2_i387"
14211 [(set (match_operand:XF 0 "register_operand" "=f")
14212 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14214 "TARGET_USE_FANCY_MATH_387
14215 && flag_unsafe_math_optimizations"
14217 [(set_attr "type" "fpspc")
14218 (set_attr "mode" "XF")])
14220 (define_insn "*fscalexf4_i387"
14221 [(set (match_operand:XF 0 "register_operand" "=f")
14222 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14223 (match_operand:XF 3 "register_operand" "1")]
14224 UNSPEC_FSCALE_FRACT))
14225 (set (match_operand:XF 1 "register_operand" "=u")
14226 (unspec:XF [(match_dup 2) (match_dup 3)]
14227 UNSPEC_FSCALE_EXP))]
14228 "TARGET_USE_FANCY_MATH_387
14229 && flag_unsafe_math_optimizations"
14231 [(set_attr "type" "fpspc")
14232 (set_attr "mode" "XF")])
14234 (define_expand "expNcorexf3"
14235 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14236 (match_operand:XF 2 "register_operand" "")))
14237 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14238 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14239 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14240 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14241 (parallel [(set (match_operand:XF 0 "register_operand" "")
14242 (unspec:XF [(match_dup 8) (match_dup 4)]
14243 UNSPEC_FSCALE_FRACT))
14245 (unspec:XF [(match_dup 8) (match_dup 4)]
14246 UNSPEC_FSCALE_EXP))])]
14247 "TARGET_USE_FANCY_MATH_387
14248 && flag_unsafe_math_optimizations"
14252 if (optimize_insn_for_size_p ())
14255 for (i = 3; i < 10; i++)
14256 operands[i] = gen_reg_rtx (XFmode);
14258 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14261 (define_expand "expxf2"
14262 [(use (match_operand:XF 0 "register_operand" ""))
14263 (use (match_operand:XF 1 "register_operand" ""))]
14264 "TARGET_USE_FANCY_MATH_387
14265 && flag_unsafe_math_optimizations"
14269 if (optimize_insn_for_size_p ())
14272 op2 = gen_reg_rtx (XFmode);
14273 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14275 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14279 (define_expand "exp<mode>2"
14280 [(use (match_operand:MODEF 0 "register_operand" ""))
14281 (use (match_operand:MODEF 1 "general_operand" ""))]
14282 "TARGET_USE_FANCY_MATH_387
14283 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14284 || TARGET_MIX_SSE_I387)
14285 && flag_unsafe_math_optimizations"
14289 if (optimize_insn_for_size_p ())
14292 op0 = gen_reg_rtx (XFmode);
14293 op1 = gen_reg_rtx (XFmode);
14295 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14296 emit_insn (gen_expxf2 (op0, op1));
14297 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14301 (define_expand "exp10xf2"
14302 [(use (match_operand:XF 0 "register_operand" ""))
14303 (use (match_operand:XF 1 "register_operand" ""))]
14304 "TARGET_USE_FANCY_MATH_387
14305 && flag_unsafe_math_optimizations"
14309 if (optimize_insn_for_size_p ())
14312 op2 = gen_reg_rtx (XFmode);
14313 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14315 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14319 (define_expand "exp10<mode>2"
14320 [(use (match_operand:MODEF 0 "register_operand" ""))
14321 (use (match_operand:MODEF 1 "general_operand" ""))]
14322 "TARGET_USE_FANCY_MATH_387
14323 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14324 || TARGET_MIX_SSE_I387)
14325 && flag_unsafe_math_optimizations"
14329 if (optimize_insn_for_size_p ())
14332 op0 = gen_reg_rtx (XFmode);
14333 op1 = gen_reg_rtx (XFmode);
14335 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14336 emit_insn (gen_exp10xf2 (op0, op1));
14337 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14341 (define_expand "exp2xf2"
14342 [(use (match_operand:XF 0 "register_operand" ""))
14343 (use (match_operand:XF 1 "register_operand" ""))]
14344 "TARGET_USE_FANCY_MATH_387
14345 && flag_unsafe_math_optimizations"
14349 if (optimize_insn_for_size_p ())
14352 op2 = gen_reg_rtx (XFmode);
14353 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14355 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14359 (define_expand "exp2<mode>2"
14360 [(use (match_operand:MODEF 0 "register_operand" ""))
14361 (use (match_operand:MODEF 1 "general_operand" ""))]
14362 "TARGET_USE_FANCY_MATH_387
14363 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14364 || TARGET_MIX_SSE_I387)
14365 && flag_unsafe_math_optimizations"
14369 if (optimize_insn_for_size_p ())
14372 op0 = gen_reg_rtx (XFmode);
14373 op1 = gen_reg_rtx (XFmode);
14375 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14376 emit_insn (gen_exp2xf2 (op0, op1));
14377 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14381 (define_expand "expm1xf2"
14382 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14384 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14385 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14386 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14387 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14388 (parallel [(set (match_dup 7)
14389 (unspec:XF [(match_dup 6) (match_dup 4)]
14390 UNSPEC_FSCALE_FRACT))
14392 (unspec:XF [(match_dup 6) (match_dup 4)]
14393 UNSPEC_FSCALE_EXP))])
14394 (parallel [(set (match_dup 10)
14395 (unspec:XF [(match_dup 9) (match_dup 8)]
14396 UNSPEC_FSCALE_FRACT))
14397 (set (match_dup 11)
14398 (unspec:XF [(match_dup 9) (match_dup 8)]
14399 UNSPEC_FSCALE_EXP))])
14400 (set (match_dup 12) (minus:XF (match_dup 10)
14401 (float_extend:XF (match_dup 13))))
14402 (set (match_operand:XF 0 "register_operand" "")
14403 (plus:XF (match_dup 12) (match_dup 7)))]
14404 "TARGET_USE_FANCY_MATH_387
14405 && flag_unsafe_math_optimizations"
14409 if (optimize_insn_for_size_p ())
14412 for (i = 2; i < 13; i++)
14413 operands[i] = gen_reg_rtx (XFmode);
14416 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14418 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14421 (define_expand "expm1<mode>2"
14422 [(use (match_operand:MODEF 0 "register_operand" ""))
14423 (use (match_operand:MODEF 1 "general_operand" ""))]
14424 "TARGET_USE_FANCY_MATH_387
14425 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14426 || TARGET_MIX_SSE_I387)
14427 && flag_unsafe_math_optimizations"
14431 if (optimize_insn_for_size_p ())
14434 op0 = gen_reg_rtx (XFmode);
14435 op1 = gen_reg_rtx (XFmode);
14437 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14438 emit_insn (gen_expm1xf2 (op0, op1));
14439 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14443 (define_expand "ldexpxf3"
14444 [(set (match_dup 3)
14445 (float:XF (match_operand:SI 2 "register_operand" "")))
14446 (parallel [(set (match_operand:XF 0 " register_operand" "")
14447 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14449 UNSPEC_FSCALE_FRACT))
14451 (unspec:XF [(match_dup 1) (match_dup 3)]
14452 UNSPEC_FSCALE_EXP))])]
14453 "TARGET_USE_FANCY_MATH_387
14454 && flag_unsafe_math_optimizations"
14456 if (optimize_insn_for_size_p ())
14459 operands[3] = gen_reg_rtx (XFmode);
14460 operands[4] = gen_reg_rtx (XFmode);
14463 (define_expand "ldexp<mode>3"
14464 [(use (match_operand:MODEF 0 "register_operand" ""))
14465 (use (match_operand:MODEF 1 "general_operand" ""))
14466 (use (match_operand:SI 2 "register_operand" ""))]
14467 "TARGET_USE_FANCY_MATH_387
14468 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14469 || TARGET_MIX_SSE_I387)
14470 && flag_unsafe_math_optimizations"
14474 if (optimize_insn_for_size_p ())
14477 op0 = gen_reg_rtx (XFmode);
14478 op1 = gen_reg_rtx (XFmode);
14480 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14481 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14482 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14486 (define_expand "scalbxf3"
14487 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14488 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14489 (match_operand:XF 2 "register_operand" "")]
14490 UNSPEC_FSCALE_FRACT))
14492 (unspec:XF [(match_dup 1) (match_dup 2)]
14493 UNSPEC_FSCALE_EXP))])]
14494 "TARGET_USE_FANCY_MATH_387
14495 && flag_unsafe_math_optimizations"
14497 if (optimize_insn_for_size_p ())
14500 operands[3] = gen_reg_rtx (XFmode);
14503 (define_expand "scalb<mode>3"
14504 [(use (match_operand:MODEF 0 "register_operand" ""))
14505 (use (match_operand:MODEF 1 "general_operand" ""))
14506 (use (match_operand:MODEF 2 "general_operand" ""))]
14507 "TARGET_USE_FANCY_MATH_387
14508 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14509 || TARGET_MIX_SSE_I387)
14510 && flag_unsafe_math_optimizations"
14514 if (optimize_insn_for_size_p ())
14517 op0 = gen_reg_rtx (XFmode);
14518 op1 = gen_reg_rtx (XFmode);
14519 op2 = gen_reg_rtx (XFmode);
14521 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14522 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14523 emit_insn (gen_scalbxf3 (op0, op1, op2));
14524 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14528 (define_expand "significandxf2"
14529 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14530 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14531 UNSPEC_XTRACT_FRACT))
14533 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14534 "TARGET_USE_FANCY_MATH_387
14535 && flag_unsafe_math_optimizations"
14536 "operands[2] = gen_reg_rtx (XFmode);")
14538 (define_expand "significand<mode>2"
14539 [(use (match_operand:MODEF 0 "register_operand" ""))
14540 (use (match_operand:MODEF 1 "register_operand" ""))]
14541 "TARGET_USE_FANCY_MATH_387
14542 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14543 || TARGET_MIX_SSE_I387)
14544 && flag_unsafe_math_optimizations"
14546 rtx op0 = gen_reg_rtx (XFmode);
14547 rtx op1 = gen_reg_rtx (XFmode);
14549 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14550 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14555 (define_insn "sse4_1_round<mode>2"
14556 [(set (match_operand:MODEF 0 "register_operand" "=x")
14557 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14558 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14561 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14562 [(set_attr "type" "ssecvt")
14563 (set_attr "prefix_extra" "1")
14564 (set_attr "prefix" "maybe_vex")
14565 (set_attr "mode" "<MODE>")])
14567 (define_insn "rintxf2"
14568 [(set (match_operand:XF 0 "register_operand" "=f")
14569 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14571 "TARGET_USE_FANCY_MATH_387
14572 && flag_unsafe_math_optimizations"
14574 [(set_attr "type" "fpspc")
14575 (set_attr "mode" "XF")])
14577 (define_expand "rint<mode>2"
14578 [(use (match_operand:MODEF 0 "register_operand" ""))
14579 (use (match_operand:MODEF 1 "register_operand" ""))]
14580 "(TARGET_USE_FANCY_MATH_387
14581 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14582 || TARGET_MIX_SSE_I387)
14583 && flag_unsafe_math_optimizations)
14584 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14585 && !flag_trapping_math)"
14587 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14588 && !flag_trapping_math)
14591 emit_insn (gen_sse4_1_round<mode>2
14592 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14593 else if (optimize_insn_for_size_p ())
14596 ix86_expand_rint (operands[0], operands[1]);
14600 rtx op0 = gen_reg_rtx (XFmode);
14601 rtx op1 = gen_reg_rtx (XFmode);
14603 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14604 emit_insn (gen_rintxf2 (op0, op1));
14606 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14611 (define_expand "round<mode>2"
14612 [(match_operand:X87MODEF 0 "register_operand" "")
14613 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14614 "(TARGET_USE_FANCY_MATH_387
14615 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14616 || TARGET_MIX_SSE_I387)
14617 && flag_unsafe_math_optimizations)
14618 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14619 && !flag_trapping_math && !flag_rounding_math)"
14621 if (optimize_insn_for_size_p ())
14624 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14625 && !flag_trapping_math && !flag_rounding_math)
14629 operands[1] = force_reg (<MODE>mode, operands[1]);
14630 ix86_expand_round_sse4 (operands[0], operands[1]);
14632 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14633 ix86_expand_round (operands[0], operands[1]);
14635 ix86_expand_rounddf_32 (operands[0], operands[1]);
14639 operands[1] = force_reg (<MODE>mode, operands[1]);
14640 ix86_emit_i387_round (operands[0], operands[1]);
14645 (define_insn_and_split "*fistdi2_1"
14646 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14647 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14649 "TARGET_USE_FANCY_MATH_387
14650 && can_create_pseudo_p ()"
14655 if (memory_operand (operands[0], VOIDmode))
14656 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14659 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14660 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14665 [(set_attr "type" "fpspc")
14666 (set_attr "mode" "DI")])
14668 (define_insn "fistdi2"
14669 [(set (match_operand:DI 0 "memory_operand" "=m")
14670 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14672 (clobber (match_scratch:XF 2 "=&1f"))]
14673 "TARGET_USE_FANCY_MATH_387"
14674 "* return output_fix_trunc (insn, operands, false);"
14675 [(set_attr "type" "fpspc")
14676 (set_attr "mode" "DI")])
14678 (define_insn "fistdi2_with_temp"
14679 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14680 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14682 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14683 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14684 "TARGET_USE_FANCY_MATH_387"
14686 [(set_attr "type" "fpspc")
14687 (set_attr "mode" "DI")])
14690 [(set (match_operand:DI 0 "register_operand" "")
14691 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14693 (clobber (match_operand:DI 2 "memory_operand" ""))
14694 (clobber (match_scratch 3 ""))]
14696 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14697 (clobber (match_dup 3))])
14698 (set (match_dup 0) (match_dup 2))])
14701 [(set (match_operand:DI 0 "memory_operand" "")
14702 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14704 (clobber (match_operand:DI 2 "memory_operand" ""))
14705 (clobber (match_scratch 3 ""))]
14707 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14708 (clobber (match_dup 3))])])
14710 (define_insn_and_split "*fist<mode>2_1"
14711 [(set (match_operand:SWI24 0 "register_operand" "")
14712 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14714 "TARGET_USE_FANCY_MATH_387
14715 && can_create_pseudo_p ()"
14720 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14721 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14725 [(set_attr "type" "fpspc")
14726 (set_attr "mode" "<MODE>")])
14728 (define_insn "fist<mode>2"
14729 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14730 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14732 "TARGET_USE_FANCY_MATH_387"
14733 "* return output_fix_trunc (insn, operands, false);"
14734 [(set_attr "type" "fpspc")
14735 (set_attr "mode" "<MODE>")])
14737 (define_insn "fist<mode>2_with_temp"
14738 [(set (match_operand:SWI24 0 "register_operand" "=r")
14739 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14741 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14742 "TARGET_USE_FANCY_MATH_387"
14744 [(set_attr "type" "fpspc")
14745 (set_attr "mode" "<MODE>")])
14748 [(set (match_operand:SWI24 0 "register_operand" "")
14749 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14751 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14753 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14754 (set (match_dup 0) (match_dup 2))])
14757 [(set (match_operand:SWI24 0 "memory_operand" "")
14758 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14760 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14762 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14764 (define_expand "lrintxf<mode>2"
14765 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14766 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14768 "TARGET_USE_FANCY_MATH_387")
14770 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14771 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14772 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14773 UNSPEC_FIX_NOTRUNC))]
14774 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14775 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14777 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14778 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14779 (match_operand:X87MODEF 1 "register_operand" "")]
14780 "(TARGET_USE_FANCY_MATH_387
14781 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14782 || TARGET_MIX_SSE_I387)
14783 && flag_unsafe_math_optimizations)
14784 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14785 && <SWI248x:MODE>mode != HImode
14786 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14787 && !flag_trapping_math && !flag_rounding_math)"
14789 if (optimize_insn_for_size_p ())
14792 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14793 && <SWI248x:MODE>mode != HImode
14794 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14795 && !flag_trapping_math && !flag_rounding_math)
14796 ix86_expand_lround (operands[0], operands[1]);
14798 ix86_emit_i387_round (operands[0], operands[1]);
14802 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14803 (define_insn_and_split "frndintxf2_floor"
14804 [(set (match_operand:XF 0 "register_operand" "")
14805 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14806 UNSPEC_FRNDINT_FLOOR))
14807 (clobber (reg:CC FLAGS_REG))]
14808 "TARGET_USE_FANCY_MATH_387
14809 && flag_unsafe_math_optimizations
14810 && can_create_pseudo_p ()"
14815 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14817 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14818 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14820 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14821 operands[2], operands[3]));
14824 [(set_attr "type" "frndint")
14825 (set_attr "i387_cw" "floor")
14826 (set_attr "mode" "XF")])
14828 (define_insn "frndintxf2_floor_i387"
14829 [(set (match_operand:XF 0 "register_operand" "=f")
14830 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14831 UNSPEC_FRNDINT_FLOOR))
14832 (use (match_operand:HI 2 "memory_operand" "m"))
14833 (use (match_operand:HI 3 "memory_operand" "m"))]
14834 "TARGET_USE_FANCY_MATH_387
14835 && flag_unsafe_math_optimizations"
14836 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14837 [(set_attr "type" "frndint")
14838 (set_attr "i387_cw" "floor")
14839 (set_attr "mode" "XF")])
14841 (define_expand "floorxf2"
14842 [(use (match_operand:XF 0 "register_operand" ""))
14843 (use (match_operand:XF 1 "register_operand" ""))]
14844 "TARGET_USE_FANCY_MATH_387
14845 && flag_unsafe_math_optimizations"
14847 if (optimize_insn_for_size_p ())
14849 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14853 (define_expand "floor<mode>2"
14854 [(use (match_operand:MODEF 0 "register_operand" ""))
14855 (use (match_operand:MODEF 1 "register_operand" ""))]
14856 "(TARGET_USE_FANCY_MATH_387
14857 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14858 || TARGET_MIX_SSE_I387)
14859 && flag_unsafe_math_optimizations)
14860 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14861 && !flag_trapping_math)"
14863 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14864 && !flag_trapping_math)
14867 emit_insn (gen_sse4_1_round<mode>2
14868 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14869 else if (optimize_insn_for_size_p ())
14871 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14872 ix86_expand_floorceil (operands[0], operands[1], true);
14874 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14880 if (optimize_insn_for_size_p ())
14883 op0 = gen_reg_rtx (XFmode);
14884 op1 = gen_reg_rtx (XFmode);
14885 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14886 emit_insn (gen_frndintxf2_floor (op0, op1));
14888 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14893 (define_insn_and_split "*fist<mode>2_floor_1"
14894 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14895 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14896 UNSPEC_FIST_FLOOR))
14897 (clobber (reg:CC FLAGS_REG))]
14898 "TARGET_USE_FANCY_MATH_387
14899 && flag_unsafe_math_optimizations
14900 && can_create_pseudo_p ()"
14905 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14907 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14908 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14909 if (memory_operand (operands[0], VOIDmode))
14910 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14911 operands[2], operands[3]));
14914 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14915 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14916 operands[2], operands[3],
14921 [(set_attr "type" "fistp")
14922 (set_attr "i387_cw" "floor")
14923 (set_attr "mode" "<MODE>")])
14925 (define_insn "fistdi2_floor"
14926 [(set (match_operand:DI 0 "memory_operand" "=m")
14927 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14928 UNSPEC_FIST_FLOOR))
14929 (use (match_operand:HI 2 "memory_operand" "m"))
14930 (use (match_operand:HI 3 "memory_operand" "m"))
14931 (clobber (match_scratch:XF 4 "=&1f"))]
14932 "TARGET_USE_FANCY_MATH_387
14933 && flag_unsafe_math_optimizations"
14934 "* return output_fix_trunc (insn, operands, false);"
14935 [(set_attr "type" "fistp")
14936 (set_attr "i387_cw" "floor")
14937 (set_attr "mode" "DI")])
14939 (define_insn "fistdi2_floor_with_temp"
14940 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14941 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14942 UNSPEC_FIST_FLOOR))
14943 (use (match_operand:HI 2 "memory_operand" "m,m"))
14944 (use (match_operand:HI 3 "memory_operand" "m,m"))
14945 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14946 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14947 "TARGET_USE_FANCY_MATH_387
14948 && flag_unsafe_math_optimizations"
14950 [(set_attr "type" "fistp")
14951 (set_attr "i387_cw" "floor")
14952 (set_attr "mode" "DI")])
14955 [(set (match_operand:DI 0 "register_operand" "")
14956 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14957 UNSPEC_FIST_FLOOR))
14958 (use (match_operand:HI 2 "memory_operand" ""))
14959 (use (match_operand:HI 3 "memory_operand" ""))
14960 (clobber (match_operand:DI 4 "memory_operand" ""))
14961 (clobber (match_scratch 5 ""))]
14963 [(parallel [(set (match_dup 4)
14964 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14965 (use (match_dup 2))
14966 (use (match_dup 3))
14967 (clobber (match_dup 5))])
14968 (set (match_dup 0) (match_dup 4))])
14971 [(set (match_operand:DI 0 "memory_operand" "")
14972 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14973 UNSPEC_FIST_FLOOR))
14974 (use (match_operand:HI 2 "memory_operand" ""))
14975 (use (match_operand:HI 3 "memory_operand" ""))
14976 (clobber (match_operand:DI 4 "memory_operand" ""))
14977 (clobber (match_scratch 5 ""))]
14979 [(parallel [(set (match_dup 0)
14980 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14981 (use (match_dup 2))
14982 (use (match_dup 3))
14983 (clobber (match_dup 5))])])
14985 (define_insn "fist<mode>2_floor"
14986 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14987 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14988 UNSPEC_FIST_FLOOR))
14989 (use (match_operand:HI 2 "memory_operand" "m"))
14990 (use (match_operand:HI 3 "memory_operand" "m"))]
14991 "TARGET_USE_FANCY_MATH_387
14992 && flag_unsafe_math_optimizations"
14993 "* return output_fix_trunc (insn, operands, false);"
14994 [(set_attr "type" "fistp")
14995 (set_attr "i387_cw" "floor")
14996 (set_attr "mode" "<MODE>")])
14998 (define_insn "fist<mode>2_floor_with_temp"
14999 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15000 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15001 UNSPEC_FIST_FLOOR))
15002 (use (match_operand:HI 2 "memory_operand" "m,m"))
15003 (use (match_operand:HI 3 "memory_operand" "m,m"))
15004 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15005 "TARGET_USE_FANCY_MATH_387
15006 && flag_unsafe_math_optimizations"
15008 [(set_attr "type" "fistp")
15009 (set_attr "i387_cw" "floor")
15010 (set_attr "mode" "<MODE>")])
15013 [(set (match_operand:SWI24 0 "register_operand" "")
15014 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15015 UNSPEC_FIST_FLOOR))
15016 (use (match_operand:HI 2 "memory_operand" ""))
15017 (use (match_operand:HI 3 "memory_operand" ""))
15018 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15020 [(parallel [(set (match_dup 4)
15021 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15022 (use (match_dup 2))
15023 (use (match_dup 3))])
15024 (set (match_dup 0) (match_dup 4))])
15027 [(set (match_operand:SWI24 0 "memory_operand" "")
15028 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15029 UNSPEC_FIST_FLOOR))
15030 (use (match_operand:HI 2 "memory_operand" ""))
15031 (use (match_operand:HI 3 "memory_operand" ""))
15032 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15034 [(parallel [(set (match_dup 0)
15035 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15036 (use (match_dup 2))
15037 (use (match_dup 3))])])
15039 (define_expand "lfloorxf<mode>2"
15040 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15041 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15042 UNSPEC_FIST_FLOOR))
15043 (clobber (reg:CC FLAGS_REG))])]
15044 "TARGET_USE_FANCY_MATH_387
15045 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15046 && flag_unsafe_math_optimizations")
15048 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15049 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15050 (match_operand:MODEF 1 "register_operand" "")]
15051 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15052 && !flag_trapping_math"
15054 if (TARGET_64BIT && optimize_insn_for_size_p ())
15056 ix86_expand_lfloorceil (operands[0], operands[1], true);
15060 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15061 (define_insn_and_split "frndintxf2_ceil"
15062 [(set (match_operand:XF 0 "register_operand" "")
15063 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15064 UNSPEC_FRNDINT_CEIL))
15065 (clobber (reg:CC FLAGS_REG))]
15066 "TARGET_USE_FANCY_MATH_387
15067 && flag_unsafe_math_optimizations
15068 && can_create_pseudo_p ()"
15073 ix86_optimize_mode_switching[I387_CEIL] = 1;
15075 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15076 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15078 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15079 operands[2], operands[3]));
15082 [(set_attr "type" "frndint")
15083 (set_attr "i387_cw" "ceil")
15084 (set_attr "mode" "XF")])
15086 (define_insn "frndintxf2_ceil_i387"
15087 [(set (match_operand:XF 0 "register_operand" "=f")
15088 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15089 UNSPEC_FRNDINT_CEIL))
15090 (use (match_operand:HI 2 "memory_operand" "m"))
15091 (use (match_operand:HI 3 "memory_operand" "m"))]
15092 "TARGET_USE_FANCY_MATH_387
15093 && flag_unsafe_math_optimizations"
15094 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15095 [(set_attr "type" "frndint")
15096 (set_attr "i387_cw" "ceil")
15097 (set_attr "mode" "XF")])
15099 (define_expand "ceilxf2"
15100 [(use (match_operand:XF 0 "register_operand" ""))
15101 (use (match_operand:XF 1 "register_operand" ""))]
15102 "TARGET_USE_FANCY_MATH_387
15103 && flag_unsafe_math_optimizations"
15105 if (optimize_insn_for_size_p ())
15107 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15111 (define_expand "ceil<mode>2"
15112 [(use (match_operand:MODEF 0 "register_operand" ""))
15113 (use (match_operand:MODEF 1 "register_operand" ""))]
15114 "(TARGET_USE_FANCY_MATH_387
15115 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15116 || TARGET_MIX_SSE_I387)
15117 && flag_unsafe_math_optimizations)
15118 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15119 && !flag_trapping_math)"
15121 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15122 && !flag_trapping_math)
15125 emit_insn (gen_sse4_1_round<mode>2
15126 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15127 else if (optimize_insn_for_size_p ())
15129 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15130 ix86_expand_floorceil (operands[0], operands[1], false);
15132 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15138 if (optimize_insn_for_size_p ())
15141 op0 = gen_reg_rtx (XFmode);
15142 op1 = gen_reg_rtx (XFmode);
15143 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15144 emit_insn (gen_frndintxf2_ceil (op0, op1));
15146 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15151 (define_insn_and_split "*fist<mode>2_ceil_1"
15152 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15153 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15155 (clobber (reg:CC FLAGS_REG))]
15156 "TARGET_USE_FANCY_MATH_387
15157 && flag_unsafe_math_optimizations
15158 && can_create_pseudo_p ()"
15163 ix86_optimize_mode_switching[I387_CEIL] = 1;
15165 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15166 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15167 if (memory_operand (operands[0], VOIDmode))
15168 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15169 operands[2], operands[3]));
15172 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15173 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15174 operands[2], operands[3],
15179 [(set_attr "type" "fistp")
15180 (set_attr "i387_cw" "ceil")
15181 (set_attr "mode" "<MODE>")])
15183 (define_insn "fistdi2_ceil"
15184 [(set (match_operand:DI 0 "memory_operand" "=m")
15185 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15187 (use (match_operand:HI 2 "memory_operand" "m"))
15188 (use (match_operand:HI 3 "memory_operand" "m"))
15189 (clobber (match_scratch:XF 4 "=&1f"))]
15190 "TARGET_USE_FANCY_MATH_387
15191 && flag_unsafe_math_optimizations"
15192 "* return output_fix_trunc (insn, operands, false);"
15193 [(set_attr "type" "fistp")
15194 (set_attr "i387_cw" "ceil")
15195 (set_attr "mode" "DI")])
15197 (define_insn "fistdi2_ceil_with_temp"
15198 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15199 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15201 (use (match_operand:HI 2 "memory_operand" "m,m"))
15202 (use (match_operand:HI 3 "memory_operand" "m,m"))
15203 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15204 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15205 "TARGET_USE_FANCY_MATH_387
15206 && flag_unsafe_math_optimizations"
15208 [(set_attr "type" "fistp")
15209 (set_attr "i387_cw" "ceil")
15210 (set_attr "mode" "DI")])
15213 [(set (match_operand:DI 0 "register_operand" "")
15214 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15216 (use (match_operand:HI 2 "memory_operand" ""))
15217 (use (match_operand:HI 3 "memory_operand" ""))
15218 (clobber (match_operand:DI 4 "memory_operand" ""))
15219 (clobber (match_scratch 5 ""))]
15221 [(parallel [(set (match_dup 4)
15222 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15223 (use (match_dup 2))
15224 (use (match_dup 3))
15225 (clobber (match_dup 5))])
15226 (set (match_dup 0) (match_dup 4))])
15229 [(set (match_operand:DI 0 "memory_operand" "")
15230 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15232 (use (match_operand:HI 2 "memory_operand" ""))
15233 (use (match_operand:HI 3 "memory_operand" ""))
15234 (clobber (match_operand:DI 4 "memory_operand" ""))
15235 (clobber (match_scratch 5 ""))]
15237 [(parallel [(set (match_dup 0)
15238 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15239 (use (match_dup 2))
15240 (use (match_dup 3))
15241 (clobber (match_dup 5))])])
15243 (define_insn "fist<mode>2_ceil"
15244 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15245 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15247 (use (match_operand:HI 2 "memory_operand" "m"))
15248 (use (match_operand:HI 3 "memory_operand" "m"))]
15249 "TARGET_USE_FANCY_MATH_387
15250 && flag_unsafe_math_optimizations"
15251 "* return output_fix_trunc (insn, operands, false);"
15252 [(set_attr "type" "fistp")
15253 (set_attr "i387_cw" "ceil")
15254 (set_attr "mode" "<MODE>")])
15256 (define_insn "fist<mode>2_ceil_with_temp"
15257 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15258 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15260 (use (match_operand:HI 2 "memory_operand" "m,m"))
15261 (use (match_operand:HI 3 "memory_operand" "m,m"))
15262 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15263 "TARGET_USE_FANCY_MATH_387
15264 && flag_unsafe_math_optimizations"
15266 [(set_attr "type" "fistp")
15267 (set_attr "i387_cw" "ceil")
15268 (set_attr "mode" "<MODE>")])
15271 [(set (match_operand:SWI24 0 "register_operand" "")
15272 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15274 (use (match_operand:HI 2 "memory_operand" ""))
15275 (use (match_operand:HI 3 "memory_operand" ""))
15276 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15278 [(parallel [(set (match_dup 4)
15279 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15280 (use (match_dup 2))
15281 (use (match_dup 3))])
15282 (set (match_dup 0) (match_dup 4))])
15285 [(set (match_operand:SWI24 0 "memory_operand" "")
15286 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15288 (use (match_operand:HI 2 "memory_operand" ""))
15289 (use (match_operand:HI 3 "memory_operand" ""))
15290 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15292 [(parallel [(set (match_dup 0)
15293 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15294 (use (match_dup 2))
15295 (use (match_dup 3))])])
15297 (define_expand "lceilxf<mode>2"
15298 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15299 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15301 (clobber (reg:CC FLAGS_REG))])]
15302 "TARGET_USE_FANCY_MATH_387
15303 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15304 && flag_unsafe_math_optimizations")
15306 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15307 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15308 (match_operand:MODEF 1 "register_operand" "")]
15309 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15310 && !flag_trapping_math"
15312 ix86_expand_lfloorceil (operands[0], operands[1], false);
15316 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15317 (define_insn_and_split "frndintxf2_trunc"
15318 [(set (match_operand:XF 0 "register_operand" "")
15319 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15320 UNSPEC_FRNDINT_TRUNC))
15321 (clobber (reg:CC FLAGS_REG))]
15322 "TARGET_USE_FANCY_MATH_387
15323 && flag_unsafe_math_optimizations
15324 && can_create_pseudo_p ()"
15329 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15331 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15332 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15334 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15335 operands[2], operands[3]));
15338 [(set_attr "type" "frndint")
15339 (set_attr "i387_cw" "trunc")
15340 (set_attr "mode" "XF")])
15342 (define_insn "frndintxf2_trunc_i387"
15343 [(set (match_operand:XF 0 "register_operand" "=f")
15344 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15345 UNSPEC_FRNDINT_TRUNC))
15346 (use (match_operand:HI 2 "memory_operand" "m"))
15347 (use (match_operand:HI 3 "memory_operand" "m"))]
15348 "TARGET_USE_FANCY_MATH_387
15349 && flag_unsafe_math_optimizations"
15350 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15351 [(set_attr "type" "frndint")
15352 (set_attr "i387_cw" "trunc")
15353 (set_attr "mode" "XF")])
15355 (define_expand "btruncxf2"
15356 [(use (match_operand:XF 0 "register_operand" ""))
15357 (use (match_operand:XF 1 "register_operand" ""))]
15358 "TARGET_USE_FANCY_MATH_387
15359 && flag_unsafe_math_optimizations"
15361 if (optimize_insn_for_size_p ())
15363 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15367 (define_expand "btrunc<mode>2"
15368 [(use (match_operand:MODEF 0 "register_operand" ""))
15369 (use (match_operand:MODEF 1 "register_operand" ""))]
15370 "(TARGET_USE_FANCY_MATH_387
15371 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15372 || TARGET_MIX_SSE_I387)
15373 && flag_unsafe_math_optimizations)
15374 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15375 && !flag_trapping_math)"
15377 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15378 && !flag_trapping_math)
15381 emit_insn (gen_sse4_1_round<mode>2
15382 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15383 else if (optimize_insn_for_size_p ())
15385 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15386 ix86_expand_trunc (operands[0], operands[1]);
15388 ix86_expand_truncdf_32 (operands[0], operands[1]);
15394 if (optimize_insn_for_size_p ())
15397 op0 = gen_reg_rtx (XFmode);
15398 op1 = gen_reg_rtx (XFmode);
15399 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15400 emit_insn (gen_frndintxf2_trunc (op0, op1));
15402 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15407 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15408 (define_insn_and_split "frndintxf2_mask_pm"
15409 [(set (match_operand:XF 0 "register_operand" "")
15410 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15411 UNSPEC_FRNDINT_MASK_PM))
15412 (clobber (reg:CC FLAGS_REG))]
15413 "TARGET_USE_FANCY_MATH_387
15414 && flag_unsafe_math_optimizations
15415 && can_create_pseudo_p ()"
15420 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15422 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15423 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15425 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15426 operands[2], operands[3]));
15429 [(set_attr "type" "frndint")
15430 (set_attr "i387_cw" "mask_pm")
15431 (set_attr "mode" "XF")])
15433 (define_insn "frndintxf2_mask_pm_i387"
15434 [(set (match_operand:XF 0 "register_operand" "=f")
15435 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15436 UNSPEC_FRNDINT_MASK_PM))
15437 (use (match_operand:HI 2 "memory_operand" "m"))
15438 (use (match_operand:HI 3 "memory_operand" "m"))]
15439 "TARGET_USE_FANCY_MATH_387
15440 && flag_unsafe_math_optimizations"
15441 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15442 [(set_attr "type" "frndint")
15443 (set_attr "i387_cw" "mask_pm")
15444 (set_attr "mode" "XF")])
15446 (define_expand "nearbyintxf2"
15447 [(use (match_operand:XF 0 "register_operand" ""))
15448 (use (match_operand:XF 1 "register_operand" ""))]
15449 "TARGET_USE_FANCY_MATH_387
15450 && flag_unsafe_math_optimizations"
15452 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15456 (define_expand "nearbyint<mode>2"
15457 [(use (match_operand:MODEF 0 "register_operand" ""))
15458 (use (match_operand:MODEF 1 "register_operand" ""))]
15459 "TARGET_USE_FANCY_MATH_387
15460 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15461 || TARGET_MIX_SSE_I387)
15462 && flag_unsafe_math_optimizations"
15464 rtx op0 = gen_reg_rtx (XFmode);
15465 rtx op1 = gen_reg_rtx (XFmode);
15467 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15468 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15470 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15474 (define_insn "fxam<mode>2_i387"
15475 [(set (match_operand:HI 0 "register_operand" "=a")
15477 [(match_operand:X87MODEF 1 "register_operand" "f")]
15479 "TARGET_USE_FANCY_MATH_387"
15480 "fxam\n\tfnstsw\t%0"
15481 [(set_attr "type" "multi")
15482 (set_attr "length" "4")
15483 (set_attr "unit" "i387")
15484 (set_attr "mode" "<MODE>")])
15486 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15487 [(set (match_operand:HI 0 "register_operand" "")
15489 [(match_operand:MODEF 1 "memory_operand" "")]
15491 "TARGET_USE_FANCY_MATH_387
15492 && can_create_pseudo_p ()"
15495 [(set (match_dup 2)(match_dup 1))
15497 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15499 operands[2] = gen_reg_rtx (<MODE>mode);
15501 MEM_VOLATILE_P (operands[1]) = 1;
15503 [(set_attr "type" "multi")
15504 (set_attr "unit" "i387")
15505 (set_attr "mode" "<MODE>")])
15507 (define_expand "isinfxf2"
15508 [(use (match_operand:SI 0 "register_operand" ""))
15509 (use (match_operand:XF 1 "register_operand" ""))]
15510 "TARGET_USE_FANCY_MATH_387
15511 && TARGET_C99_FUNCTIONS"
15513 rtx mask = GEN_INT (0x45);
15514 rtx val = GEN_INT (0x05);
15518 rtx scratch = gen_reg_rtx (HImode);
15519 rtx res = gen_reg_rtx (QImode);
15521 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15523 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15524 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15525 cond = gen_rtx_fmt_ee (EQ, QImode,
15526 gen_rtx_REG (CCmode, FLAGS_REG),
15528 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15529 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15533 (define_expand "isinf<mode>2"
15534 [(use (match_operand:SI 0 "register_operand" ""))
15535 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15536 "TARGET_USE_FANCY_MATH_387
15537 && TARGET_C99_FUNCTIONS
15538 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15540 rtx mask = GEN_INT (0x45);
15541 rtx val = GEN_INT (0x05);
15545 rtx scratch = gen_reg_rtx (HImode);
15546 rtx res = gen_reg_rtx (QImode);
15548 /* Remove excess precision by forcing value through memory. */
15549 if (memory_operand (operands[1], VOIDmode))
15550 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15553 enum ix86_stack_slot slot = (virtuals_instantiated
15556 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15558 emit_move_insn (temp, operands[1]);
15559 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15562 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15563 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15564 cond = gen_rtx_fmt_ee (EQ, QImode,
15565 gen_rtx_REG (CCmode, FLAGS_REG),
15567 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15568 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15572 (define_expand "signbitxf2"
15573 [(use (match_operand:SI 0 "register_operand" ""))
15574 (use (match_operand:XF 1 "register_operand" ""))]
15575 "TARGET_USE_FANCY_MATH_387"
15577 rtx scratch = gen_reg_rtx (HImode);
15579 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15580 emit_insn (gen_andsi3 (operands[0],
15581 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15585 (define_insn "movmsk_df"
15586 [(set (match_operand:SI 0 "register_operand" "=r")
15588 [(match_operand:DF 1 "register_operand" "x")]
15590 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15591 "%vmovmskpd\t{%1, %0|%0, %1}"
15592 [(set_attr "type" "ssemov")
15593 (set_attr "prefix" "maybe_vex")
15594 (set_attr "mode" "DF")])
15596 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15597 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15598 (define_expand "signbitdf2"
15599 [(use (match_operand:SI 0 "register_operand" ""))
15600 (use (match_operand:DF 1 "register_operand" ""))]
15601 "TARGET_USE_FANCY_MATH_387
15602 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15604 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15606 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15607 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15611 rtx scratch = gen_reg_rtx (HImode);
15613 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15614 emit_insn (gen_andsi3 (operands[0],
15615 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15620 (define_expand "signbitsf2"
15621 [(use (match_operand:SI 0 "register_operand" ""))
15622 (use (match_operand:SF 1 "register_operand" ""))]
15623 "TARGET_USE_FANCY_MATH_387
15624 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15626 rtx scratch = gen_reg_rtx (HImode);
15628 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15629 emit_insn (gen_andsi3 (operands[0],
15630 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15634 ;; Block operation instructions
15637 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15640 [(set_attr "length" "1")
15641 (set_attr "length_immediate" "0")
15642 (set_attr "modrm" "0")])
15644 (define_expand "movmem<mode>"
15645 [(use (match_operand:BLK 0 "memory_operand" ""))
15646 (use (match_operand:BLK 1 "memory_operand" ""))
15647 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15648 (use (match_operand:SWI48 3 "const_int_operand" ""))
15649 (use (match_operand:SI 4 "const_int_operand" ""))
15650 (use (match_operand:SI 5 "const_int_operand" ""))]
15653 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15654 operands[4], operands[5]))
15660 ;; Most CPUs don't like single string operations
15661 ;; Handle this case here to simplify previous expander.
15663 (define_expand "strmov"
15664 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15665 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15666 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15667 (clobber (reg:CC FLAGS_REG))])
15668 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15669 (clobber (reg:CC FLAGS_REG))])]
15672 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15674 /* If .md ever supports :P for Pmode, these can be directly
15675 in the pattern above. */
15676 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15677 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15679 /* Can't use this if the user has appropriated esi or edi. */
15680 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15681 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15683 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15684 operands[2], operands[3],
15685 operands[5], operands[6]));
15689 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15692 (define_expand "strmov_singleop"
15693 [(parallel [(set (match_operand 1 "memory_operand" "")
15694 (match_operand 3 "memory_operand" ""))
15695 (set (match_operand 0 "register_operand" "")
15696 (match_operand 4 "" ""))
15697 (set (match_operand 2 "register_operand" "")
15698 (match_operand 5 "" ""))])]
15700 "ix86_current_function_needs_cld = 1;")
15702 (define_insn "*strmovdi_rex_1"
15703 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15704 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15705 (set (match_operand:DI 0 "register_operand" "=D")
15706 (plus:DI (match_dup 2)
15708 (set (match_operand:DI 1 "register_operand" "=S")
15709 (plus:DI (match_dup 3)
15712 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15714 [(set_attr "type" "str")
15715 (set_attr "memory" "both")
15716 (set_attr "mode" "DI")])
15718 (define_insn "*strmovsi_1"
15719 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15720 (mem:SI (match_operand:P 3 "register_operand" "1")))
15721 (set (match_operand:P 0 "register_operand" "=D")
15722 (plus:P (match_dup 2)
15724 (set (match_operand:P 1 "register_operand" "=S")
15725 (plus:P (match_dup 3)
15727 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15729 [(set_attr "type" "str")
15730 (set_attr "memory" "both")
15731 (set_attr "mode" "SI")])
15733 (define_insn "*strmovhi_1"
15734 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15735 (mem:HI (match_operand:P 3 "register_operand" "1")))
15736 (set (match_operand:P 0 "register_operand" "=D")
15737 (plus:P (match_dup 2)
15739 (set (match_operand:P 1 "register_operand" "=S")
15740 (plus:P (match_dup 3)
15742 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15744 [(set_attr "type" "str")
15745 (set_attr "memory" "both")
15746 (set_attr "mode" "HI")])
15748 (define_insn "*strmovqi_1"
15749 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15750 (mem:QI (match_operand:P 3 "register_operand" "1")))
15751 (set (match_operand:P 0 "register_operand" "=D")
15752 (plus:P (match_dup 2)
15754 (set (match_operand:P 1 "register_operand" "=S")
15755 (plus:P (match_dup 3)
15757 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15759 [(set_attr "type" "str")
15760 (set_attr "memory" "both")
15761 (set (attr "prefix_rex")
15763 (match_test "<P:MODE>mode == DImode")
15765 (const_string "*")))
15766 (set_attr "mode" "QI")])
15768 (define_expand "rep_mov"
15769 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15770 (set (match_operand 0 "register_operand" "")
15771 (match_operand 5 "" ""))
15772 (set (match_operand 2 "register_operand" "")
15773 (match_operand 6 "" ""))
15774 (set (match_operand 1 "memory_operand" "")
15775 (match_operand 3 "memory_operand" ""))
15776 (use (match_dup 4))])]
15778 "ix86_current_function_needs_cld = 1;")
15780 (define_insn "*rep_movdi_rex64"
15781 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15782 (set (match_operand:DI 0 "register_operand" "=D")
15783 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15785 (match_operand:DI 3 "register_operand" "0")))
15786 (set (match_operand:DI 1 "register_operand" "=S")
15787 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15788 (match_operand:DI 4 "register_operand" "1")))
15789 (set (mem:BLK (match_dup 3))
15790 (mem:BLK (match_dup 4)))
15791 (use (match_dup 5))]
15793 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15795 [(set_attr "type" "str")
15796 (set_attr "prefix_rep" "1")
15797 (set_attr "memory" "both")
15798 (set_attr "mode" "DI")])
15800 (define_insn "*rep_movsi"
15801 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15802 (set (match_operand:P 0 "register_operand" "=D")
15803 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15805 (match_operand:P 3 "register_operand" "0")))
15806 (set (match_operand:P 1 "register_operand" "=S")
15807 (plus:P (ashift:P (match_dup 5) (const_int 2))
15808 (match_operand:P 4 "register_operand" "1")))
15809 (set (mem:BLK (match_dup 3))
15810 (mem:BLK (match_dup 4)))
15811 (use (match_dup 5))]
15812 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15813 "rep{%;} movs{l|d}"
15814 [(set_attr "type" "str")
15815 (set_attr "prefix_rep" "1")
15816 (set_attr "memory" "both")
15817 (set_attr "mode" "SI")])
15819 (define_insn "*rep_movqi"
15820 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15821 (set (match_operand:P 0 "register_operand" "=D")
15822 (plus:P (match_operand:P 3 "register_operand" "0")
15823 (match_operand:P 5 "register_operand" "2")))
15824 (set (match_operand:P 1 "register_operand" "=S")
15825 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15826 (set (mem:BLK (match_dup 3))
15827 (mem:BLK (match_dup 4)))
15828 (use (match_dup 5))]
15829 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15831 [(set_attr "type" "str")
15832 (set_attr "prefix_rep" "1")
15833 (set_attr "memory" "both")
15834 (set_attr "mode" "QI")])
15836 (define_expand "setmem<mode>"
15837 [(use (match_operand:BLK 0 "memory_operand" ""))
15838 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15839 (use (match_operand:QI 2 "nonmemory_operand" ""))
15840 (use (match_operand 3 "const_int_operand" ""))
15841 (use (match_operand:SI 4 "const_int_operand" ""))
15842 (use (match_operand:SI 5 "const_int_operand" ""))]
15845 if (ix86_expand_setmem (operands[0], operands[1],
15846 operands[2], operands[3],
15847 operands[4], operands[5]))
15853 ;; Most CPUs don't like single string operations
15854 ;; Handle this case here to simplify previous expander.
15856 (define_expand "strset"
15857 [(set (match_operand 1 "memory_operand" "")
15858 (match_operand 2 "register_operand" ""))
15859 (parallel [(set (match_operand 0 "register_operand" "")
15861 (clobber (reg:CC FLAGS_REG))])]
15864 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15865 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15867 /* If .md ever supports :P for Pmode, this can be directly
15868 in the pattern above. */
15869 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15870 GEN_INT (GET_MODE_SIZE (GET_MODE
15872 /* Can't use this if the user has appropriated eax or edi. */
15873 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15874 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15876 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15882 (define_expand "strset_singleop"
15883 [(parallel [(set (match_operand 1 "memory_operand" "")
15884 (match_operand 2 "register_operand" ""))
15885 (set (match_operand 0 "register_operand" "")
15886 (match_operand 3 "" ""))])]
15888 "ix86_current_function_needs_cld = 1;")
15890 (define_insn "*strsetdi_rex_1"
15891 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15892 (match_operand:DI 2 "register_operand" "a"))
15893 (set (match_operand:DI 0 "register_operand" "=D")
15894 (plus:DI (match_dup 1)
15897 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15899 [(set_attr "type" "str")
15900 (set_attr "memory" "store")
15901 (set_attr "mode" "DI")])
15903 (define_insn "*strsetsi_1"
15904 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15905 (match_operand:SI 2 "register_operand" "a"))
15906 (set (match_operand:P 0 "register_operand" "=D")
15907 (plus:P (match_dup 1)
15909 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15911 [(set_attr "type" "str")
15912 (set_attr "memory" "store")
15913 (set_attr "mode" "SI")])
15915 (define_insn "*strsethi_1"
15916 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15917 (match_operand:HI 2 "register_operand" "a"))
15918 (set (match_operand:P 0 "register_operand" "=D")
15919 (plus:P (match_dup 1)
15921 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15923 [(set_attr "type" "str")
15924 (set_attr "memory" "store")
15925 (set_attr "mode" "HI")])
15927 (define_insn "*strsetqi_1"
15928 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15929 (match_operand:QI 2 "register_operand" "a"))
15930 (set (match_operand:P 0 "register_operand" "=D")
15931 (plus:P (match_dup 1)
15933 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15935 [(set_attr "type" "str")
15936 (set_attr "memory" "store")
15937 (set (attr "prefix_rex")
15939 (match_test "<P:MODE>mode == DImode")
15941 (const_string "*")))
15942 (set_attr "mode" "QI")])
15944 (define_expand "rep_stos"
15945 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15946 (set (match_operand 0 "register_operand" "")
15947 (match_operand 4 "" ""))
15948 (set (match_operand 2 "memory_operand" "") (const_int 0))
15949 (use (match_operand 3 "register_operand" ""))
15950 (use (match_dup 1))])]
15952 "ix86_current_function_needs_cld = 1;")
15954 (define_insn "*rep_stosdi_rex64"
15955 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15956 (set (match_operand:DI 0 "register_operand" "=D")
15957 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15959 (match_operand:DI 3 "register_operand" "0")))
15960 (set (mem:BLK (match_dup 3))
15962 (use (match_operand:DI 2 "register_operand" "a"))
15963 (use (match_dup 4))]
15965 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15967 [(set_attr "type" "str")
15968 (set_attr "prefix_rep" "1")
15969 (set_attr "memory" "store")
15970 (set_attr "mode" "DI")])
15972 (define_insn "*rep_stossi"
15973 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15974 (set (match_operand:P 0 "register_operand" "=D")
15975 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15977 (match_operand:P 3 "register_operand" "0")))
15978 (set (mem:BLK (match_dup 3))
15980 (use (match_operand:SI 2 "register_operand" "a"))
15981 (use (match_dup 4))]
15982 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15983 "rep{%;} stos{l|d}"
15984 [(set_attr "type" "str")
15985 (set_attr "prefix_rep" "1")
15986 (set_attr "memory" "store")
15987 (set_attr "mode" "SI")])
15989 (define_insn "*rep_stosqi"
15990 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15991 (set (match_operand:P 0 "register_operand" "=D")
15992 (plus:P (match_operand:P 3 "register_operand" "0")
15993 (match_operand:P 4 "register_operand" "1")))
15994 (set (mem:BLK (match_dup 3))
15996 (use (match_operand:QI 2 "register_operand" "a"))
15997 (use (match_dup 4))]
15998 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16000 [(set_attr "type" "str")
16001 (set_attr "prefix_rep" "1")
16002 (set_attr "memory" "store")
16003 (set (attr "prefix_rex")
16005 (match_test "<P:MODE>mode == DImode")
16007 (const_string "*")))
16008 (set_attr "mode" "QI")])
16010 (define_expand "cmpstrnsi"
16011 [(set (match_operand:SI 0 "register_operand" "")
16012 (compare:SI (match_operand:BLK 1 "general_operand" "")
16013 (match_operand:BLK 2 "general_operand" "")))
16014 (use (match_operand 3 "general_operand" ""))
16015 (use (match_operand 4 "immediate_operand" ""))]
16018 rtx addr1, addr2, out, outlow, count, countreg, align;
16020 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16023 /* Can't use this if the user has appropriated ecx, esi or edi. */
16024 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16029 out = gen_reg_rtx (SImode);
16031 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16032 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16033 if (addr1 != XEXP (operands[1], 0))
16034 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16035 if (addr2 != XEXP (operands[2], 0))
16036 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16038 count = operands[3];
16039 countreg = ix86_zero_extend_to_Pmode (count);
16041 /* %%% Iff we are testing strict equality, we can use known alignment
16042 to good advantage. This may be possible with combine, particularly
16043 once cc0 is dead. */
16044 align = operands[4];
16046 if (CONST_INT_P (count))
16048 if (INTVAL (count) == 0)
16050 emit_move_insn (operands[0], const0_rtx);
16053 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16054 operands[1], operands[2]));
16058 rtx (*gen_cmp) (rtx, rtx);
16060 gen_cmp = (TARGET_64BIT
16061 ? gen_cmpdi_1 : gen_cmpsi_1);
16063 emit_insn (gen_cmp (countreg, countreg));
16064 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16065 operands[1], operands[2]));
16068 outlow = gen_lowpart (QImode, out);
16069 emit_insn (gen_cmpintqi (outlow));
16070 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16072 if (operands[0] != out)
16073 emit_move_insn (operands[0], out);
16078 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16080 (define_expand "cmpintqi"
16081 [(set (match_dup 1)
16082 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16084 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16085 (parallel [(set (match_operand:QI 0 "register_operand" "")
16086 (minus:QI (match_dup 1)
16088 (clobber (reg:CC FLAGS_REG))])]
16091 operands[1] = gen_reg_rtx (QImode);
16092 operands[2] = gen_reg_rtx (QImode);
16095 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16096 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16098 (define_expand "cmpstrnqi_nz_1"
16099 [(parallel [(set (reg:CC FLAGS_REG)
16100 (compare:CC (match_operand 4 "memory_operand" "")
16101 (match_operand 5 "memory_operand" "")))
16102 (use (match_operand 2 "register_operand" ""))
16103 (use (match_operand:SI 3 "immediate_operand" ""))
16104 (clobber (match_operand 0 "register_operand" ""))
16105 (clobber (match_operand 1 "register_operand" ""))
16106 (clobber (match_dup 2))])]
16108 "ix86_current_function_needs_cld = 1;")
16110 (define_insn "*cmpstrnqi_nz_1"
16111 [(set (reg:CC FLAGS_REG)
16112 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16113 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16114 (use (match_operand:P 6 "register_operand" "2"))
16115 (use (match_operand:SI 3 "immediate_operand" "i"))
16116 (clobber (match_operand:P 0 "register_operand" "=S"))
16117 (clobber (match_operand:P 1 "register_operand" "=D"))
16118 (clobber (match_operand:P 2 "register_operand" "=c"))]
16119 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16121 [(set_attr "type" "str")
16122 (set_attr "mode" "QI")
16123 (set (attr "prefix_rex")
16125 (match_test "<P:MODE>mode == DImode")
16127 (const_string "*")))
16128 (set_attr "prefix_rep" "1")])
16130 ;; The same, but the count is not known to not be zero.
16132 (define_expand "cmpstrnqi_1"
16133 [(parallel [(set (reg:CC FLAGS_REG)
16134 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16136 (compare:CC (match_operand 4 "memory_operand" "")
16137 (match_operand 5 "memory_operand" ""))
16139 (use (match_operand:SI 3 "immediate_operand" ""))
16140 (use (reg:CC FLAGS_REG))
16141 (clobber (match_operand 0 "register_operand" ""))
16142 (clobber (match_operand 1 "register_operand" ""))
16143 (clobber (match_dup 2))])]
16145 "ix86_current_function_needs_cld = 1;")
16147 (define_insn "*cmpstrnqi_1"
16148 [(set (reg:CC FLAGS_REG)
16149 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16151 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16152 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16154 (use (match_operand:SI 3 "immediate_operand" "i"))
16155 (use (reg:CC FLAGS_REG))
16156 (clobber (match_operand:P 0 "register_operand" "=S"))
16157 (clobber (match_operand:P 1 "register_operand" "=D"))
16158 (clobber (match_operand:P 2 "register_operand" "=c"))]
16159 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16161 [(set_attr "type" "str")
16162 (set_attr "mode" "QI")
16163 (set (attr "prefix_rex")
16165 (match_test "<P:MODE>mode == DImode")
16167 (const_string "*")))
16168 (set_attr "prefix_rep" "1")])
16170 (define_expand "strlen<mode>"
16171 [(set (match_operand:P 0 "register_operand" "")
16172 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16173 (match_operand:QI 2 "immediate_operand" "")
16174 (match_operand 3 "immediate_operand" "")]
16178 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16184 (define_expand "strlenqi_1"
16185 [(parallel [(set (match_operand 0 "register_operand" "")
16186 (match_operand 2 "" ""))
16187 (clobber (match_operand 1 "register_operand" ""))
16188 (clobber (reg:CC FLAGS_REG))])]
16190 "ix86_current_function_needs_cld = 1;")
16192 (define_insn "*strlenqi_1"
16193 [(set (match_operand:P 0 "register_operand" "=&c")
16194 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16195 (match_operand:QI 2 "register_operand" "a")
16196 (match_operand:P 3 "immediate_operand" "i")
16197 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16198 (clobber (match_operand:P 1 "register_operand" "=D"))
16199 (clobber (reg:CC FLAGS_REG))]
16200 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16202 [(set_attr "type" "str")
16203 (set_attr "mode" "QI")
16204 (set (attr "prefix_rex")
16206 (match_test "<P:MODE>mode == DImode")
16208 (const_string "*")))
16209 (set_attr "prefix_rep" "1")])
16211 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16212 ;; handled in combine, but it is not currently up to the task.
16213 ;; When used for their truth value, the cmpstrn* expanders generate
16222 ;; The intermediate three instructions are unnecessary.
16224 ;; This one handles cmpstrn*_nz_1...
16227 (set (reg:CC FLAGS_REG)
16228 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16229 (mem:BLK (match_operand 5 "register_operand" ""))))
16230 (use (match_operand 6 "register_operand" ""))
16231 (use (match_operand:SI 3 "immediate_operand" ""))
16232 (clobber (match_operand 0 "register_operand" ""))
16233 (clobber (match_operand 1 "register_operand" ""))
16234 (clobber (match_operand 2 "register_operand" ""))])
16235 (set (match_operand:QI 7 "register_operand" "")
16236 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16237 (set (match_operand:QI 8 "register_operand" "")
16238 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16239 (set (reg FLAGS_REG)
16240 (compare (match_dup 7) (match_dup 8)))
16242 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16244 (set (reg:CC FLAGS_REG)
16245 (compare:CC (mem:BLK (match_dup 4))
16246 (mem:BLK (match_dup 5))))
16247 (use (match_dup 6))
16248 (use (match_dup 3))
16249 (clobber (match_dup 0))
16250 (clobber (match_dup 1))
16251 (clobber (match_dup 2))])])
16253 ;; ...and this one handles cmpstrn*_1.
16256 (set (reg:CC FLAGS_REG)
16257 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16259 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16260 (mem:BLK (match_operand 5 "register_operand" "")))
16262 (use (match_operand:SI 3 "immediate_operand" ""))
16263 (use (reg:CC FLAGS_REG))
16264 (clobber (match_operand 0 "register_operand" ""))
16265 (clobber (match_operand 1 "register_operand" ""))
16266 (clobber (match_operand 2 "register_operand" ""))])
16267 (set (match_operand:QI 7 "register_operand" "")
16268 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16269 (set (match_operand:QI 8 "register_operand" "")
16270 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16271 (set (reg FLAGS_REG)
16272 (compare (match_dup 7) (match_dup 8)))
16274 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16276 (set (reg:CC FLAGS_REG)
16277 (if_then_else:CC (ne (match_dup 6)
16279 (compare:CC (mem:BLK (match_dup 4))
16280 (mem:BLK (match_dup 5)))
16282 (use (match_dup 3))
16283 (use (reg:CC FLAGS_REG))
16284 (clobber (match_dup 0))
16285 (clobber (match_dup 1))
16286 (clobber (match_dup 2))])])
16288 ;; Conditional move instructions.
16290 (define_expand "mov<mode>cc"
16291 [(set (match_operand:SWIM 0 "register_operand" "")
16292 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16293 (match_operand:SWIM 2 "<general_operand>" "")
16294 (match_operand:SWIM 3 "<general_operand>" "")))]
16296 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16298 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16299 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16300 ;; So just document what we're doing explicitly.
16302 (define_expand "x86_mov<mode>cc_0_m1"
16304 [(set (match_operand:SWI48 0 "register_operand" "")
16305 (if_then_else:SWI48
16306 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16307 [(match_operand 1 "flags_reg_operand" "")
16311 (clobber (reg:CC FLAGS_REG))])])
16313 (define_insn "*x86_mov<mode>cc_0_m1"
16314 [(set (match_operand:SWI48 0 "register_operand" "=r")
16315 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16316 [(reg FLAGS_REG) (const_int 0)])
16319 (clobber (reg:CC FLAGS_REG))]
16321 "sbb{<imodesuffix>}\t%0, %0"
16322 ; Since we don't have the proper number of operands for an alu insn,
16323 ; fill in all the blanks.
16324 [(set_attr "type" "alu")
16325 (set_attr "use_carry" "1")
16326 (set_attr "pent_pair" "pu")
16327 (set_attr "memory" "none")
16328 (set_attr "imm_disp" "false")
16329 (set_attr "mode" "<MODE>")
16330 (set_attr "length_immediate" "0")])
16332 (define_insn "*x86_mov<mode>cc_0_m1_se"
16333 [(set (match_operand:SWI48 0 "register_operand" "=r")
16334 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16335 [(reg FLAGS_REG) (const_int 0)])
16338 (clobber (reg:CC FLAGS_REG))]
16340 "sbb{<imodesuffix>}\t%0, %0"
16341 [(set_attr "type" "alu")
16342 (set_attr "use_carry" "1")
16343 (set_attr "pent_pair" "pu")
16344 (set_attr "memory" "none")
16345 (set_attr "imm_disp" "false")
16346 (set_attr "mode" "<MODE>")
16347 (set_attr "length_immediate" "0")])
16349 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16350 [(set (match_operand:SWI48 0 "register_operand" "=r")
16351 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16352 [(reg FLAGS_REG) (const_int 0)])))]
16354 "sbb{<imodesuffix>}\t%0, %0"
16355 [(set_attr "type" "alu")
16356 (set_attr "use_carry" "1")
16357 (set_attr "pent_pair" "pu")
16358 (set_attr "memory" "none")
16359 (set_attr "imm_disp" "false")
16360 (set_attr "mode" "<MODE>")
16361 (set_attr "length_immediate" "0")])
16363 (define_insn "*mov<mode>cc_noc"
16364 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16365 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16366 [(reg FLAGS_REG) (const_int 0)])
16367 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16368 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16369 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16371 cmov%O2%C1\t{%2, %0|%0, %2}
16372 cmov%O2%c1\t{%3, %0|%0, %3}"
16373 [(set_attr "type" "icmov")
16374 (set_attr "mode" "<MODE>")])
16376 (define_insn_and_split "*movqicc_noc"
16377 [(set (match_operand:QI 0 "register_operand" "=r,r")
16378 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16379 [(match_operand 4 "flags_reg_operand" "")
16381 (match_operand:QI 2 "register_operand" "r,0")
16382 (match_operand:QI 3 "register_operand" "0,r")))]
16383 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16385 "&& reload_completed"
16386 [(set (match_dup 0)
16387 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16390 "operands[0] = gen_lowpart (SImode, operands[0]);
16391 operands[2] = gen_lowpart (SImode, operands[2]);
16392 operands[3] = gen_lowpart (SImode, operands[3]);"
16393 [(set_attr "type" "icmov")
16394 (set_attr "mode" "SI")])
16396 (define_expand "mov<mode>cc"
16397 [(set (match_operand:X87MODEF 0 "register_operand" "")
16398 (if_then_else:X87MODEF
16399 (match_operand 1 "ix86_fp_comparison_operator" "")
16400 (match_operand:X87MODEF 2 "register_operand" "")
16401 (match_operand:X87MODEF 3 "register_operand" "")))]
16402 "(TARGET_80387 && TARGET_CMOVE)
16403 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16404 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16406 (define_insn "*movxfcc_1"
16407 [(set (match_operand:XF 0 "register_operand" "=f,f")
16408 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16409 [(reg FLAGS_REG) (const_int 0)])
16410 (match_operand:XF 2 "register_operand" "f,0")
16411 (match_operand:XF 3 "register_operand" "0,f")))]
16412 "TARGET_80387 && TARGET_CMOVE"
16414 fcmov%F1\t{%2, %0|%0, %2}
16415 fcmov%f1\t{%3, %0|%0, %3}"
16416 [(set_attr "type" "fcmov")
16417 (set_attr "mode" "XF")])
16419 (define_insn "*movdfcc_1_rex64"
16420 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16421 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16422 [(reg FLAGS_REG) (const_int 0)])
16423 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16424 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16425 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16426 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16428 fcmov%F1\t{%2, %0|%0, %2}
16429 fcmov%f1\t{%3, %0|%0, %3}
16430 cmov%O2%C1\t{%2, %0|%0, %2}
16431 cmov%O2%c1\t{%3, %0|%0, %3}"
16432 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16433 (set_attr "mode" "DF,DF,DI,DI")])
16435 (define_insn "*movdfcc_1"
16436 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16437 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16438 [(reg FLAGS_REG) (const_int 0)])
16439 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16440 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16441 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16442 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16444 fcmov%F1\t{%2, %0|%0, %2}
16445 fcmov%f1\t{%3, %0|%0, %3}
16448 [(set_attr "type" "fcmov,fcmov,multi,multi")
16449 (set_attr "mode" "DF,DF,DI,DI")])
16452 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16453 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16454 [(match_operand 4 "flags_reg_operand" "")
16456 (match_operand:DF 2 "nonimmediate_operand" "")
16457 (match_operand:DF 3 "nonimmediate_operand" "")))]
16458 "!TARGET_64BIT && reload_completed"
16459 [(set (match_dup 2)
16460 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16464 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16468 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16469 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16472 (define_insn "*movsfcc_1_387"
16473 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16474 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16475 [(reg FLAGS_REG) (const_int 0)])
16476 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16477 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16478 "TARGET_80387 && TARGET_CMOVE
16479 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16481 fcmov%F1\t{%2, %0|%0, %2}
16482 fcmov%f1\t{%3, %0|%0, %3}
16483 cmov%O2%C1\t{%2, %0|%0, %2}
16484 cmov%O2%c1\t{%3, %0|%0, %3}"
16485 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16486 (set_attr "mode" "SF,SF,SI,SI")])
16488 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16489 ;; the scalar versions to have only XMM registers as operands.
16491 ;; XOP conditional move
16492 (define_insn "*xop_pcmov_<mode>"
16493 [(set (match_operand:MODEF 0 "register_operand" "=x")
16494 (if_then_else:MODEF
16495 (match_operand:MODEF 1 "register_operand" "x")
16496 (match_operand:MODEF 2 "register_operand" "x")
16497 (match_operand:MODEF 3 "register_operand" "x")))]
16499 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16500 [(set_attr "type" "sse4arg")])
16502 ;; These versions of the min/max patterns are intentionally ignorant of
16503 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16504 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16505 ;; are undefined in this condition, we're certain this is correct.
16507 (define_insn "<code><mode>3"
16508 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16510 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16511 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16512 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16514 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16515 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16516 [(set_attr "isa" "noavx,avx")
16517 (set_attr "prefix" "orig,vex")
16518 (set_attr "type" "sseadd")
16519 (set_attr "mode" "<MODE>")])
16521 ;; These versions of the min/max patterns implement exactly the operations
16522 ;; min = (op1 < op2 ? op1 : op2)
16523 ;; max = (!(op1 < op2) ? op1 : op2)
16524 ;; Their operands are not commutative, and thus they may be used in the
16525 ;; presence of -0.0 and NaN.
16527 (define_insn "*ieee_smin<mode>3"
16528 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16530 [(match_operand:MODEF 1 "register_operand" "0,x")
16531 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16533 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16535 min<ssemodesuffix>\t{%2, %0|%0, %2}
16536 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16537 [(set_attr "isa" "noavx,avx")
16538 (set_attr "prefix" "orig,vex")
16539 (set_attr "type" "sseadd")
16540 (set_attr "mode" "<MODE>")])
16542 (define_insn "*ieee_smax<mode>3"
16543 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16545 [(match_operand:MODEF 1 "register_operand" "0,x")
16546 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16548 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16550 max<ssemodesuffix>\t{%2, %0|%0, %2}
16551 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16552 [(set_attr "isa" "noavx,avx")
16553 (set_attr "prefix" "orig,vex")
16554 (set_attr "type" "sseadd")
16555 (set_attr "mode" "<MODE>")])
16557 ;; Make two stack loads independent:
16559 ;; fld %st(0) -> fld bb
16560 ;; fmul bb fmul %st(1), %st
16562 ;; Actually we only match the last two instructions for simplicity.
16564 [(set (match_operand 0 "fp_register_operand" "")
16565 (match_operand 1 "fp_register_operand" ""))
16567 (match_operator 2 "binary_fp_operator"
16569 (match_operand 3 "memory_operand" "")]))]
16570 "REGNO (operands[0]) != REGNO (operands[1])"
16571 [(set (match_dup 0) (match_dup 3))
16572 (set (match_dup 0) (match_dup 4))]
16574 ;; The % modifier is not operational anymore in peephole2's, so we have to
16575 ;; swap the operands manually in the case of addition and multiplication.
16579 if (COMMUTATIVE_ARITH_P (operands[2]))
16580 op0 = operands[0], op1 = operands[1];
16582 op0 = operands[1], op1 = operands[0];
16584 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16585 GET_MODE (operands[2]),
16589 ;; Conditional addition patterns
16590 (define_expand "add<mode>cc"
16591 [(match_operand:SWI 0 "register_operand" "")
16592 (match_operand 1 "ordered_comparison_operator" "")
16593 (match_operand:SWI 2 "register_operand" "")
16594 (match_operand:SWI 3 "const_int_operand" "")]
16596 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16598 ;; Misc patterns (?)
16600 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16601 ;; Otherwise there will be nothing to keep
16603 ;; [(set (reg ebp) (reg esp))]
16604 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16605 ;; (clobber (eflags)]
16606 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16608 ;; in proper program order.
16610 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16611 [(set (match_operand:P 0 "register_operand" "=r,r")
16612 (plus:P (match_operand:P 1 "register_operand" "0,r")
16613 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16614 (clobber (reg:CC FLAGS_REG))
16615 (clobber (mem:BLK (scratch)))]
16618 switch (get_attr_type (insn))
16621 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16624 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16625 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16626 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16628 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16631 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16632 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16635 [(set (attr "type")
16636 (cond [(and (eq_attr "alternative" "0")
16637 (not (match_test "TARGET_OPT_AGU")))
16638 (const_string "alu")
16639 (match_operand:<MODE> 2 "const0_operand" "")
16640 (const_string "imov")
16642 (const_string "lea")))
16643 (set (attr "length_immediate")
16644 (cond [(eq_attr "type" "imov")
16646 (and (eq_attr "type" "alu")
16647 (match_operand 2 "const128_operand" ""))
16650 (const_string "*")))
16651 (set_attr "mode" "<MODE>")])
16653 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16654 [(set (match_operand:P 0 "register_operand" "=r")
16655 (minus:P (match_operand:P 1 "register_operand" "0")
16656 (match_operand:P 2 "register_operand" "r")))
16657 (clobber (reg:CC FLAGS_REG))
16658 (clobber (mem:BLK (scratch)))]
16660 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16661 [(set_attr "type" "alu")
16662 (set_attr "mode" "<MODE>")])
16664 (define_insn "allocate_stack_worker_probe_<mode>"
16665 [(set (match_operand:P 0 "register_operand" "=a")
16666 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16667 UNSPECV_STACK_PROBE))
16668 (clobber (reg:CC FLAGS_REG))]
16669 "ix86_target_stack_probe ()"
16670 "call\t___chkstk_ms"
16671 [(set_attr "type" "multi")
16672 (set_attr "length" "5")])
16674 (define_expand "allocate_stack"
16675 [(match_operand 0 "register_operand" "")
16676 (match_operand 1 "general_operand" "")]
16677 "ix86_target_stack_probe ()"
16681 #ifndef CHECK_STACK_LIMIT
16682 #define CHECK_STACK_LIMIT 0
16685 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16686 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16688 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16689 stack_pointer_rtx, 0, OPTAB_DIRECT);
16690 if (x != stack_pointer_rtx)
16691 emit_move_insn (stack_pointer_rtx, x);
16695 x = copy_to_mode_reg (Pmode, operands[1]);
16697 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16699 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16700 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16701 stack_pointer_rtx, 0, OPTAB_DIRECT);
16702 if (x != stack_pointer_rtx)
16703 emit_move_insn (stack_pointer_rtx, x);
16706 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16710 ;; Use IOR for stack probes, this is shorter.
16711 (define_expand "probe_stack"
16712 [(match_operand 0 "memory_operand" "")]
16715 rtx (*gen_ior3) (rtx, rtx, rtx);
16717 gen_ior3 = (GET_MODE (operands[0]) == DImode
16718 ? gen_iordi3 : gen_iorsi3);
16720 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16724 (define_insn "adjust_stack_and_probe<mode>"
16725 [(set (match_operand:P 0 "register_operand" "=r")
16726 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16727 UNSPECV_PROBE_STACK_RANGE))
16728 (set (reg:P SP_REG)
16729 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16730 (clobber (reg:CC FLAGS_REG))
16731 (clobber (mem:BLK (scratch)))]
16733 "* return output_adjust_stack_and_probe (operands[0]);"
16734 [(set_attr "type" "multi")])
16736 (define_insn "probe_stack_range<mode>"
16737 [(set (match_operand:P 0 "register_operand" "=r")
16738 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16739 (match_operand:P 2 "const_int_operand" "n")]
16740 UNSPECV_PROBE_STACK_RANGE))
16741 (clobber (reg:CC FLAGS_REG))]
16743 "* return output_probe_stack_range (operands[0], operands[2]);"
16744 [(set_attr "type" "multi")])
16746 (define_expand "builtin_setjmp_receiver"
16747 [(label_ref (match_operand 0 "" ""))]
16748 "!TARGET_64BIT && flag_pic"
16754 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16755 rtx label_rtx = gen_label_rtx ();
16756 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16757 xops[0] = xops[1] = picreg;
16758 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16759 ix86_expand_binary_operator (MINUS, SImode, xops);
16763 emit_insn (gen_set_got (pic_offset_table_rtx));
16767 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16770 [(set (match_operand 0 "register_operand" "")
16771 (match_operator 3 "promotable_binary_operator"
16772 [(match_operand 1 "register_operand" "")
16773 (match_operand 2 "aligned_operand" "")]))
16774 (clobber (reg:CC FLAGS_REG))]
16775 "! TARGET_PARTIAL_REG_STALL && reload_completed
16776 && ((GET_MODE (operands[0]) == HImode
16777 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16778 /* ??? next two lines just !satisfies_constraint_K (...) */
16779 || !CONST_INT_P (operands[2])
16780 || satisfies_constraint_K (operands[2])))
16781 || (GET_MODE (operands[0]) == QImode
16782 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16783 [(parallel [(set (match_dup 0)
16784 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16785 (clobber (reg:CC FLAGS_REG))])]
16787 operands[0] = gen_lowpart (SImode, operands[0]);
16788 operands[1] = gen_lowpart (SImode, operands[1]);
16789 if (GET_CODE (operands[3]) != ASHIFT)
16790 operands[2] = gen_lowpart (SImode, operands[2]);
16791 PUT_MODE (operands[3], SImode);
16794 ; Promote the QImode tests, as i386 has encoding of the AND
16795 ; instruction with 32-bit sign-extended immediate and thus the
16796 ; instruction size is unchanged, except in the %eax case for
16797 ; which it is increased by one byte, hence the ! optimize_size.
16799 [(set (match_operand 0 "flags_reg_operand" "")
16800 (match_operator 2 "compare_operator"
16801 [(and (match_operand 3 "aligned_operand" "")
16802 (match_operand 4 "const_int_operand" ""))
16804 (set (match_operand 1 "register_operand" "")
16805 (and (match_dup 3) (match_dup 4)))]
16806 "! TARGET_PARTIAL_REG_STALL && reload_completed
16807 && optimize_insn_for_speed_p ()
16808 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16809 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16810 /* Ensure that the operand will remain sign-extended immediate. */
16811 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16812 [(parallel [(set (match_dup 0)
16813 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16816 (and:SI (match_dup 3) (match_dup 4)))])]
16819 = gen_int_mode (INTVAL (operands[4])
16820 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16821 operands[1] = gen_lowpart (SImode, operands[1]);
16822 operands[3] = gen_lowpart (SImode, operands[3]);
16825 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16826 ; the TEST instruction with 32-bit sign-extended immediate and thus
16827 ; the instruction size would at least double, which is not what we
16828 ; want even with ! optimize_size.
16830 [(set (match_operand 0 "flags_reg_operand" "")
16831 (match_operator 1 "compare_operator"
16832 [(and (match_operand:HI 2 "aligned_operand" "")
16833 (match_operand:HI 3 "const_int_operand" ""))
16835 "! TARGET_PARTIAL_REG_STALL && reload_completed
16836 && ! TARGET_FAST_PREFIX
16837 && optimize_insn_for_speed_p ()
16838 /* Ensure that the operand will remain sign-extended immediate. */
16839 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16840 [(set (match_dup 0)
16841 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16845 = gen_int_mode (INTVAL (operands[3])
16846 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16847 operands[2] = gen_lowpart (SImode, operands[2]);
16851 [(set (match_operand 0 "register_operand" "")
16852 (neg (match_operand 1 "register_operand" "")))
16853 (clobber (reg:CC FLAGS_REG))]
16854 "! TARGET_PARTIAL_REG_STALL && reload_completed
16855 && (GET_MODE (operands[0]) == HImode
16856 || (GET_MODE (operands[0]) == QImode
16857 && (TARGET_PROMOTE_QImode
16858 || optimize_insn_for_size_p ())))"
16859 [(parallel [(set (match_dup 0)
16860 (neg:SI (match_dup 1)))
16861 (clobber (reg:CC FLAGS_REG))])]
16863 operands[0] = gen_lowpart (SImode, operands[0]);
16864 operands[1] = gen_lowpart (SImode, operands[1]);
16868 [(set (match_operand 0 "register_operand" "")
16869 (not (match_operand 1 "register_operand" "")))]
16870 "! TARGET_PARTIAL_REG_STALL && reload_completed
16871 && (GET_MODE (operands[0]) == HImode
16872 || (GET_MODE (operands[0]) == QImode
16873 && (TARGET_PROMOTE_QImode
16874 || optimize_insn_for_size_p ())))"
16875 [(set (match_dup 0)
16876 (not:SI (match_dup 1)))]
16878 operands[0] = gen_lowpart (SImode, operands[0]);
16879 operands[1] = gen_lowpart (SImode, operands[1]);
16883 [(set (match_operand 0 "register_operand" "")
16884 (if_then_else (match_operator 1 "ordered_comparison_operator"
16885 [(reg FLAGS_REG) (const_int 0)])
16886 (match_operand 2 "register_operand" "")
16887 (match_operand 3 "register_operand" "")))]
16888 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16889 && (GET_MODE (operands[0]) == HImode
16890 || (GET_MODE (operands[0]) == QImode
16891 && (TARGET_PROMOTE_QImode
16892 || optimize_insn_for_size_p ())))"
16893 [(set (match_dup 0)
16894 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16896 operands[0] = gen_lowpart (SImode, operands[0]);
16897 operands[2] = gen_lowpart (SImode, operands[2]);
16898 operands[3] = gen_lowpart (SImode, operands[3]);
16901 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16902 ;; transform a complex memory operation into two memory to register operations.
16904 ;; Don't push memory operands
16906 [(set (match_operand:SWI 0 "push_operand" "")
16907 (match_operand:SWI 1 "memory_operand" ""))
16908 (match_scratch:SWI 2 "<r>")]
16909 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16910 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16911 [(set (match_dup 2) (match_dup 1))
16912 (set (match_dup 0) (match_dup 2))])
16914 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16917 [(set (match_operand:SF 0 "push_operand" "")
16918 (match_operand:SF 1 "memory_operand" ""))
16919 (match_scratch:SF 2 "r")]
16920 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16921 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16922 [(set (match_dup 2) (match_dup 1))
16923 (set (match_dup 0) (match_dup 2))])
16925 ;; Don't move an immediate directly to memory when the instruction
16928 [(match_scratch:SWI124 1 "<r>")
16929 (set (match_operand:SWI124 0 "memory_operand" "")
16931 "optimize_insn_for_speed_p ()
16932 && !TARGET_USE_MOV0
16933 && TARGET_SPLIT_LONG_MOVES
16934 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16935 && peep2_regno_dead_p (0, FLAGS_REG)"
16936 [(parallel [(set (match_dup 2) (const_int 0))
16937 (clobber (reg:CC FLAGS_REG))])
16938 (set (match_dup 0) (match_dup 1))]
16939 "operands[2] = gen_lowpart (SImode, operands[1]);")
16942 [(match_scratch:SWI124 2 "<r>")
16943 (set (match_operand:SWI124 0 "memory_operand" "")
16944 (match_operand:SWI124 1 "immediate_operand" ""))]
16945 "optimize_insn_for_speed_p ()
16946 && TARGET_SPLIT_LONG_MOVES
16947 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16948 [(set (match_dup 2) (match_dup 1))
16949 (set (match_dup 0) (match_dup 2))])
16951 ;; Don't compare memory with zero, load and use a test instead.
16953 [(set (match_operand 0 "flags_reg_operand" "")
16954 (match_operator 1 "compare_operator"
16955 [(match_operand:SI 2 "memory_operand" "")
16957 (match_scratch:SI 3 "r")]
16958 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16959 [(set (match_dup 3) (match_dup 2))
16960 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16962 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16963 ;; Don't split NOTs with a displacement operand, because resulting XOR
16964 ;; will not be pairable anyway.
16966 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16967 ;; represented using a modRM byte. The XOR replacement is long decoded,
16968 ;; so this split helps here as well.
16970 ;; Note: Can't do this as a regular split because we can't get proper
16971 ;; lifetime information then.
16974 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16975 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16976 "optimize_insn_for_speed_p ()
16977 && ((TARGET_NOT_UNPAIRABLE
16978 && (!MEM_P (operands[0])
16979 || !memory_displacement_operand (operands[0], <MODE>mode)))
16980 || (TARGET_NOT_VECTORMODE
16981 && long_memory_operand (operands[0], <MODE>mode)))
16982 && peep2_regno_dead_p (0, FLAGS_REG)"
16983 [(parallel [(set (match_dup 0)
16984 (xor:SWI124 (match_dup 1) (const_int -1)))
16985 (clobber (reg:CC FLAGS_REG))])])
16987 ;; Non pairable "test imm, reg" instructions can be translated to
16988 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16989 ;; byte opcode instead of two, have a short form for byte operands),
16990 ;; so do it for other CPUs as well. Given that the value was dead,
16991 ;; this should not create any new dependencies. Pass on the sub-word
16992 ;; versions if we're concerned about partial register stalls.
16995 [(set (match_operand 0 "flags_reg_operand" "")
16996 (match_operator 1 "compare_operator"
16997 [(and:SI (match_operand:SI 2 "register_operand" "")
16998 (match_operand:SI 3 "immediate_operand" ""))
17000 "ix86_match_ccmode (insn, CCNOmode)
17001 && (true_regnum (operands[2]) != AX_REG
17002 || satisfies_constraint_K (operands[3]))
17003 && peep2_reg_dead_p (1, operands[2])"
17005 [(set (match_dup 0)
17006 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17009 (and:SI (match_dup 2) (match_dup 3)))])])
17011 ;; We don't need to handle HImode case, because it will be promoted to SImode
17012 ;; on ! TARGET_PARTIAL_REG_STALL
17015 [(set (match_operand 0 "flags_reg_operand" "")
17016 (match_operator 1 "compare_operator"
17017 [(and:QI (match_operand:QI 2 "register_operand" "")
17018 (match_operand:QI 3 "immediate_operand" ""))
17020 "! TARGET_PARTIAL_REG_STALL
17021 && ix86_match_ccmode (insn, CCNOmode)
17022 && true_regnum (operands[2]) != AX_REG
17023 && peep2_reg_dead_p (1, operands[2])"
17025 [(set (match_dup 0)
17026 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17029 (and:QI (match_dup 2) (match_dup 3)))])])
17032 [(set (match_operand 0 "flags_reg_operand" "")
17033 (match_operator 1 "compare_operator"
17036 (match_operand 2 "ext_register_operand" "")
17039 (match_operand 3 "const_int_operand" ""))
17041 "! TARGET_PARTIAL_REG_STALL
17042 && ix86_match_ccmode (insn, CCNOmode)
17043 && true_regnum (operands[2]) != AX_REG
17044 && peep2_reg_dead_p (1, operands[2])"
17045 [(parallel [(set (match_dup 0)
17054 (set (zero_extract:SI (match_dup 2)
17062 (match_dup 3)))])])
17064 ;; Don't do logical operations with memory inputs.
17066 [(match_scratch:SI 2 "r")
17067 (parallel [(set (match_operand:SI 0 "register_operand" "")
17068 (match_operator:SI 3 "arith_or_logical_operator"
17070 (match_operand:SI 1 "memory_operand" "")]))
17071 (clobber (reg:CC FLAGS_REG))])]
17072 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17073 [(set (match_dup 2) (match_dup 1))
17074 (parallel [(set (match_dup 0)
17075 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17076 (clobber (reg:CC FLAGS_REG))])])
17079 [(match_scratch:SI 2 "r")
17080 (parallel [(set (match_operand:SI 0 "register_operand" "")
17081 (match_operator:SI 3 "arith_or_logical_operator"
17082 [(match_operand:SI 1 "memory_operand" "")
17084 (clobber (reg:CC FLAGS_REG))])]
17085 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17086 [(set (match_dup 2) (match_dup 1))
17087 (parallel [(set (match_dup 0)
17088 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17089 (clobber (reg:CC FLAGS_REG))])])
17091 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17092 ;; refers to the destination of the load!
17095 [(set (match_operand:SI 0 "register_operand" "")
17096 (match_operand:SI 1 "register_operand" ""))
17097 (parallel [(set (match_dup 0)
17098 (match_operator:SI 3 "commutative_operator"
17100 (match_operand:SI 2 "memory_operand" "")]))
17101 (clobber (reg:CC FLAGS_REG))])]
17102 "REGNO (operands[0]) != REGNO (operands[1])
17103 && GENERAL_REGNO_P (REGNO (operands[0]))
17104 && GENERAL_REGNO_P (REGNO (operands[1]))"
17105 [(set (match_dup 0) (match_dup 4))
17106 (parallel [(set (match_dup 0)
17107 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17108 (clobber (reg:CC FLAGS_REG))])]
17109 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17112 [(set (match_operand 0 "register_operand" "")
17113 (match_operand 1 "register_operand" ""))
17115 (match_operator 3 "commutative_operator"
17117 (match_operand 2 "memory_operand" "")]))]
17118 "REGNO (operands[0]) != REGNO (operands[1])
17119 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17120 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17121 [(set (match_dup 0) (match_dup 2))
17123 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17125 ; Don't do logical operations with memory outputs
17127 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17128 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17129 ; the same decoder scheduling characteristics as the original.
17132 [(match_scratch:SI 2 "r")
17133 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17134 (match_operator:SI 3 "arith_or_logical_operator"
17136 (match_operand:SI 1 "nonmemory_operand" "")]))
17137 (clobber (reg:CC FLAGS_REG))])]
17138 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17139 /* Do not split stack checking probes. */
17140 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17141 [(set (match_dup 2) (match_dup 0))
17142 (parallel [(set (match_dup 2)
17143 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17144 (clobber (reg:CC FLAGS_REG))])
17145 (set (match_dup 0) (match_dup 2))])
17148 [(match_scratch:SI 2 "r")
17149 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17150 (match_operator:SI 3 "arith_or_logical_operator"
17151 [(match_operand:SI 1 "nonmemory_operand" "")
17153 (clobber (reg:CC FLAGS_REG))])]
17154 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17155 /* Do not split stack checking probes. */
17156 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17157 [(set (match_dup 2) (match_dup 0))
17158 (parallel [(set (match_dup 2)
17159 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17160 (clobber (reg:CC FLAGS_REG))])
17161 (set (match_dup 0) (match_dup 2))])
17163 ;; Attempt to use arith or logical operations with memory outputs with
17164 ;; setting of flags.
17166 [(set (match_operand:SWI 0 "register_operand" "")
17167 (match_operand:SWI 1 "memory_operand" ""))
17168 (parallel [(set (match_dup 0)
17169 (match_operator:SWI 3 "plusminuslogic_operator"
17171 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17172 (clobber (reg:CC FLAGS_REG))])
17173 (set (match_dup 1) (match_dup 0))
17174 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17175 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17176 && peep2_reg_dead_p (4, operands[0])
17177 && !reg_overlap_mentioned_p (operands[0], operands[1])
17178 && ix86_match_ccmode (peep2_next_insn (3),
17179 (GET_CODE (operands[3]) == PLUS
17180 || GET_CODE (operands[3]) == MINUS)
17181 ? CCGOCmode : CCNOmode)"
17182 [(parallel [(set (match_dup 4) (match_dup 5))
17183 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17184 (match_dup 2)]))])]
17186 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17187 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17188 copy_rtx (operands[1]),
17189 copy_rtx (operands[2]));
17190 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17191 operands[5], const0_rtx);
17195 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17196 (match_operator:SWI 2 "plusminuslogic_operator"
17198 (match_operand:SWI 1 "memory_operand" "")]))
17199 (clobber (reg:CC FLAGS_REG))])
17200 (set (match_dup 1) (match_dup 0))
17201 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17202 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17203 && GET_CODE (operands[2]) != MINUS
17204 && peep2_reg_dead_p (3, operands[0])
17205 && !reg_overlap_mentioned_p (operands[0], operands[1])
17206 && ix86_match_ccmode (peep2_next_insn (2),
17207 GET_CODE (operands[2]) == PLUS
17208 ? CCGOCmode : CCNOmode)"
17209 [(parallel [(set (match_dup 3) (match_dup 4))
17210 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17211 (match_dup 0)]))])]
17213 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17214 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17215 copy_rtx (operands[1]),
17216 copy_rtx (operands[0]));
17217 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17218 operands[4], const0_rtx);
17222 [(set (match_operand:SWI12 0 "register_operand" "")
17223 (match_operand:SWI12 1 "memory_operand" ""))
17224 (parallel [(set (match_operand:SI 4 "register_operand" "")
17225 (match_operator:SI 3 "plusminuslogic_operator"
17227 (match_operand:SI 2 "nonmemory_operand" "")]))
17228 (clobber (reg:CC FLAGS_REG))])
17229 (set (match_dup 1) (match_dup 0))
17230 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17231 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17232 && REG_P (operands[0]) && REG_P (operands[4])
17233 && REGNO (operands[0]) == REGNO (operands[4])
17234 && peep2_reg_dead_p (4, operands[0])
17235 && (<MODE>mode != QImode
17236 || immediate_operand (operands[2], SImode)
17237 || q_regs_operand (operands[2], SImode))
17238 && !reg_overlap_mentioned_p (operands[0], operands[1])
17239 && ix86_match_ccmode (peep2_next_insn (3),
17240 (GET_CODE (operands[3]) == PLUS
17241 || GET_CODE (operands[3]) == MINUS)
17242 ? CCGOCmode : CCNOmode)"
17243 [(parallel [(set (match_dup 4) (match_dup 5))
17244 (set (match_dup 1) (match_dup 6))])]
17246 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17247 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17248 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17249 copy_rtx (operands[1]), operands[2]);
17250 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17251 operands[5], const0_rtx);
17252 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17253 copy_rtx (operands[1]),
17254 copy_rtx (operands[2]));
17257 ;; Attempt to always use XOR for zeroing registers.
17259 [(set (match_operand 0 "register_operand" "")
17260 (match_operand 1 "const0_operand" ""))]
17261 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17262 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17263 && GENERAL_REG_P (operands[0])
17264 && peep2_regno_dead_p (0, FLAGS_REG)"
17265 [(parallel [(set (match_dup 0) (const_int 0))
17266 (clobber (reg:CC FLAGS_REG))])]
17267 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17270 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17272 "(GET_MODE (operands[0]) == QImode
17273 || GET_MODE (operands[0]) == HImode)
17274 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17275 && peep2_regno_dead_p (0, FLAGS_REG)"
17276 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17277 (clobber (reg:CC FLAGS_REG))])])
17279 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17281 [(set (match_operand:SWI248 0 "register_operand" "")
17283 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17284 && peep2_regno_dead_p (0, FLAGS_REG)"
17285 [(parallel [(set (match_dup 0) (const_int -1))
17286 (clobber (reg:CC FLAGS_REG))])]
17288 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17289 operands[0] = gen_lowpart (SImode, operands[0]);
17292 ;; Attempt to convert simple lea to add/shift.
17293 ;; These can be created by move expanders.
17296 [(set (match_operand:SWI48 0 "register_operand" "")
17297 (plus:SWI48 (match_dup 0)
17298 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17299 "peep2_regno_dead_p (0, FLAGS_REG)"
17300 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17301 (clobber (reg:CC FLAGS_REG))])])
17304 [(set (match_operand:SI 0 "register_operand" "")
17305 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17306 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17308 && peep2_regno_dead_p (0, FLAGS_REG)
17309 && REGNO (operands[0]) == REGNO (operands[1])"
17310 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17311 (clobber (reg:CC FLAGS_REG))])]
17312 "operands[2] = gen_lowpart (SImode, operands[2]);")
17315 [(set (match_operand:SWI48 0 "register_operand" "")
17316 (mult:SWI48 (match_dup 0)
17317 (match_operand:SWI48 1 "const_int_operand" "")))]
17318 "exact_log2 (INTVAL (operands[1])) >= 0
17319 && peep2_regno_dead_p (0, FLAGS_REG)"
17320 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17321 (clobber (reg:CC FLAGS_REG))])]
17322 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17325 [(set (match_operand:SI 0 "register_operand" "")
17326 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17327 (match_operand:DI 2 "const_int_operand" "")) 0))]
17329 && exact_log2 (INTVAL (operands[2])) >= 0
17330 && REGNO (operands[0]) == REGNO (operands[1])
17331 && peep2_regno_dead_p (0, FLAGS_REG)"
17332 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17333 (clobber (reg:CC FLAGS_REG))])]
17334 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17336 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17337 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17338 ;; On many CPUs it is also faster, since special hardware to avoid esp
17339 ;; dependencies is present.
17341 ;; While some of these conversions may be done using splitters, we use
17342 ;; peepholes in order to allow combine_stack_adjustments pass to see
17343 ;; nonobfuscated RTL.
17345 ;; Convert prologue esp subtractions to push.
17346 ;; We need register to push. In order to keep verify_flow_info happy we have
17348 ;; - use scratch and clobber it in order to avoid dependencies
17349 ;; - use already live register
17350 ;; We can't use the second way right now, since there is no reliable way how to
17351 ;; verify that given register is live. First choice will also most likely in
17352 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17353 ;; call clobbered registers are dead. We may want to use base pointer as an
17354 ;; alternative when no register is available later.
17357 [(match_scratch:P 1 "r")
17358 (parallel [(set (reg:P SP_REG)
17359 (plus:P (reg:P SP_REG)
17360 (match_operand:P 0 "const_int_operand" "")))
17361 (clobber (reg:CC FLAGS_REG))
17362 (clobber (mem:BLK (scratch)))])]
17363 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17364 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17365 [(clobber (match_dup 1))
17366 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17367 (clobber (mem:BLK (scratch)))])])
17370 [(match_scratch:P 1 "r")
17371 (parallel [(set (reg:P SP_REG)
17372 (plus:P (reg:P SP_REG)
17373 (match_operand:P 0 "const_int_operand" "")))
17374 (clobber (reg:CC FLAGS_REG))
17375 (clobber (mem:BLK (scratch)))])]
17376 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17377 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17378 [(clobber (match_dup 1))
17379 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17380 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17381 (clobber (mem:BLK (scratch)))])])
17383 ;; Convert esp subtractions to push.
17385 [(match_scratch:P 1 "r")
17386 (parallel [(set (reg:P SP_REG)
17387 (plus:P (reg:P SP_REG)
17388 (match_operand:P 0 "const_int_operand" "")))
17389 (clobber (reg:CC FLAGS_REG))])]
17390 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17391 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17392 [(clobber (match_dup 1))
17393 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17396 [(match_scratch:P 1 "r")
17397 (parallel [(set (reg:P SP_REG)
17398 (plus:P (reg:P SP_REG)
17399 (match_operand:P 0 "const_int_operand" "")))
17400 (clobber (reg:CC FLAGS_REG))])]
17401 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17402 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17403 [(clobber (match_dup 1))
17404 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17405 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17407 ;; Convert epilogue deallocator to pop.
17409 [(match_scratch:P 1 "r")
17410 (parallel [(set (reg:P SP_REG)
17411 (plus:P (reg:P SP_REG)
17412 (match_operand:P 0 "const_int_operand" "")))
17413 (clobber (reg:CC FLAGS_REG))
17414 (clobber (mem:BLK (scratch)))])]
17415 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17416 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17417 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17418 (clobber (mem:BLK (scratch)))])])
17420 ;; Two pops case is tricky, since pop causes dependency
17421 ;; on destination register. We use two registers if available.
17423 [(match_scratch:P 1 "r")
17424 (match_scratch:P 2 "r")
17425 (parallel [(set (reg:P SP_REG)
17426 (plus:P (reg:P SP_REG)
17427 (match_operand:P 0 "const_int_operand" "")))
17428 (clobber (reg:CC FLAGS_REG))
17429 (clobber (mem:BLK (scratch)))])]
17430 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17431 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17432 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17433 (clobber (mem:BLK (scratch)))])
17434 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17437 [(match_scratch:P 1 "r")
17438 (parallel [(set (reg:P SP_REG)
17439 (plus:P (reg:P SP_REG)
17440 (match_operand:P 0 "const_int_operand" "")))
17441 (clobber (reg:CC FLAGS_REG))
17442 (clobber (mem:BLK (scratch)))])]
17443 "optimize_insn_for_size_p ()
17444 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17445 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17446 (clobber (mem:BLK (scratch)))])
17447 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17449 ;; Convert esp additions to pop.
17451 [(match_scratch:P 1 "r")
17452 (parallel [(set (reg:P SP_REG)
17453 (plus:P (reg:P SP_REG)
17454 (match_operand:P 0 "const_int_operand" "")))
17455 (clobber (reg:CC FLAGS_REG))])]
17456 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17457 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17459 ;; Two pops case is tricky, since pop causes dependency
17460 ;; on destination register. We use two registers if available.
17462 [(match_scratch:P 1 "r")
17463 (match_scratch:P 2 "r")
17464 (parallel [(set (reg:P SP_REG)
17465 (plus:P (reg:P SP_REG)
17466 (match_operand:P 0 "const_int_operand" "")))
17467 (clobber (reg:CC FLAGS_REG))])]
17468 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17469 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17470 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17473 [(match_scratch:P 1 "r")
17474 (parallel [(set (reg:P SP_REG)
17475 (plus:P (reg:P SP_REG)
17476 (match_operand:P 0 "const_int_operand" "")))
17477 (clobber (reg:CC FLAGS_REG))])]
17478 "optimize_insn_for_size_p ()
17479 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17480 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17481 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17483 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17484 ;; required and register dies. Similarly for 128 to -128.
17486 [(set (match_operand 0 "flags_reg_operand" "")
17487 (match_operator 1 "compare_operator"
17488 [(match_operand 2 "register_operand" "")
17489 (match_operand 3 "const_int_operand" "")]))]
17490 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17491 && incdec_operand (operands[3], GET_MODE (operands[3])))
17492 || (!TARGET_FUSE_CMP_AND_BRANCH
17493 && INTVAL (operands[3]) == 128))
17494 && ix86_match_ccmode (insn, CCGCmode)
17495 && peep2_reg_dead_p (1, operands[2])"
17496 [(parallel [(set (match_dup 0)
17497 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17498 (clobber (match_dup 2))])])
17500 ;; Convert imul by three, five and nine into lea
17503 [(set (match_operand:SWI48 0 "register_operand" "")
17504 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17505 (match_operand:SWI48 2 "const359_operand" "")))
17506 (clobber (reg:CC FLAGS_REG))])]
17507 "!TARGET_PARTIAL_REG_STALL
17508 || <MODE>mode == SImode
17509 || optimize_function_for_size_p (cfun)"
17510 [(set (match_dup 0)
17511 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17513 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17517 [(set (match_operand:SWI48 0 "register_operand" "")
17518 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17519 (match_operand:SWI48 2 "const359_operand" "")))
17520 (clobber (reg:CC FLAGS_REG))])]
17521 "optimize_insn_for_speed_p ()
17522 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17523 [(set (match_dup 0) (match_dup 1))
17525 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17527 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17529 ;; imul $32bit_imm, mem, reg is vector decoded, while
17530 ;; imul $32bit_imm, reg, reg is direct decoded.
17532 [(match_scratch:SWI48 3 "r")
17533 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17534 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17535 (match_operand:SWI48 2 "immediate_operand" "")))
17536 (clobber (reg:CC FLAGS_REG))])]
17537 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17538 && !satisfies_constraint_K (operands[2])"
17539 [(set (match_dup 3) (match_dup 1))
17540 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17541 (clobber (reg:CC FLAGS_REG))])])
17544 [(match_scratch:SI 3 "r")
17545 (parallel [(set (match_operand:DI 0 "register_operand" "")
17547 (mult:SI (match_operand:SI 1 "memory_operand" "")
17548 (match_operand:SI 2 "immediate_operand" ""))))
17549 (clobber (reg:CC FLAGS_REG))])]
17551 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17552 && !satisfies_constraint_K (operands[2])"
17553 [(set (match_dup 3) (match_dup 1))
17554 (parallel [(set (match_dup 0)
17555 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17556 (clobber (reg:CC FLAGS_REG))])])
17558 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17559 ;; Convert it into imul reg, reg
17560 ;; It would be better to force assembler to encode instruction using long
17561 ;; immediate, but there is apparently no way to do so.
17563 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17565 (match_operand:SWI248 1 "nonimmediate_operand" "")
17566 (match_operand:SWI248 2 "const_int_operand" "")))
17567 (clobber (reg:CC FLAGS_REG))])
17568 (match_scratch:SWI248 3 "r")]
17569 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17570 && satisfies_constraint_K (operands[2])"
17571 [(set (match_dup 3) (match_dup 2))
17572 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17573 (clobber (reg:CC FLAGS_REG))])]
17575 if (!rtx_equal_p (operands[0], operands[1]))
17576 emit_move_insn (operands[0], operands[1]);
17579 ;; After splitting up read-modify operations, array accesses with memory
17580 ;; operands might end up in form:
17582 ;; movl 4(%esp), %edx
17584 ;; instead of pre-splitting:
17586 ;; addl 4(%esp), %eax
17588 ;; movl 4(%esp), %edx
17589 ;; leal (%edx,%eax,4), %eax
17592 [(match_scratch:P 5 "r")
17593 (parallel [(set (match_operand 0 "register_operand" "")
17594 (ashift (match_operand 1 "register_operand" "")
17595 (match_operand 2 "const_int_operand" "")))
17596 (clobber (reg:CC FLAGS_REG))])
17597 (parallel [(set (match_operand 3 "register_operand" "")
17598 (plus (match_dup 0)
17599 (match_operand 4 "x86_64_general_operand" "")))
17600 (clobber (reg:CC FLAGS_REG))])]
17601 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17602 /* Validate MODE for lea. */
17603 && ((!TARGET_PARTIAL_REG_STALL
17604 && (GET_MODE (operands[0]) == QImode
17605 || GET_MODE (operands[0]) == HImode))
17606 || GET_MODE (operands[0]) == SImode
17607 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17608 && (rtx_equal_p (operands[0], operands[3])
17609 || peep2_reg_dead_p (2, operands[0]))
17610 /* We reorder load and the shift. */
17611 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17612 [(set (match_dup 5) (match_dup 4))
17613 (set (match_dup 0) (match_dup 1))]
17615 enum machine_mode op1mode = GET_MODE (operands[1]);
17616 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17617 int scale = 1 << INTVAL (operands[2]);
17618 rtx index = gen_lowpart (Pmode, operands[1]);
17619 rtx base = gen_lowpart (Pmode, operands[5]);
17620 rtx dest = gen_lowpart (mode, operands[3]);
17622 operands[1] = gen_rtx_PLUS (Pmode, base,
17623 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17624 operands[5] = base;
17626 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17627 if (op1mode != Pmode)
17628 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17629 operands[0] = dest;
17632 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17633 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17634 ;; caught for use by garbage collectors and the like. Using an insn that
17635 ;; maps to SIGILL makes it more likely the program will rightfully die.
17636 ;; Keeping with tradition, "6" is in honor of #UD.
17637 (define_insn "trap"
17638 [(trap_if (const_int 1) (const_int 6))]
17640 { return ASM_SHORT "0x0b0f"; }
17641 [(set_attr "length" "2")])
17643 (define_expand "prefetch"
17644 [(prefetch (match_operand 0 "address_operand" "")
17645 (match_operand:SI 1 "const_int_operand" "")
17646 (match_operand:SI 2 "const_int_operand" ""))]
17647 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17649 int rw = INTVAL (operands[1]);
17650 int locality = INTVAL (operands[2]);
17652 gcc_assert (rw == 0 || rw == 1);
17653 gcc_assert (locality >= 0 && locality <= 3);
17654 gcc_assert (GET_MODE (operands[0]) == Pmode
17655 || GET_MODE (operands[0]) == VOIDmode);
17657 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17658 supported by SSE counterpart or the SSE prefetch is not available
17659 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17661 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17662 operands[2] = GEN_INT (3);
17664 operands[1] = const0_rtx;
17667 (define_insn "*prefetch_sse_<mode>"
17668 [(prefetch (match_operand:P 0 "address_operand" "p")
17670 (match_operand:SI 1 "const_int_operand" ""))]
17671 "TARGET_PREFETCH_SSE"
17673 static const char * const patterns[4] = {
17674 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17677 int locality = INTVAL (operands[1]);
17678 gcc_assert (locality >= 0 && locality <= 3);
17680 return patterns[locality];
17682 [(set_attr "type" "sse")
17683 (set_attr "atom_sse_attr" "prefetch")
17684 (set (attr "length_address")
17685 (symbol_ref "memory_address_length (operands[0])"))
17686 (set_attr "memory" "none")])
17688 (define_insn "*prefetch_3dnow_<mode>"
17689 [(prefetch (match_operand:P 0 "address_operand" "p")
17690 (match_operand:SI 1 "const_int_operand" "n")
17694 if (INTVAL (operands[1]) == 0)
17695 return "prefetch\t%a0";
17697 return "prefetchw\t%a0";
17699 [(set_attr "type" "mmx")
17700 (set (attr "length_address")
17701 (symbol_ref "memory_address_length (operands[0])"))
17702 (set_attr "memory" "none")])
17704 (define_expand "stack_protect_set"
17705 [(match_operand 0 "memory_operand" "")
17706 (match_operand 1 "memory_operand" "")]
17709 rtx (*insn)(rtx, rtx);
17711 #ifdef TARGET_THREAD_SSP_OFFSET
17712 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17713 insn = (TARGET_LP64
17714 ? gen_stack_tls_protect_set_di
17715 : gen_stack_tls_protect_set_si);
17717 insn = (TARGET_LP64
17718 ? gen_stack_protect_set_di
17719 : gen_stack_protect_set_si);
17722 emit_insn (insn (operands[0], operands[1]));
17726 (define_insn "stack_protect_set_<mode>"
17727 [(set (match_operand:PTR 0 "memory_operand" "=m")
17728 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17730 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17731 (clobber (reg:CC FLAGS_REG))]
17733 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17734 [(set_attr "type" "multi")])
17736 (define_insn "stack_tls_protect_set_<mode>"
17737 [(set (match_operand:PTR 0 "memory_operand" "=m")
17738 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17739 UNSPEC_SP_TLS_SET))
17740 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17741 (clobber (reg:CC FLAGS_REG))]
17743 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17744 [(set_attr "type" "multi")])
17746 (define_expand "stack_protect_test"
17747 [(match_operand 0 "memory_operand" "")
17748 (match_operand 1 "memory_operand" "")
17749 (match_operand 2 "" "")]
17752 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17754 rtx (*insn)(rtx, rtx, rtx);
17756 #ifdef TARGET_THREAD_SSP_OFFSET
17757 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17758 insn = (TARGET_LP64
17759 ? gen_stack_tls_protect_test_di
17760 : gen_stack_tls_protect_test_si);
17762 insn = (TARGET_LP64
17763 ? gen_stack_protect_test_di
17764 : gen_stack_protect_test_si);
17767 emit_insn (insn (flags, operands[0], operands[1]));
17769 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17770 flags, const0_rtx, operands[2]));
17774 (define_insn "stack_protect_test_<mode>"
17775 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17776 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17777 (match_operand:PTR 2 "memory_operand" "m")]
17779 (clobber (match_scratch:PTR 3 "=&r"))]
17781 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17782 [(set_attr "type" "multi")])
17784 (define_insn "stack_tls_protect_test_<mode>"
17785 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17786 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17787 (match_operand:PTR 2 "const_int_operand" "i")]
17788 UNSPEC_SP_TLS_TEST))
17789 (clobber (match_scratch:PTR 3 "=r"))]
17791 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17792 [(set_attr "type" "multi")])
17794 (define_insn "sse4_2_crc32<mode>"
17795 [(set (match_operand:SI 0 "register_operand" "=r")
17797 [(match_operand:SI 1 "register_operand" "0")
17798 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17800 "TARGET_SSE4_2 || TARGET_CRC32"
17801 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17802 [(set_attr "type" "sselog1")
17803 (set_attr "prefix_rep" "1")
17804 (set_attr "prefix_extra" "1")
17805 (set (attr "prefix_data16")
17806 (if_then_else (match_operand:HI 2 "" "")
17808 (const_string "*")))
17809 (set (attr "prefix_rex")
17810 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17812 (const_string "*")))
17813 (set_attr "mode" "SI")])
17815 (define_insn "sse4_2_crc32di"
17816 [(set (match_operand:DI 0 "register_operand" "=r")
17818 [(match_operand:DI 1 "register_operand" "0")
17819 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17821 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17822 "crc32{q}\t{%2, %0|%0, %2}"
17823 [(set_attr "type" "sselog1")
17824 (set_attr "prefix_rep" "1")
17825 (set_attr "prefix_extra" "1")
17826 (set_attr "mode" "DI")])
17828 (define_expand "rdpmc"
17829 [(match_operand:DI 0 "register_operand" "")
17830 (match_operand:SI 1 "register_operand" "")]
17833 rtx reg = gen_reg_rtx (DImode);
17836 /* Force operand 1 into ECX. */
17837 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17838 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17839 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17844 rtvec vec = rtvec_alloc (2);
17845 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17846 rtx upper = gen_reg_rtx (DImode);
17847 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17848 gen_rtvec (1, const0_rtx),
17850 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17851 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17853 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17854 NULL, 1, OPTAB_DIRECT);
17855 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17859 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17860 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17864 (define_insn "*rdpmc"
17865 [(set (match_operand:DI 0 "register_operand" "=A")
17866 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17870 [(set_attr "type" "other")
17871 (set_attr "length" "2")])
17873 (define_insn "*rdpmc_rex64"
17874 [(set (match_operand:DI 0 "register_operand" "=a")
17875 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17877 (set (match_operand:DI 1 "register_operand" "=d")
17878 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17881 [(set_attr "type" "other")
17882 (set_attr "length" "2")])
17884 (define_expand "rdtsc"
17885 [(set (match_operand:DI 0 "register_operand" "")
17886 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17891 rtvec vec = rtvec_alloc (2);
17892 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17893 rtx upper = gen_reg_rtx (DImode);
17894 rtx lower = gen_reg_rtx (DImode);
17895 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17896 gen_rtvec (1, const0_rtx),
17898 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17899 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17901 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17902 NULL, 1, OPTAB_DIRECT);
17903 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17905 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17910 (define_insn "*rdtsc"
17911 [(set (match_operand:DI 0 "register_operand" "=A")
17912 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17915 [(set_attr "type" "other")
17916 (set_attr "length" "2")])
17918 (define_insn "*rdtsc_rex64"
17919 [(set (match_operand:DI 0 "register_operand" "=a")
17920 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17921 (set (match_operand:DI 1 "register_operand" "=d")
17922 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17925 [(set_attr "type" "other")
17926 (set_attr "length" "2")])
17928 (define_expand "rdtscp"
17929 [(match_operand:DI 0 "register_operand" "")
17930 (match_operand:SI 1 "memory_operand" "")]
17933 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17934 gen_rtvec (1, const0_rtx),
17936 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17937 gen_rtvec (1, const0_rtx),
17939 rtx reg = gen_reg_rtx (DImode);
17940 rtx tmp = gen_reg_rtx (SImode);
17944 rtvec vec = rtvec_alloc (3);
17945 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17946 rtx upper = gen_reg_rtx (DImode);
17947 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17948 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17949 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17951 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17952 NULL, 1, OPTAB_DIRECT);
17953 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17958 rtvec vec = rtvec_alloc (2);
17959 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17960 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17961 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17964 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17965 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17969 (define_insn "*rdtscp"
17970 [(set (match_operand:DI 0 "register_operand" "=A")
17971 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17972 (set (match_operand:SI 1 "register_operand" "=c")
17973 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17976 [(set_attr "type" "other")
17977 (set_attr "length" "3")])
17979 (define_insn "*rdtscp_rex64"
17980 [(set (match_operand:DI 0 "register_operand" "=a")
17981 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17982 (set (match_operand:DI 1 "register_operand" "=d")
17983 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17984 (set (match_operand:SI 2 "register_operand" "=c")
17985 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17988 [(set_attr "type" "other")
17989 (set_attr "length" "3")])
17991 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17993 ;; LWP instructions
17995 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17997 (define_expand "lwp_llwpcb"
17998 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17999 UNSPECV_LLWP_INTRINSIC)]
18002 (define_insn "*lwp_llwpcb<mode>1"
18003 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18004 UNSPECV_LLWP_INTRINSIC)]
18007 [(set_attr "type" "lwp")
18008 (set_attr "mode" "<MODE>")
18009 (set_attr "length" "5")])
18011 (define_expand "lwp_slwpcb"
18012 [(set (match_operand 0 "register_operand" "=r")
18013 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18018 insn = (TARGET_64BIT
18020 : gen_lwp_slwpcbsi);
18022 emit_insn (insn (operands[0]));
18026 (define_insn "lwp_slwpcb<mode>"
18027 [(set (match_operand:P 0 "register_operand" "=r")
18028 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18031 [(set_attr "type" "lwp")
18032 (set_attr "mode" "<MODE>")
18033 (set_attr "length" "5")])
18035 (define_expand "lwp_lwpval<mode>3"
18036 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18037 (match_operand:SI 2 "nonimmediate_operand" "rm")
18038 (match_operand:SI 3 "const_int_operand" "i")]
18039 UNSPECV_LWPVAL_INTRINSIC)]
18041 ;; Avoid unused variable warning.
18042 "(void) operands[0];")
18044 (define_insn "*lwp_lwpval<mode>3_1"
18045 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18046 (match_operand:SI 1 "nonimmediate_operand" "rm")
18047 (match_operand:SI 2 "const_int_operand" "i")]
18048 UNSPECV_LWPVAL_INTRINSIC)]
18050 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18051 [(set_attr "type" "lwp")
18052 (set_attr "mode" "<MODE>")
18053 (set (attr "length")
18054 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18056 (define_expand "lwp_lwpins<mode>3"
18057 [(set (reg:CCC FLAGS_REG)
18058 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18059 (match_operand:SI 2 "nonimmediate_operand" "rm")
18060 (match_operand:SI 3 "const_int_operand" "i")]
18061 UNSPECV_LWPINS_INTRINSIC))
18062 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18063 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18066 (define_insn "*lwp_lwpins<mode>3_1"
18067 [(set (reg:CCC FLAGS_REG)
18068 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18069 (match_operand:SI 1 "nonimmediate_operand" "rm")
18070 (match_operand:SI 2 "const_int_operand" "i")]
18071 UNSPECV_LWPINS_INTRINSIC))]
18073 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18074 [(set_attr "type" "lwp")
18075 (set_attr "mode" "<MODE>")
18076 (set (attr "length")
18077 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18079 (define_insn "rdfsbase<mode>"
18080 [(set (match_operand:SWI48 0 "register_operand" "=r")
18081 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18082 "TARGET_64BIT && TARGET_FSGSBASE"
18084 [(set_attr "type" "other")
18085 (set_attr "prefix_extra" "2")])
18087 (define_insn "rdgsbase<mode>"
18088 [(set (match_operand:SWI48 0 "register_operand" "=r")
18089 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18090 "TARGET_64BIT && TARGET_FSGSBASE"
18092 [(set_attr "type" "other")
18093 (set_attr "prefix_extra" "2")])
18095 (define_insn "wrfsbase<mode>"
18096 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18098 "TARGET_64BIT && TARGET_FSGSBASE"
18100 [(set_attr "type" "other")
18101 (set_attr "prefix_extra" "2")])
18103 (define_insn "wrgsbase<mode>"
18104 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18106 "TARGET_64BIT && TARGET_FSGSBASE"
18108 [(set_attr "type" "other")
18109 (set_attr "prefix_extra" "2")])
18111 (define_insn "rdrand<mode>_1"
18112 [(set (match_operand:SWI248 0 "register_operand" "=r")
18113 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18114 (set (reg:CCC FLAGS_REG)
18115 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18118 [(set_attr "type" "other")
18119 (set_attr "prefix_extra" "1")])
18121 (define_expand "pause"
18122 [(set (match_dup 0)
18123 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18126 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18127 MEM_VOLATILE_P (operands[0]) = 1;
18130 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18131 ;; They have the same encoding.
18132 (define_insn "*pause"
18133 [(set (match_operand:BLK 0 "" "")
18134 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18137 [(set_attr "length" "2")
18138 (set_attr "memory" "unknown")])
18142 (include "sync.md")