1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; E -- print address with DImode register names if TARGET_64BIT.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; p -- print raw symbol name.
58 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
59 ;; & -- print some in-use local-dynamic symbol name.
60 ;; H -- print a memory address offset by 8; used for sse high-parts
61 ;; Y -- print condition for XOP pcom* instruction.
62 ;; + -- print a branch hint as 'cs' or 'ds' prefix
63 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
64 ;; @ -- print a segment register of thread base pointer load
66 (define_c_enum "unspec" [
67 ;; Relocation specifiers
78 UNSPEC_MACHOPIC_OFFSET
86 UNSPEC_MEMORY_BLOCKAGE
96 ;; Other random patterns
105 UNSPEC_LD_MPIC ; load_macho_picbase
107 UNSPEC_DIV_ALREADY_SPLIT
108 UNSPEC_MS_TO_SYSV_CALL
109 UNSPEC_CALL_NEEDS_VZEROUPPER
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
181 (define_c_enum "unspecv" [
184 UNSPECV_PROBE_STACK_RANGE
187 UNSPECV_SPLIT_STACK_RETURN
193 UNSPECV_LLWP_INTRINSIC
194 UNSPECV_SLWP_INTRINSIC
195 UNSPECV_LWPVAL_INTRINSIC
196 UNSPECV_LWPINS_INTRINSIC
202 ;; For RDRAND support
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,
633 (const_string "base"))
635 (define_attr "enabled" ""
636 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
637 (eq_attr "isa" "sse2_noavx")
638 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
639 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
640 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
641 (eq_attr "isa" "sse4_noavx")
642 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
643 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
644 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
645 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
646 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
647 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
651 ;; Describe a user's asm statement.
652 (define_asm_attributes
653 [(set_attr "length" "128")
654 (set_attr "type" "multi")])
656 (define_code_iterator plusminus [plus minus])
658 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
660 ;; Base name for define_insn
661 (define_code_attr plusminus_insn
662 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
663 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
665 ;; Base name for insn mnemonic.
666 (define_code_attr plusminus_mnemonic
667 [(plus "add") (ss_plus "adds") (us_plus "addus")
668 (minus "sub") (ss_minus "subs") (us_minus "subus")])
669 (define_code_attr plusminus_carry_mnemonic
670 [(plus "adc") (minus "sbb")])
672 ;; Mark commutative operators as such in constraints.
673 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
674 (minus "") (ss_minus "") (us_minus "")])
676 ;; Mapping of max and min
677 (define_code_iterator maxmin [smax smin umax umin])
679 ;; Mapping of signed max and min
680 (define_code_iterator smaxmin [smax smin])
682 ;; Mapping of unsigned max and min
683 (define_code_iterator umaxmin [umax umin])
685 ;; Base name for integer and FP insn mnemonic
686 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
687 (umax "maxu") (umin "minu")])
688 (define_code_attr maxmin_float [(smax "max") (smin "min")])
690 ;; Mapping of logic operators
691 (define_code_iterator any_logic [and ior xor])
692 (define_code_iterator any_or [ior xor])
694 ;; Base name for insn mnemonic.
695 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
697 ;; Mapping of logic-shift operators
698 (define_code_iterator any_lshift [ashift lshiftrt])
700 ;; Mapping of shift-right operators
701 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
703 ;; Base name for define_insn
704 (define_code_attr shift_insn
705 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
707 ;; Base name for insn mnemonic.
708 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
709 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
711 ;; Mapping of rotate operators
712 (define_code_iterator any_rotate [rotate rotatert])
714 ;; Base name for define_insn
715 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
717 ;; Base name for insn mnemonic.
718 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
720 ;; Mapping of abs neg operators
721 (define_code_iterator absneg [abs neg])
723 ;; Base name for x87 insn mnemonic.
724 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
726 ;; Used in signed and unsigned widening multiplications.
727 (define_code_iterator any_extend [sign_extend zero_extend])
729 ;; Prefix for insn menmonic.
730 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
732 ;; Prefix for define_insn
733 (define_code_attr u [(sign_extend "") (zero_extend "u")])
734 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
736 ;; All integer modes.
737 (define_mode_iterator SWI1248x [QI HI SI DI])
739 ;; All integer modes without QImode.
740 (define_mode_iterator SWI248x [HI SI DI])
742 ;; All integer modes without QImode and HImode.
743 (define_mode_iterator SWI48x [SI DI])
745 ;; All integer modes without SImode and DImode.
746 (define_mode_iterator SWI12 [QI HI])
748 ;; All integer modes without DImode.
749 (define_mode_iterator SWI124 [QI HI SI])
751 ;; All integer modes without QImode and DImode.
752 (define_mode_iterator SWI24 [HI SI])
754 ;; Single word integer modes.
755 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
757 ;; Single word integer modes without QImode.
758 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
760 ;; Single word integer modes without QImode and HImode.
761 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
763 ;; All math-dependant single and double word integer modes.
764 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
765 (HI "TARGET_HIMODE_MATH")
766 SI DI (TI "TARGET_64BIT")])
768 ;; Math-dependant single word integer modes.
769 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
770 (HI "TARGET_HIMODE_MATH")
771 SI (DI "TARGET_64BIT")])
773 ;; Math-dependant integer modes without DImode.
774 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
775 (HI "TARGET_HIMODE_MATH")
778 ;; Math-dependant single word integer modes without QImode.
779 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
780 SI (DI "TARGET_64BIT")])
782 ;; Double word integer modes.
783 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
784 (TI "TARGET_64BIT")])
786 ;; Double word integer modes as mode attribute.
787 (define_mode_attr DWI [(SI "DI") (DI "TI")])
788 (define_mode_attr dwi [(SI "di") (DI "ti")])
790 ;; Half mode for double word integer modes.
791 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
792 (DI "TARGET_64BIT")])
794 ;; Instruction suffix for integer modes.
795 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
797 ;; Pointer size prefix for integer modes (Intel asm dialect)
798 (define_mode_attr iptrsize [(QI "BYTE")
803 ;; Register class for integer modes.
804 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
806 ;; Immediate operand constraint for integer modes.
807 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
809 ;; General operand constraint for word modes.
810 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
812 ;; Immediate operand constraint for double integer modes.
813 (define_mode_attr di [(SI "nF") (DI "e")])
815 ;; Immediate operand constraint for shifts.
816 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
818 ;; General operand predicate for integer modes.
819 (define_mode_attr general_operand
820 [(QI "general_operand")
821 (HI "general_operand")
822 (SI "x86_64_general_operand")
823 (DI "x86_64_general_operand")
824 (TI "x86_64_general_operand")])
826 ;; General sign/zero extend operand predicate for integer modes.
827 (define_mode_attr general_szext_operand
828 [(QI "general_operand")
829 (HI "general_operand")
830 (SI "x86_64_szext_general_operand")
831 (DI "x86_64_szext_general_operand")])
833 ;; Immediate operand predicate for integer modes.
834 (define_mode_attr immediate_operand
835 [(QI "immediate_operand")
836 (HI "immediate_operand")
837 (SI "x86_64_immediate_operand")
838 (DI "x86_64_immediate_operand")])
840 ;; Nonmemory operand predicate for integer modes.
841 (define_mode_attr nonmemory_operand
842 [(QI "nonmemory_operand")
843 (HI "nonmemory_operand")
844 (SI "x86_64_nonmemory_operand")
845 (DI "x86_64_nonmemory_operand")])
847 ;; Operand predicate for shifts.
848 (define_mode_attr shift_operand
849 [(QI "nonimmediate_operand")
850 (HI "nonimmediate_operand")
851 (SI "nonimmediate_operand")
852 (DI "shiftdi_operand")
853 (TI "register_operand")])
855 ;; Operand predicate for shift argument.
856 (define_mode_attr shift_immediate_operand
857 [(QI "const_1_to_31_operand")
858 (HI "const_1_to_31_operand")
859 (SI "const_1_to_31_operand")
860 (DI "const_1_to_63_operand")])
862 ;; Input operand predicate for arithmetic left shifts.
863 (define_mode_attr ashl_input_operand
864 [(QI "nonimmediate_operand")
865 (HI "nonimmediate_operand")
866 (SI "nonimmediate_operand")
867 (DI "ashldi_input_operand")
868 (TI "reg_or_pm1_operand")])
870 ;; SSE and x87 SFmode and DFmode floating point modes
871 (define_mode_iterator MODEF [SF DF])
873 ;; All x87 floating point modes
874 (define_mode_iterator X87MODEF [SF DF XF])
876 ;; SSE instruction suffix for various modes
877 (define_mode_attr ssemodesuffix
879 (V8SF "ps") (V4DF "pd")
880 (V4SF "ps") (V2DF "pd")
881 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
882 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
884 ;; SSE vector suffix for floating point modes
885 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
887 ;; SSE vector mode corresponding to a scalar mode
888 (define_mode_attr ssevecmode
889 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
891 ;; Instruction suffix for REX 64bit operators.
892 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
894 ;; This mode iterator allows :P to be used for patterns that operate on
895 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
896 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
898 ;; This mode iterator allows :PTR to be used for patterns that operate on
899 ;; ptr_mode sized quantities.
900 (define_mode_iterator PTR
901 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
903 ;; Scheduling descriptions
905 (include "pentium.md")
908 (include "athlon.md")
909 (include "bdver1.md")
915 ;; Operand and operator predicates and constraints
917 (include "predicates.md")
918 (include "constraints.md")
921 ;; Compare and branch/compare and store instructions.
923 (define_expand "cbranch<mode>4"
924 [(set (reg:CC FLAGS_REG)
925 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
926 (match_operand:SDWIM 2 "<general_operand>" "")))
927 (set (pc) (if_then_else
928 (match_operator 0 "ordered_comparison_operator"
929 [(reg:CC FLAGS_REG) (const_int 0)])
930 (label_ref (match_operand 3 "" ""))
934 if (MEM_P (operands[1]) && MEM_P (operands[2]))
935 operands[1] = force_reg (<MODE>mode, operands[1]);
936 ix86_expand_branch (GET_CODE (operands[0]),
937 operands[1], operands[2], operands[3]);
941 (define_expand "cstore<mode>4"
942 [(set (reg:CC FLAGS_REG)
943 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
944 (match_operand:SWIM 3 "<general_operand>" "")))
945 (set (match_operand:QI 0 "register_operand" "")
946 (match_operator 1 "ordered_comparison_operator"
947 [(reg:CC FLAGS_REG) (const_int 0)]))]
950 if (MEM_P (operands[2]) && MEM_P (operands[3]))
951 operands[2] = force_reg (<MODE>mode, operands[2]);
952 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
953 operands[2], operands[3]);
957 (define_expand "cmp<mode>_1"
958 [(set (reg:CC FLAGS_REG)
959 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
960 (match_operand:SWI48 1 "<general_operand>" "")))])
962 (define_insn "*cmp<mode>_ccno_1"
963 [(set (reg FLAGS_REG)
964 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
965 (match_operand:SWI 1 "const0_operand" "")))]
966 "ix86_match_ccmode (insn, CCNOmode)"
968 test{<imodesuffix>}\t%0, %0
969 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
970 [(set_attr "type" "test,icmp")
971 (set_attr "length_immediate" "0,1")
972 (set_attr "mode" "<MODE>")])
974 (define_insn "*cmp<mode>_1"
975 [(set (reg FLAGS_REG)
976 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
977 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
978 "ix86_match_ccmode (insn, CCmode)"
979 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
980 [(set_attr "type" "icmp")
981 (set_attr "mode" "<MODE>")])
983 (define_insn "*cmp<mode>_minus_1"
984 [(set (reg FLAGS_REG)
986 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
987 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
989 "ix86_match_ccmode (insn, CCGOCmode)"
990 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
991 [(set_attr "type" "icmp")
992 (set_attr "mode" "<MODE>")])
994 (define_insn "*cmpqi_ext_1"
995 [(set (reg FLAGS_REG)
997 (match_operand:QI 0 "general_operand" "Qm")
1000 (match_operand 1 "ext_register_operand" "Q")
1002 (const_int 8)) 0)))]
1003 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1004 "cmp{b}\t{%h1, %0|%0, %h1}"
1005 [(set_attr "type" "icmp")
1006 (set_attr "mode" "QI")])
1008 (define_insn "*cmpqi_ext_1_rex64"
1009 [(set (reg FLAGS_REG)
1011 (match_operand:QI 0 "register_operand" "Q")
1014 (match_operand 1 "ext_register_operand" "Q")
1016 (const_int 8)) 0)))]
1017 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1018 "cmp{b}\t{%h1, %0|%0, %h1}"
1019 [(set_attr "type" "icmp")
1020 (set_attr "mode" "QI")])
1022 (define_insn "*cmpqi_ext_2"
1023 [(set (reg FLAGS_REG)
1027 (match_operand 0 "ext_register_operand" "Q")
1030 (match_operand:QI 1 "const0_operand" "")))]
1031 "ix86_match_ccmode (insn, CCNOmode)"
1033 [(set_attr "type" "test")
1034 (set_attr "length_immediate" "0")
1035 (set_attr "mode" "QI")])
1037 (define_expand "cmpqi_ext_3"
1038 [(set (reg:CC FLAGS_REG)
1042 (match_operand 0 "ext_register_operand" "")
1045 (match_operand:QI 1 "immediate_operand" "")))])
1047 (define_insn "*cmpqi_ext_3_insn"
1048 [(set (reg FLAGS_REG)
1052 (match_operand 0 "ext_register_operand" "Q")
1055 (match_operand:QI 1 "general_operand" "Qmn")))]
1056 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1057 "cmp{b}\t{%1, %h0|%h0, %1}"
1058 [(set_attr "type" "icmp")
1059 (set_attr "modrm" "1")
1060 (set_attr "mode" "QI")])
1062 (define_insn "*cmpqi_ext_3_insn_rex64"
1063 [(set (reg FLAGS_REG)
1067 (match_operand 0 "ext_register_operand" "Q")
1070 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1071 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1072 "cmp{b}\t{%1, %h0|%h0, %1}"
1073 [(set_attr "type" "icmp")
1074 (set_attr "modrm" "1")
1075 (set_attr "mode" "QI")])
1077 (define_insn "*cmpqi_ext_4"
1078 [(set (reg FLAGS_REG)
1082 (match_operand 0 "ext_register_operand" "Q")
1087 (match_operand 1 "ext_register_operand" "Q")
1089 (const_int 8)) 0)))]
1090 "ix86_match_ccmode (insn, CCmode)"
1091 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1092 [(set_attr "type" "icmp")
1093 (set_attr "mode" "QI")])
1095 ;; These implement float point compares.
1096 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1097 ;; which would allow mix and match FP modes on the compares. Which is what
1098 ;; the old patterns did, but with many more of them.
1100 (define_expand "cbranchxf4"
1101 [(set (reg:CC FLAGS_REG)
1102 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1103 (match_operand:XF 2 "nonmemory_operand" "")))
1104 (set (pc) (if_then_else
1105 (match_operator 0 "ix86_fp_comparison_operator"
1108 (label_ref (match_operand 3 "" ""))
1112 ix86_expand_branch (GET_CODE (operands[0]),
1113 operands[1], operands[2], operands[3]);
1117 (define_expand "cstorexf4"
1118 [(set (reg:CC FLAGS_REG)
1119 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1120 (match_operand:XF 3 "nonmemory_operand" "")))
1121 (set (match_operand:QI 0 "register_operand" "")
1122 (match_operator 1 "ix86_fp_comparison_operator"
1127 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1128 operands[2], operands[3]);
1132 (define_expand "cbranch<mode>4"
1133 [(set (reg:CC FLAGS_REG)
1134 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1135 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1136 (set (pc) (if_then_else
1137 (match_operator 0 "ix86_fp_comparison_operator"
1140 (label_ref (match_operand 3 "" ""))
1142 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1144 ix86_expand_branch (GET_CODE (operands[0]),
1145 operands[1], operands[2], operands[3]);
1149 (define_expand "cstore<mode>4"
1150 [(set (reg:CC FLAGS_REG)
1151 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1152 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1153 (set (match_operand:QI 0 "register_operand" "")
1154 (match_operator 1 "ix86_fp_comparison_operator"
1157 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1159 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1160 operands[2], operands[3]);
1164 (define_expand "cbranchcc4"
1165 [(set (pc) (if_then_else
1166 (match_operator 0 "comparison_operator"
1167 [(match_operand 1 "flags_reg_operand" "")
1168 (match_operand 2 "const0_operand" "")])
1169 (label_ref (match_operand 3 "" ""))
1173 ix86_expand_branch (GET_CODE (operands[0]),
1174 operands[1], operands[2], operands[3]);
1178 (define_expand "cstorecc4"
1179 [(set (match_operand:QI 0 "register_operand" "")
1180 (match_operator 1 "comparison_operator"
1181 [(match_operand 2 "flags_reg_operand" "")
1182 (match_operand 3 "const0_operand" "")]))]
1185 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1186 operands[2], operands[3]);
1191 ;; FP compares, step 1:
1192 ;; Set the FP condition codes.
1194 ;; CCFPmode compare with exceptions
1195 ;; CCFPUmode compare with no exceptions
1197 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1198 ;; used to manage the reg stack popping would not be preserved.
1200 (define_insn "*cmpfp_0"
1201 [(set (match_operand:HI 0 "register_operand" "=a")
1204 (match_operand 1 "register_operand" "f")
1205 (match_operand 2 "const0_operand" ""))]
1207 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1208 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1209 "* return output_fp_compare (insn, operands, false, false);"
1210 [(set_attr "type" "multi")
1211 (set_attr "unit" "i387")
1213 (cond [(match_operand:SF 1 "" "")
1215 (match_operand:DF 1 "" "")
1218 (const_string "XF")))])
1220 (define_insn_and_split "*cmpfp_0_cc"
1221 [(set (reg:CCFP FLAGS_REG)
1223 (match_operand 1 "register_operand" "f")
1224 (match_operand 2 "const0_operand" "")))
1225 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1226 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1227 && TARGET_SAHF && !TARGET_CMOVE
1228 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1230 "&& reload_completed"
1233 [(compare:CCFP (match_dup 1)(match_dup 2))]
1235 (set (reg:CC FLAGS_REG)
1236 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1238 [(set_attr "type" "multi")
1239 (set_attr "unit" "i387")
1241 (cond [(match_operand:SF 1 "" "")
1243 (match_operand:DF 1 "" "")
1246 (const_string "XF")))])
1248 (define_insn "*cmpfp_xf"
1249 [(set (match_operand:HI 0 "register_operand" "=a")
1252 (match_operand:XF 1 "register_operand" "f")
1253 (match_operand:XF 2 "register_operand" "f"))]
1256 "* return output_fp_compare (insn, operands, false, false);"
1257 [(set_attr "type" "multi")
1258 (set_attr "unit" "i387")
1259 (set_attr "mode" "XF")])
1261 (define_insn_and_split "*cmpfp_xf_cc"
1262 [(set (reg:CCFP FLAGS_REG)
1264 (match_operand:XF 1 "register_operand" "f")
1265 (match_operand:XF 2 "register_operand" "f")))
1266 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1268 && TARGET_SAHF && !TARGET_CMOVE"
1270 "&& reload_completed"
1273 [(compare:CCFP (match_dup 1)(match_dup 2))]
1275 (set (reg:CC FLAGS_REG)
1276 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1278 [(set_attr "type" "multi")
1279 (set_attr "unit" "i387")
1280 (set_attr "mode" "XF")])
1282 (define_insn "*cmpfp_<mode>"
1283 [(set (match_operand:HI 0 "register_operand" "=a")
1286 (match_operand:MODEF 1 "register_operand" "f")
1287 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1290 "* return output_fp_compare (insn, operands, false, false);"
1291 [(set_attr "type" "multi")
1292 (set_attr "unit" "i387")
1293 (set_attr "mode" "<MODE>")])
1295 (define_insn_and_split "*cmpfp_<mode>_cc"
1296 [(set (reg:CCFP FLAGS_REG)
1298 (match_operand:MODEF 1 "register_operand" "f")
1299 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1300 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1302 && TARGET_SAHF && !TARGET_CMOVE"
1304 "&& reload_completed"
1307 [(compare:CCFP (match_dup 1)(match_dup 2))]
1309 (set (reg:CC FLAGS_REG)
1310 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1312 [(set_attr "type" "multi")
1313 (set_attr "unit" "i387")
1314 (set_attr "mode" "<MODE>")])
1316 (define_insn "*cmpfp_u"
1317 [(set (match_operand:HI 0 "register_operand" "=a")
1320 (match_operand 1 "register_operand" "f")
1321 (match_operand 2 "register_operand" "f"))]
1323 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1324 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1325 "* return output_fp_compare (insn, operands, false, true);"
1326 [(set_attr "type" "multi")
1327 (set_attr "unit" "i387")
1329 (cond [(match_operand:SF 1 "" "")
1331 (match_operand:DF 1 "" "")
1334 (const_string "XF")))])
1336 (define_insn_and_split "*cmpfp_u_cc"
1337 [(set (reg:CCFPU FLAGS_REG)
1339 (match_operand 1 "register_operand" "f")
1340 (match_operand 2 "register_operand" "f")))
1341 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1342 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1343 && TARGET_SAHF && !TARGET_CMOVE
1344 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1346 "&& reload_completed"
1349 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1351 (set (reg:CC FLAGS_REG)
1352 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1354 [(set_attr "type" "multi")
1355 (set_attr "unit" "i387")
1357 (cond [(match_operand:SF 1 "" "")
1359 (match_operand:DF 1 "" "")
1362 (const_string "XF")))])
1364 (define_insn "*cmpfp_<mode>"
1365 [(set (match_operand:HI 0 "register_operand" "=a")
1368 (match_operand 1 "register_operand" "f")
1369 (match_operator 3 "float_operator"
1370 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1372 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1373 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1374 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1375 "* return output_fp_compare (insn, operands, false, false);"
1376 [(set_attr "type" "multi")
1377 (set_attr "unit" "i387")
1378 (set_attr "fp_int_src" "true")
1379 (set_attr "mode" "<MODE>")])
1381 (define_insn_and_split "*cmpfp_<mode>_cc"
1382 [(set (reg:CCFP FLAGS_REG)
1384 (match_operand 1 "register_operand" "f")
1385 (match_operator 3 "float_operator"
1386 [(match_operand:SWI24 2 "memory_operand" "m")])))
1387 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1388 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1389 && TARGET_SAHF && !TARGET_CMOVE
1390 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1391 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1393 "&& reload_completed"
1398 (match_op_dup 3 [(match_dup 2)]))]
1400 (set (reg:CC FLAGS_REG)
1401 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1403 [(set_attr "type" "multi")
1404 (set_attr "unit" "i387")
1405 (set_attr "fp_int_src" "true")
1406 (set_attr "mode" "<MODE>")])
1408 ;; FP compares, step 2
1409 ;; Move the fpsw to ax.
1411 (define_insn "x86_fnstsw_1"
1412 [(set (match_operand:HI 0 "register_operand" "=a")
1413 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1416 [(set (attr "length")
1417 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1418 (set_attr "mode" "SI")
1419 (set_attr "unit" "i387")])
1421 ;; FP compares, step 3
1422 ;; Get ax into flags, general case.
1424 (define_insn "x86_sahf_1"
1425 [(set (reg:CC FLAGS_REG)
1426 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1430 #ifndef HAVE_AS_IX86_SAHF
1432 return ASM_BYTE "0x9e";
1437 [(set_attr "length" "1")
1438 (set_attr "athlon_decode" "vector")
1439 (set_attr "amdfam10_decode" "direct")
1440 (set_attr "bdver1_decode" "direct")
1441 (set_attr "mode" "SI")])
1443 ;; Pentium Pro can do steps 1 through 3 in one go.
1444 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1445 ;; (these i387 instructions set flags directly)
1446 (define_insn "*cmpfp_i_mixed"
1447 [(set (reg:CCFP FLAGS_REG)
1448 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1449 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1450 "TARGET_MIX_SSE_I387
1451 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1452 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1453 "* return output_fp_compare (insn, operands, true, false);"
1454 [(set_attr "type" "fcmp,ssecomi")
1455 (set_attr "prefix" "orig,maybe_vex")
1457 (if_then_else (match_operand:SF 1 "" "")
1459 (const_string "DF")))
1460 (set (attr "prefix_rep")
1461 (if_then_else (eq_attr "type" "ssecomi")
1463 (const_string "*")))
1464 (set (attr "prefix_data16")
1465 (cond [(eq_attr "type" "fcmp")
1467 (eq_attr "mode" "DF")
1470 (const_string "0")))
1471 (set_attr "athlon_decode" "vector")
1472 (set_attr "amdfam10_decode" "direct")
1473 (set_attr "bdver1_decode" "double")])
1475 (define_insn "*cmpfp_i_sse"
1476 [(set (reg:CCFP FLAGS_REG)
1477 (compare:CCFP (match_operand 0 "register_operand" "x")
1478 (match_operand 1 "nonimmediate_operand" "xm")))]
1480 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1481 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1482 "* return output_fp_compare (insn, operands, true, false);"
1483 [(set_attr "type" "ssecomi")
1484 (set_attr "prefix" "maybe_vex")
1486 (if_then_else (match_operand:SF 1 "" "")
1488 (const_string "DF")))
1489 (set_attr "prefix_rep" "0")
1490 (set (attr "prefix_data16")
1491 (if_then_else (eq_attr "mode" "DF")
1493 (const_string "0")))
1494 (set_attr "athlon_decode" "vector")
1495 (set_attr "amdfam10_decode" "direct")
1496 (set_attr "bdver1_decode" "double")])
1498 (define_insn "*cmpfp_i_i387"
1499 [(set (reg:CCFP FLAGS_REG)
1500 (compare:CCFP (match_operand 0 "register_operand" "f")
1501 (match_operand 1 "register_operand" "f")))]
1502 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1504 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1505 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1506 "* return output_fp_compare (insn, operands, true, false);"
1507 [(set_attr "type" "fcmp")
1509 (cond [(match_operand:SF 1 "" "")
1511 (match_operand:DF 1 "" "")
1514 (const_string "XF")))
1515 (set_attr "athlon_decode" "vector")
1516 (set_attr "amdfam10_decode" "direct")
1517 (set_attr "bdver1_decode" "double")])
1519 (define_insn "*cmpfp_iu_mixed"
1520 [(set (reg:CCFPU FLAGS_REG)
1521 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1522 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1523 "TARGET_MIX_SSE_I387
1524 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1525 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1526 "* return output_fp_compare (insn, operands, true, true);"
1527 [(set_attr "type" "fcmp,ssecomi")
1528 (set_attr "prefix" "orig,maybe_vex")
1530 (if_then_else (match_operand:SF 1 "" "")
1532 (const_string "DF")))
1533 (set (attr "prefix_rep")
1534 (if_then_else (eq_attr "type" "ssecomi")
1536 (const_string "*")))
1537 (set (attr "prefix_data16")
1538 (cond [(eq_attr "type" "fcmp")
1540 (eq_attr "mode" "DF")
1543 (const_string "0")))
1544 (set_attr "athlon_decode" "vector")
1545 (set_attr "amdfam10_decode" "direct")
1546 (set_attr "bdver1_decode" "double")])
1548 (define_insn "*cmpfp_iu_sse"
1549 [(set (reg:CCFPU FLAGS_REG)
1550 (compare:CCFPU (match_operand 0 "register_operand" "x")
1551 (match_operand 1 "nonimmediate_operand" "xm")))]
1553 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1554 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1555 "* return output_fp_compare (insn, operands, true, true);"
1556 [(set_attr "type" "ssecomi")
1557 (set_attr "prefix" "maybe_vex")
1559 (if_then_else (match_operand:SF 1 "" "")
1561 (const_string "DF")))
1562 (set_attr "prefix_rep" "0")
1563 (set (attr "prefix_data16")
1564 (if_then_else (eq_attr "mode" "DF")
1566 (const_string "0")))
1567 (set_attr "athlon_decode" "vector")
1568 (set_attr "amdfam10_decode" "direct")
1569 (set_attr "bdver1_decode" "double")])
1571 (define_insn "*cmpfp_iu_387"
1572 [(set (reg:CCFPU FLAGS_REG)
1573 (compare:CCFPU (match_operand 0 "register_operand" "f")
1574 (match_operand 1 "register_operand" "f")))]
1575 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1577 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1578 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1579 "* return output_fp_compare (insn, operands, true, true);"
1580 [(set_attr "type" "fcmp")
1582 (cond [(match_operand:SF 1 "" "")
1584 (match_operand:DF 1 "" "")
1587 (const_string "XF")))
1588 (set_attr "athlon_decode" "vector")
1589 (set_attr "amdfam10_decode" "direct")
1590 (set_attr "bdver1_decode" "direct")])
1592 ;; Push/pop instructions.
1594 (define_insn "*push<mode>2"
1595 [(set (match_operand:DWI 0 "push_operand" "=<")
1596 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1599 [(set_attr "type" "multi")
1600 (set_attr "mode" "<MODE>")])
1603 [(set (match_operand:TI 0 "push_operand" "")
1604 (match_operand:TI 1 "general_operand" ""))]
1605 "TARGET_64BIT && reload_completed
1606 && !SSE_REG_P (operands[1])"
1608 "ix86_split_long_move (operands); DONE;")
1610 (define_insn "*pushdi2_rex64"
1611 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1612 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1617 [(set_attr "type" "push,multi")
1618 (set_attr "mode" "DI")])
1620 ;; Convert impossible pushes of immediate to existing instructions.
1621 ;; First try to get scratch register and go through it. In case this
1622 ;; fails, push sign extended lower part first and then overwrite
1623 ;; upper part by 32bit move.
1625 [(match_scratch:DI 2 "r")
1626 (set (match_operand:DI 0 "push_operand" "")
1627 (match_operand:DI 1 "immediate_operand" ""))]
1628 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1629 && !x86_64_immediate_operand (operands[1], DImode)"
1630 [(set (match_dup 2) (match_dup 1))
1631 (set (match_dup 0) (match_dup 2))])
1633 ;; We need to define this as both peepholer and splitter for case
1634 ;; peephole2 pass is not run.
1635 ;; "&& 1" is needed to keep it from matching the previous pattern.
1637 [(set (match_operand:DI 0 "push_operand" "")
1638 (match_operand:DI 1 "immediate_operand" ""))]
1639 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1640 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1641 [(set (match_dup 0) (match_dup 1))
1642 (set (match_dup 2) (match_dup 3))]
1644 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1646 operands[1] = gen_lowpart (DImode, operands[2]);
1647 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1652 [(set (match_operand:DI 0 "push_operand" "")
1653 (match_operand:DI 1 "immediate_operand" ""))]
1654 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1655 ? epilogue_completed : reload_completed)
1656 && !symbolic_operand (operands[1], DImode)
1657 && !x86_64_immediate_operand (operands[1], DImode)"
1658 [(set (match_dup 0) (match_dup 1))
1659 (set (match_dup 2) (match_dup 3))]
1661 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1663 operands[1] = gen_lowpart (DImode, operands[2]);
1664 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1669 [(set (match_operand:DI 0 "push_operand" "")
1670 (match_operand:DI 1 "general_operand" ""))]
1671 "!TARGET_64BIT && reload_completed
1672 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1674 "ix86_split_long_move (operands); DONE;")
1676 (define_insn "*pushsi2"
1677 [(set (match_operand:SI 0 "push_operand" "=<")
1678 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1681 [(set_attr "type" "push")
1682 (set_attr "mode" "SI")])
1684 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1685 ;; "push a byte/word". But actually we use pushl, which has the effect
1686 ;; of rounding the amount pushed up to a word.
1688 ;; For TARGET_64BIT we always round up to 8 bytes.
1689 (define_insn "*push<mode>2_rex64"
1690 [(set (match_operand:SWI124 0 "push_operand" "=X")
1691 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1694 [(set_attr "type" "push")
1695 (set_attr "mode" "DI")])
1697 (define_insn "*push<mode>2"
1698 [(set (match_operand:SWI12 0 "push_operand" "=X")
1699 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1702 [(set_attr "type" "push")
1703 (set_attr "mode" "SI")])
1705 (define_insn "*push<mode>2_prologue"
1706 [(set (match_operand:P 0 "push_operand" "=<")
1707 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1708 (clobber (mem:BLK (scratch)))]
1710 "push{<imodesuffix>}\t%1"
1711 [(set_attr "type" "push")
1712 (set_attr "mode" "<MODE>")])
1714 (define_insn "*pop<mode>1"
1715 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1716 (match_operand:P 1 "pop_operand" ">"))]
1718 "pop{<imodesuffix>}\t%0"
1719 [(set_attr "type" "pop")
1720 (set_attr "mode" "<MODE>")])
1722 (define_insn "*pop<mode>1_epilogue"
1723 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1724 (match_operand:P 1 "pop_operand" ">"))
1725 (clobber (mem:BLK (scratch)))]
1727 "pop{<imodesuffix>}\t%0"
1728 [(set_attr "type" "pop")
1729 (set_attr "mode" "<MODE>")])
1731 ;; Move instructions.
1733 (define_expand "movoi"
1734 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1735 (match_operand:OI 1 "general_operand" ""))]
1737 "ix86_expand_move (OImode, operands); DONE;")
1739 (define_expand "movti"
1740 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1741 (match_operand:TI 1 "nonimmediate_operand" ""))]
1742 "TARGET_64BIT || TARGET_SSE"
1745 ix86_expand_move (TImode, operands);
1746 else if (push_operand (operands[0], TImode))
1747 ix86_expand_push (TImode, operands[1]);
1749 ix86_expand_vector_move (TImode, operands);
1753 ;; This expands to what emit_move_complex would generate if we didn't
1754 ;; have a movti pattern. Having this avoids problems with reload on
1755 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1756 ;; to have around all the time.
1757 (define_expand "movcdi"
1758 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1759 (match_operand:CDI 1 "general_operand" ""))]
1762 if (push_operand (operands[0], CDImode))
1763 emit_move_complex_push (CDImode, operands[0], operands[1]);
1765 emit_move_complex_parts (operands[0], operands[1]);
1769 (define_expand "mov<mode>"
1770 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1771 (match_operand:SWI1248x 1 "general_operand" ""))]
1773 "ix86_expand_move (<MODE>mode, operands); DONE;")
1775 (define_insn "*mov<mode>_xor"
1776 [(set (match_operand:SWI48 0 "register_operand" "=r")
1777 (match_operand:SWI48 1 "const0_operand" ""))
1778 (clobber (reg:CC FLAGS_REG))]
1781 [(set_attr "type" "alu1")
1782 (set_attr "mode" "SI")
1783 (set_attr "length_immediate" "0")])
1785 (define_insn "*mov<mode>_or"
1786 [(set (match_operand:SWI48 0 "register_operand" "=r")
1787 (match_operand:SWI48 1 "const_int_operand" ""))
1788 (clobber (reg:CC FLAGS_REG))]
1790 && operands[1] == constm1_rtx"
1791 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1792 [(set_attr "type" "alu1")
1793 (set_attr "mode" "<MODE>")
1794 (set_attr "length_immediate" "1")])
1796 (define_insn "*movoi_internal_avx"
1797 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1798 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1799 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1801 switch (which_alternative)
1804 return standard_sse_constant_opcode (insn, operands[1]);
1807 if (misaligned_operand (operands[0], OImode)
1808 || misaligned_operand (operands[1], OImode))
1809 return "vmovdqu\t{%1, %0|%0, %1}";
1811 return "vmovdqa\t{%1, %0|%0, %1}";
1816 [(set_attr "type" "sselog1,ssemov,ssemov")
1817 (set_attr "prefix" "vex")
1818 (set_attr "mode" "OI")])
1820 (define_insn "*movti_internal_rex64"
1821 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,m")
1822 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1823 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1825 switch (which_alternative)
1831 return standard_sse_constant_opcode (insn, operands[1]);
1834 /* TDmode values are passed as TImode on the stack. Moving them
1835 to stack may result in unaligned memory access. */
1836 if (misaligned_operand (operands[0], TImode)
1837 || misaligned_operand (operands[1], TImode))
1839 if (get_attr_mode (insn) == MODE_V4SF)
1840 return "%vmovups\t{%1, %0|%0, %1}";
1842 return "%vmovdqu\t{%1, %0|%0, %1}";
1846 if (get_attr_mode (insn) == MODE_V4SF)
1847 return "%vmovaps\t{%1, %0|%0, %1}";
1849 return "%vmovdqa\t{%1, %0|%0, %1}";
1855 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1856 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1858 (cond [(eq_attr "alternative" "2,3")
1860 (match_test "optimize_function_for_size_p (cfun)")
1861 (const_string "V4SF")
1862 (const_string "TI"))
1863 (eq_attr "alternative" "4")
1865 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1866 (match_test "optimize_function_for_size_p (cfun)"))
1867 (const_string "V4SF")
1868 (const_string "TI"))]
1869 (const_string "DI")))])
1872 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1873 (match_operand:TI 1 "general_operand" ""))]
1875 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1877 "ix86_split_long_move (operands); DONE;")
1879 (define_insn "*movti_internal_sse"
1880 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1881 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1882 "TARGET_SSE && !TARGET_64BIT
1883 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1885 switch (which_alternative)
1888 return standard_sse_constant_opcode (insn, operands[1]);
1891 /* TDmode values are passed as TImode on the stack. Moving them
1892 to stack may result in unaligned memory access. */
1893 if (misaligned_operand (operands[0], TImode)
1894 || misaligned_operand (operands[1], TImode))
1896 if (get_attr_mode (insn) == MODE_V4SF)
1897 return "%vmovups\t{%1, %0|%0, %1}";
1899 return "%vmovdqu\t{%1, %0|%0, %1}";
1903 if (get_attr_mode (insn) == MODE_V4SF)
1904 return "%vmovaps\t{%1, %0|%0, %1}";
1906 return "%vmovdqa\t{%1, %0|%0, %1}";
1912 [(set_attr "type" "sselog1,ssemov,ssemov")
1913 (set_attr "prefix" "maybe_vex")
1915 (cond [(ior (not (match_test "TARGET_SSE2"))
1916 (match_test "optimize_function_for_size_p (cfun)"))
1917 (const_string "V4SF")
1918 (and (eq_attr "alternative" "2")
1919 (match_test "TARGET_SSE_TYPELESS_STORES"))
1920 (const_string "V4SF")]
1921 (const_string "TI")))])
1923 (define_insn "*movdi_internal_rex64"
1924 [(set (match_operand:DI 0 "nonimmediate_operand"
1925 "=r,r ,r,m ,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1926 (match_operand:DI 1 "general_operand"
1927 "Z ,rem,i,re,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1928 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1930 switch (get_attr_type (insn))
1933 if (SSE_REG_P (operands[0]))
1934 return "movq2dq\t{%1, %0|%0, %1}";
1936 return "movdq2q\t{%1, %0|%0, %1}";
1939 if (get_attr_mode (insn) == MODE_TI)
1940 return "%vmovdqa\t{%1, %0|%0, %1}";
1941 /* Handle broken assemblers that require movd instead of movq. */
1942 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1943 return "%vmovd\t{%1, %0|%0, %1}";
1945 return "%vmovq\t{%1, %0|%0, %1}";
1948 /* Handle broken assemblers that require movd instead of movq. */
1949 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1950 return "movd\t{%1, %0|%0, %1}";
1952 return "movq\t{%1, %0|%0, %1}";
1955 return standard_sse_constant_opcode (insn, operands[1]);
1958 return "pxor\t%0, %0";
1961 return "lea{q}\t{%E1, %0|%0, %E1}";
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{%E1, %0|%0, %E1}";
1972 return "mov{q}\t{%1, %0|%0, %1}";
1976 (cond [(eq_attr "alternative" "4")
1977 (const_string "mmx")
1978 (eq_attr "alternative" "5,6,7,8")
1979 (const_string "mmxmov")
1980 (eq_attr "alternative" "9")
1981 (const_string "sselog1")
1982 (eq_attr "alternative" "10,11,12,13,14")
1983 (const_string "ssemov")
1984 (eq_attr "alternative" "15,16")
1985 (const_string "ssecvt")
1986 (match_operand 1 "pic_32bit_operand" "")
1987 (const_string "lea")
1989 (const_string "imov")))
1992 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1994 (const_string "*")))
1995 (set (attr "length_immediate")
1997 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1999 (const_string "*")))
2000 (set (attr "prefix_rex")
2001 (if_then_else (eq_attr "alternative" "7,8")
2003 (const_string "*")))
2004 (set (attr "prefix_data16")
2005 (if_then_else (eq_attr "alternative" "10")
2007 (const_string "*")))
2008 (set (attr "prefix")
2009 (if_then_else (eq_attr "alternative" "11,12,13,14,15")
2010 (const_string "maybe_vex")
2011 (const_string "orig")))
2012 (set_attr "mode" "SI,DI,DI,DI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2014 ;; Reload patterns to support multi-word load/store
2015 ;; with non-offsetable address.
2016 (define_expand "reload_noff_store"
2017 [(parallel [(match_operand 0 "memory_operand" "=m")
2018 (match_operand 1 "register_operand" "r")
2019 (match_operand:DI 2 "register_operand" "=&r")])]
2022 rtx mem = operands[0];
2023 rtx addr = XEXP (mem, 0);
2025 emit_move_insn (operands[2], addr);
2026 mem = replace_equiv_address_nv (mem, operands[2]);
2028 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2032 (define_expand "reload_noff_load"
2033 [(parallel [(match_operand 0 "register_operand" "=r")
2034 (match_operand 1 "memory_operand" "m")
2035 (match_operand:DI 2 "register_operand" "=r")])]
2038 rtx mem = operands[1];
2039 rtx addr = XEXP (mem, 0);
2041 emit_move_insn (operands[2], addr);
2042 mem = replace_equiv_address_nv (mem, operands[2]);
2044 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2048 (define_insn "*movdi_internal"
2049 [(set (match_operand:DI 0 "nonimmediate_operand"
2050 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2051 (match_operand:DI 1 "general_operand"
2052 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2053 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2055 switch (get_attr_type (insn))
2058 if (SSE_REG_P (operands[0]))
2059 return "movq2dq\t{%1, %0|%0, %1}";
2061 return "movdq2q\t{%1, %0|%0, %1}";
2064 switch (get_attr_mode (insn))
2067 return "%vmovdqa\t{%1, %0|%0, %1}";
2069 return "%vmovq\t{%1, %0|%0, %1}";
2071 return "movaps\t{%1, %0|%0, %1}";
2073 return "movlps\t{%1, %0|%0, %1}";
2079 return "movq\t{%1, %0|%0, %1}";
2082 return standard_sse_constant_opcode (insn, operands[1]);
2085 return "pxor\t%0, %0";
2095 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2096 (const_string "sse2")
2097 (eq_attr "alternative" "9,10,11,12")
2098 (const_string "noavx")
2100 (const_string "*")))
2102 (cond [(eq_attr "alternative" "0,1")
2103 (const_string "multi")
2104 (eq_attr "alternative" "2")
2105 (const_string "mmx")
2106 (eq_attr "alternative" "3,4")
2107 (const_string "mmxmov")
2108 (eq_attr "alternative" "5,9")
2109 (const_string "sselog1")
2110 (eq_attr "alternative" "13,14")
2111 (const_string "ssecvt")
2113 (const_string "ssemov")))
2114 (set (attr "prefix")
2115 (if_then_else (eq_attr "alternative" "5,6,7,8")
2116 (const_string "maybe_vex")
2117 (const_string "orig")))
2118 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2121 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2122 (match_operand:DI 1 "general_operand" ""))]
2123 "!TARGET_64BIT && reload_completed
2124 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2125 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2127 "ix86_split_long_move (operands); DONE;")
2129 (define_insn "*movsi_internal"
2130 [(set (match_operand:SI 0 "nonimmediate_operand"
2131 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2132 (match_operand:SI 1 "general_operand"
2133 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2134 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2136 switch (get_attr_type (insn))
2139 return standard_sse_constant_opcode (insn, operands[1]);
2142 switch (get_attr_mode (insn))
2145 return "%vmovdqa\t{%1, %0|%0, %1}";
2147 return "%vmovaps\t{%1, %0|%0, %1}";
2149 return "%vmovd\t{%1, %0|%0, %1}";
2151 return "%vmovss\t{%1, %0|%0, %1}";
2157 return "pxor\t%0, %0";
2160 if (get_attr_mode (insn) == MODE_DI)
2161 return "movq\t{%1, %0|%0, %1}";
2162 return "movd\t{%1, %0|%0, %1}";
2165 return "lea{l}\t{%E1, %0|%0, %E1}";
2168 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2169 if (ix86_use_lea_for_mov (insn, operands))
2170 return "lea{l}\t{%E1, %0|%0, %E1}";
2172 return "mov{l}\t{%1, %0|%0, %1}";
2176 (cond [(eq_attr "alternative" "2")
2177 (const_string "mmx")
2178 (eq_attr "alternative" "3,4,5")
2179 (const_string "mmxmov")
2180 (eq_attr "alternative" "6")
2181 (const_string "sselog1")
2182 (eq_attr "alternative" "7,8,9,10,11")
2183 (const_string "ssemov")
2184 (match_operand 1 "pic_32bit_operand" "")
2185 (const_string "lea")
2187 (const_string "imov")))
2188 (set (attr "prefix")
2189 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2190 (const_string "orig")
2191 (const_string "maybe_vex")))
2192 (set (attr "prefix_data16")
2193 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2195 (const_string "*")))
2197 (cond [(eq_attr "alternative" "2,3")
2199 (eq_attr "alternative" "6,7")
2201 (not (match_test "TARGET_SSE2"))
2202 (const_string "V4SF")
2203 (const_string "TI"))
2204 (and (eq_attr "alternative" "8,9,10,11")
2205 (not (match_test "TARGET_SSE2")))
2208 (const_string "SI")))])
2210 (define_insn "*movhi_internal"
2211 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2212 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2213 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2215 switch (get_attr_type (insn))
2218 /* movzwl is faster than movw on p2 due to partial word stalls,
2219 though not as fast as an aligned movl. */
2220 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2222 if (get_attr_mode (insn) == MODE_SI)
2223 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2225 return "mov{w}\t{%1, %0|%0, %1}";
2229 (cond [(match_test "optimize_function_for_size_p (cfun)")
2230 (const_string "imov")
2231 (and (eq_attr "alternative" "0")
2232 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2233 (not (match_test "TARGET_HIMODE_MATH"))))
2234 (const_string "imov")
2235 (and (eq_attr "alternative" "1,2")
2236 (match_operand:HI 1 "aligned_operand" ""))
2237 (const_string "imov")
2238 (and (match_test "TARGET_MOVX")
2239 (eq_attr "alternative" "0,2"))
2240 (const_string "imovx")
2242 (const_string "imov")))
2244 (cond [(eq_attr "type" "imovx")
2246 (and (eq_attr "alternative" "1,2")
2247 (match_operand:HI 1 "aligned_operand" ""))
2249 (and (eq_attr "alternative" "0")
2250 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2251 (not (match_test "TARGET_HIMODE_MATH"))))
2254 (const_string "HI")))])
2256 ;; Situation is quite tricky about when to choose full sized (SImode) move
2257 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2258 ;; partial register dependency machines (such as AMD Athlon), where QImode
2259 ;; moves issue extra dependency and for partial register stalls machines
2260 ;; that don't use QImode patterns (and QImode move cause stall on the next
2263 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2264 ;; register stall machines with, where we use QImode instructions, since
2265 ;; partial register stall can be caused there. Then we use movzx.
2266 (define_insn "*movqi_internal"
2267 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2268 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2269 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2271 switch (get_attr_type (insn))
2274 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2275 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2277 if (get_attr_mode (insn) == MODE_SI)
2278 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2280 return "mov{b}\t{%1, %0|%0, %1}";
2284 (cond [(and (eq_attr "alternative" "5")
2285 (not (match_operand:QI 1 "aligned_operand" "")))
2286 (const_string "imovx")
2287 (match_test "optimize_function_for_size_p (cfun)")
2288 (const_string "imov")
2289 (and (eq_attr "alternative" "3")
2290 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2291 (not (match_test "TARGET_QIMODE_MATH"))))
2292 (const_string "imov")
2293 (eq_attr "alternative" "3,5")
2294 (const_string "imovx")
2295 (and (match_test "TARGET_MOVX")
2296 (eq_attr "alternative" "2"))
2297 (const_string "imovx")
2299 (const_string "imov")))
2301 (cond [(eq_attr "alternative" "3,4,5")
2303 (eq_attr "alternative" "6")
2305 (eq_attr "type" "imovx")
2307 (and (eq_attr "type" "imov")
2308 (and (eq_attr "alternative" "0,1")
2309 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2310 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2311 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2313 ;; Avoid partial register stalls when not using QImode arithmetic
2314 (and (eq_attr "type" "imov")
2315 (and (eq_attr "alternative" "0,1")
2316 (and (match_test "TARGET_PARTIAL_REG_STALL")
2317 (not (match_test "TARGET_QIMODE_MATH")))))
2320 (const_string "QI")))])
2322 ;; Stores and loads of ax to arbitrary constant address.
2323 ;; We fake an second form of instruction to force reload to load address
2324 ;; into register when rax is not available
2325 (define_insn "*movabs<mode>_1"
2326 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2327 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2328 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2330 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2331 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2332 [(set_attr "type" "imov")
2333 (set_attr "modrm" "0,*")
2334 (set_attr "length_address" "8,0")
2335 (set_attr "length_immediate" "0,*")
2336 (set_attr "memory" "store")
2337 (set_attr "mode" "<MODE>")])
2339 (define_insn "*movabs<mode>_2"
2340 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2341 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2342 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2344 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2345 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2346 [(set_attr "type" "imov")
2347 (set_attr "modrm" "0,*")
2348 (set_attr "length_address" "8,0")
2349 (set_attr "length_immediate" "0")
2350 (set_attr "memory" "load")
2351 (set_attr "mode" "<MODE>")])
2353 (define_insn "*swap<mode>"
2354 [(set (match_operand:SWI48 0 "register_operand" "+r")
2355 (match_operand:SWI48 1 "register_operand" "+r"))
2359 "xchg{<imodesuffix>}\t%1, %0"
2360 [(set_attr "type" "imov")
2361 (set_attr "mode" "<MODE>")
2362 (set_attr "pent_pair" "np")
2363 (set_attr "athlon_decode" "vector")
2364 (set_attr "amdfam10_decode" "double")
2365 (set_attr "bdver1_decode" "double")])
2367 (define_insn "*swap<mode>_1"
2368 [(set (match_operand:SWI12 0 "register_operand" "+r")
2369 (match_operand:SWI12 1 "register_operand" "+r"))
2372 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2374 [(set_attr "type" "imov")
2375 (set_attr "mode" "SI")
2376 (set_attr "pent_pair" "np")
2377 (set_attr "athlon_decode" "vector")
2378 (set_attr "amdfam10_decode" "double")
2379 (set_attr "bdver1_decode" "double")])
2381 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2382 ;; is disabled for AMDFAM10
2383 (define_insn "*swap<mode>_2"
2384 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2385 (match_operand:SWI12 1 "register_operand" "+<r>"))
2388 "TARGET_PARTIAL_REG_STALL"
2389 "xchg{<imodesuffix>}\t%1, %0"
2390 [(set_attr "type" "imov")
2391 (set_attr "mode" "<MODE>")
2392 (set_attr "pent_pair" "np")
2393 (set_attr "athlon_decode" "vector")])
2395 (define_expand "movstrict<mode>"
2396 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2397 (match_operand:SWI12 1 "general_operand" ""))]
2400 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2402 if (GET_CODE (operands[0]) == SUBREG
2403 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2405 /* Don't generate memory->memory moves, go through a register */
2406 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2407 operands[1] = force_reg (<MODE>mode, operands[1]);
2410 (define_insn "*movstrict<mode>_1"
2411 [(set (strict_low_part
2412 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2413 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2414 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2415 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2416 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2417 [(set_attr "type" "imov")
2418 (set_attr "mode" "<MODE>")])
2420 (define_insn "*movstrict<mode>_xor"
2421 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2422 (match_operand:SWI12 1 "const0_operand" ""))
2423 (clobber (reg:CC FLAGS_REG))]
2425 "xor{<imodesuffix>}\t%0, %0"
2426 [(set_attr "type" "alu1")
2427 (set_attr "mode" "<MODE>")
2428 (set_attr "length_immediate" "0")])
2430 (define_insn "*mov<mode>_extv_1"
2431 [(set (match_operand:SWI24 0 "register_operand" "=R")
2432 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2436 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2437 [(set_attr "type" "imovx")
2438 (set_attr "mode" "SI")])
2440 (define_insn "*movqi_extv_1_rex64"
2441 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2442 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2447 switch (get_attr_type (insn))
2450 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2452 return "mov{b}\t{%h1, %0|%0, %h1}";
2456 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2457 (match_test "TARGET_MOVX"))
2458 (const_string "imovx")
2459 (const_string "imov")))
2461 (if_then_else (eq_attr "type" "imovx")
2463 (const_string "QI")))])
2465 (define_insn "*movqi_extv_1"
2466 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2467 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2472 switch (get_attr_type (insn))
2475 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2477 return "mov{b}\t{%h1, %0|%0, %h1}";
2481 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2482 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2483 (match_test "TARGET_MOVX")))
2484 (const_string "imovx")
2485 (const_string "imov")))
2487 (if_then_else (eq_attr "type" "imovx")
2489 (const_string "QI")))])
2491 (define_insn "*mov<mode>_extzv_1"
2492 [(set (match_operand:SWI48 0 "register_operand" "=R")
2493 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2497 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2498 [(set_attr "type" "imovx")
2499 (set_attr "mode" "SI")])
2501 (define_insn "*movqi_extzv_2_rex64"
2502 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2504 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2509 switch (get_attr_type (insn))
2512 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2514 return "mov{b}\t{%h1, %0|%0, %h1}";
2518 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2519 (match_test "TARGET_MOVX"))
2520 (const_string "imovx")
2521 (const_string "imov")))
2523 (if_then_else (eq_attr "type" "imovx")
2525 (const_string "QI")))])
2527 (define_insn "*movqi_extzv_2"
2528 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2530 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2535 switch (get_attr_type (insn))
2538 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2540 return "mov{b}\t{%h1, %0|%0, %h1}";
2544 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2545 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2546 (match_test "TARGET_MOVX")))
2547 (const_string "imovx")
2548 (const_string "imov")))
2550 (if_then_else (eq_attr "type" "imovx")
2552 (const_string "QI")))])
2554 (define_expand "mov<mode>_insv_1"
2555 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2558 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2560 (define_insn "*mov<mode>_insv_1_rex64"
2561 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2564 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2567 if (CONST_INT_P (operands[1]))
2568 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2569 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2571 [(set_attr "type" "imov")
2572 (set_attr "mode" "QI")])
2574 (define_insn "*movsi_insv_1"
2575 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2578 (match_operand:SI 1 "general_operand" "Qmn"))]
2581 if (CONST_INT_P (operands[1]))
2582 operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2583 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2585 [(set_attr "type" "imov")
2586 (set_attr "mode" "QI")])
2588 (define_insn "*movqi_insv_2"
2589 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2592 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2595 "mov{b}\t{%h1, %h0|%h0, %h1}"
2596 [(set_attr "type" "imov")
2597 (set_attr "mode" "QI")])
2599 ;; Floating point push instructions.
2601 (define_insn "*pushtf"
2602 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2603 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2606 /* This insn should be already split before reg-stack. */
2609 [(set_attr "type" "multi")
2610 (set_attr "unit" "sse,*,*")
2611 (set_attr "mode" "TF,SI,SI")])
2613 ;; %%% Kill this when call knows how to work this out.
2615 [(set (match_operand:TF 0 "push_operand" "")
2616 (match_operand:TF 1 "sse_reg_operand" ""))]
2617 "TARGET_SSE2 && reload_completed"
2618 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2619 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2621 (define_insn "*pushxf"
2622 [(set (match_operand:XF 0 "push_operand" "=<,<")
2623 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2624 "optimize_function_for_speed_p (cfun)"
2626 /* This insn should be already split before reg-stack. */
2629 [(set_attr "type" "multi")
2630 (set_attr "unit" "i387,*")
2631 (set_attr "mode" "XF,SI")])
2633 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2634 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2635 ;; Pushing using integer instructions is longer except for constants
2636 ;; and direct memory references (assuming that any given constant is pushed
2637 ;; only once, but this ought to be handled elsewhere).
2639 (define_insn "*pushxf_nointeger"
2640 [(set (match_operand:XF 0 "push_operand" "=<,<")
2641 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2642 "optimize_function_for_size_p (cfun)"
2644 /* This insn should be already split before reg-stack. */
2647 [(set_attr "type" "multi")
2648 (set_attr "unit" "i387,*")
2649 (set_attr "mode" "XF,SI")])
2651 ;; %%% Kill this when call knows how to work this out.
2653 [(set (match_operand:XF 0 "push_operand" "")
2654 (match_operand:XF 1 "fp_register_operand" ""))]
2656 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2657 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2658 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2660 (define_insn "*pushdf_rex64"
2661 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2662 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2665 /* This insn should be already split before reg-stack. */
2668 [(set_attr "type" "multi")
2669 (set_attr "unit" "i387,*,*")
2670 (set_attr "mode" "DF,DI,DF")])
2672 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2673 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2674 ;; On the average, pushdf using integers can be still shorter.
2676 (define_insn "*pushdf"
2677 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2678 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2681 /* This insn should be already split before reg-stack. */
2684 [(set_attr "isa" "*,*,sse2")
2685 (set_attr "type" "multi")
2686 (set_attr "unit" "i387,*,*")
2687 (set_attr "mode" "DF,DI,DF")])
2689 ;; %%% Kill this when call knows how to work this out.
2691 [(set (match_operand:DF 0 "push_operand" "")
2692 (match_operand:DF 1 "any_fp_register_operand" ""))]
2694 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2695 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2697 (define_insn "*pushsf_rex64"
2698 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2699 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2702 /* Anything else should be already split before reg-stack. */
2703 gcc_assert (which_alternative == 1);
2704 return "push{q}\t%q1";
2706 [(set_attr "type" "multi,push,multi")
2707 (set_attr "unit" "i387,*,*")
2708 (set_attr "mode" "SF,DI,SF")])
2710 (define_insn "*pushsf"
2711 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2712 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2715 /* Anything else should be already split before reg-stack. */
2716 gcc_assert (which_alternative == 1);
2717 return "push{l}\t%1";
2719 [(set_attr "type" "multi,push,multi")
2720 (set_attr "unit" "i387,*,*")
2721 (set_attr "mode" "SF,SI,SF")])
2723 ;; %%% Kill this when call knows how to work this out.
2725 [(set (match_operand:SF 0 "push_operand" "")
2726 (match_operand:SF 1 "any_fp_register_operand" ""))]
2728 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2729 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2730 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2733 [(set (match_operand:SF 0 "push_operand" "")
2734 (match_operand:SF 1 "memory_operand" ""))]
2736 && (operands[2] = find_constant_src (insn))"
2737 [(set (match_dup 0) (match_dup 2))])
2740 [(set (match_operand 0 "push_operand" "")
2741 (match_operand 1 "general_operand" ""))]
2743 && (GET_MODE (operands[0]) == TFmode
2744 || GET_MODE (operands[0]) == XFmode
2745 || GET_MODE (operands[0]) == DFmode)
2746 && !ANY_FP_REG_P (operands[1])"
2748 "ix86_split_long_move (operands); DONE;")
2750 ;; Floating point move instructions.
2752 (define_expand "movtf"
2753 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2754 (match_operand:TF 1 "nonimmediate_operand" ""))]
2755 "TARGET_64BIT || TARGET_SSE2"
2757 ix86_expand_move (TFmode, operands);
2761 (define_expand "mov<mode>"
2762 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2763 (match_operand:X87MODEF 1 "general_operand" ""))]
2765 "ix86_expand_move (<MODE>mode, operands); DONE;")
2767 (define_insn "*movtf_internal_rex64"
2768 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2769 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,*r"))]
2770 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2771 && (!can_create_pseudo_p ()
2772 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2773 || GET_CODE (operands[1]) != CONST_DOUBLE
2774 || (optimize_function_for_size_p (cfun)
2775 && standard_sse_constant_p (operands[1])
2776 && !memory_operand (operands[0], TFmode))
2777 || (!TARGET_MEMORY_MISMATCH_STALL
2778 && memory_operand (operands[0], TFmode)))"
2780 switch (which_alternative)
2784 /* Handle misaligned load/store since we
2785 don't have movmisaligntf pattern. */
2786 if (misaligned_operand (operands[0], TFmode)
2787 || misaligned_operand (operands[1], TFmode))
2789 if (get_attr_mode (insn) == MODE_V4SF)
2790 return "%vmovups\t{%1, %0|%0, %1}";
2792 return "%vmovdqu\t{%1, %0|%0, %1}";
2796 if (get_attr_mode (insn) == MODE_V4SF)
2797 return "%vmovaps\t{%1, %0|%0, %1}";
2799 return "%vmovdqa\t{%1, %0|%0, %1}";
2803 return standard_sse_constant_opcode (insn, operands[1]);
2813 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2814 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2816 (cond [(eq_attr "alternative" "0,2")
2818 (match_test "optimize_function_for_size_p (cfun)")
2819 (const_string "V4SF")
2820 (const_string "TI"))
2821 (eq_attr "alternative" "1")
2823 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2824 (match_test "optimize_function_for_size_p (cfun)"))
2825 (const_string "V4SF")
2826 (const_string "TI"))]
2827 (const_string "DI")))])
2829 (define_insn "*movtf_internal_sse2"
2830 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x")
2831 (match_operand:TF 1 "general_operand" "xm,x,C"))]
2832 "TARGET_SSE2 && !TARGET_64BIT
2833 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2834 && (!can_create_pseudo_p ()
2835 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2836 || GET_CODE (operands[1]) != CONST_DOUBLE
2837 || (optimize_function_for_size_p (cfun)
2838 && standard_sse_constant_p (operands[1])
2839 && !memory_operand (operands[0], TFmode))
2840 || (!TARGET_MEMORY_MISMATCH_STALL
2841 && memory_operand (operands[0], TFmode)))"
2843 switch (which_alternative)
2847 /* Handle misaligned load/store since we
2848 don't have movmisaligntf pattern. */
2849 if (misaligned_operand (operands[0], TFmode)
2850 || misaligned_operand (operands[1], TFmode))
2852 if (get_attr_mode (insn) == MODE_V4SF)
2853 return "%vmovups\t{%1, %0|%0, %1}";
2855 return "%vmovdqu\t{%1, %0|%0, %1}";
2859 if (get_attr_mode (insn) == MODE_V4SF)
2860 return "%vmovaps\t{%1, %0|%0, %1}";
2862 return "%vmovdqa\t{%1, %0|%0, %1}";
2866 return standard_sse_constant_opcode (insn, operands[1]);
2872 [(set_attr "type" "ssemov,ssemov,sselog1")
2873 (set_attr "prefix" "maybe_vex")
2875 (cond [(eq_attr "alternative" "0,2")
2877 (match_test "optimize_function_for_size_p (cfun)")
2878 (const_string "V4SF")
2879 (const_string "TI"))
2880 (eq_attr "alternative" "1")
2882 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2883 (match_test "optimize_function_for_size_p (cfun)"))
2884 (const_string "V4SF")
2885 (const_string "TI"))]
2886 (const_string "DI")))])
2888 (define_insn "*movxf_internal_rex64"
2889 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2890 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,Yx*rC"))]
2891 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2892 && (!can_create_pseudo_p ()
2893 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2894 || GET_CODE (operands[1]) != CONST_DOUBLE
2895 || (optimize_function_for_size_p (cfun)
2896 && standard_80387_constant_p (operands[1]) > 0
2897 && !memory_operand (operands[0], XFmode))
2898 || (!TARGET_MEMORY_MISMATCH_STALL
2899 && memory_operand (operands[0], XFmode)))"
2901 switch (which_alternative)
2905 return output_387_reg_move (insn, operands);
2908 return standard_80387_constant_opcode (operands[1]);
2918 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2919 (set_attr "mode" "XF,XF,XF,SI,SI")])
2921 ;; Possible store forwarding (partial memory) stall in alternative 4.
2922 (define_insn "*movxf_internal"
2923 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2924 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,Yx*rF"))]
2925 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2926 && (!can_create_pseudo_p ()
2927 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2928 || GET_CODE (operands[1]) != CONST_DOUBLE
2929 || (optimize_function_for_size_p (cfun)
2930 && standard_80387_constant_p (operands[1]) > 0
2931 && !memory_operand (operands[0], XFmode))
2932 || (!TARGET_MEMORY_MISMATCH_STALL
2933 && memory_operand (operands[0], XFmode)))"
2935 switch (which_alternative)
2939 return output_387_reg_move (insn, operands);
2942 return standard_80387_constant_opcode (operands[1]);
2952 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2953 (set_attr "mode" "XF,XF,XF,SI,SI")])
2955 (define_insn "*movdf_internal_rex64"
2956 [(set (match_operand:DF 0 "nonimmediate_operand"
2957 "=?Yf*f,?m ,?Yf*f,?r,?m,?r,?r,x,x,x,m,Yi,r ")
2958 (match_operand:DF 1 "general_operand"
2959 "Yf*fm ,Yf*f ,G ,rm,rC,C ,F ,C,x,m,x,r ,Yi"))]
2960 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2961 && (!can_create_pseudo_p ()
2962 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2963 || GET_CODE (operands[1]) != CONST_DOUBLE
2964 || (optimize_function_for_size_p (cfun)
2965 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2966 && standard_80387_constant_p (operands[1]) > 0)
2967 || (TARGET_SSE2 && TARGET_SSE_MATH
2968 && standard_sse_constant_p (operands[1]))))
2969 || memory_operand (operands[0], DFmode))"
2971 switch (which_alternative)
2975 return output_387_reg_move (insn, operands);
2978 return standard_80387_constant_opcode (operands[1]);
2982 return "mov{q}\t{%1, %0|%0, %1}";
2985 return "mov{l}\t{%1, %k0|%k0, %1}";
2988 return "movabs{q}\t{%1, %0|%0, %1}";
2991 return standard_sse_constant_opcode (insn, operands[1]);
2996 switch (get_attr_mode (insn))
2999 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3000 return "%vmovapd\t{%1, %0|%0, %1}";
3002 return "%vmovaps\t{%1, %0|%0, %1}";
3005 return "%vmovq\t{%1, %0|%0, %1}";
3007 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3008 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3009 return "%vmovsd\t{%1, %0|%0, %1}";
3011 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3013 return "%vmovlps\t{%1, %d0|%d0, %1}";
3020 /* Handle broken assemblers that require movd instead of movq. */
3021 return "%vmovd\t{%1, %0|%0, %1}";
3028 (cond [(eq_attr "alternative" "0,1,2")
3029 (const_string "fmov")
3030 (eq_attr "alternative" "3,4,5,6")
3031 (const_string "imov")
3032 (eq_attr "alternative" "7")
3033 (const_string "sselog1")
3035 (const_string "ssemov")))
3038 (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3040 (const_string "*")))
3041 (set (attr "length_immediate")
3043 (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3045 (const_string "*")))
3046 (set (attr "prefix")
3047 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3048 (const_string "orig")
3049 (const_string "maybe_vex")))
3050 (set (attr "prefix_data16")
3051 (if_then_else (eq_attr "mode" "V1DF")
3053 (const_string "*")))
3055 (cond [(eq_attr "alternative" "0,1,2")
3057 (eq_attr "alternative" "3,4,6,11,12")
3059 (eq_attr "alternative" "5")
3062 /* xorps is one byte shorter. */
3063 (eq_attr "alternative" "7")
3064 (cond [(match_test "optimize_function_for_size_p (cfun)")
3065 (const_string "V4SF")
3066 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3069 (const_string "V2DF"))
3071 /* For architectures resolving dependencies on
3072 whole SSE registers use APD move to break dependency
3073 chains, otherwise use short move to avoid extra work.
3075 movaps encodes one byte shorter. */
3076 (eq_attr "alternative" "8")
3078 [(match_test "optimize_function_for_size_p (cfun)")
3079 (const_string "V4SF")
3080 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3081 (const_string "V2DF")
3083 (const_string "DF"))
3084 /* For architectures resolving dependencies on register
3085 parts we may avoid extra work to zero out upper part
3087 (eq_attr "alternative" "9")
3089 (match_test "TARGET_SSE_SPLIT_REGS")
3090 (const_string "V1DF")
3091 (const_string "DF"))
3093 (const_string "DF")))])
3095 ;; Possible store forwarding (partial memory) stall in alternative 4.
3096 (define_insn "*movdf_internal"
3097 [(set (match_operand:DF 0 "nonimmediate_operand"
3098 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3099 (match_operand:DF 1 "general_operand"
3100 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,C,x,m,x,C ,*x,m ,*x"))]
3101 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3102 && (!can_create_pseudo_p ()
3103 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3104 || GET_CODE (operands[1]) != CONST_DOUBLE
3105 || (optimize_function_for_size_p (cfun)
3106 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3107 && standard_80387_constant_p (operands[1]) > 0)
3108 || (TARGET_SSE2 && TARGET_SSE_MATH
3109 && standard_sse_constant_p (operands[1])))
3110 && !memory_operand (operands[0], DFmode))
3111 || (!TARGET_MEMORY_MISMATCH_STALL
3112 && memory_operand (operands[0], DFmode)))"
3114 switch (which_alternative)
3118 return output_387_reg_move (insn, operands);
3121 return standard_80387_constant_opcode (operands[1]);
3129 return standard_sse_constant_opcode (insn, operands[1]);
3137 switch (get_attr_mode (insn))
3140 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3141 return "%vmovapd\t{%1, %0|%0, %1}";
3143 return "%vmovaps\t{%1, %0|%0, %1}";
3146 return "%vmovq\t{%1, %0|%0, %1}";
3148 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3149 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3150 return "%vmovsd\t{%1, %0|%0, %1}";
3152 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3154 return "%vmovlps\t{%1, %d0|%d0, %1}";
3164 (if_then_else (eq_attr "alternative" "5,6,7,8")
3165 (const_string "sse2")
3166 (const_string "*")))
3168 (cond [(eq_attr "alternative" "0,1,2")
3169 (const_string "fmov")
3170 (eq_attr "alternative" "3,4")
3171 (const_string "multi")
3172 (eq_attr "alternative" "5,9")
3173 (const_string "sselog1")
3175 (const_string "ssemov")))
3176 (set (attr "prefix")
3177 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3178 (const_string "orig")
3179 (const_string "maybe_vex")))
3180 (set (attr "prefix_data16")
3181 (if_then_else (eq_attr "mode" "V1DF")
3183 (const_string "*")))
3185 (cond [(eq_attr "alternative" "0,1,2")
3187 (eq_attr "alternative" "3,4")
3190 /* For SSE1, we have many fewer alternatives. */
3191 (not (match_test "TARGET_SSE2"))
3193 (eq_attr "alternative" "5,6,9,10")
3194 (const_string "V4SF")
3195 (const_string "V2SF"))
3197 /* xorps is one byte shorter. */
3198 (eq_attr "alternative" "5,9")
3199 (cond [(match_test "optimize_function_for_size_p (cfun)")
3200 (const_string "V4SF")
3201 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3204 (const_string "V2DF"))
3206 /* For architectures resolving dependencies on
3207 whole SSE registers use APD move to break dependency
3208 chains, otherwise use short move to avoid extra work.
3210 movaps encodes one byte shorter. */
3211 (eq_attr "alternative" "6,10")
3213 [(match_test "optimize_function_for_size_p (cfun)")
3214 (const_string "V4SF")
3215 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3216 (const_string "V2DF")
3218 (const_string "DF"))
3219 /* For architectures resolving dependencies on register
3220 parts we may avoid extra work to zero out upper part
3222 (eq_attr "alternative" "7,11")
3224 (match_test "TARGET_SSE_SPLIT_REGS")
3225 (const_string "V1DF")
3226 (const_string "DF"))
3228 (const_string "DF")))])
3230 (define_insn "*movsf_internal"
3231 [(set (match_operand:SF 0 "nonimmediate_operand"
3232 "=Yf*f,m ,Yf*f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3233 (match_operand:SF 1 "general_operand"
3234 "Yf*fm,Yf*f,G ,rmF,rF,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3235 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3236 && (!can_create_pseudo_p ()
3237 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3238 || GET_CODE (operands[1]) != CONST_DOUBLE
3239 || (optimize_function_for_size_p (cfun)
3240 && ((!TARGET_SSE_MATH
3241 && standard_80387_constant_p (operands[1]) > 0)
3243 && standard_sse_constant_p (operands[1]))))
3244 || memory_operand (operands[0], SFmode))"
3246 switch (which_alternative)
3250 return output_387_reg_move (insn, operands);
3253 return standard_80387_constant_opcode (operands[1]);
3257 return "mov{l}\t{%1, %0|%0, %1}";
3260 return standard_sse_constant_opcode (insn, operands[1]);
3263 if (get_attr_mode (insn) == MODE_V4SF)
3264 return "%vmovaps\t{%1, %0|%0, %1}";
3266 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3270 return "%vmovss\t{%1, %0|%0, %1}";
3276 return "movd\t{%1, %0|%0, %1}";
3279 return "movq\t{%1, %0|%0, %1}";
3283 return "%vmovd\t{%1, %0|%0, %1}";
3290 (cond [(eq_attr "alternative" "0,1,2")
3291 (const_string "fmov")
3292 (eq_attr "alternative" "3,4")
3293 (const_string "imov")
3294 (eq_attr "alternative" "5")
3295 (const_string "sselog1")
3296 (eq_attr "alternative" "9,10,11,14,15")
3297 (const_string "mmxmov")
3299 (const_string "ssemov")))
3300 (set (attr "prefix")
3301 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3302 (const_string "maybe_vex")
3303 (const_string "orig")))
3305 (cond [(eq_attr "alternative" "3,4,9,10")
3307 (eq_attr "alternative" "5")
3309 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3310 (match_test "TARGET_SSE2"))
3311 (not (match_test "optimize_function_for_size_p (cfun)")))
3313 (const_string "V4SF"))
3314 /* For architectures resolving dependencies on
3315 whole SSE registers use APS move to break dependency
3316 chains, otherwise use short move to avoid extra work.
3318 Do the same for architectures resolving dependencies on
3319 the parts. While in DF mode it is better to always handle
3320 just register parts, the SF mode is different due to lack
3321 of instructions to load just part of the register. It is
3322 better to maintain the whole registers in single format
3323 to avoid problems on using packed logical operations. */
3324 (eq_attr "alternative" "6")
3326 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3327 (match_test "TARGET_SSE_SPLIT_REGS"))
3328 (const_string "V4SF")
3329 (const_string "SF"))
3330 (eq_attr "alternative" "11")
3331 (const_string "DI")]
3332 (const_string "SF")))])
3335 [(set (match_operand 0 "any_fp_register_operand" "")
3336 (match_operand 1 "memory_operand" ""))]
3338 && (GET_MODE (operands[0]) == TFmode
3339 || GET_MODE (operands[0]) == XFmode
3340 || GET_MODE (operands[0]) == DFmode
3341 || GET_MODE (operands[0]) == SFmode)
3342 && (operands[2] = find_constant_src (insn))"
3343 [(set (match_dup 0) (match_dup 2))]
3345 rtx c = operands[2];
3346 int r = REGNO (operands[0]);
3348 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3349 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3354 [(set (match_operand 0 "any_fp_register_operand" "")
3355 (float_extend (match_operand 1 "memory_operand" "")))]
3357 && (GET_MODE (operands[0]) == TFmode
3358 || GET_MODE (operands[0]) == XFmode
3359 || GET_MODE (operands[0]) == DFmode)
3360 && (operands[2] = find_constant_src (insn))"
3361 [(set (match_dup 0) (match_dup 2))]
3363 rtx c = operands[2];
3364 int r = REGNO (operands[0]);
3366 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3367 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3371 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3373 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3374 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3376 && (standard_80387_constant_p (operands[1]) == 8
3377 || standard_80387_constant_p (operands[1]) == 9)"
3378 [(set (match_dup 0)(match_dup 1))
3380 (neg:X87MODEF (match_dup 0)))]
3384 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3385 if (real_isnegzero (&r))
3386 operands[1] = CONST0_RTX (<MODE>mode);
3388 operands[1] = CONST1_RTX (<MODE>mode);
3392 [(set (match_operand 0 "nonimmediate_operand" "")
3393 (match_operand 1 "general_operand" ""))]
3395 && (GET_MODE (operands[0]) == TFmode
3396 || GET_MODE (operands[0]) == XFmode
3397 || GET_MODE (operands[0]) == DFmode)
3398 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3400 "ix86_split_long_move (operands); DONE;")
3402 (define_insn "swapxf"
3403 [(set (match_operand:XF 0 "register_operand" "+f")
3404 (match_operand:XF 1 "register_operand" "+f"))
3409 if (STACK_TOP_P (operands[0]))
3414 [(set_attr "type" "fxch")
3415 (set_attr "mode" "XF")])
3417 (define_insn "*swap<mode>"
3418 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3419 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3422 "TARGET_80387 || reload_completed"
3424 if (STACK_TOP_P (operands[0]))
3429 [(set_attr "type" "fxch")
3430 (set_attr "mode" "<MODE>")])
3432 ;; Zero extension instructions
3434 (define_expand "zero_extendsidi2"
3435 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3436 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3441 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3446 (define_insn "*zero_extendsidi2_rex64"
3447 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3449 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3452 mov{l}\t{%1, %k0|%k0, %1}
3454 movd\t{%1, %0|%0, %1}
3455 movd\t{%1, %0|%0, %1}
3456 %vmovd\t{%1, %0|%0, %1}
3457 %vmovd\t{%1, %0|%0, %1}"
3458 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3459 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3460 (set_attr "prefix_0f" "0,*,*,*,*,*")
3461 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3464 [(set (match_operand:DI 0 "memory_operand" "")
3465 (zero_extend:DI (match_dup 0)))]
3467 [(set (match_dup 4) (const_int 0))]
3468 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3470 ;; %%% Kill me once multi-word ops are sane.
3471 (define_insn "zero_extendsidi2_1"
3472 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3474 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3475 (clobber (reg:CC FLAGS_REG))]
3481 movd\t{%1, %0|%0, %1}
3482 movd\t{%1, %0|%0, %1}
3483 %vmovd\t{%1, %0|%0, %1}
3484 %vmovd\t{%1, %0|%0, %1}"
3485 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3486 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3487 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3488 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3491 [(set (match_operand:DI 0 "register_operand" "")
3492 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3493 (clobber (reg:CC FLAGS_REG))]
3494 "!TARGET_64BIT && reload_completed
3495 && true_regnum (operands[0]) == true_regnum (operands[1])"
3496 [(set (match_dup 4) (const_int 0))]
3497 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3500 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3501 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3502 (clobber (reg:CC FLAGS_REG))]
3503 "!TARGET_64BIT && reload_completed
3504 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3505 [(set (match_dup 3) (match_dup 1))
3506 (set (match_dup 4) (const_int 0))]
3507 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3509 (define_insn "zero_extend<mode>di2"
3510 [(set (match_operand:DI 0 "register_operand" "=r")
3512 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3514 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3515 [(set_attr "type" "imovx")
3516 (set_attr "mode" "SI")])
3518 (define_expand "zero_extendhisi2"
3519 [(set (match_operand:SI 0 "register_operand" "")
3520 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3523 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3525 operands[1] = force_reg (HImode, operands[1]);
3526 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3531 (define_insn_and_split "zero_extendhisi2_and"
3532 [(set (match_operand:SI 0 "register_operand" "=r")
3533 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3534 (clobber (reg:CC FLAGS_REG))]
3535 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3537 "&& reload_completed"
3538 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3539 (clobber (reg:CC FLAGS_REG))])]
3541 [(set_attr "type" "alu1")
3542 (set_attr "mode" "SI")])
3544 (define_insn "*zero_extendhisi2_movzwl"
3545 [(set (match_operand:SI 0 "register_operand" "=r")
3546 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3547 "!TARGET_ZERO_EXTEND_WITH_AND
3548 || optimize_function_for_size_p (cfun)"
3549 "movz{wl|x}\t{%1, %0|%0, %1}"
3550 [(set_attr "type" "imovx")
3551 (set_attr "mode" "SI")])
3553 (define_expand "zero_extendqi<mode>2"
3555 [(set (match_operand:SWI24 0 "register_operand" "")
3556 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3557 (clobber (reg:CC FLAGS_REG))])])
3559 (define_insn "*zero_extendqi<mode>2_and"
3560 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3561 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3562 (clobber (reg:CC FLAGS_REG))]
3563 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3565 [(set_attr "type" "alu1")
3566 (set_attr "mode" "<MODE>")])
3568 ;; When source and destination does not overlap, clear destination
3569 ;; first and then do the movb
3571 [(set (match_operand:SWI24 0 "register_operand" "")
3572 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3573 (clobber (reg:CC FLAGS_REG))]
3575 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3576 && ANY_QI_REG_P (operands[0])
3577 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3578 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3579 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3581 operands[2] = gen_lowpart (QImode, operands[0]);
3582 ix86_expand_clear (operands[0]);
3585 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3586 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3587 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3588 (clobber (reg:CC FLAGS_REG))]
3589 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3591 [(set_attr "type" "imovx,alu1")
3592 (set_attr "mode" "<MODE>")])
3594 ;; For the movzbl case strip only the clobber
3596 [(set (match_operand:SWI24 0 "register_operand" "")
3597 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3598 (clobber (reg:CC FLAGS_REG))]
3600 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3601 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3603 (zero_extend:SWI24 (match_dup 1)))])
3605 ; zero extend to SImode to avoid partial register stalls
3606 (define_insn "*zero_extendqi<mode>2_movzbl"
3607 [(set (match_operand:SWI24 0 "register_operand" "=r")
3608 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3610 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3611 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3612 [(set_attr "type" "imovx")
3613 (set_attr "mode" "SI")])
3615 ;; Rest is handled by single and.
3617 [(set (match_operand:SWI24 0 "register_operand" "")
3618 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3619 (clobber (reg:CC FLAGS_REG))]
3621 && true_regnum (operands[0]) == true_regnum (operands[1])"
3622 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3623 (clobber (reg:CC FLAGS_REG))])])
3625 ;; Sign extension instructions
3627 (define_expand "extendsidi2"
3628 [(set (match_operand:DI 0 "register_operand" "")
3629 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3634 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3639 (define_insn "*extendsidi2_rex64"
3640 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3641 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3645 movs{lq|x}\t{%1, %0|%0, %1}"
3646 [(set_attr "type" "imovx")
3647 (set_attr "mode" "DI")
3648 (set_attr "prefix_0f" "0")
3649 (set_attr "modrm" "0,1")])
3651 (define_insn "extendsidi2_1"
3652 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3653 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3654 (clobber (reg:CC FLAGS_REG))
3655 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3659 ;; Extend to memory case when source register does die.
3661 [(set (match_operand:DI 0 "memory_operand" "")
3662 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3663 (clobber (reg:CC FLAGS_REG))
3664 (clobber (match_operand:SI 2 "register_operand" ""))]
3666 && dead_or_set_p (insn, operands[1])
3667 && !reg_mentioned_p (operands[1], operands[0]))"
3668 [(set (match_dup 3) (match_dup 1))
3669 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3670 (clobber (reg:CC FLAGS_REG))])
3671 (set (match_dup 4) (match_dup 1))]
3672 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3674 ;; Extend to memory case when source register does not die.
3676 [(set (match_operand:DI 0 "memory_operand" "")
3677 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3678 (clobber (reg:CC FLAGS_REG))
3679 (clobber (match_operand:SI 2 "register_operand" ""))]
3683 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3685 emit_move_insn (operands[3], operands[1]);
3687 /* Generate a cltd if possible and doing so it profitable. */
3688 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3689 && true_regnum (operands[1]) == AX_REG
3690 && true_regnum (operands[2]) == DX_REG)
3692 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3696 emit_move_insn (operands[2], operands[1]);
3697 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3699 emit_move_insn (operands[4], operands[2]);
3703 ;; Extend to register case. Optimize case where source and destination
3704 ;; registers match and cases where we can use cltd.
3706 [(set (match_operand:DI 0 "register_operand" "")
3707 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3708 (clobber (reg:CC FLAGS_REG))
3709 (clobber (match_scratch:SI 2 ""))]
3713 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3715 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3716 emit_move_insn (operands[3], operands[1]);
3718 /* Generate a cltd if possible and doing so it profitable. */
3719 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3720 && true_regnum (operands[3]) == AX_REG
3721 && true_regnum (operands[4]) == DX_REG)
3723 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3727 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3728 emit_move_insn (operands[4], operands[1]);
3730 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3734 (define_insn "extend<mode>di2"
3735 [(set (match_operand:DI 0 "register_operand" "=r")
3737 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3739 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3740 [(set_attr "type" "imovx")
3741 (set_attr "mode" "DI")])
3743 (define_insn "extendhisi2"
3744 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3745 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3748 switch (get_attr_prefix_0f (insn))
3751 return "{cwtl|cwde}";
3753 return "movs{wl|x}\t{%1, %0|%0, %1}";
3756 [(set_attr "type" "imovx")
3757 (set_attr "mode" "SI")
3758 (set (attr "prefix_0f")
3759 ;; movsx is short decodable while cwtl is vector decoded.
3760 (if_then_else (and (eq_attr "cpu" "!k6")
3761 (eq_attr "alternative" "0"))
3763 (const_string "1")))
3765 (if_then_else (eq_attr "prefix_0f" "0")
3767 (const_string "1")))])
3769 (define_insn "*extendhisi2_zext"
3770 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3773 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3776 switch (get_attr_prefix_0f (insn))
3779 return "{cwtl|cwde}";
3781 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3784 [(set_attr "type" "imovx")
3785 (set_attr "mode" "SI")
3786 (set (attr "prefix_0f")
3787 ;; movsx is short decodable while cwtl is vector decoded.
3788 (if_then_else (and (eq_attr "cpu" "!k6")
3789 (eq_attr "alternative" "0"))
3791 (const_string "1")))
3793 (if_then_else (eq_attr "prefix_0f" "0")
3795 (const_string "1")))])
3797 (define_insn "extendqisi2"
3798 [(set (match_operand:SI 0 "register_operand" "=r")
3799 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3801 "movs{bl|x}\t{%1, %0|%0, %1}"
3802 [(set_attr "type" "imovx")
3803 (set_attr "mode" "SI")])
3805 (define_insn "*extendqisi2_zext"
3806 [(set (match_operand:DI 0 "register_operand" "=r")
3808 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3810 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3811 [(set_attr "type" "imovx")
3812 (set_attr "mode" "SI")])
3814 (define_insn "extendqihi2"
3815 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3816 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3819 switch (get_attr_prefix_0f (insn))
3822 return "{cbtw|cbw}";
3824 return "movs{bw|x}\t{%1, %0|%0, %1}";
3827 [(set_attr "type" "imovx")
3828 (set_attr "mode" "HI")
3829 (set (attr "prefix_0f")
3830 ;; movsx is short decodable while cwtl is vector decoded.
3831 (if_then_else (and (eq_attr "cpu" "!k6")
3832 (eq_attr "alternative" "0"))
3834 (const_string "1")))
3836 (if_then_else (eq_attr "prefix_0f" "0")
3838 (const_string "1")))])
3840 ;; Conversions between float and double.
3842 ;; These are all no-ops in the model used for the 80387.
3843 ;; So just emit moves.
3845 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3847 [(set (match_operand:DF 0 "push_operand" "")
3848 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3850 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3851 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3854 [(set (match_operand:XF 0 "push_operand" "")
3855 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3857 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3858 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3859 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3861 (define_expand "extendsfdf2"
3862 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3863 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3864 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3866 /* ??? Needed for compress_float_constant since all fp constants
3867 are TARGET_LEGITIMATE_CONSTANT_P. */
3868 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3870 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3871 && standard_80387_constant_p (operands[1]) > 0)
3873 operands[1] = simplify_const_unary_operation
3874 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3875 emit_move_insn_1 (operands[0], operands[1]);
3878 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3882 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3884 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3886 We do the conversion post reload to avoid producing of 128bit spills
3887 that might lead to ICE on 32bit target. The sequence unlikely combine
3890 [(set (match_operand:DF 0 "register_operand" "")
3892 (match_operand:SF 1 "nonimmediate_operand" "")))]
3893 "TARGET_USE_VECTOR_FP_CONVERTS
3894 && optimize_insn_for_speed_p ()
3895 && reload_completed && SSE_REG_P (operands[0])"
3900 (parallel [(const_int 0) (const_int 1)]))))]
3902 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3903 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3904 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3905 Try to avoid move when unpacking can be done in source. */
3906 if (REG_P (operands[1]))
3908 /* If it is unsafe to overwrite upper half of source, we need
3909 to move to destination and unpack there. */
3910 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3911 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3912 && true_regnum (operands[0]) != true_regnum (operands[1]))
3914 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3915 emit_move_insn (tmp, operands[1]);
3918 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3919 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3923 emit_insn (gen_vec_setv4sf_0 (operands[3],
3924 CONST0_RTX (V4SFmode), operands[1]));
3927 (define_insn "*extendsfdf2_mixed"
3928 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3930 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3931 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3933 switch (which_alternative)
3937 return output_387_reg_move (insn, operands);
3940 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3946 [(set_attr "type" "fmov,fmov,ssecvt")
3947 (set_attr "prefix" "orig,orig,maybe_vex")
3948 (set_attr "mode" "SF,XF,DF")])
3950 (define_insn "*extendsfdf2_sse"
3951 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3952 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3953 "TARGET_SSE2 && TARGET_SSE_MATH"
3954 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3955 [(set_attr "type" "ssecvt")
3956 (set_attr "prefix" "maybe_vex")
3957 (set_attr "mode" "DF")])
3959 (define_insn "*extendsfdf2_i387"
3960 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3961 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3963 "* return output_387_reg_move (insn, operands);"
3964 [(set_attr "type" "fmov")
3965 (set_attr "mode" "SF,XF")])
3967 (define_expand "extend<mode>xf2"
3968 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3969 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3972 /* ??? Needed for compress_float_constant since all fp constants
3973 are TARGET_LEGITIMATE_CONSTANT_P. */
3974 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3976 if (standard_80387_constant_p (operands[1]) > 0)
3978 operands[1] = simplify_const_unary_operation
3979 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3980 emit_move_insn_1 (operands[0], operands[1]);
3983 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3987 (define_insn "*extend<mode>xf2_i387"
3988 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3990 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3992 "* return output_387_reg_move (insn, operands);"
3993 [(set_attr "type" "fmov")
3994 (set_attr "mode" "<MODE>,XF")])
3996 ;; %%% This seems bad bad news.
3997 ;; This cannot output into an f-reg because there is no way to be sure
3998 ;; of truncating in that case. Otherwise this is just like a simple move
3999 ;; insn. So we pretend we can output to a reg in order to get better
4000 ;; register preferencing, but we really use a stack slot.
4002 ;; Conversion from DFmode to SFmode.
4004 (define_expand "truncdfsf2"
4005 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4007 (match_operand:DF 1 "nonimmediate_operand" "")))]
4008 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4010 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4012 else if (flag_unsafe_math_optimizations)
4016 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4017 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4022 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4024 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4026 We do the conversion post reload to avoid producing of 128bit spills
4027 that might lead to ICE on 32bit target. The sequence unlikely combine
4030 [(set (match_operand:SF 0 "register_operand" "")
4032 (match_operand:DF 1 "nonimmediate_operand" "")))]
4033 "TARGET_USE_VECTOR_FP_CONVERTS
4034 && optimize_insn_for_speed_p ()
4035 && reload_completed && SSE_REG_P (operands[0])"
4038 (float_truncate:V2SF
4042 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4043 operands[3] = CONST0_RTX (V2SFmode);
4044 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4045 /* Use movsd for loading from memory, unpcklpd for registers.
4046 Try to avoid move when unpacking can be done in source, or SSE3
4047 movddup is available. */
4048 if (REG_P (operands[1]))
4051 && true_regnum (operands[0]) != true_regnum (operands[1])
4052 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4053 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4055 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4056 emit_move_insn (tmp, operands[1]);
4059 else if (!TARGET_SSE3)
4060 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4061 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4064 emit_insn (gen_sse2_loadlpd (operands[4],
4065 CONST0_RTX (V2DFmode), operands[1]));
4068 (define_expand "truncdfsf2_with_temp"
4069 [(parallel [(set (match_operand:SF 0 "" "")
4070 (float_truncate:SF (match_operand:DF 1 "" "")))
4071 (clobber (match_operand:SF 2 "" ""))])])
4073 (define_insn "*truncdfsf_fast_mixed"
4074 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4076 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4077 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4079 switch (which_alternative)
4082 return output_387_reg_move (insn, operands);
4084 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4089 [(set_attr "type" "fmov,ssecvt")
4090 (set_attr "prefix" "orig,maybe_vex")
4091 (set_attr "mode" "SF")])
4093 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4094 ;; because nothing we do here is unsafe.
4095 (define_insn "*truncdfsf_fast_sse"
4096 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4098 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4099 "TARGET_SSE2 && TARGET_SSE_MATH"
4100 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4101 [(set_attr "type" "ssecvt")
4102 (set_attr "prefix" "maybe_vex")
4103 (set_attr "mode" "SF")])
4105 (define_insn "*truncdfsf_fast_i387"
4106 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4108 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4109 "TARGET_80387 && flag_unsafe_math_optimizations"
4110 "* return output_387_reg_move (insn, operands);"
4111 [(set_attr "type" "fmov")
4112 (set_attr "mode" "SF")])
4114 (define_insn "*truncdfsf_mixed"
4115 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4117 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4118 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4119 "TARGET_MIX_SSE_I387"
4121 switch (which_alternative)
4124 return output_387_reg_move (insn, operands);
4126 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4132 [(set_attr "isa" "*,sse2,*,*,*")
4133 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4134 (set_attr "unit" "*,*,i387,i387,i387")
4135 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4136 (set_attr "mode" "SF")])
4138 (define_insn "*truncdfsf_i387"
4139 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4141 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4142 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4145 switch (which_alternative)
4148 return output_387_reg_move (insn, operands);
4154 [(set_attr "type" "fmov,multi,multi,multi")
4155 (set_attr "unit" "*,i387,i387,i387")
4156 (set_attr "mode" "SF")])
4158 (define_insn "*truncdfsf2_i387_1"
4159 [(set (match_operand:SF 0 "memory_operand" "=m")
4161 (match_operand:DF 1 "register_operand" "f")))]
4163 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4164 && !TARGET_MIX_SSE_I387"
4165 "* return output_387_reg_move (insn, operands);"
4166 [(set_attr "type" "fmov")
4167 (set_attr "mode" "SF")])
4170 [(set (match_operand:SF 0 "register_operand" "")
4172 (match_operand:DF 1 "fp_register_operand" "")))
4173 (clobber (match_operand 2 "" ""))]
4175 [(set (match_dup 2) (match_dup 1))
4176 (set (match_dup 0) (match_dup 2))]
4177 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4179 ;; Conversion from XFmode to {SF,DF}mode
4181 (define_expand "truncxf<mode>2"
4182 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4183 (float_truncate:MODEF
4184 (match_operand:XF 1 "register_operand" "")))
4185 (clobber (match_dup 2))])]
4188 if (flag_unsafe_math_optimizations)
4190 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4191 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4192 if (reg != operands[0])
4193 emit_move_insn (operands[0], reg);
4197 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4200 (define_insn "*truncxfsf2_mixed"
4201 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4203 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4204 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4207 gcc_assert (!which_alternative);
4208 return output_387_reg_move (insn, operands);
4210 [(set_attr "type" "fmov,multi,multi,multi")
4211 (set_attr "unit" "*,i387,i387,i387")
4212 (set_attr "mode" "SF")])
4214 (define_insn "*truncxfdf2_mixed"
4215 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4217 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4218 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4221 gcc_assert (!which_alternative);
4222 return output_387_reg_move (insn, operands);
4224 [(set_attr "isa" "*,*,sse2,*")
4225 (set_attr "type" "fmov,multi,multi,multi")
4226 (set_attr "unit" "*,i387,i387,i387")
4227 (set_attr "mode" "DF")])
4229 (define_insn "truncxf<mode>2_i387_noop"
4230 [(set (match_operand:MODEF 0 "register_operand" "=f")
4231 (float_truncate:MODEF
4232 (match_operand:XF 1 "register_operand" "f")))]
4233 "TARGET_80387 && flag_unsafe_math_optimizations"
4234 "* return output_387_reg_move (insn, operands);"
4235 [(set_attr "type" "fmov")
4236 (set_attr "mode" "<MODE>")])
4238 (define_insn "*truncxf<mode>2_i387"
4239 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4240 (float_truncate:MODEF
4241 (match_operand:XF 1 "register_operand" "f")))]
4243 "* return output_387_reg_move (insn, operands);"
4244 [(set_attr "type" "fmov")
4245 (set_attr "mode" "<MODE>")])
4248 [(set (match_operand:MODEF 0 "register_operand" "")
4249 (float_truncate:MODEF
4250 (match_operand:XF 1 "register_operand" "")))
4251 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4252 "TARGET_80387 && reload_completed"
4253 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4254 (set (match_dup 0) (match_dup 2))])
4257 [(set (match_operand:MODEF 0 "memory_operand" "")
4258 (float_truncate:MODEF
4259 (match_operand:XF 1 "register_operand" "")))
4260 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4262 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4264 ;; Signed conversion to DImode.
4266 (define_expand "fix_truncxfdi2"
4267 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4268 (fix:DI (match_operand:XF 1 "register_operand" "")))
4269 (clobber (reg:CC FLAGS_REG))])]
4274 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4279 (define_expand "fix_trunc<mode>di2"
4280 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4281 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4282 (clobber (reg:CC FLAGS_REG))])]
4283 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4286 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4288 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4291 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4293 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4294 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4295 if (out != operands[0])
4296 emit_move_insn (operands[0], out);
4301 ;; Signed conversion to SImode.
4303 (define_expand "fix_truncxfsi2"
4304 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4305 (fix:SI (match_operand:XF 1 "register_operand" "")))
4306 (clobber (reg:CC FLAGS_REG))])]
4311 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4316 (define_expand "fix_trunc<mode>si2"
4317 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4318 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4319 (clobber (reg:CC FLAGS_REG))])]
4320 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4323 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4325 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4328 if (SSE_FLOAT_MODE_P (<MODE>mode))
4330 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4331 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4332 if (out != operands[0])
4333 emit_move_insn (operands[0], out);
4338 ;; Signed conversion to HImode.
4340 (define_expand "fix_trunc<mode>hi2"
4341 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4342 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4343 (clobber (reg:CC FLAGS_REG))])]
4345 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4349 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4354 ;; Unsigned conversion to SImode.
4356 (define_expand "fixuns_trunc<mode>si2"
4358 [(set (match_operand:SI 0 "register_operand" "")
4360 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4362 (clobber (match_scratch:<ssevecmode> 3 ""))
4363 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4364 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4366 enum machine_mode mode = <MODE>mode;
4367 enum machine_mode vecmode = <ssevecmode>mode;
4368 REAL_VALUE_TYPE TWO31r;
4371 if (optimize_insn_for_size_p ())
4374 real_ldexp (&TWO31r, &dconst1, 31);
4375 two31 = const_double_from_real_value (TWO31r, mode);
4376 two31 = ix86_build_const_vector (vecmode, true, two31);
4377 operands[2] = force_reg (vecmode, two31);
4380 (define_insn_and_split "*fixuns_trunc<mode>_1"
4381 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4383 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4384 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4385 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4386 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4387 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4388 && optimize_function_for_speed_p (cfun)"
4390 "&& reload_completed"
4393 ix86_split_convert_uns_si_sse (operands);
4397 ;; Unsigned conversion to HImode.
4398 ;; Without these patterns, we'll try the unsigned SI conversion which
4399 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4401 (define_expand "fixuns_trunc<mode>hi2"
4403 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4404 (set (match_operand:HI 0 "nonimmediate_operand" "")
4405 (subreg:HI (match_dup 2) 0))]
4406 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4407 "operands[2] = gen_reg_rtx (SImode);")
4409 ;; When SSE is available, it is always faster to use it!
4410 (define_insn "fix_trunc<mode>di_sse"
4411 [(set (match_operand:DI 0 "register_operand" "=r,r")
4412 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4413 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4414 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4415 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4416 [(set_attr "type" "sseicvt")
4417 (set_attr "prefix" "maybe_vex")
4418 (set_attr "prefix_rex" "1")
4419 (set_attr "mode" "<MODE>")
4420 (set_attr "athlon_decode" "double,vector")
4421 (set_attr "amdfam10_decode" "double,double")
4422 (set_attr "bdver1_decode" "double,double")])
4424 (define_insn "fix_trunc<mode>si_sse"
4425 [(set (match_operand:SI 0 "register_operand" "=r,r")
4426 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4427 "SSE_FLOAT_MODE_P (<MODE>mode)
4428 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4429 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4430 [(set_attr "type" "sseicvt")
4431 (set_attr "prefix" "maybe_vex")
4432 (set_attr "mode" "<MODE>")
4433 (set_attr "athlon_decode" "double,vector")
4434 (set_attr "amdfam10_decode" "double,double")
4435 (set_attr "bdver1_decode" "double,double")])
4437 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4439 [(set (match_operand:MODEF 0 "register_operand" "")
4440 (match_operand:MODEF 1 "memory_operand" ""))
4441 (set (match_operand:SWI48x 2 "register_operand" "")
4442 (fix:SWI48x (match_dup 0)))]
4443 "TARGET_SHORTEN_X87_SSE
4444 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4445 && peep2_reg_dead_p (2, operands[0])"
4446 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4448 ;; Avoid vector decoded forms of the instruction.
4450 [(match_scratch:DF 2 "x")
4451 (set (match_operand:SWI48x 0 "register_operand" "")
4452 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4453 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4454 [(set (match_dup 2) (match_dup 1))
4455 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4458 [(match_scratch:SF 2 "x")
4459 (set (match_operand:SWI48x 0 "register_operand" "")
4460 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4461 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4462 [(set (match_dup 2) (match_dup 1))
4463 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4465 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4466 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4467 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4468 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4470 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4471 && (TARGET_64BIT || <MODE>mode != DImode))
4473 && can_create_pseudo_p ()"
4478 if (memory_operand (operands[0], VOIDmode))
4479 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4482 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4483 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4489 [(set_attr "type" "fisttp")
4490 (set_attr "mode" "<MODE>")])
4492 (define_insn "fix_trunc<mode>_i387_fisttp"
4493 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4494 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4495 (clobber (match_scratch:XF 2 "=&1f"))]
4496 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4498 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4499 && (TARGET_64BIT || <MODE>mode != DImode))
4500 && TARGET_SSE_MATH)"
4501 "* return output_fix_trunc (insn, operands, true);"
4502 [(set_attr "type" "fisttp")
4503 (set_attr "mode" "<MODE>")])
4505 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4506 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4507 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4508 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4509 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4510 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4512 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4513 && (TARGET_64BIT || <MODE>mode != DImode))
4514 && TARGET_SSE_MATH)"
4516 [(set_attr "type" "fisttp")
4517 (set_attr "mode" "<MODE>")])
4520 [(set (match_operand:SWI248x 0 "register_operand" "")
4521 (fix:SWI248x (match_operand 1 "register_operand" "")))
4522 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4523 (clobber (match_scratch 3 ""))]
4525 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4526 (clobber (match_dup 3))])
4527 (set (match_dup 0) (match_dup 2))])
4530 [(set (match_operand:SWI248x 0 "memory_operand" "")
4531 (fix:SWI248x (match_operand 1 "register_operand" "")))
4532 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4533 (clobber (match_scratch 3 ""))]
4535 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4536 (clobber (match_dup 3))])])
4538 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4539 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4540 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4541 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4542 ;; function in i386.c.
4543 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4544 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4545 (fix:SWI248x (match_operand 1 "register_operand" "")))
4546 (clobber (reg:CC FLAGS_REG))]
4547 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4549 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4550 && (TARGET_64BIT || <MODE>mode != DImode))
4551 && can_create_pseudo_p ()"
4556 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4558 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4559 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4560 if (memory_operand (operands[0], VOIDmode))
4561 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4562 operands[2], operands[3]));
4565 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4566 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4567 operands[2], operands[3],
4572 [(set_attr "type" "fistp")
4573 (set_attr "i387_cw" "trunc")
4574 (set_attr "mode" "<MODE>")])
4576 (define_insn "fix_truncdi_i387"
4577 [(set (match_operand:DI 0 "memory_operand" "=m")
4578 (fix:DI (match_operand 1 "register_operand" "f")))
4579 (use (match_operand:HI 2 "memory_operand" "m"))
4580 (use (match_operand:HI 3 "memory_operand" "m"))
4581 (clobber (match_scratch:XF 4 "=&1f"))]
4582 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4584 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4585 "* return output_fix_trunc (insn, operands, false);"
4586 [(set_attr "type" "fistp")
4587 (set_attr "i387_cw" "trunc")
4588 (set_attr "mode" "DI")])
4590 (define_insn "fix_truncdi_i387_with_temp"
4591 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4592 (fix:DI (match_operand 1 "register_operand" "f,f")))
4593 (use (match_operand:HI 2 "memory_operand" "m,m"))
4594 (use (match_operand:HI 3 "memory_operand" "m,m"))
4595 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4596 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4597 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4599 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4601 [(set_attr "type" "fistp")
4602 (set_attr "i387_cw" "trunc")
4603 (set_attr "mode" "DI")])
4606 [(set (match_operand:DI 0 "register_operand" "")
4607 (fix:DI (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:DI 4 "memory_operand" ""))
4611 (clobber (match_scratch 5 ""))]
4613 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4616 (clobber (match_dup 5))])
4617 (set (match_dup 0) (match_dup 4))])
4620 [(set (match_operand:DI 0 "memory_operand" "")
4621 (fix:DI (match_operand 1 "register_operand" "")))
4622 (use (match_operand:HI 2 "memory_operand" ""))
4623 (use (match_operand:HI 3 "memory_operand" ""))
4624 (clobber (match_operand:DI 4 "memory_operand" ""))
4625 (clobber (match_scratch 5 ""))]
4627 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4630 (clobber (match_dup 5))])])
4632 (define_insn "fix_trunc<mode>_i387"
4633 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4634 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4635 (use (match_operand:HI 2 "memory_operand" "m"))
4636 (use (match_operand:HI 3 "memory_operand" "m"))]
4637 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4639 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4640 "* return output_fix_trunc (insn, operands, false);"
4641 [(set_attr "type" "fistp")
4642 (set_attr "i387_cw" "trunc")
4643 (set_attr "mode" "<MODE>")])
4645 (define_insn "fix_trunc<mode>_i387_with_temp"
4646 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4647 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4648 (use (match_operand:HI 2 "memory_operand" "m,m"))
4649 (use (match_operand:HI 3 "memory_operand" "m,m"))
4650 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4651 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4653 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4655 [(set_attr "type" "fistp")
4656 (set_attr "i387_cw" "trunc")
4657 (set_attr "mode" "<MODE>")])
4660 [(set (match_operand:SWI24 0 "register_operand" "")
4661 (fix:SWI24 (match_operand 1 "register_operand" "")))
4662 (use (match_operand:HI 2 "memory_operand" ""))
4663 (use (match_operand:HI 3 "memory_operand" ""))
4664 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4666 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4668 (use (match_dup 3))])
4669 (set (match_dup 0) (match_dup 4))])
4672 [(set (match_operand:SWI24 0 "memory_operand" "")
4673 (fix:SWI24 (match_operand 1 "register_operand" "")))
4674 (use (match_operand:HI 2 "memory_operand" ""))
4675 (use (match_operand:HI 3 "memory_operand" ""))
4676 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4678 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4680 (use (match_dup 3))])])
4682 (define_insn "x86_fnstcw_1"
4683 [(set (match_operand:HI 0 "memory_operand" "=m")
4684 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4687 [(set (attr "length")
4688 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4689 (set_attr "mode" "HI")
4690 (set_attr "unit" "i387")
4691 (set_attr "bdver1_decode" "vector")])
4693 (define_insn "x86_fldcw_1"
4694 [(set (reg:HI FPCR_REG)
4695 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4698 [(set (attr "length")
4699 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4700 (set_attr "mode" "HI")
4701 (set_attr "unit" "i387")
4702 (set_attr "athlon_decode" "vector")
4703 (set_attr "amdfam10_decode" "vector")
4704 (set_attr "bdver1_decode" "vector")])
4706 ;; Conversion between fixed point and floating point.
4708 ;; Even though we only accept memory inputs, the backend _really_
4709 ;; wants to be able to do this between registers.
4711 (define_expand "floathi<mode>2"
4712 [(set (match_operand:X87MODEF 0 "register_operand" "")
4713 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4715 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4716 || TARGET_MIX_SSE_I387)")
4718 ;; Pre-reload splitter to add memory clobber to the pattern.
4719 (define_insn_and_split "*floathi<mode>2_1"
4720 [(set (match_operand:X87MODEF 0 "register_operand" "")
4721 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4723 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4724 || TARGET_MIX_SSE_I387)
4725 && can_create_pseudo_p ()"
4728 [(parallel [(set (match_dup 0)
4729 (float:X87MODEF (match_dup 1)))
4730 (clobber (match_dup 2))])]
4731 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4733 (define_insn "*floathi<mode>2_i387_with_temp"
4734 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4735 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4736 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4738 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4739 || TARGET_MIX_SSE_I387)"
4741 [(set_attr "type" "fmov,multi")
4742 (set_attr "mode" "<MODE>")
4743 (set_attr "unit" "*,i387")
4744 (set_attr "fp_int_src" "true")])
4746 (define_insn "*floathi<mode>2_i387"
4747 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4748 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4750 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4751 || TARGET_MIX_SSE_I387)"
4753 [(set_attr "type" "fmov")
4754 (set_attr "mode" "<MODE>")
4755 (set_attr "fp_int_src" "true")])
4758 [(set (match_operand:X87MODEF 0 "register_operand" "")
4759 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4760 (clobber (match_operand:HI 2 "memory_operand" ""))]
4762 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4763 || TARGET_MIX_SSE_I387)
4764 && reload_completed"
4765 [(set (match_dup 2) (match_dup 1))
4766 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4769 [(set (match_operand:X87MODEF 0 "register_operand" "")
4770 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4771 (clobber (match_operand:HI 2 "memory_operand" ""))]
4773 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4774 || TARGET_MIX_SSE_I387)
4775 && reload_completed"
4776 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4778 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4779 [(set (match_operand:X87MODEF 0 "register_operand" "")
4781 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4783 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4784 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4786 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4787 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4788 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4790 rtx reg = gen_reg_rtx (XFmode);
4791 rtx (*insn)(rtx, rtx);
4793 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4795 if (<X87MODEF:MODE>mode == SFmode)
4796 insn = gen_truncxfsf2;
4797 else if (<X87MODEF:MODE>mode == DFmode)
4798 insn = gen_truncxfdf2;
4802 emit_insn (insn (operands[0], reg));
4807 ;; Pre-reload splitter to add memory clobber to the pattern.
4808 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4809 [(set (match_operand:X87MODEF 0 "register_operand" "")
4810 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4812 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4813 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4814 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4815 || TARGET_MIX_SSE_I387))
4816 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4817 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4818 && ((<SWI48x:MODE>mode == SImode
4819 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4820 && optimize_function_for_speed_p (cfun)
4821 && flag_trapping_math)
4822 || !(TARGET_INTER_UNIT_CONVERSIONS
4823 || optimize_function_for_size_p (cfun)))))
4824 && can_create_pseudo_p ()"
4827 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4828 (clobber (match_dup 2))])]
4830 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4832 /* Avoid store forwarding (partial memory) stall penalty
4833 by passing DImode value through XMM registers. */
4834 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4835 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4836 && optimize_function_for_speed_p (cfun))
4838 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4845 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4846 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4848 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4849 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4850 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4851 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4853 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4854 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4855 (set_attr "unit" "*,i387,*,*,*")
4856 (set_attr "athlon_decode" "*,*,double,direct,double")
4857 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4858 (set_attr "bdver1_decode" "*,*,double,direct,double")
4859 (set_attr "fp_int_src" "true")])
4861 (define_insn "*floatsi<mode>2_vector_mixed"
4862 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4863 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4864 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4865 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4869 [(set_attr "type" "fmov,sseicvt")
4870 (set_attr "mode" "<MODE>,<ssevecmode>")
4871 (set_attr "unit" "i387,*")
4872 (set_attr "athlon_decode" "*,direct")
4873 (set_attr "amdfam10_decode" "*,double")
4874 (set_attr "bdver1_decode" "*,direct")
4875 (set_attr "fp_int_src" "true")])
4877 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4878 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4880 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4881 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4882 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4883 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4885 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4886 (set_attr "mode" "<MODEF:MODE>")
4887 (set_attr "unit" "*,i387,*,*")
4888 (set_attr "athlon_decode" "*,*,double,direct")
4889 (set_attr "amdfam10_decode" "*,*,vector,double")
4890 (set_attr "bdver1_decode" "*,*,double,direct")
4891 (set_attr "fp_int_src" "true")])
4894 [(set (match_operand:MODEF 0 "register_operand" "")
4895 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4896 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4897 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4898 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4899 && TARGET_INTER_UNIT_CONVERSIONS
4901 && (SSE_REG_P (operands[0])
4902 || (GET_CODE (operands[0]) == SUBREG
4903 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4904 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4907 [(set (match_operand:MODEF 0 "register_operand" "")
4908 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4909 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4910 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4911 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4912 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4914 && (SSE_REG_P (operands[0])
4915 || (GET_CODE (operands[0]) == SUBREG
4916 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4917 [(set (match_dup 2) (match_dup 1))
4918 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4920 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4921 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4923 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4924 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4925 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4926 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4929 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4930 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4931 [(set_attr "type" "fmov,sseicvt,sseicvt")
4932 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4933 (set_attr "mode" "<MODEF:MODE>")
4934 (set (attr "prefix_rex")
4936 (and (eq_attr "prefix" "maybe_vex")
4937 (match_test "<SWI48x:MODE>mode == DImode"))
4939 (const_string "*")))
4940 (set_attr "unit" "i387,*,*")
4941 (set_attr "athlon_decode" "*,double,direct")
4942 (set_attr "amdfam10_decode" "*,vector,double")
4943 (set_attr "bdver1_decode" "*,double,direct")
4944 (set_attr "fp_int_src" "true")])
4946 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4947 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4949 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4950 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4951 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4952 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4955 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4956 [(set_attr "type" "fmov,sseicvt")
4957 (set_attr "prefix" "orig,maybe_vex")
4958 (set_attr "mode" "<MODEF:MODE>")
4959 (set (attr "prefix_rex")
4961 (and (eq_attr "prefix" "maybe_vex")
4962 (match_test "<SWI48x:MODE>mode == DImode"))
4964 (const_string "*")))
4965 (set_attr "athlon_decode" "*,direct")
4966 (set_attr "amdfam10_decode" "*,double")
4967 (set_attr "bdver1_decode" "*,direct")
4968 (set_attr "fp_int_src" "true")])
4970 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4971 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4973 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4974 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4975 "TARGET_SSE2 && TARGET_SSE_MATH
4976 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4978 [(set_attr "type" "sseicvt")
4979 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4980 (set_attr "athlon_decode" "double,direct,double")
4981 (set_attr "amdfam10_decode" "vector,double,double")
4982 (set_attr "bdver1_decode" "double,direct,double")
4983 (set_attr "fp_int_src" "true")])
4985 (define_insn "*floatsi<mode>2_vector_sse"
4986 [(set (match_operand:MODEF 0 "register_operand" "=x")
4987 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4988 "TARGET_SSE2 && TARGET_SSE_MATH
4989 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4991 [(set_attr "type" "sseicvt")
4992 (set_attr "mode" "<MODE>")
4993 (set_attr "athlon_decode" "direct")
4994 (set_attr "amdfam10_decode" "double")
4995 (set_attr "bdver1_decode" "direct")
4996 (set_attr "fp_int_src" "true")])
4999 [(set (match_operand:MODEF 0 "register_operand" "")
5000 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5001 (clobber (match_operand:SI 2 "memory_operand" ""))]
5002 "TARGET_SSE2 && TARGET_SSE_MATH
5003 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5005 && (SSE_REG_P (operands[0])
5006 || (GET_CODE (operands[0]) == SUBREG
5007 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5010 rtx op1 = operands[1];
5012 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5014 if (GET_CODE (op1) == SUBREG)
5015 op1 = SUBREG_REG (op1);
5017 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5019 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5020 emit_insn (gen_sse2_loadld (operands[4],
5021 CONST0_RTX (V4SImode), operands[1]));
5023 /* We can ignore possible trapping value in the
5024 high part of SSE register for non-trapping math. */
5025 else if (SSE_REG_P (op1) && !flag_trapping_math)
5026 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5029 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5030 emit_move_insn (operands[2], operands[1]);
5031 emit_insn (gen_sse2_loadld (operands[4],
5032 CONST0_RTX (V4SImode), operands[2]));
5034 if (<ssevecmode>mode == V4SFmode)
5035 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5037 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5042 [(set (match_operand:MODEF 0 "register_operand" "")
5043 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5044 (clobber (match_operand:SI 2 "memory_operand" ""))]
5045 "TARGET_SSE2 && TARGET_SSE_MATH
5046 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5048 && (SSE_REG_P (operands[0])
5049 || (GET_CODE (operands[0]) == SUBREG
5050 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5053 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5055 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5057 emit_insn (gen_sse2_loadld (operands[4],
5058 CONST0_RTX (V4SImode), operands[1]));
5059 if (<ssevecmode>mode == V4SFmode)
5060 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5062 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5067 [(set (match_operand:MODEF 0 "register_operand" "")
5068 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5069 "TARGET_SSE2 && TARGET_SSE_MATH
5070 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5072 && (SSE_REG_P (operands[0])
5073 || (GET_CODE (operands[0]) == SUBREG
5074 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5077 rtx op1 = operands[1];
5079 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5081 if (GET_CODE (op1) == SUBREG)
5082 op1 = SUBREG_REG (op1);
5084 if (GENERAL_REG_P (op1))
5086 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5087 if (TARGET_INTER_UNIT_MOVES)
5088 emit_insn (gen_sse2_loadld (operands[4],
5089 CONST0_RTX (V4SImode), operands[1]));
5092 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5094 emit_insn (gen_sse2_loadld (operands[4],
5095 CONST0_RTX (V4SImode), operands[5]));
5096 ix86_free_from_memory (GET_MODE (operands[1]));
5099 /* We can ignore possible trapping value in the
5100 high part of SSE register for non-trapping math. */
5101 else if (SSE_REG_P (op1) && !flag_trapping_math)
5102 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5105 if (<ssevecmode>mode == V4SFmode)
5106 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5108 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5113 [(set (match_operand:MODEF 0 "register_operand" "")
5114 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5115 "TARGET_SSE2 && TARGET_SSE_MATH
5116 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5118 && (SSE_REG_P (operands[0])
5119 || (GET_CODE (operands[0]) == SUBREG
5120 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5123 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5125 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5127 emit_insn (gen_sse2_loadld (operands[4],
5128 CONST0_RTX (V4SImode), operands[1]));
5129 if (<ssevecmode>mode == V4SFmode)
5130 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5132 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5136 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5137 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5139 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5140 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5141 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5142 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5144 [(set_attr "type" "sseicvt")
5145 (set_attr "mode" "<MODEF:MODE>")
5146 (set_attr "athlon_decode" "double,direct")
5147 (set_attr "amdfam10_decode" "vector,double")
5148 (set_attr "bdver1_decode" "double,direct")
5149 (set_attr "fp_int_src" "true")])
5151 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5152 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5154 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5155 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5156 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5157 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5158 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5159 [(set_attr "type" "sseicvt")
5160 (set_attr "prefix" "maybe_vex")
5161 (set_attr "mode" "<MODEF:MODE>")
5162 (set (attr "prefix_rex")
5164 (and (eq_attr "prefix" "maybe_vex")
5165 (match_test "<SWI48x:MODE>mode == DImode"))
5167 (const_string "*")))
5168 (set_attr "athlon_decode" "double,direct")
5169 (set_attr "amdfam10_decode" "vector,double")
5170 (set_attr "bdver1_decode" "double,direct")
5171 (set_attr "fp_int_src" "true")])
5174 [(set (match_operand:MODEF 0 "register_operand" "")
5175 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5176 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5177 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5178 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5179 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5181 && (SSE_REG_P (operands[0])
5182 || (GET_CODE (operands[0]) == SUBREG
5183 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5184 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5186 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5187 [(set (match_operand:MODEF 0 "register_operand" "=x")
5189 (match_operand:SWI48x 1 "memory_operand" "m")))]
5190 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5191 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5192 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5193 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5194 [(set_attr "type" "sseicvt")
5195 (set_attr "prefix" "maybe_vex")
5196 (set_attr "mode" "<MODEF:MODE>")
5197 (set (attr "prefix_rex")
5199 (and (eq_attr "prefix" "maybe_vex")
5200 (match_test "<SWI48x:MODE>mode == DImode"))
5202 (const_string "*")))
5203 (set_attr "athlon_decode" "direct")
5204 (set_attr "amdfam10_decode" "double")
5205 (set_attr "bdver1_decode" "direct")
5206 (set_attr "fp_int_src" "true")])
5209 [(set (match_operand:MODEF 0 "register_operand" "")
5210 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5211 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5212 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5213 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5214 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5216 && (SSE_REG_P (operands[0])
5217 || (GET_CODE (operands[0]) == SUBREG
5218 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5219 [(set (match_dup 2) (match_dup 1))
5220 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5223 [(set (match_operand:MODEF 0 "register_operand" "")
5224 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5225 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5226 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5227 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5229 && (SSE_REG_P (operands[0])
5230 || (GET_CODE (operands[0]) == SUBREG
5231 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5232 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5234 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5235 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5237 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5238 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5240 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5244 [(set_attr "type" "fmov,multi")
5245 (set_attr "mode" "<X87MODEF:MODE>")
5246 (set_attr "unit" "*,i387")
5247 (set_attr "fp_int_src" "true")])
5249 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5250 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5252 (match_operand:SWI48x 1 "memory_operand" "m")))]
5254 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5256 [(set_attr "type" "fmov")
5257 (set_attr "mode" "<X87MODEF:MODE>")
5258 (set_attr "fp_int_src" "true")])
5261 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5262 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5263 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5265 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5266 && reload_completed"
5267 [(set (match_dup 2) (match_dup 1))
5268 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5271 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5272 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5273 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5275 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5276 && reload_completed"
5277 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5279 ;; Avoid store forwarding (partial memory) stall penalty
5280 ;; by passing DImode value through XMM registers. */
5282 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5283 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5285 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5286 (clobber (match_scratch:V4SI 3 "=X,x"))
5287 (clobber (match_scratch:V4SI 4 "=X,x"))
5288 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5289 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5290 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5291 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5293 [(set_attr "type" "multi")
5294 (set_attr "mode" "<X87MODEF:MODE>")
5295 (set_attr "unit" "i387")
5296 (set_attr "fp_int_src" "true")])
5299 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5300 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5301 (clobber (match_scratch:V4SI 3 ""))
5302 (clobber (match_scratch:V4SI 4 ""))
5303 (clobber (match_operand:DI 2 "memory_operand" ""))]
5304 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5305 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5306 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5307 && reload_completed"
5308 [(set (match_dup 2) (match_dup 3))
5309 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5311 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5312 Assemble the 64-bit DImode value in an xmm register. */
5313 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5314 gen_rtx_SUBREG (SImode, operands[1], 0)));
5315 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5316 gen_rtx_SUBREG (SImode, operands[1], 4)));
5317 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5320 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5324 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5325 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5326 (clobber (match_scratch:V4SI 3 ""))
5327 (clobber (match_scratch:V4SI 4 ""))
5328 (clobber (match_operand:DI 2 "memory_operand" ""))]
5329 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5330 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5331 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5332 && reload_completed"
5333 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5335 ;; Avoid store forwarding (partial memory) stall penalty by extending
5336 ;; SImode value to DImode through XMM register instead of pushing two
5337 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5338 ;; targets benefit from this optimization. Also note that fild
5339 ;; loads from memory only.
5341 (define_insn "*floatunssi<mode>2_1"
5342 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5343 (unsigned_float:X87MODEF
5344 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5345 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5346 (clobber (match_scratch:SI 3 "=X,x"))]
5348 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5351 [(set_attr "type" "multi")
5352 (set_attr "mode" "<MODE>")])
5355 [(set (match_operand:X87MODEF 0 "register_operand" "")
5356 (unsigned_float:X87MODEF
5357 (match_operand:SI 1 "register_operand" "")))
5358 (clobber (match_operand:DI 2 "memory_operand" ""))
5359 (clobber (match_scratch:SI 3 ""))]
5361 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5363 && reload_completed"
5364 [(set (match_dup 2) (match_dup 1))
5366 (float:X87MODEF (match_dup 2)))]
5367 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5370 [(set (match_operand:X87MODEF 0 "register_operand" "")
5371 (unsigned_float:X87MODEF
5372 (match_operand:SI 1 "memory_operand" "")))
5373 (clobber (match_operand:DI 2 "memory_operand" ""))
5374 (clobber (match_scratch:SI 3 ""))]
5376 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5378 && reload_completed"
5379 [(set (match_dup 2) (match_dup 3))
5381 (float:X87MODEF (match_dup 2)))]
5383 emit_move_insn (operands[3], operands[1]);
5384 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5387 (define_expand "floatunssi<mode>2"
5389 [(set (match_operand:X87MODEF 0 "register_operand" "")
5390 (unsigned_float:X87MODEF
5391 (match_operand:SI 1 "nonimmediate_operand" "")))
5392 (clobber (match_dup 2))
5393 (clobber (match_scratch:SI 3 ""))])]
5395 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5397 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5399 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5401 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5405 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5408 (define_expand "floatunsdisf2"
5409 [(use (match_operand:SF 0 "register_operand" ""))
5410 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5411 "TARGET_64BIT && TARGET_SSE_MATH"
5412 "x86_emit_floatuns (operands); DONE;")
5414 (define_expand "floatunsdidf2"
5415 [(use (match_operand:DF 0 "register_operand" ""))
5416 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5417 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5418 && TARGET_SSE2 && TARGET_SSE_MATH"
5421 x86_emit_floatuns (operands);
5423 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5427 ;; Load effective address instructions
5429 (define_insn_and_split "*lea<mode>"
5430 [(set (match_operand:SWI48 0 "register_operand" "=r")
5431 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5434 rtx addr = operands[1];
5436 if (SImode_address_operand (addr, VOIDmode))
5438 gcc_assert (TARGET_64BIT);
5439 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5442 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5444 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5447 ix86_split_lea_for_addr (operands, <MODE>mode);
5450 [(set_attr "type" "lea")
5453 (match_operand 1 "SImode_address_operand")
5455 (const_string "<MODE>")))])
5459 (define_expand "add<mode>3"
5460 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5461 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5462 (match_operand:SDWIM 2 "<general_operand>" "")))]
5464 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5466 (define_insn_and_split "*add<dwi>3_doubleword"
5467 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5469 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5470 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5471 (clobber (reg:CC FLAGS_REG))]
5472 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5475 [(parallel [(set (reg:CC FLAGS_REG)
5476 (unspec:CC [(match_dup 1) (match_dup 2)]
5479 (plus:DWIH (match_dup 1) (match_dup 2)))])
5480 (parallel [(set (match_dup 3)
5484 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5486 (clobber (reg:CC FLAGS_REG))])]
5487 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5489 (define_insn "*add<mode>3_cc"
5490 [(set (reg:CC FLAGS_REG)
5492 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5493 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5495 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5496 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5497 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5498 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5499 [(set_attr "type" "alu")
5500 (set_attr "mode" "<MODE>")])
5502 (define_insn "addqi3_cc"
5503 [(set (reg:CC FLAGS_REG)
5505 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5506 (match_operand:QI 2 "general_operand" "qn,qm")]
5508 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5509 (plus:QI (match_dup 1) (match_dup 2)))]
5510 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5511 "add{b}\t{%2, %0|%0, %2}"
5512 [(set_attr "type" "alu")
5513 (set_attr "mode" "QI")])
5515 (define_insn "*add<mode>_1"
5516 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5518 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5519 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5520 (clobber (reg:CC FLAGS_REG))]
5521 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5523 switch (get_attr_type (insn))
5529 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5530 if (operands[2] == const1_rtx)
5531 return "inc{<imodesuffix>}\t%0";
5534 gcc_assert (operands[2] == constm1_rtx);
5535 return "dec{<imodesuffix>}\t%0";
5539 /* For most processors, ADD is faster than LEA. This alternative
5540 was added to use ADD as much as possible. */
5541 if (which_alternative == 2)
5544 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5547 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5548 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5549 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5551 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5555 (cond [(eq_attr "alternative" "3")
5556 (const_string "lea")
5557 (match_operand:SWI48 2 "incdec_operand" "")
5558 (const_string "incdec")
5560 (const_string "alu")))
5561 (set (attr "length_immediate")
5563 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5565 (const_string "*")))
5566 (set_attr "mode" "<MODE>")])
5568 ;; It may seem that nonimmediate operand is proper one for operand 1.
5569 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5570 ;; we take care in ix86_binary_operator_ok to not allow two memory
5571 ;; operands so proper swapping will be done in reload. This allow
5572 ;; patterns constructed from addsi_1 to match.
5574 (define_insn "addsi_1_zext"
5575 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5577 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5578 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5579 (clobber (reg:CC FLAGS_REG))]
5580 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5582 switch (get_attr_type (insn))
5588 if (operands[2] == const1_rtx)
5589 return "inc{l}\t%k0";
5592 gcc_assert (operands[2] == constm1_rtx);
5593 return "dec{l}\t%k0";
5597 /* For most processors, ADD is faster than LEA. This alternative
5598 was added to use ADD as much as possible. */
5599 if (which_alternative == 1)
5602 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5605 if (x86_maybe_negate_const_int (&operands[2], SImode))
5606 return "sub{l}\t{%2, %k0|%k0, %2}";
5608 return "add{l}\t{%2, %k0|%k0, %2}";
5612 (cond [(eq_attr "alternative" "2")
5613 (const_string "lea")
5614 (match_operand:SI 2 "incdec_operand" "")
5615 (const_string "incdec")
5617 (const_string "alu")))
5618 (set (attr "length_immediate")
5620 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5622 (const_string "*")))
5623 (set_attr "mode" "SI")])
5625 (define_insn "*addhi_1"
5626 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5627 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5628 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5629 (clobber (reg:CC FLAGS_REG))]
5630 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5632 switch (get_attr_type (insn))
5638 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5639 if (operands[2] == const1_rtx)
5640 return "inc{w}\t%0";
5643 gcc_assert (operands[2] == constm1_rtx);
5644 return "dec{w}\t%0";
5648 /* For most processors, ADD is faster than LEA. This alternative
5649 was added to use ADD as much as possible. */
5650 if (which_alternative == 2)
5653 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5656 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5657 if (x86_maybe_negate_const_int (&operands[2], HImode))
5658 return "sub{w}\t{%2, %0|%0, %2}";
5660 return "add{w}\t{%2, %0|%0, %2}";
5664 (cond [(eq_attr "alternative" "3")
5665 (const_string "lea")
5666 (match_operand:HI 2 "incdec_operand" "")
5667 (const_string "incdec")
5669 (const_string "alu")))
5670 (set (attr "length_immediate")
5672 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5674 (const_string "*")))
5675 (set_attr "mode" "HI,HI,HI,SI")])
5677 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5678 (define_insn "*addqi_1"
5679 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5680 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5681 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5682 (clobber (reg:CC FLAGS_REG))]
5683 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5685 bool widen = (which_alternative == 3 || which_alternative == 4);
5687 switch (get_attr_type (insn))
5693 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5694 if (operands[2] == const1_rtx)
5695 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5698 gcc_assert (operands[2] == constm1_rtx);
5699 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5703 /* For most processors, ADD is faster than LEA. These alternatives
5704 were added to use ADD as much as possible. */
5705 if (which_alternative == 2 || which_alternative == 4)
5708 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5711 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5712 if (x86_maybe_negate_const_int (&operands[2], QImode))
5715 return "sub{l}\t{%2, %k0|%k0, %2}";
5717 return "sub{b}\t{%2, %0|%0, %2}";
5720 return "add{l}\t{%k2, %k0|%k0, %k2}";
5722 return "add{b}\t{%2, %0|%0, %2}";
5726 (cond [(eq_attr "alternative" "5")
5727 (const_string "lea")
5728 (match_operand:QI 2 "incdec_operand" "")
5729 (const_string "incdec")
5731 (const_string "alu")))
5732 (set (attr "length_immediate")
5734 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5736 (const_string "*")))
5737 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5739 (define_insn "*addqi_1_slp"
5740 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5741 (plus:QI (match_dup 0)
5742 (match_operand:QI 1 "general_operand" "qn,qm")))
5743 (clobber (reg:CC FLAGS_REG))]
5744 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5745 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5747 switch (get_attr_type (insn))
5750 if (operands[1] == const1_rtx)
5751 return "inc{b}\t%0";
5754 gcc_assert (operands[1] == constm1_rtx);
5755 return "dec{b}\t%0";
5759 if (x86_maybe_negate_const_int (&operands[1], QImode))
5760 return "sub{b}\t{%1, %0|%0, %1}";
5762 return "add{b}\t{%1, %0|%0, %1}";
5766 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5767 (const_string "incdec")
5768 (const_string "alu1")))
5769 (set (attr "memory")
5770 (if_then_else (match_operand 1 "memory_operand" "")
5771 (const_string "load")
5772 (const_string "none")))
5773 (set_attr "mode" "QI")])
5775 ;; Split non destructive adds if we cannot use lea.
5777 [(set (match_operand:SWI48 0 "register_operand" "")
5778 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5779 (match_operand:SWI48 2 "nonmemory_operand" "")))
5780 (clobber (reg:CC FLAGS_REG))]
5781 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5782 [(set (match_dup 0) (match_dup 1))
5783 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5784 (clobber (reg:CC FLAGS_REG))])])
5786 ;; Convert add to the lea pattern to avoid flags dependency.
5788 [(set (match_operand:SWI 0 "register_operand" "")
5789 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5790 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5791 (clobber (reg:CC FLAGS_REG))]
5792 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5795 enum machine_mode mode = <MODE>mode;
5798 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5801 operands[0] = gen_lowpart (mode, operands[0]);
5802 operands[1] = gen_lowpart (mode, operands[1]);
5803 operands[2] = gen_lowpart (mode, operands[2]);
5806 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5808 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5812 ;; Convert add to the lea pattern to avoid flags dependency.
5814 [(set (match_operand:DI 0 "register_operand" "")
5816 (plus:SI (match_operand:SI 1 "register_operand" "")
5817 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5818 (clobber (reg:CC FLAGS_REG))]
5819 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5821 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5823 (define_insn "*add<mode>_2"
5824 [(set (reg FLAGS_REG)
5827 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5828 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5830 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5831 (plus:SWI (match_dup 1) (match_dup 2)))]
5832 "ix86_match_ccmode (insn, CCGOCmode)
5833 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5835 switch (get_attr_type (insn))
5838 if (operands[2] == const1_rtx)
5839 return "inc{<imodesuffix>}\t%0";
5842 gcc_assert (operands[2] == constm1_rtx);
5843 return "dec{<imodesuffix>}\t%0";
5847 if (which_alternative == 2)
5850 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5853 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5854 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5855 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5857 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5861 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5862 (const_string "incdec")
5863 (const_string "alu")))
5864 (set (attr "length_immediate")
5866 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5868 (const_string "*")))
5869 (set_attr "mode" "<MODE>")])
5871 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5872 (define_insn "*addsi_2_zext"
5873 [(set (reg FLAGS_REG)
5875 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5876 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5878 (set (match_operand:DI 0 "register_operand" "=r,r")
5879 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5880 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5881 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5883 switch (get_attr_type (insn))
5886 if (operands[2] == const1_rtx)
5887 return "inc{l}\t%k0";
5890 gcc_assert (operands[2] == constm1_rtx);
5891 return "dec{l}\t%k0";
5895 if (which_alternative == 1)
5898 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5901 if (x86_maybe_negate_const_int (&operands[2], SImode))
5902 return "sub{l}\t{%2, %k0|%k0, %2}";
5904 return "add{l}\t{%2, %k0|%k0, %2}";
5908 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5909 (const_string "incdec")
5910 (const_string "alu")))
5911 (set (attr "length_immediate")
5913 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5915 (const_string "*")))
5916 (set_attr "mode" "SI")])
5918 (define_insn "*add<mode>_3"
5919 [(set (reg FLAGS_REG)
5921 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5922 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5923 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5924 "ix86_match_ccmode (insn, CCZmode)
5925 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5927 switch (get_attr_type (insn))
5930 if (operands[2] == const1_rtx)
5931 return "inc{<imodesuffix>}\t%0";
5934 gcc_assert (operands[2] == constm1_rtx);
5935 return "dec{<imodesuffix>}\t%0";
5939 if (which_alternative == 1)
5942 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5945 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5946 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5947 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5949 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5953 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5954 (const_string "incdec")
5955 (const_string "alu")))
5956 (set (attr "length_immediate")
5958 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5960 (const_string "*")))
5961 (set_attr "mode" "<MODE>")])
5963 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5964 (define_insn "*addsi_3_zext"
5965 [(set (reg FLAGS_REG)
5967 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5968 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5969 (set (match_operand:DI 0 "register_operand" "=r,r")
5970 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5971 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5972 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5974 switch (get_attr_type (insn))
5977 if (operands[2] == const1_rtx)
5978 return "inc{l}\t%k0";
5981 gcc_assert (operands[2] == constm1_rtx);
5982 return "dec{l}\t%k0";
5986 if (which_alternative == 1)
5989 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5992 if (x86_maybe_negate_const_int (&operands[2], SImode))
5993 return "sub{l}\t{%2, %k0|%k0, %2}";
5995 return "add{l}\t{%2, %k0|%k0, %2}";
5999 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6000 (const_string "incdec")
6001 (const_string "alu")))
6002 (set (attr "length_immediate")
6004 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6006 (const_string "*")))
6007 (set_attr "mode" "SI")])
6009 ; For comparisons against 1, -1 and 128, we may generate better code
6010 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6011 ; is matched then. We can't accept general immediate, because for
6012 ; case of overflows, the result is messed up.
6013 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6014 ; only for comparisons not depending on it.
6016 (define_insn "*adddi_4"
6017 [(set (reg FLAGS_REG)
6019 (match_operand:DI 1 "nonimmediate_operand" "0")
6020 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6021 (clobber (match_scratch:DI 0 "=rm"))]
6023 && ix86_match_ccmode (insn, CCGCmode)"
6025 switch (get_attr_type (insn))
6028 if (operands[2] == constm1_rtx)
6029 return "inc{q}\t%0";
6032 gcc_assert (operands[2] == const1_rtx);
6033 return "dec{q}\t%0";
6037 if (x86_maybe_negate_const_int (&operands[2], DImode))
6038 return "add{q}\t{%2, %0|%0, %2}";
6040 return "sub{q}\t{%2, %0|%0, %2}";
6044 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6045 (const_string "incdec")
6046 (const_string "alu")))
6047 (set (attr "length_immediate")
6049 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6051 (const_string "*")))
6052 (set_attr "mode" "DI")])
6054 ; For comparisons against 1, -1 and 128, we may generate better code
6055 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6056 ; is matched then. We can't accept general immediate, because for
6057 ; case of overflows, the result is messed up.
6058 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6059 ; only for comparisons not depending on it.
6061 (define_insn "*add<mode>_4"
6062 [(set (reg FLAGS_REG)
6064 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6065 (match_operand:SWI124 2 "const_int_operand" "n")))
6066 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6067 "ix86_match_ccmode (insn, CCGCmode)"
6069 switch (get_attr_type (insn))
6072 if (operands[2] == constm1_rtx)
6073 return "inc{<imodesuffix>}\t%0";
6076 gcc_assert (operands[2] == const1_rtx);
6077 return "dec{<imodesuffix>}\t%0";
6081 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6082 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6084 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6088 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6089 (const_string "incdec")
6090 (const_string "alu")))
6091 (set (attr "length_immediate")
6093 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6095 (const_string "*")))
6096 (set_attr "mode" "<MODE>")])
6098 (define_insn "*add<mode>_5"
6099 [(set (reg FLAGS_REG)
6102 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6103 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6105 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6106 "ix86_match_ccmode (insn, CCGOCmode)
6107 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6109 switch (get_attr_type (insn))
6112 if (operands[2] == const1_rtx)
6113 return "inc{<imodesuffix>}\t%0";
6116 gcc_assert (operands[2] == constm1_rtx);
6117 return "dec{<imodesuffix>}\t%0";
6121 if (which_alternative == 1)
6124 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6127 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6128 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6129 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6131 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6135 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6136 (const_string "incdec")
6137 (const_string "alu")))
6138 (set (attr "length_immediate")
6140 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6142 (const_string "*")))
6143 (set_attr "mode" "<MODE>")])
6145 (define_insn "*addqi_ext_1_rex64"
6146 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6151 (match_operand 1 "ext_register_operand" "0")
6154 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6155 (clobber (reg:CC FLAGS_REG))]
6158 switch (get_attr_type (insn))
6161 if (operands[2] == const1_rtx)
6162 return "inc{b}\t%h0";
6165 gcc_assert (operands[2] == constm1_rtx);
6166 return "dec{b}\t%h0";
6170 return "add{b}\t{%2, %h0|%h0, %2}";
6174 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6175 (const_string "incdec")
6176 (const_string "alu")))
6177 (set_attr "modrm" "1")
6178 (set_attr "mode" "QI")])
6180 (define_insn "addqi_ext_1"
6181 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6186 (match_operand 1 "ext_register_operand" "0")
6189 (match_operand:QI 2 "general_operand" "Qmn")))
6190 (clobber (reg:CC FLAGS_REG))]
6193 switch (get_attr_type (insn))
6196 if (operands[2] == const1_rtx)
6197 return "inc{b}\t%h0";
6200 gcc_assert (operands[2] == constm1_rtx);
6201 return "dec{b}\t%h0";
6205 return "add{b}\t{%2, %h0|%h0, %2}";
6209 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6210 (const_string "incdec")
6211 (const_string "alu")))
6212 (set_attr "modrm" "1")
6213 (set_attr "mode" "QI")])
6215 (define_insn "*addqi_ext_2"
6216 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6221 (match_operand 1 "ext_register_operand" "%0")
6225 (match_operand 2 "ext_register_operand" "Q")
6228 (clobber (reg:CC FLAGS_REG))]
6230 "add{b}\t{%h2, %h0|%h0, %h2}"
6231 [(set_attr "type" "alu")
6232 (set_attr "mode" "QI")])
6234 ;; The lea patterns for modes less than 32 bits need to be matched by
6235 ;; several insns converted to real lea by splitters.
6237 (define_insn_and_split "*lea_general_1"
6238 [(set (match_operand 0 "register_operand" "=r")
6239 (plus (plus (match_operand 1 "index_register_operand" "l")
6240 (match_operand 2 "register_operand" "r"))
6241 (match_operand 3 "immediate_operand" "i")))]
6242 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6243 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6244 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6245 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6246 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6247 || GET_MODE (operands[3]) == VOIDmode)"
6249 "&& reload_completed"
6252 enum machine_mode mode = SImode;
6255 operands[0] = gen_lowpart (mode, operands[0]);
6256 operands[1] = gen_lowpart (mode, operands[1]);
6257 operands[2] = gen_lowpart (mode, operands[2]);
6258 operands[3] = gen_lowpart (mode, operands[3]);
6260 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6263 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6266 [(set_attr "type" "lea")
6267 (set_attr "mode" "SI")])
6269 (define_insn_and_split "*lea_general_2"
6270 [(set (match_operand 0 "register_operand" "=r")
6271 (plus (mult (match_operand 1 "index_register_operand" "l")
6272 (match_operand 2 "const248_operand" "n"))
6273 (match_operand 3 "nonmemory_operand" "ri")))]
6274 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6275 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6276 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6277 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6278 || GET_MODE (operands[3]) == VOIDmode)"
6280 "&& reload_completed"
6283 enum machine_mode mode = SImode;
6286 operands[0] = gen_lowpart (mode, operands[0]);
6287 operands[1] = gen_lowpart (mode, operands[1]);
6288 operands[3] = gen_lowpart (mode, operands[3]);
6290 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6293 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6296 [(set_attr "type" "lea")
6297 (set_attr "mode" "SI")])
6299 (define_insn_and_split "*lea_general_3"
6300 [(set (match_operand 0 "register_operand" "=r")
6301 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6302 (match_operand 2 "const248_operand" "n"))
6303 (match_operand 3 "register_operand" "r"))
6304 (match_operand 4 "immediate_operand" "i")))]
6305 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6306 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6307 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6308 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6310 "&& reload_completed"
6313 enum machine_mode mode = SImode;
6316 operands[0] = gen_lowpart (mode, operands[0]);
6317 operands[1] = gen_lowpart (mode, operands[1]);
6318 operands[3] = gen_lowpart (mode, operands[3]);
6319 operands[4] = gen_lowpart (mode, operands[4]);
6321 pat = gen_rtx_PLUS (mode,
6323 gen_rtx_MULT (mode, operands[1],
6328 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6331 [(set_attr "type" "lea")
6332 (set_attr "mode" "SI")])
6334 (define_insn_and_split "*lea_general_4"
6335 [(set (match_operand 0 "register_operand" "=r")
6337 (match_operand 1 "index_register_operand" "l")
6338 (match_operand 2 "const_int_operand" "n"))
6339 (match_operand 3 "const_int_operand" "n")))]
6340 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6341 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6342 || GET_MODE (operands[0]) == SImode
6343 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6344 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6345 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6346 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6347 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6349 "&& reload_completed"
6352 enum machine_mode mode = GET_MODE (operands[0]);
6355 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6358 operands[0] = gen_lowpart (mode, operands[0]);
6359 operands[1] = gen_lowpart (mode, operands[1]);
6362 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6364 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6365 INTVAL (operands[3]));
6367 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6370 [(set_attr "type" "lea")
6372 (if_then_else (match_operand:DI 0 "" "")
6374 (const_string "SI")))])
6376 ;; Subtract instructions
6378 (define_expand "sub<mode>3"
6379 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6380 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6381 (match_operand:SDWIM 2 "<general_operand>" "")))]
6383 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6385 (define_insn_and_split "*sub<dwi>3_doubleword"
6386 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6388 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6389 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6390 (clobber (reg:CC FLAGS_REG))]
6391 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6394 [(parallel [(set (reg:CC FLAGS_REG)
6395 (compare:CC (match_dup 1) (match_dup 2)))
6397 (minus:DWIH (match_dup 1) (match_dup 2)))])
6398 (parallel [(set (match_dup 3)
6402 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6404 (clobber (reg:CC FLAGS_REG))])]
6405 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6407 (define_insn "*sub<mode>_1"
6408 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6410 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6411 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6412 (clobber (reg:CC FLAGS_REG))]
6413 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6414 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6415 [(set_attr "type" "alu")
6416 (set_attr "mode" "<MODE>")])
6418 (define_insn "*subsi_1_zext"
6419 [(set (match_operand:DI 0 "register_operand" "=r")
6421 (minus:SI (match_operand:SI 1 "register_operand" "0")
6422 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6423 (clobber (reg:CC FLAGS_REG))]
6424 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6425 "sub{l}\t{%2, %k0|%k0, %2}"
6426 [(set_attr "type" "alu")
6427 (set_attr "mode" "SI")])
6429 (define_insn "*subqi_1_slp"
6430 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6431 (minus:QI (match_dup 0)
6432 (match_operand:QI 1 "general_operand" "qn,qm")))
6433 (clobber (reg:CC FLAGS_REG))]
6434 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6435 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6436 "sub{b}\t{%1, %0|%0, %1}"
6437 [(set_attr "type" "alu1")
6438 (set_attr "mode" "QI")])
6440 (define_insn "*sub<mode>_2"
6441 [(set (reg FLAGS_REG)
6444 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6445 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6447 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6448 (minus:SWI (match_dup 1) (match_dup 2)))]
6449 "ix86_match_ccmode (insn, CCGOCmode)
6450 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6451 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6452 [(set_attr "type" "alu")
6453 (set_attr "mode" "<MODE>")])
6455 (define_insn "*subsi_2_zext"
6456 [(set (reg FLAGS_REG)
6458 (minus:SI (match_operand:SI 1 "register_operand" "0")
6459 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6461 (set (match_operand:DI 0 "register_operand" "=r")
6463 (minus:SI (match_dup 1)
6465 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6466 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6467 "sub{l}\t{%2, %k0|%k0, %2}"
6468 [(set_attr "type" "alu")
6469 (set_attr "mode" "SI")])
6471 (define_insn "*sub<mode>_3"
6472 [(set (reg FLAGS_REG)
6473 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6474 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6475 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6476 (minus:SWI (match_dup 1) (match_dup 2)))]
6477 "ix86_match_ccmode (insn, CCmode)
6478 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6479 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6480 [(set_attr "type" "alu")
6481 (set_attr "mode" "<MODE>")])
6483 (define_insn "*subsi_3_zext"
6484 [(set (reg FLAGS_REG)
6485 (compare (match_operand:SI 1 "register_operand" "0")
6486 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6487 (set (match_operand:DI 0 "register_operand" "=r")
6489 (minus:SI (match_dup 1)
6491 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6492 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6493 "sub{l}\t{%2, %1|%1, %2}"
6494 [(set_attr "type" "alu")
6495 (set_attr "mode" "SI")])
6497 ;; Add with carry and subtract with borrow
6499 (define_expand "<plusminus_insn><mode>3_carry"
6501 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6503 (match_operand:SWI 1 "nonimmediate_operand" "")
6504 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6505 [(match_operand 3 "flags_reg_operand" "")
6507 (match_operand:SWI 2 "<general_operand>" ""))))
6508 (clobber (reg:CC FLAGS_REG))])]
6509 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6511 (define_insn "*<plusminus_insn><mode>3_carry"
6512 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6514 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6516 (match_operator 3 "ix86_carry_flag_operator"
6517 [(reg FLAGS_REG) (const_int 0)])
6518 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6519 (clobber (reg:CC FLAGS_REG))]
6520 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6521 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6522 [(set_attr "type" "alu")
6523 (set_attr "use_carry" "1")
6524 (set_attr "pent_pair" "pu")
6525 (set_attr "mode" "<MODE>")])
6527 (define_insn "*addsi3_carry_zext"
6528 [(set (match_operand:DI 0 "register_operand" "=r")
6530 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6531 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6532 [(reg FLAGS_REG) (const_int 0)])
6533 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6534 (clobber (reg:CC FLAGS_REG))]
6535 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6536 "adc{l}\t{%2, %k0|%k0, %2}"
6537 [(set_attr "type" "alu")
6538 (set_attr "use_carry" "1")
6539 (set_attr "pent_pair" "pu")
6540 (set_attr "mode" "SI")])
6542 (define_insn "*subsi3_carry_zext"
6543 [(set (match_operand:DI 0 "register_operand" "=r")
6545 (minus:SI (match_operand:SI 1 "register_operand" "0")
6546 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6547 [(reg FLAGS_REG) (const_int 0)])
6548 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6549 (clobber (reg:CC FLAGS_REG))]
6550 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6551 "sbb{l}\t{%2, %k0|%k0, %2}"
6552 [(set_attr "type" "alu")
6553 (set_attr "pent_pair" "pu")
6554 (set_attr "mode" "SI")])
6556 ;; Overflow setting add and subtract instructions
6558 (define_insn "*add<mode>3_cconly_overflow"
6559 [(set (reg:CCC FLAGS_REG)
6562 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6563 (match_operand:SWI 2 "<general_operand>" "<g>"))
6565 (clobber (match_scratch:SWI 0 "=<r>"))]
6566 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6567 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6568 [(set_attr "type" "alu")
6569 (set_attr "mode" "<MODE>")])
6571 (define_insn "*sub<mode>3_cconly_overflow"
6572 [(set (reg:CCC FLAGS_REG)
6575 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6576 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6579 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6580 [(set_attr "type" "icmp")
6581 (set_attr "mode" "<MODE>")])
6583 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6584 [(set (reg:CCC FLAGS_REG)
6587 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6588 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6590 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6591 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6592 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6593 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6594 [(set_attr "type" "alu")
6595 (set_attr "mode" "<MODE>")])
6597 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6598 [(set (reg:CCC FLAGS_REG)
6601 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6602 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6604 (set (match_operand:DI 0 "register_operand" "=r")
6605 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6606 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6607 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6608 [(set_attr "type" "alu")
6609 (set_attr "mode" "SI")])
6611 ;; The patterns that match these are at the end of this file.
6613 (define_expand "<plusminus_insn>xf3"
6614 [(set (match_operand:XF 0 "register_operand" "")
6616 (match_operand:XF 1 "register_operand" "")
6617 (match_operand:XF 2 "register_operand" "")))]
6620 (define_expand "<plusminus_insn><mode>3"
6621 [(set (match_operand:MODEF 0 "register_operand" "")
6623 (match_operand:MODEF 1 "register_operand" "")
6624 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6625 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6626 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6628 ;; Multiply instructions
6630 (define_expand "mul<mode>3"
6631 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6633 (match_operand:SWIM248 1 "register_operand" "")
6634 (match_operand:SWIM248 2 "<general_operand>" "")))
6635 (clobber (reg:CC FLAGS_REG))])])
6637 (define_expand "mulqi3"
6638 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6640 (match_operand:QI 1 "register_operand" "")
6641 (match_operand:QI 2 "nonimmediate_operand" "")))
6642 (clobber (reg:CC FLAGS_REG))])]
6643 "TARGET_QIMODE_MATH")
6646 ;; IMUL reg32/64, reg32/64, imm8 Direct
6647 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6648 ;; IMUL reg32/64, reg32/64, imm32 Direct
6649 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6650 ;; IMUL reg32/64, reg32/64 Direct
6651 ;; IMUL reg32/64, mem32/64 Direct
6653 ;; On BDVER1, all above IMULs use DirectPath
6655 (define_insn "*mul<mode>3_1"
6656 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6658 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6659 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6660 (clobber (reg:CC FLAGS_REG))]
6661 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6663 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6664 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6665 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6666 [(set_attr "type" "imul")
6667 (set_attr "prefix_0f" "0,0,1")
6668 (set (attr "athlon_decode")
6669 (cond [(eq_attr "cpu" "athlon")
6670 (const_string "vector")
6671 (eq_attr "alternative" "1")
6672 (const_string "vector")
6673 (and (eq_attr "alternative" "2")
6674 (match_operand 1 "memory_operand" ""))
6675 (const_string "vector")]
6676 (const_string "direct")))
6677 (set (attr "amdfam10_decode")
6678 (cond [(and (eq_attr "alternative" "0,1")
6679 (match_operand 1 "memory_operand" ""))
6680 (const_string "vector")]
6681 (const_string "direct")))
6682 (set_attr "bdver1_decode" "direct")
6683 (set_attr "mode" "<MODE>")])
6685 (define_insn "*mulsi3_1_zext"
6686 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6688 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6689 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6690 (clobber (reg:CC FLAGS_REG))]
6692 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6694 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6695 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6696 imul{l}\t{%2, %k0|%k0, %2}"
6697 [(set_attr "type" "imul")
6698 (set_attr "prefix_0f" "0,0,1")
6699 (set (attr "athlon_decode")
6700 (cond [(eq_attr "cpu" "athlon")
6701 (const_string "vector")
6702 (eq_attr "alternative" "1")
6703 (const_string "vector")
6704 (and (eq_attr "alternative" "2")
6705 (match_operand 1 "memory_operand" ""))
6706 (const_string "vector")]
6707 (const_string "direct")))
6708 (set (attr "amdfam10_decode")
6709 (cond [(and (eq_attr "alternative" "0,1")
6710 (match_operand 1 "memory_operand" ""))
6711 (const_string "vector")]
6712 (const_string "direct")))
6713 (set_attr "bdver1_decode" "direct")
6714 (set_attr "mode" "SI")])
6717 ;; IMUL reg16, reg16, imm8 VectorPath
6718 ;; IMUL reg16, mem16, imm8 VectorPath
6719 ;; IMUL reg16, reg16, imm16 VectorPath
6720 ;; IMUL reg16, mem16, imm16 VectorPath
6721 ;; IMUL reg16, reg16 Direct
6722 ;; IMUL reg16, mem16 Direct
6724 ;; On BDVER1, all HI MULs use DoublePath
6726 (define_insn "*mulhi3_1"
6727 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6728 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6729 (match_operand:HI 2 "general_operand" "K,n,mr")))
6730 (clobber (reg:CC FLAGS_REG))]
6732 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6734 imul{w}\t{%2, %1, %0|%0, %1, %2}
6735 imul{w}\t{%2, %1, %0|%0, %1, %2}
6736 imul{w}\t{%2, %0|%0, %2}"
6737 [(set_attr "type" "imul")
6738 (set_attr "prefix_0f" "0,0,1")
6739 (set (attr "athlon_decode")
6740 (cond [(eq_attr "cpu" "athlon")
6741 (const_string "vector")
6742 (eq_attr "alternative" "1,2")
6743 (const_string "vector")]
6744 (const_string "direct")))
6745 (set (attr "amdfam10_decode")
6746 (cond [(eq_attr "alternative" "0,1")
6747 (const_string "vector")]
6748 (const_string "direct")))
6749 (set_attr "bdver1_decode" "double")
6750 (set_attr "mode" "HI")])
6752 ;;On AMDFAM10 and BDVER1
6756 (define_insn "*mulqi3_1"
6757 [(set (match_operand:QI 0 "register_operand" "=a")
6758 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6759 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6760 (clobber (reg:CC FLAGS_REG))]
6762 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6764 [(set_attr "type" "imul")
6765 (set_attr "length_immediate" "0")
6766 (set (attr "athlon_decode")
6767 (if_then_else (eq_attr "cpu" "athlon")
6768 (const_string "vector")
6769 (const_string "direct")))
6770 (set_attr "amdfam10_decode" "direct")
6771 (set_attr "bdver1_decode" "direct")
6772 (set_attr "mode" "QI")])
6774 (define_expand "<u>mul<mode><dwi>3"
6775 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6778 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6780 (match_operand:DWIH 2 "register_operand" ""))))
6781 (clobber (reg:CC FLAGS_REG))])])
6783 (define_expand "<u>mulqihi3"
6784 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6787 (match_operand:QI 1 "nonimmediate_operand" ""))
6789 (match_operand:QI 2 "register_operand" ""))))
6790 (clobber (reg:CC FLAGS_REG))])]
6791 "TARGET_QIMODE_MATH")
6793 (define_insn "*bmi2_umulditi3_1"
6794 [(set (match_operand:DI 0 "register_operand" "=r")
6796 (match_operand:DI 2 "nonimmediate_operand" "%d")
6797 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6798 (set (match_operand:DI 1 "register_operand" "=r")
6801 (mult:TI (zero_extend:TI (match_dup 2))
6802 (zero_extend:TI (match_dup 3)))
6804 "TARGET_64BIT && TARGET_BMI2
6805 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6806 "mulx\t{%3, %0, %1|%1, %0, %3}"
6807 [(set_attr "type" "imulx")
6808 (set_attr "prefix" "vex")
6809 (set_attr "mode" "DI")])
6811 (define_insn "*bmi2_umulsidi3_1"
6812 [(set (match_operand:SI 0 "register_operand" "=r")
6814 (match_operand:SI 2 "nonimmediate_operand" "%d")
6815 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6816 (set (match_operand:SI 1 "register_operand" "=r")
6819 (mult:DI (zero_extend:DI (match_dup 2))
6820 (zero_extend:DI (match_dup 3)))
6822 "!TARGET_64BIT && TARGET_BMI2
6823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6824 "mulx\t{%3, %0, %1|%1, %0, %3}"
6825 [(set_attr "type" "imulx")
6826 (set_attr "prefix" "vex")
6827 (set_attr "mode" "SI")])
6829 (define_insn "*umul<mode><dwi>3_1"
6830 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6833 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6835 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6836 (clobber (reg:CC FLAGS_REG))]
6837 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6839 mul{<imodesuffix>}\t%2
6841 [(set_attr "isa" "*,bmi2")
6842 (set_attr "type" "imul,imulx")
6843 (set_attr "length_immediate" "0,*")
6844 (set (attr "athlon_decode")
6845 (cond [(eq_attr "alternative" "0")
6846 (if_then_else (eq_attr "cpu" "athlon")
6847 (const_string "vector")
6848 (const_string "double"))]
6849 (const_string "*")))
6850 (set_attr "amdfam10_decode" "double,*")
6851 (set_attr "bdver1_decode" "direct,*")
6852 (set_attr "prefix" "orig,vex")
6853 (set_attr "mode" "<MODE>")])
6855 ;; Convert mul to the mulx pattern to avoid flags dependency.
6857 [(set (match_operand:<DWI> 0 "register_operand" "")
6860 (match_operand:DWIH 1 "register_operand" ""))
6862 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6863 (clobber (reg:CC FLAGS_REG))]
6864 "TARGET_BMI2 && reload_completed
6865 && true_regnum (operands[1]) == DX_REG"
6866 [(parallel [(set (match_dup 3)
6867 (mult:DWIH (match_dup 1) (match_dup 2)))
6871 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6872 (zero_extend:<DWI> (match_dup 2)))
6875 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6877 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6880 (define_insn "*mul<mode><dwi>3_1"
6881 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6884 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6886 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6887 (clobber (reg:CC FLAGS_REG))]
6888 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6889 "imul{<imodesuffix>}\t%2"
6890 [(set_attr "type" "imul")
6891 (set_attr "length_immediate" "0")
6892 (set (attr "athlon_decode")
6893 (if_then_else (eq_attr "cpu" "athlon")
6894 (const_string "vector")
6895 (const_string "double")))
6896 (set_attr "amdfam10_decode" "double")
6897 (set_attr "bdver1_decode" "direct")
6898 (set_attr "mode" "<MODE>")])
6900 (define_insn "*<u>mulqihi3_1"
6901 [(set (match_operand:HI 0 "register_operand" "=a")
6904 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6906 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6907 (clobber (reg:CC FLAGS_REG))]
6909 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6910 "<sgnprefix>mul{b}\t%2"
6911 [(set_attr "type" "imul")
6912 (set_attr "length_immediate" "0")
6913 (set (attr "athlon_decode")
6914 (if_then_else (eq_attr "cpu" "athlon")
6915 (const_string "vector")
6916 (const_string "direct")))
6917 (set_attr "amdfam10_decode" "direct")
6918 (set_attr "bdver1_decode" "direct")
6919 (set_attr "mode" "QI")])
6921 (define_expand "<s>mul<mode>3_highpart"
6922 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6927 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6929 (match_operand:SWI48 2 "register_operand" "")))
6931 (clobber (match_scratch:SWI48 3 ""))
6932 (clobber (reg:CC FLAGS_REG))])]
6934 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6936 (define_insn "*<s>muldi3_highpart_1"
6937 [(set (match_operand:DI 0 "register_operand" "=d")
6942 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6944 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6946 (clobber (match_scratch:DI 3 "=1"))
6947 (clobber (reg:CC FLAGS_REG))]
6949 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6950 "<sgnprefix>mul{q}\t%2"
6951 [(set_attr "type" "imul")
6952 (set_attr "length_immediate" "0")
6953 (set (attr "athlon_decode")
6954 (if_then_else (eq_attr "cpu" "athlon")
6955 (const_string "vector")
6956 (const_string "double")))
6957 (set_attr "amdfam10_decode" "double")
6958 (set_attr "bdver1_decode" "direct")
6959 (set_attr "mode" "DI")])
6961 (define_insn "*<s>mulsi3_highpart_1"
6962 [(set (match_operand:SI 0 "register_operand" "=d")
6967 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6969 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6971 (clobber (match_scratch:SI 3 "=1"))
6972 (clobber (reg:CC FLAGS_REG))]
6973 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6974 "<sgnprefix>mul{l}\t%2"
6975 [(set_attr "type" "imul")
6976 (set_attr "length_immediate" "0")
6977 (set (attr "athlon_decode")
6978 (if_then_else (eq_attr "cpu" "athlon")
6979 (const_string "vector")
6980 (const_string "double")))
6981 (set_attr "amdfam10_decode" "double")
6982 (set_attr "bdver1_decode" "direct")
6983 (set_attr "mode" "SI")])
6985 (define_insn "*<s>mulsi3_highpart_zext"
6986 [(set (match_operand:DI 0 "register_operand" "=d")
6987 (zero_extend:DI (truncate:SI
6989 (mult:DI (any_extend:DI
6990 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6992 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6994 (clobber (match_scratch:SI 3 "=1"))
6995 (clobber (reg:CC FLAGS_REG))]
6997 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6998 "<sgnprefix>mul{l}\t%2"
6999 [(set_attr "type" "imul")
7000 (set_attr "length_immediate" "0")
7001 (set (attr "athlon_decode")
7002 (if_then_else (eq_attr "cpu" "athlon")
7003 (const_string "vector")
7004 (const_string "double")))
7005 (set_attr "amdfam10_decode" "double")
7006 (set_attr "bdver1_decode" "direct")
7007 (set_attr "mode" "SI")])
7009 ;; The patterns that match these are at the end of this file.
7011 (define_expand "mulxf3"
7012 [(set (match_operand:XF 0 "register_operand" "")
7013 (mult:XF (match_operand:XF 1 "register_operand" "")
7014 (match_operand:XF 2 "register_operand" "")))]
7017 (define_expand "mul<mode>3"
7018 [(set (match_operand:MODEF 0 "register_operand" "")
7019 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7020 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7021 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7022 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7024 ;; Divide instructions
7026 ;; The patterns that match these are at the end of this file.
7028 (define_expand "divxf3"
7029 [(set (match_operand:XF 0 "register_operand" "")
7030 (div:XF (match_operand:XF 1 "register_operand" "")
7031 (match_operand:XF 2 "register_operand" "")))]
7034 (define_expand "divdf3"
7035 [(set (match_operand:DF 0 "register_operand" "")
7036 (div:DF (match_operand:DF 1 "register_operand" "")
7037 (match_operand:DF 2 "nonimmediate_operand" "")))]
7038 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7039 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7041 (define_expand "divsf3"
7042 [(set (match_operand:SF 0 "register_operand" "")
7043 (div:SF (match_operand:SF 1 "register_operand" "")
7044 (match_operand:SF 2 "nonimmediate_operand" "")))]
7045 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7050 && optimize_insn_for_speed_p ()
7051 && flag_finite_math_only && !flag_trapping_math
7052 && flag_unsafe_math_optimizations)
7054 ix86_emit_swdivsf (operands[0], operands[1],
7055 operands[2], SFmode);
7060 ;; Divmod instructions.
7062 (define_expand "divmod<mode>4"
7063 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7065 (match_operand:SWIM248 1 "register_operand" "")
7066 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7067 (set (match_operand:SWIM248 3 "register_operand" "")
7068 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7069 (clobber (reg:CC FLAGS_REG))])])
7071 ;; Split with 8bit unsigned divide:
7072 ;; if (dividend an divisor are in [0-255])
7073 ;; use 8bit unsigned integer divide
7075 ;; use original integer divide
7077 [(set (match_operand:SWI48 0 "register_operand" "")
7078 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7079 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7080 (set (match_operand:SWI48 1 "register_operand" "")
7081 (mod:SWI48 (match_dup 2) (match_dup 3)))
7082 (clobber (reg:CC FLAGS_REG))]
7083 "TARGET_USE_8BIT_IDIV
7084 && TARGET_QIMODE_MATH
7085 && can_create_pseudo_p ()
7086 && !optimize_insn_for_size_p ()"
7088 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7090 (define_insn_and_split "divmod<mode>4_1"
7091 [(set (match_operand:SWI48 0 "register_operand" "=a")
7092 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7093 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7094 (set (match_operand:SWI48 1 "register_operand" "=&d")
7095 (mod:SWI48 (match_dup 2) (match_dup 3)))
7096 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7097 (clobber (reg:CC FLAGS_REG))]
7101 [(parallel [(set (match_dup 1)
7102 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7103 (clobber (reg:CC FLAGS_REG))])
7104 (parallel [(set (match_dup 0)
7105 (div:SWI48 (match_dup 2) (match_dup 3)))
7107 (mod:SWI48 (match_dup 2) (match_dup 3)))
7109 (clobber (reg:CC FLAGS_REG))])]
7111 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7113 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7114 operands[4] = operands[2];
7117 /* Avoid use of cltd in favor of a mov+shift. */
7118 emit_move_insn (operands[1], operands[2]);
7119 operands[4] = operands[1];
7122 [(set_attr "type" "multi")
7123 (set_attr "mode" "<MODE>")])
7125 (define_insn_and_split "*divmod<mode>4"
7126 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7127 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7128 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7129 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7130 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7131 (clobber (reg:CC FLAGS_REG))]
7135 [(parallel [(set (match_dup 1)
7136 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7137 (clobber (reg:CC FLAGS_REG))])
7138 (parallel [(set (match_dup 0)
7139 (div:SWIM248 (match_dup 2) (match_dup 3)))
7141 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7143 (clobber (reg:CC FLAGS_REG))])]
7145 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7147 if (<MODE>mode != HImode
7148 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7149 operands[4] = operands[2];
7152 /* Avoid use of cltd in favor of a mov+shift. */
7153 emit_move_insn (operands[1], operands[2]);
7154 operands[4] = operands[1];
7157 [(set_attr "type" "multi")
7158 (set_attr "mode" "<MODE>")])
7160 (define_insn "*divmod<mode>4_noext"
7161 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7162 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7163 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7164 (set (match_operand:SWIM248 1 "register_operand" "=d")
7165 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7166 (use (match_operand:SWIM248 4 "register_operand" "1"))
7167 (clobber (reg:CC FLAGS_REG))]
7169 "idiv{<imodesuffix>}\t%3"
7170 [(set_attr "type" "idiv")
7171 (set_attr "mode" "<MODE>")])
7173 (define_expand "divmodqi4"
7174 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7176 (match_operand:QI 1 "register_operand" "")
7177 (match_operand:QI 2 "nonimmediate_operand" "")))
7178 (set (match_operand:QI 3 "register_operand" "")
7179 (mod:QI (match_dup 1) (match_dup 2)))
7180 (clobber (reg:CC FLAGS_REG))])]
7181 "TARGET_QIMODE_MATH"
7186 tmp0 = gen_reg_rtx (HImode);
7187 tmp1 = gen_reg_rtx (HImode);
7189 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7191 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7192 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7194 /* Extract remainder from AH. */
7195 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7196 insn = emit_move_insn (operands[3], tmp1);
7198 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7199 set_unique_reg_note (insn, REG_EQUAL, mod);
7201 /* Extract quotient from AL. */
7202 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7204 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7205 set_unique_reg_note (insn, REG_EQUAL, div);
7210 ;; Divide AX by r/m8, with result stored in
7213 ;; Change div/mod to HImode and extend the second argument to HImode
7214 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7215 ;; combine may fail.
7216 (define_insn "divmodhiqi3"
7217 [(set (match_operand:HI 0 "register_operand" "=a")
7222 (mod:HI (match_operand:HI 1 "register_operand" "0")
7224 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7228 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7229 (clobber (reg:CC FLAGS_REG))]
7230 "TARGET_QIMODE_MATH"
7232 [(set_attr "type" "idiv")
7233 (set_attr "mode" "QI")])
7235 (define_expand "udivmod<mode>4"
7236 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7238 (match_operand:SWIM248 1 "register_operand" "")
7239 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7240 (set (match_operand:SWIM248 3 "register_operand" "")
7241 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7242 (clobber (reg:CC FLAGS_REG))])])
7244 ;; Split with 8bit unsigned divide:
7245 ;; if (dividend an divisor are in [0-255])
7246 ;; use 8bit unsigned integer divide
7248 ;; use original integer divide
7250 [(set (match_operand:SWI48 0 "register_operand" "")
7251 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7252 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7253 (set (match_operand:SWI48 1 "register_operand" "")
7254 (umod:SWI48 (match_dup 2) (match_dup 3)))
7255 (clobber (reg:CC FLAGS_REG))]
7256 "TARGET_USE_8BIT_IDIV
7257 && TARGET_QIMODE_MATH
7258 && can_create_pseudo_p ()
7259 && !optimize_insn_for_size_p ()"
7261 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7263 (define_insn_and_split "udivmod<mode>4_1"
7264 [(set (match_operand:SWI48 0 "register_operand" "=a")
7265 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7266 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7267 (set (match_operand:SWI48 1 "register_operand" "=&d")
7268 (umod:SWI48 (match_dup 2) (match_dup 3)))
7269 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7270 (clobber (reg:CC FLAGS_REG))]
7274 [(set (match_dup 1) (const_int 0))
7275 (parallel [(set (match_dup 0)
7276 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7278 (umod:SWI48 (match_dup 2) (match_dup 3)))
7280 (clobber (reg:CC FLAGS_REG))])]
7282 [(set_attr "type" "multi")
7283 (set_attr "mode" "<MODE>")])
7285 (define_insn_and_split "*udivmod<mode>4"
7286 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7287 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7288 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7289 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7290 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7291 (clobber (reg:CC FLAGS_REG))]
7295 [(set (match_dup 1) (const_int 0))
7296 (parallel [(set (match_dup 0)
7297 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7299 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7301 (clobber (reg:CC FLAGS_REG))])]
7303 [(set_attr "type" "multi")
7304 (set_attr "mode" "<MODE>")])
7306 (define_insn "*udivmod<mode>4_noext"
7307 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7308 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7309 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7310 (set (match_operand:SWIM248 1 "register_operand" "=d")
7311 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7312 (use (match_operand:SWIM248 4 "register_operand" "1"))
7313 (clobber (reg:CC FLAGS_REG))]
7315 "div{<imodesuffix>}\t%3"
7316 [(set_attr "type" "idiv")
7317 (set_attr "mode" "<MODE>")])
7319 (define_expand "udivmodqi4"
7320 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7322 (match_operand:QI 1 "register_operand" "")
7323 (match_operand:QI 2 "nonimmediate_operand" "")))
7324 (set (match_operand:QI 3 "register_operand" "")
7325 (umod:QI (match_dup 1) (match_dup 2)))
7326 (clobber (reg:CC FLAGS_REG))])]
7327 "TARGET_QIMODE_MATH"
7332 tmp0 = gen_reg_rtx (HImode);
7333 tmp1 = gen_reg_rtx (HImode);
7335 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7337 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7338 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7340 /* Extract remainder from AH. */
7341 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7342 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7343 insn = emit_move_insn (operands[3], tmp1);
7345 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7346 set_unique_reg_note (insn, REG_EQUAL, mod);
7348 /* Extract quotient from AL. */
7349 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7351 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7352 set_unique_reg_note (insn, REG_EQUAL, div);
7357 (define_insn "udivmodhiqi3"
7358 [(set (match_operand:HI 0 "register_operand" "=a")
7363 (mod:HI (match_operand:HI 1 "register_operand" "0")
7365 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7369 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7370 (clobber (reg:CC FLAGS_REG))]
7371 "TARGET_QIMODE_MATH"
7373 [(set_attr "type" "idiv")
7374 (set_attr "mode" "QI")])
7376 ;; We cannot use div/idiv for double division, because it causes
7377 ;; "division by zero" on the overflow and that's not what we expect
7378 ;; from truncate. Because true (non truncating) double division is
7379 ;; never generated, we can't create this insn anyway.
7382 ; [(set (match_operand:SI 0 "register_operand" "=a")
7384 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7386 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7387 ; (set (match_operand:SI 3 "register_operand" "=d")
7389 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7390 ; (clobber (reg:CC FLAGS_REG))]
7392 ; "div{l}\t{%2, %0|%0, %2}"
7393 ; [(set_attr "type" "idiv")])
7395 ;;- Logical AND instructions
7397 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7398 ;; Note that this excludes ah.
7400 (define_expand "testsi_ccno_1"
7401 [(set (reg:CCNO FLAGS_REG)
7403 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7404 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7407 (define_expand "testqi_ccz_1"
7408 [(set (reg:CCZ FLAGS_REG)
7409 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7410 (match_operand:QI 1 "nonmemory_operand" ""))
7413 (define_expand "testdi_ccno_1"
7414 [(set (reg:CCNO FLAGS_REG)
7416 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7417 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7419 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7421 (define_insn "*testdi_1"
7422 [(set (reg FLAGS_REG)
7425 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7426 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7428 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7429 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7431 test{l}\t{%k1, %k0|%k0, %k1}
7432 test{l}\t{%k1, %k0|%k0, %k1}
7433 test{q}\t{%1, %0|%0, %1}
7434 test{q}\t{%1, %0|%0, %1}
7435 test{q}\t{%1, %0|%0, %1}"
7436 [(set_attr "type" "test")
7437 (set_attr "modrm" "0,1,0,1,1")
7438 (set_attr "mode" "SI,SI,DI,DI,DI")])
7440 (define_insn "*testqi_1_maybe_si"
7441 [(set (reg FLAGS_REG)
7444 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7445 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7447 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7448 && ix86_match_ccmode (insn,
7449 CONST_INT_P (operands[1])
7450 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7452 if (which_alternative == 3)
7454 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7455 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7456 return "test{l}\t{%1, %k0|%k0, %1}";
7458 return "test{b}\t{%1, %0|%0, %1}";
7460 [(set_attr "type" "test")
7461 (set_attr "modrm" "0,1,1,1")
7462 (set_attr "mode" "QI,QI,QI,SI")
7463 (set_attr "pent_pair" "uv,np,uv,np")])
7465 (define_insn "*test<mode>_1"
7466 [(set (reg FLAGS_REG)
7469 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7470 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7472 "ix86_match_ccmode (insn, CCNOmode)
7473 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7474 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7475 [(set_attr "type" "test")
7476 (set_attr "modrm" "0,1,1")
7477 (set_attr "mode" "<MODE>")
7478 (set_attr "pent_pair" "uv,np,uv")])
7480 (define_expand "testqi_ext_ccno_0"
7481 [(set (reg:CCNO FLAGS_REG)
7485 (match_operand 0 "ext_register_operand" "")
7488 (match_operand 1 "const_int_operand" ""))
7491 (define_insn "*testqi_ext_0"
7492 [(set (reg FLAGS_REG)
7496 (match_operand 0 "ext_register_operand" "Q")
7499 (match_operand 1 "const_int_operand" "n"))
7501 "ix86_match_ccmode (insn, CCNOmode)"
7502 "test{b}\t{%1, %h0|%h0, %1}"
7503 [(set_attr "type" "test")
7504 (set_attr "mode" "QI")
7505 (set_attr "length_immediate" "1")
7506 (set_attr "modrm" "1")
7507 (set_attr "pent_pair" "np")])
7509 (define_insn "*testqi_ext_1_rex64"
7510 [(set (reg FLAGS_REG)
7514 (match_operand 0 "ext_register_operand" "Q")
7518 (match_operand:QI 1 "register_operand" "Q")))
7520 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7521 "test{b}\t{%1, %h0|%h0, %1}"
7522 [(set_attr "type" "test")
7523 (set_attr "mode" "QI")])
7525 (define_insn "*testqi_ext_1"
7526 [(set (reg FLAGS_REG)
7530 (match_operand 0 "ext_register_operand" "Q")
7534 (match_operand:QI 1 "general_operand" "Qm")))
7536 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7537 "test{b}\t{%1, %h0|%h0, %1}"
7538 [(set_attr "type" "test")
7539 (set_attr "mode" "QI")])
7541 (define_insn "*testqi_ext_2"
7542 [(set (reg FLAGS_REG)
7546 (match_operand 0 "ext_register_operand" "Q")
7550 (match_operand 1 "ext_register_operand" "Q")
7554 "ix86_match_ccmode (insn, CCNOmode)"
7555 "test{b}\t{%h1, %h0|%h0, %h1}"
7556 [(set_attr "type" "test")
7557 (set_attr "mode" "QI")])
7559 (define_insn "*testqi_ext_3_rex64"
7560 [(set (reg FLAGS_REG)
7561 (compare (zero_extract:DI
7562 (match_operand 0 "nonimmediate_operand" "rm")
7563 (match_operand:DI 1 "const_int_operand" "")
7564 (match_operand:DI 2 "const_int_operand" ""))
7567 && ix86_match_ccmode (insn, CCNOmode)
7568 && INTVAL (operands[1]) > 0
7569 && INTVAL (operands[2]) >= 0
7570 /* Ensure that resulting mask is zero or sign extended operand. */
7571 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7572 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7573 && INTVAL (operands[1]) > 32))
7574 && (GET_MODE (operands[0]) == SImode
7575 || GET_MODE (operands[0]) == DImode
7576 || GET_MODE (operands[0]) == HImode
7577 || GET_MODE (operands[0]) == QImode)"
7580 ;; Combine likes to form bit extractions for some tests. Humor it.
7581 (define_insn "*testqi_ext_3"
7582 [(set (reg FLAGS_REG)
7583 (compare (zero_extract:SI
7584 (match_operand 0 "nonimmediate_operand" "rm")
7585 (match_operand:SI 1 "const_int_operand" "")
7586 (match_operand:SI 2 "const_int_operand" ""))
7588 "ix86_match_ccmode (insn, CCNOmode)
7589 && INTVAL (operands[1]) > 0
7590 && INTVAL (operands[2]) >= 0
7591 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7592 && (GET_MODE (operands[0]) == SImode
7593 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7594 || GET_MODE (operands[0]) == HImode
7595 || GET_MODE (operands[0]) == QImode)"
7599 [(set (match_operand 0 "flags_reg_operand" "")
7600 (match_operator 1 "compare_operator"
7602 (match_operand 2 "nonimmediate_operand" "")
7603 (match_operand 3 "const_int_operand" "")
7604 (match_operand 4 "const_int_operand" ""))
7606 "ix86_match_ccmode (insn, CCNOmode)"
7607 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7609 rtx val = operands[2];
7610 HOST_WIDE_INT len = INTVAL (operands[3]);
7611 HOST_WIDE_INT pos = INTVAL (operands[4]);
7613 enum machine_mode mode, submode;
7615 mode = GET_MODE (val);
7618 /* ??? Combine likes to put non-volatile mem extractions in QImode
7619 no matter the size of the test. So find a mode that works. */
7620 if (! MEM_VOLATILE_P (val))
7622 mode = smallest_mode_for_size (pos + len, MODE_INT);
7623 val = adjust_address (val, mode, 0);
7626 else if (GET_CODE (val) == SUBREG
7627 && (submode = GET_MODE (SUBREG_REG (val)),
7628 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7629 && pos + len <= GET_MODE_BITSIZE (submode)
7630 && GET_MODE_CLASS (submode) == MODE_INT)
7632 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7634 val = SUBREG_REG (val);
7636 else if (mode == HImode && pos + len <= 8)
7638 /* Small HImode tests can be converted to QImode. */
7640 val = gen_lowpart (QImode, val);
7643 if (len == HOST_BITS_PER_WIDE_INT)
7646 mask = ((HOST_WIDE_INT)1 << len) - 1;
7649 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7652 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7653 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7654 ;; this is relatively important trick.
7655 ;; Do the conversion only post-reload to avoid limiting of the register class
7658 [(set (match_operand 0 "flags_reg_operand" "")
7659 (match_operator 1 "compare_operator"
7660 [(and (match_operand 2 "register_operand" "")
7661 (match_operand 3 "const_int_operand" ""))
7664 && QI_REG_P (operands[2])
7665 && GET_MODE (operands[2]) != QImode
7666 && ((ix86_match_ccmode (insn, CCZmode)
7667 && !(INTVAL (operands[3]) & ~(255 << 8)))
7668 || (ix86_match_ccmode (insn, CCNOmode)
7669 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7672 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7676 operands[2] = gen_lowpart (SImode, operands[2]);
7677 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7681 [(set (match_operand 0 "flags_reg_operand" "")
7682 (match_operator 1 "compare_operator"
7683 [(and (match_operand 2 "nonimmediate_operand" "")
7684 (match_operand 3 "const_int_operand" ""))
7687 && GET_MODE (operands[2]) != QImode
7688 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7689 && ((ix86_match_ccmode (insn, CCZmode)
7690 && !(INTVAL (operands[3]) & ~255))
7691 || (ix86_match_ccmode (insn, CCNOmode)
7692 && !(INTVAL (operands[3]) & ~127)))"
7694 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7697 operands[2] = gen_lowpart (QImode, operands[2]);
7698 operands[3] = gen_lowpart (QImode, operands[3]);
7701 ;; %%% This used to optimize known byte-wide and operations to memory,
7702 ;; and sometimes to QImode registers. If this is considered useful,
7703 ;; it should be done with splitters.
7705 (define_expand "and<mode>3"
7706 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7707 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7708 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7711 if (<MODE>mode == DImode
7712 && GET_CODE (operands[2]) == CONST_INT
7713 && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7714 && REG_P (operands[1]))
7715 emit_insn (gen_zero_extendsidi2 (operands[0],
7716 gen_lowpart (SImode, operands[1])));
7718 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7722 (define_insn "*anddi_1"
7723 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7725 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7726 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7727 (clobber (reg:CC FLAGS_REG))]
7728 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7730 switch (get_attr_type (insn))
7734 enum machine_mode mode;
7736 gcc_assert (CONST_INT_P (operands[2]));
7737 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7739 else if (INTVAL (operands[2]) == 0xffff)
7743 gcc_assert (INTVAL (operands[2]) == 0xff);
7747 operands[1] = gen_lowpart (mode, operands[1]);
7749 return "mov{l}\t{%1, %k0|%k0, %1}";
7750 else if (mode == HImode)
7751 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7753 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7757 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7758 if (get_attr_mode (insn) == MODE_SI)
7759 return "and{l}\t{%k2, %k0|%k0, %k2}";
7761 return "and{q}\t{%2, %0|%0, %2}";
7764 [(set_attr "type" "alu,alu,alu,imovx")
7765 (set_attr "length_immediate" "*,*,*,0")
7766 (set (attr "prefix_rex")
7768 (and (eq_attr "type" "imovx")
7769 (and (match_test "INTVAL (operands[2]) == 0xff")
7770 (match_operand 1 "ext_QIreg_operand" "")))
7772 (const_string "*")))
7773 (set_attr "mode" "SI,DI,DI,SI")])
7775 (define_insn "*andsi_1"
7776 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7777 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7778 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7779 (clobber (reg:CC FLAGS_REG))]
7780 "ix86_binary_operator_ok (AND, SImode, operands)"
7782 switch (get_attr_type (insn))
7786 enum machine_mode mode;
7788 gcc_assert (CONST_INT_P (operands[2]));
7789 if (INTVAL (operands[2]) == 0xffff)
7793 gcc_assert (INTVAL (operands[2]) == 0xff);
7797 operands[1] = gen_lowpart (mode, operands[1]);
7799 return "movz{wl|x}\t{%1, %0|%0, %1}";
7801 return "movz{bl|x}\t{%1, %0|%0, %1}";
7805 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7806 return "and{l}\t{%2, %0|%0, %2}";
7809 [(set_attr "type" "alu,alu,imovx")
7810 (set (attr "prefix_rex")
7812 (and (eq_attr "type" "imovx")
7813 (and (match_test "INTVAL (operands[2]) == 0xff")
7814 (match_operand 1 "ext_QIreg_operand" "")))
7816 (const_string "*")))
7817 (set_attr "length_immediate" "*,*,0")
7818 (set_attr "mode" "SI")])
7820 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7821 (define_insn "*andsi_1_zext"
7822 [(set (match_operand:DI 0 "register_operand" "=r")
7824 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7825 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7826 (clobber (reg:CC FLAGS_REG))]
7827 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7828 "and{l}\t{%2, %k0|%k0, %2}"
7829 [(set_attr "type" "alu")
7830 (set_attr "mode" "SI")])
7832 (define_insn "*andhi_1"
7833 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7834 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7835 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7836 (clobber (reg:CC FLAGS_REG))]
7837 "ix86_binary_operator_ok (AND, HImode, operands)"
7839 switch (get_attr_type (insn))
7842 gcc_assert (CONST_INT_P (operands[2]));
7843 gcc_assert (INTVAL (operands[2]) == 0xff);
7844 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7847 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7849 return "and{w}\t{%2, %0|%0, %2}";
7852 [(set_attr "type" "alu,alu,imovx")
7853 (set_attr "length_immediate" "*,*,0")
7854 (set (attr "prefix_rex")
7856 (and (eq_attr "type" "imovx")
7857 (match_operand 1 "ext_QIreg_operand" ""))
7859 (const_string "*")))
7860 (set_attr "mode" "HI,HI,SI")])
7862 ;; %%% Potential partial reg stall on alternative 2. What to do?
7863 (define_insn "*andqi_1"
7864 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7865 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7866 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7867 (clobber (reg:CC FLAGS_REG))]
7868 "ix86_binary_operator_ok (AND, QImode, operands)"
7870 and{b}\t{%2, %0|%0, %2}
7871 and{b}\t{%2, %0|%0, %2}
7872 and{l}\t{%k2, %k0|%k0, %k2}"
7873 [(set_attr "type" "alu")
7874 (set_attr "mode" "QI,QI,SI")])
7876 (define_insn "*andqi_1_slp"
7877 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7878 (and:QI (match_dup 0)
7879 (match_operand:QI 1 "general_operand" "qn,qmn")))
7880 (clobber (reg:CC FLAGS_REG))]
7881 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7882 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7883 "and{b}\t{%1, %0|%0, %1}"
7884 [(set_attr "type" "alu1")
7885 (set_attr "mode" "QI")])
7888 [(set (match_operand 0 "register_operand" "")
7890 (const_int -65536)))
7891 (clobber (reg:CC FLAGS_REG))]
7892 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7893 || optimize_function_for_size_p (cfun)"
7894 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7895 "operands[1] = gen_lowpart (HImode, operands[0]);")
7898 [(set (match_operand 0 "ext_register_operand" "")
7901 (clobber (reg:CC FLAGS_REG))]
7902 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7903 && reload_completed"
7904 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7905 "operands[1] = gen_lowpart (QImode, operands[0]);")
7908 [(set (match_operand 0 "ext_register_operand" "")
7910 (const_int -65281)))
7911 (clobber (reg:CC FLAGS_REG))]
7912 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7913 && reload_completed"
7914 [(parallel [(set (zero_extract:SI (match_dup 0)
7918 (zero_extract:SI (match_dup 0)
7921 (zero_extract:SI (match_dup 0)
7924 (clobber (reg:CC FLAGS_REG))])]
7925 "operands[0] = gen_lowpart (SImode, operands[0]);")
7927 (define_insn "*anddi_2"
7928 [(set (reg FLAGS_REG)
7931 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7932 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7934 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7935 (and:DI (match_dup 1) (match_dup 2)))]
7936 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7937 && ix86_binary_operator_ok (AND, DImode, operands)"
7939 and{l}\t{%k2, %k0|%k0, %k2}
7940 and{q}\t{%2, %0|%0, %2}
7941 and{q}\t{%2, %0|%0, %2}"
7942 [(set_attr "type" "alu")
7943 (set_attr "mode" "SI,DI,DI")])
7945 (define_insn "*andqi_2_maybe_si"
7946 [(set (reg FLAGS_REG)
7948 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7949 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7951 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7952 (and:QI (match_dup 1) (match_dup 2)))]
7953 "ix86_binary_operator_ok (AND, QImode, operands)
7954 && ix86_match_ccmode (insn,
7955 CONST_INT_P (operands[2])
7956 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7958 if (which_alternative == 2)
7960 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7961 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7962 return "and{l}\t{%2, %k0|%k0, %2}";
7964 return "and{b}\t{%2, %0|%0, %2}";
7966 [(set_attr "type" "alu")
7967 (set_attr "mode" "QI,QI,SI")])
7969 (define_insn "*and<mode>_2"
7970 [(set (reg FLAGS_REG)
7971 (compare (and:SWI124
7972 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7973 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7975 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7976 (and:SWI124 (match_dup 1) (match_dup 2)))]
7977 "ix86_match_ccmode (insn, CCNOmode)
7978 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7979 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7980 [(set_attr "type" "alu")
7981 (set_attr "mode" "<MODE>")])
7983 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7984 (define_insn "*andsi_2_zext"
7985 [(set (reg FLAGS_REG)
7987 (match_operand:SI 1 "nonimmediate_operand" "%0")
7988 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7990 (set (match_operand:DI 0 "register_operand" "=r")
7991 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7992 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7993 && ix86_binary_operator_ok (AND, SImode, operands)"
7994 "and{l}\t{%2, %k0|%k0, %2}"
7995 [(set_attr "type" "alu")
7996 (set_attr "mode" "SI")])
7998 (define_insn "*andqi_2_slp"
7999 [(set (reg FLAGS_REG)
8001 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8002 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8004 (set (strict_low_part (match_dup 0))
8005 (and:QI (match_dup 0) (match_dup 1)))]
8006 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8007 && ix86_match_ccmode (insn, CCNOmode)
8008 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8009 "and{b}\t{%1, %0|%0, %1}"
8010 [(set_attr "type" "alu1")
8011 (set_attr "mode" "QI")])
8013 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8014 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8015 ;; for a QImode operand, which of course failed.
8016 (define_insn "andqi_ext_0"
8017 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8022 (match_operand 1 "ext_register_operand" "0")
8025 (match_operand 2 "const_int_operand" "n")))
8026 (clobber (reg:CC FLAGS_REG))]
8028 "and{b}\t{%2, %h0|%h0, %2}"
8029 [(set_attr "type" "alu")
8030 (set_attr "length_immediate" "1")
8031 (set_attr "modrm" "1")
8032 (set_attr "mode" "QI")])
8034 ;; Generated by peephole translating test to and. This shows up
8035 ;; often in fp comparisons.
8036 (define_insn "*andqi_ext_0_cc"
8037 [(set (reg FLAGS_REG)
8041 (match_operand 1 "ext_register_operand" "0")
8044 (match_operand 2 "const_int_operand" "n"))
8046 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8055 "ix86_match_ccmode (insn, CCNOmode)"
8056 "and{b}\t{%2, %h0|%h0, %2}"
8057 [(set_attr "type" "alu")
8058 (set_attr "length_immediate" "1")
8059 (set_attr "modrm" "1")
8060 (set_attr "mode" "QI")])
8062 (define_insn "*andqi_ext_1_rex64"
8063 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8068 (match_operand 1 "ext_register_operand" "0")
8072 (match_operand 2 "ext_register_operand" "Q"))))
8073 (clobber (reg:CC FLAGS_REG))]
8075 "and{b}\t{%2, %h0|%h0, %2}"
8076 [(set_attr "type" "alu")
8077 (set_attr "length_immediate" "0")
8078 (set_attr "mode" "QI")])
8080 (define_insn "*andqi_ext_1"
8081 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8086 (match_operand 1 "ext_register_operand" "0")
8090 (match_operand:QI 2 "general_operand" "Qm"))))
8091 (clobber (reg:CC FLAGS_REG))]
8093 "and{b}\t{%2, %h0|%h0, %2}"
8094 [(set_attr "type" "alu")
8095 (set_attr "length_immediate" "0")
8096 (set_attr "mode" "QI")])
8098 (define_insn "*andqi_ext_2"
8099 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8104 (match_operand 1 "ext_register_operand" "%0")
8108 (match_operand 2 "ext_register_operand" "Q")
8111 (clobber (reg:CC FLAGS_REG))]
8113 "and{b}\t{%h2, %h0|%h0, %h2}"
8114 [(set_attr "type" "alu")
8115 (set_attr "length_immediate" "0")
8116 (set_attr "mode" "QI")])
8118 ;; Convert wide AND instructions with immediate operand to shorter QImode
8119 ;; equivalents when possible.
8120 ;; Don't do the splitting with memory operands, since it introduces risk
8121 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8122 ;; for size, but that can (should?) be handled by generic code instead.
8124 [(set (match_operand 0 "register_operand" "")
8125 (and (match_operand 1 "register_operand" "")
8126 (match_operand 2 "const_int_operand" "")))
8127 (clobber (reg:CC FLAGS_REG))]
8129 && QI_REG_P (operands[0])
8130 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8131 && !(~INTVAL (operands[2]) & ~(255 << 8))
8132 && GET_MODE (operands[0]) != QImode"
8133 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8134 (and:SI (zero_extract:SI (match_dup 1)
8135 (const_int 8) (const_int 8))
8137 (clobber (reg:CC FLAGS_REG))])]
8139 operands[0] = gen_lowpart (SImode, operands[0]);
8140 operands[1] = gen_lowpart (SImode, operands[1]);
8141 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8144 ;; Since AND can be encoded with sign extended immediate, this is only
8145 ;; profitable when 7th bit is not set.
8147 [(set (match_operand 0 "register_operand" "")
8148 (and (match_operand 1 "general_operand" "")
8149 (match_operand 2 "const_int_operand" "")))
8150 (clobber (reg:CC FLAGS_REG))]
8152 && ANY_QI_REG_P (operands[0])
8153 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8154 && !(~INTVAL (operands[2]) & ~255)
8155 && !(INTVAL (operands[2]) & 128)
8156 && GET_MODE (operands[0]) != QImode"
8157 [(parallel [(set (strict_low_part (match_dup 0))
8158 (and:QI (match_dup 1)
8160 (clobber (reg:CC FLAGS_REG))])]
8162 operands[0] = gen_lowpart (QImode, operands[0]);
8163 operands[1] = gen_lowpart (QImode, operands[1]);
8164 operands[2] = gen_lowpart (QImode, operands[2]);
8167 ;; Logical inclusive and exclusive OR instructions
8169 ;; %%% This used to optimize known byte-wide and operations to memory.
8170 ;; If this is considered useful, it should be done with splitters.
8172 (define_expand "<code><mode>3"
8173 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8174 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8175 (match_operand:SWIM 2 "<general_operand>" "")))]
8177 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8179 (define_insn "*<code><mode>_1"
8180 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8182 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8183 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8184 (clobber (reg:CC FLAGS_REG))]
8185 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8186 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8187 [(set_attr "type" "alu")
8188 (set_attr "mode" "<MODE>")])
8190 ;; %%% Potential partial reg stall on alternative 2. What to do?
8191 (define_insn "*<code>qi_1"
8192 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8193 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8194 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8195 (clobber (reg:CC FLAGS_REG))]
8196 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8198 <logic>{b}\t{%2, %0|%0, %2}
8199 <logic>{b}\t{%2, %0|%0, %2}
8200 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8201 [(set_attr "type" "alu")
8202 (set_attr "mode" "QI,QI,SI")])
8204 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8205 (define_insn "*<code>si_1_zext"
8206 [(set (match_operand:DI 0 "register_operand" "=r")
8208 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8209 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8210 (clobber (reg:CC FLAGS_REG))]
8211 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8212 "<logic>{l}\t{%2, %k0|%k0, %2}"
8213 [(set_attr "type" "alu")
8214 (set_attr "mode" "SI")])
8216 (define_insn "*<code>si_1_zext_imm"
8217 [(set (match_operand:DI 0 "register_operand" "=r")
8219 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8220 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8221 (clobber (reg:CC FLAGS_REG))]
8222 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8223 "<logic>{l}\t{%2, %k0|%k0, %2}"
8224 [(set_attr "type" "alu")
8225 (set_attr "mode" "SI")])
8227 (define_insn "*<code>qi_1_slp"
8228 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8229 (any_or:QI (match_dup 0)
8230 (match_operand:QI 1 "general_operand" "qmn,qn")))
8231 (clobber (reg:CC FLAGS_REG))]
8232 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8233 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8234 "<logic>{b}\t{%1, %0|%0, %1}"
8235 [(set_attr "type" "alu1")
8236 (set_attr "mode" "QI")])
8238 (define_insn "*<code><mode>_2"
8239 [(set (reg FLAGS_REG)
8240 (compare (any_or:SWI
8241 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8242 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8244 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8245 (any_or:SWI (match_dup 1) (match_dup 2)))]
8246 "ix86_match_ccmode (insn, CCNOmode)
8247 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8248 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8249 [(set_attr "type" "alu")
8250 (set_attr "mode" "<MODE>")])
8252 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8253 ;; ??? Special case for immediate operand is missing - it is tricky.
8254 (define_insn "*<code>si_2_zext"
8255 [(set (reg FLAGS_REG)
8256 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8257 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8259 (set (match_operand:DI 0 "register_operand" "=r")
8260 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8261 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8262 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8263 "<logic>{l}\t{%2, %k0|%k0, %2}"
8264 [(set_attr "type" "alu")
8265 (set_attr "mode" "SI")])
8267 (define_insn "*<code>si_2_zext_imm"
8268 [(set (reg FLAGS_REG)
8270 (match_operand:SI 1 "nonimmediate_operand" "%0")
8271 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8273 (set (match_operand:DI 0 "register_operand" "=r")
8274 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8275 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8276 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8277 "<logic>{l}\t{%2, %k0|%k0, %2}"
8278 [(set_attr "type" "alu")
8279 (set_attr "mode" "SI")])
8281 (define_insn "*<code>qi_2_slp"
8282 [(set (reg FLAGS_REG)
8283 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8284 (match_operand:QI 1 "general_operand" "qmn,qn"))
8286 (set (strict_low_part (match_dup 0))
8287 (any_or:QI (match_dup 0) (match_dup 1)))]
8288 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8289 && ix86_match_ccmode (insn, CCNOmode)
8290 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8291 "<logic>{b}\t{%1, %0|%0, %1}"
8292 [(set_attr "type" "alu1")
8293 (set_attr "mode" "QI")])
8295 (define_insn "*<code><mode>_3"
8296 [(set (reg FLAGS_REG)
8297 (compare (any_or:SWI
8298 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8299 (match_operand:SWI 2 "<general_operand>" "<g>"))
8301 (clobber (match_scratch:SWI 0 "=<r>"))]
8302 "ix86_match_ccmode (insn, CCNOmode)
8303 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8304 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8305 [(set_attr "type" "alu")
8306 (set_attr "mode" "<MODE>")])
8308 (define_insn "*<code>qi_ext_0"
8309 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8314 (match_operand 1 "ext_register_operand" "0")
8317 (match_operand 2 "const_int_operand" "n")))
8318 (clobber (reg:CC FLAGS_REG))]
8319 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8320 "<logic>{b}\t{%2, %h0|%h0, %2}"
8321 [(set_attr "type" "alu")
8322 (set_attr "length_immediate" "1")
8323 (set_attr "modrm" "1")
8324 (set_attr "mode" "QI")])
8326 (define_insn "*<code>qi_ext_1_rex64"
8327 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8332 (match_operand 1 "ext_register_operand" "0")
8336 (match_operand 2 "ext_register_operand" "Q"))))
8337 (clobber (reg:CC FLAGS_REG))]
8339 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8340 "<logic>{b}\t{%2, %h0|%h0, %2}"
8341 [(set_attr "type" "alu")
8342 (set_attr "length_immediate" "0")
8343 (set_attr "mode" "QI")])
8345 (define_insn "*<code>qi_ext_1"
8346 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8351 (match_operand 1 "ext_register_operand" "0")
8355 (match_operand:QI 2 "general_operand" "Qm"))))
8356 (clobber (reg:CC FLAGS_REG))]
8358 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8359 "<logic>{b}\t{%2, %h0|%h0, %2}"
8360 [(set_attr "type" "alu")
8361 (set_attr "length_immediate" "0")
8362 (set_attr "mode" "QI")])
8364 (define_insn "*<code>qi_ext_2"
8365 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8369 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8372 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8375 (clobber (reg:CC FLAGS_REG))]
8376 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8377 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8378 [(set_attr "type" "alu")
8379 (set_attr "length_immediate" "0")
8380 (set_attr "mode" "QI")])
8383 [(set (match_operand 0 "register_operand" "")
8384 (any_or (match_operand 1 "register_operand" "")
8385 (match_operand 2 "const_int_operand" "")))
8386 (clobber (reg:CC FLAGS_REG))]
8388 && QI_REG_P (operands[0])
8389 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8390 && !(INTVAL (operands[2]) & ~(255 << 8))
8391 && GET_MODE (operands[0]) != QImode"
8392 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8393 (any_or:SI (zero_extract:SI (match_dup 1)
8394 (const_int 8) (const_int 8))
8396 (clobber (reg:CC FLAGS_REG))])]
8398 operands[0] = gen_lowpart (SImode, operands[0]);
8399 operands[1] = gen_lowpart (SImode, operands[1]);
8400 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8403 ;; Since OR can be encoded with sign extended immediate, this is only
8404 ;; profitable when 7th bit is set.
8406 [(set (match_operand 0 "register_operand" "")
8407 (any_or (match_operand 1 "general_operand" "")
8408 (match_operand 2 "const_int_operand" "")))
8409 (clobber (reg:CC FLAGS_REG))]
8411 && ANY_QI_REG_P (operands[0])
8412 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8413 && !(INTVAL (operands[2]) & ~255)
8414 && (INTVAL (operands[2]) & 128)
8415 && GET_MODE (operands[0]) != QImode"
8416 [(parallel [(set (strict_low_part (match_dup 0))
8417 (any_or:QI (match_dup 1)
8419 (clobber (reg:CC FLAGS_REG))])]
8421 operands[0] = gen_lowpart (QImode, operands[0]);
8422 operands[1] = gen_lowpart (QImode, operands[1]);
8423 operands[2] = gen_lowpart (QImode, operands[2]);
8426 (define_expand "xorqi_cc_ext_1"
8428 (set (reg:CCNO FLAGS_REG)
8432 (match_operand 1 "ext_register_operand" "")
8435 (match_operand:QI 2 "general_operand" ""))
8437 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8447 (define_insn "*xorqi_cc_ext_1_rex64"
8448 [(set (reg FLAGS_REG)
8452 (match_operand 1 "ext_register_operand" "0")
8455 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8457 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8466 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8467 "xor{b}\t{%2, %h0|%h0, %2}"
8468 [(set_attr "type" "alu")
8469 (set_attr "modrm" "1")
8470 (set_attr "mode" "QI")])
8472 (define_insn "*xorqi_cc_ext_1"
8473 [(set (reg FLAGS_REG)
8477 (match_operand 1 "ext_register_operand" "0")
8480 (match_operand:QI 2 "general_operand" "qmn"))
8482 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8491 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8492 "xor{b}\t{%2, %h0|%h0, %2}"
8493 [(set_attr "type" "alu")
8494 (set_attr "modrm" "1")
8495 (set_attr "mode" "QI")])
8497 ;; Negation instructions
8499 (define_expand "neg<mode>2"
8500 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8501 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8503 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8505 (define_insn_and_split "*neg<dwi>2_doubleword"
8506 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8507 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8508 (clobber (reg:CC FLAGS_REG))]
8509 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8513 [(set (reg:CCZ FLAGS_REG)
8514 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8515 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8518 (plus:DWIH (match_dup 3)
8519 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8521 (clobber (reg:CC FLAGS_REG))])
8524 (neg:DWIH (match_dup 2)))
8525 (clobber (reg:CC FLAGS_REG))])]
8526 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8528 (define_insn "*neg<mode>2_1"
8529 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8530 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8531 (clobber (reg:CC FLAGS_REG))]
8532 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8533 "neg{<imodesuffix>}\t%0"
8534 [(set_attr "type" "negnot")
8535 (set_attr "mode" "<MODE>")])
8537 ;; Combine is quite creative about this pattern.
8538 (define_insn "*negsi2_1_zext"
8539 [(set (match_operand:DI 0 "register_operand" "=r")
8541 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8544 (clobber (reg:CC FLAGS_REG))]
8545 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8547 [(set_attr "type" "negnot")
8548 (set_attr "mode" "SI")])
8550 ;; The problem with neg is that it does not perform (compare x 0),
8551 ;; it really performs (compare 0 x), which leaves us with the zero
8552 ;; flag being the only useful item.
8554 (define_insn "*neg<mode>2_cmpz"
8555 [(set (reg:CCZ FLAGS_REG)
8557 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8559 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8560 (neg:SWI (match_dup 1)))]
8561 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8562 "neg{<imodesuffix>}\t%0"
8563 [(set_attr "type" "negnot")
8564 (set_attr "mode" "<MODE>")])
8566 (define_insn "*negsi2_cmpz_zext"
8567 [(set (reg:CCZ FLAGS_REG)
8571 (match_operand:DI 1 "register_operand" "0")
8575 (set (match_operand:DI 0 "register_operand" "=r")
8576 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8579 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8581 [(set_attr "type" "negnot")
8582 (set_attr "mode" "SI")])
8584 ;; Changing of sign for FP values is doable using integer unit too.
8586 (define_expand "<code><mode>2"
8587 [(set (match_operand:X87MODEF 0 "register_operand" "")
8588 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8589 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8590 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8592 (define_insn "*absneg<mode>2_mixed"
8593 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8594 (match_operator:MODEF 3 "absneg_operator"
8595 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8596 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8597 (clobber (reg:CC FLAGS_REG))]
8598 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8601 (define_insn "*absneg<mode>2_sse"
8602 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8603 (match_operator:MODEF 3 "absneg_operator"
8604 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8605 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8606 (clobber (reg:CC FLAGS_REG))]
8607 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8610 (define_insn "*absneg<mode>2_i387"
8611 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8612 (match_operator:X87MODEF 3 "absneg_operator"
8613 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8614 (use (match_operand 2 "" ""))
8615 (clobber (reg:CC FLAGS_REG))]
8616 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8619 (define_expand "<code>tf2"
8620 [(set (match_operand:TF 0 "register_operand" "")
8621 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8623 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8625 (define_insn "*absnegtf2_sse"
8626 [(set (match_operand:TF 0 "register_operand" "=x,x")
8627 (match_operator:TF 3 "absneg_operator"
8628 [(match_operand:TF 1 "register_operand" "0,x")]))
8629 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8630 (clobber (reg:CC FLAGS_REG))]
8634 ;; Splitters for fp abs and neg.
8637 [(set (match_operand 0 "fp_register_operand" "")
8638 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8639 (use (match_operand 2 "" ""))
8640 (clobber (reg:CC FLAGS_REG))]
8642 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8645 [(set (match_operand 0 "register_operand" "")
8646 (match_operator 3 "absneg_operator"
8647 [(match_operand 1 "register_operand" "")]))
8648 (use (match_operand 2 "nonimmediate_operand" ""))
8649 (clobber (reg:CC FLAGS_REG))]
8650 "reload_completed && SSE_REG_P (operands[0])"
8651 [(set (match_dup 0) (match_dup 3))]
8653 enum machine_mode mode = GET_MODE (operands[0]);
8654 enum machine_mode vmode = GET_MODE (operands[2]);
8657 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8658 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8659 if (operands_match_p (operands[0], operands[2]))
8662 operands[1] = operands[2];
8665 if (GET_CODE (operands[3]) == ABS)
8666 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8668 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8673 [(set (match_operand:SF 0 "register_operand" "")
8674 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8675 (use (match_operand:V4SF 2 "" ""))
8676 (clobber (reg:CC FLAGS_REG))]
8678 [(parallel [(set (match_dup 0) (match_dup 1))
8679 (clobber (reg:CC FLAGS_REG))])]
8682 operands[0] = gen_lowpart (SImode, operands[0]);
8683 if (GET_CODE (operands[1]) == ABS)
8685 tmp = gen_int_mode (0x7fffffff, SImode);
8686 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8690 tmp = gen_int_mode (0x80000000, SImode);
8691 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8697 [(set (match_operand:DF 0 "register_operand" "")
8698 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8699 (use (match_operand 2 "" ""))
8700 (clobber (reg:CC FLAGS_REG))]
8702 [(parallel [(set (match_dup 0) (match_dup 1))
8703 (clobber (reg:CC FLAGS_REG))])]
8708 tmp = gen_lowpart (DImode, operands[0]);
8709 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8712 if (GET_CODE (operands[1]) == ABS)
8715 tmp = gen_rtx_NOT (DImode, tmp);
8719 operands[0] = gen_highpart (SImode, operands[0]);
8720 if (GET_CODE (operands[1]) == ABS)
8722 tmp = gen_int_mode (0x7fffffff, SImode);
8723 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8727 tmp = gen_int_mode (0x80000000, SImode);
8728 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8735 [(set (match_operand:XF 0 "register_operand" "")
8736 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8737 (use (match_operand 2 "" ""))
8738 (clobber (reg:CC FLAGS_REG))]
8740 [(parallel [(set (match_dup 0) (match_dup 1))
8741 (clobber (reg:CC FLAGS_REG))])]
8744 operands[0] = gen_rtx_REG (SImode,
8745 true_regnum (operands[0])
8746 + (TARGET_64BIT ? 1 : 2));
8747 if (GET_CODE (operands[1]) == ABS)
8749 tmp = GEN_INT (0x7fff);
8750 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8754 tmp = GEN_INT (0x8000);
8755 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8760 ;; Conditionalize these after reload. If they match before reload, we
8761 ;; lose the clobber and ability to use integer instructions.
8763 (define_insn "*<code><mode>2_1"
8764 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8765 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8767 && (reload_completed
8768 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8769 "f<absneg_mnemonic>"
8770 [(set_attr "type" "fsgn")
8771 (set_attr "mode" "<MODE>")])
8773 (define_insn "*<code>extendsfdf2"
8774 [(set (match_operand:DF 0 "register_operand" "=f")
8775 (absneg:DF (float_extend:DF
8776 (match_operand:SF 1 "register_operand" "0"))))]
8777 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8778 "f<absneg_mnemonic>"
8779 [(set_attr "type" "fsgn")
8780 (set_attr "mode" "DF")])
8782 (define_insn "*<code>extendsfxf2"
8783 [(set (match_operand:XF 0 "register_operand" "=f")
8784 (absneg:XF (float_extend:XF
8785 (match_operand:SF 1 "register_operand" "0"))))]
8787 "f<absneg_mnemonic>"
8788 [(set_attr "type" "fsgn")
8789 (set_attr "mode" "XF")])
8791 (define_insn "*<code>extenddfxf2"
8792 [(set (match_operand:XF 0 "register_operand" "=f")
8793 (absneg:XF (float_extend:XF
8794 (match_operand:DF 1 "register_operand" "0"))))]
8796 "f<absneg_mnemonic>"
8797 [(set_attr "type" "fsgn")
8798 (set_attr "mode" "XF")])
8800 ;; Copysign instructions
8802 (define_mode_iterator CSGNMODE [SF DF TF])
8803 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8805 (define_expand "copysign<mode>3"
8806 [(match_operand:CSGNMODE 0 "register_operand" "")
8807 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8808 (match_operand:CSGNMODE 2 "register_operand" "")]
8809 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8810 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8811 "ix86_expand_copysign (operands); DONE;")
8813 (define_insn_and_split "copysign<mode>3_const"
8814 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8816 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8817 (match_operand:CSGNMODE 2 "register_operand" "0")
8818 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8820 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8821 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8823 "&& reload_completed"
8825 "ix86_split_copysign_const (operands); DONE;")
8827 (define_insn "copysign<mode>3_var"
8828 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8830 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8831 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8832 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8833 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8835 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8836 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8837 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8841 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8843 [(match_operand:CSGNMODE 2 "register_operand" "")
8844 (match_operand:CSGNMODE 3 "register_operand" "")
8845 (match_operand:<CSGNVMODE> 4 "" "")
8846 (match_operand:<CSGNVMODE> 5 "" "")]
8848 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8849 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8850 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8851 && reload_completed"
8853 "ix86_split_copysign_var (operands); DONE;")
8855 ;; One complement instructions
8857 (define_expand "one_cmpl<mode>2"
8858 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8859 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8861 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8863 (define_insn "*one_cmpl<mode>2_1"
8864 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8865 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8866 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8867 "not{<imodesuffix>}\t%0"
8868 [(set_attr "type" "negnot")
8869 (set_attr "mode" "<MODE>")])
8871 ;; %%% Potential partial reg stall on alternative 1. What to do?
8872 (define_insn "*one_cmplqi2_1"
8873 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8874 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8875 "ix86_unary_operator_ok (NOT, QImode, operands)"
8879 [(set_attr "type" "negnot")
8880 (set_attr "mode" "QI,SI")])
8882 ;; ??? Currently never generated - xor is used instead.
8883 (define_insn "*one_cmplsi2_1_zext"
8884 [(set (match_operand:DI 0 "register_operand" "=r")
8886 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8887 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8889 [(set_attr "type" "negnot")
8890 (set_attr "mode" "SI")])
8892 (define_insn "*one_cmpl<mode>2_2"
8893 [(set (reg FLAGS_REG)
8894 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8896 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8897 (not:SWI (match_dup 1)))]
8898 "ix86_match_ccmode (insn, CCNOmode)
8899 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8901 [(set_attr "type" "alu1")
8902 (set_attr "mode" "<MODE>")])
8905 [(set (match_operand 0 "flags_reg_operand" "")
8906 (match_operator 2 "compare_operator"
8907 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8909 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8910 (not:SWI (match_dup 3)))]
8911 "ix86_match_ccmode (insn, CCNOmode)"
8912 [(parallel [(set (match_dup 0)
8913 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8916 (xor:SWI (match_dup 3) (const_int -1)))])])
8918 ;; ??? Currently never generated - xor is used instead.
8919 (define_insn "*one_cmplsi2_2_zext"
8920 [(set (reg FLAGS_REG)
8921 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8923 (set (match_operand:DI 0 "register_operand" "=r")
8924 (zero_extend:DI (not:SI (match_dup 1))))]
8925 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8926 && ix86_unary_operator_ok (NOT, SImode, operands)"
8928 [(set_attr "type" "alu1")
8929 (set_attr "mode" "SI")])
8932 [(set (match_operand 0 "flags_reg_operand" "")
8933 (match_operator 2 "compare_operator"
8934 [(not:SI (match_operand:SI 3 "register_operand" ""))
8936 (set (match_operand:DI 1 "register_operand" "")
8937 (zero_extend:DI (not:SI (match_dup 3))))]
8938 "ix86_match_ccmode (insn, CCNOmode)"
8939 [(parallel [(set (match_dup 0)
8940 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8943 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8945 ;; Shift instructions
8947 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8948 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8949 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8950 ;; from the assembler input.
8952 ;; This instruction shifts the target reg/mem as usual, but instead of
8953 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8954 ;; is a left shift double, bits are taken from the high order bits of
8955 ;; reg, else if the insn is a shift right double, bits are taken from the
8956 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8957 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8959 ;; Since sh[lr]d does not change the `reg' operand, that is done
8960 ;; separately, making all shifts emit pairs of shift double and normal
8961 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8962 ;; support a 63 bit shift, each shift where the count is in a reg expands
8963 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8965 ;; If the shift count is a constant, we need never emit more than one
8966 ;; shift pair, instead using moves and sign extension for counts greater
8969 (define_expand "ashl<mode>3"
8970 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8971 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8972 (match_operand:QI 2 "nonmemory_operand" "")))]
8974 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8976 (define_insn "*ashl<mode>3_doubleword"
8977 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8978 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8979 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8980 (clobber (reg:CC FLAGS_REG))]
8983 [(set_attr "type" "multi")])
8986 [(set (match_operand:DWI 0 "register_operand" "")
8987 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8988 (match_operand:QI 2 "nonmemory_operand" "")))
8989 (clobber (reg:CC FLAGS_REG))]
8990 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8992 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8994 ;; By default we don't ask for a scratch register, because when DWImode
8995 ;; values are manipulated, registers are already at a premium. But if
8996 ;; we have one handy, we won't turn it away.
8999 [(match_scratch:DWIH 3 "r")
9000 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9002 (match_operand:<DWI> 1 "nonmemory_operand" "")
9003 (match_operand:QI 2 "nonmemory_operand" "")))
9004 (clobber (reg:CC FLAGS_REG))])
9008 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9010 (define_insn "x86_64_shld"
9011 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9012 (ior:DI (ashift:DI (match_dup 0)
9013 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9014 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9015 (minus:QI (const_int 64) (match_dup 2)))))
9016 (clobber (reg:CC FLAGS_REG))]
9018 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9019 [(set_attr "type" "ishift")
9020 (set_attr "prefix_0f" "1")
9021 (set_attr "mode" "DI")
9022 (set_attr "athlon_decode" "vector")
9023 (set_attr "amdfam10_decode" "vector")
9024 (set_attr "bdver1_decode" "vector")])
9026 (define_insn "x86_shld"
9027 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9028 (ior:SI (ashift:SI (match_dup 0)
9029 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9030 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9031 (minus:QI (const_int 32) (match_dup 2)))))
9032 (clobber (reg:CC FLAGS_REG))]
9034 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9035 [(set_attr "type" "ishift")
9036 (set_attr "prefix_0f" "1")
9037 (set_attr "mode" "SI")
9038 (set_attr "pent_pair" "np")
9039 (set_attr "athlon_decode" "vector")
9040 (set_attr "amdfam10_decode" "vector")
9041 (set_attr "bdver1_decode" "vector")])
9043 (define_expand "x86_shift<mode>_adj_1"
9044 [(set (reg:CCZ FLAGS_REG)
9045 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9048 (set (match_operand:SWI48 0 "register_operand" "")
9049 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9050 (match_operand:SWI48 1 "register_operand" "")
9053 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9054 (match_operand:SWI48 3 "register_operand" "")
9057 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9059 (define_expand "x86_shift<mode>_adj_2"
9060 [(use (match_operand:SWI48 0 "register_operand" ""))
9061 (use (match_operand:SWI48 1 "register_operand" ""))
9062 (use (match_operand:QI 2 "register_operand" ""))]
9065 rtx label = gen_label_rtx ();
9068 emit_insn (gen_testqi_ccz_1 (operands[2],
9069 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9071 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9072 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9073 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9074 gen_rtx_LABEL_REF (VOIDmode, label),
9076 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9077 JUMP_LABEL (tmp) = label;
9079 emit_move_insn (operands[0], operands[1]);
9080 ix86_expand_clear (operands[1]);
9083 LABEL_NUSES (label) = 1;
9088 ;; Avoid useless masking of count operand.
9089 (define_insn_and_split "*ashl<mode>3_mask"
9090 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9092 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9095 (match_operand:SI 2 "nonimmediate_operand" "c")
9096 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9097 (clobber (reg:CC FLAGS_REG))]
9098 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9099 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9100 == GET_MODE_BITSIZE (<MODE>mode)-1"
9103 [(parallel [(set (match_dup 0)
9104 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9105 (clobber (reg:CC FLAGS_REG))])]
9107 if (can_create_pseudo_p ())
9108 operands [2] = force_reg (SImode, operands[2]);
9110 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9112 [(set_attr "type" "ishift")
9113 (set_attr "mode" "<MODE>")])
9115 (define_insn "*bmi2_ashl<mode>3_1"
9116 [(set (match_operand:SWI48 0 "register_operand" "=r")
9117 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9118 (match_operand:SWI48 2 "register_operand" "r")))]
9120 "shlx\t{%2, %1, %0|%0, %1, %2}"
9121 [(set_attr "type" "ishiftx")
9122 (set_attr "mode" "<MODE>")])
9124 (define_insn "*ashl<mode>3_1"
9125 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9126 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9127 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9128 (clobber (reg:CC FLAGS_REG))]
9129 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9131 switch (get_attr_type (insn))
9138 gcc_assert (operands[2] == const1_rtx);
9139 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9140 return "add{<imodesuffix>}\t%0, %0";
9143 if (operands[2] == const1_rtx
9144 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9145 return "sal{<imodesuffix>}\t%0";
9147 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9150 [(set_attr "isa" "*,*,bmi2")
9152 (cond [(eq_attr "alternative" "1")
9153 (const_string "lea")
9154 (eq_attr "alternative" "2")
9155 (const_string "ishiftx")
9156 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9157 (match_operand 0 "register_operand" ""))
9158 (match_operand 2 "const1_operand" ""))
9159 (const_string "alu")
9161 (const_string "ishift")))
9162 (set (attr "length_immediate")
9164 (ior (eq_attr "type" "alu")
9165 (and (eq_attr "type" "ishift")
9166 (and (match_operand 2 "const1_operand" "")
9167 (ior (match_test "TARGET_SHIFT1")
9168 (match_test "optimize_function_for_size_p (cfun)")))))
9170 (const_string "*")))
9171 (set_attr "mode" "<MODE>")])
9173 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9175 [(set (match_operand:SWI48 0 "register_operand" "")
9176 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9177 (match_operand:QI 2 "register_operand" "")))
9178 (clobber (reg:CC FLAGS_REG))]
9179 "TARGET_BMI2 && reload_completed"
9181 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9182 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9184 (define_insn "*bmi2_ashlsi3_1_zext"
9185 [(set (match_operand:DI 0 "register_operand" "=r")
9187 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9188 (match_operand:SI 2 "register_operand" "r"))))]
9189 "TARGET_64BIT && TARGET_BMI2"
9190 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9191 [(set_attr "type" "ishiftx")
9192 (set_attr "mode" "SI")])
9194 (define_insn "*ashlsi3_1_zext"
9195 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9197 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9198 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9199 (clobber (reg:CC FLAGS_REG))]
9200 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9202 switch (get_attr_type (insn))
9209 gcc_assert (operands[2] == const1_rtx);
9210 return "add{l}\t%k0, %k0";
9213 if (operands[2] == const1_rtx
9214 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9215 return "sal{l}\t%k0";
9217 return "sal{l}\t{%2, %k0|%k0, %2}";
9220 [(set_attr "isa" "*,*,bmi2")
9222 (cond [(eq_attr "alternative" "1")
9223 (const_string "lea")
9224 (eq_attr "alternative" "2")
9225 (const_string "ishiftx")
9226 (and (match_test "TARGET_DOUBLE_WITH_ADD")
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" "SI")])
9242 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9244 [(set (match_operand:DI 0 "register_operand" "")
9246 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9247 (match_operand:QI 2 "register_operand" ""))))
9248 (clobber (reg:CC FLAGS_REG))]
9249 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9251 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9252 "operands[2] = gen_lowpart (SImode, operands[2]);")
9254 (define_insn "*ashlhi3_1"
9255 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9256 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9257 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9258 (clobber (reg:CC FLAGS_REG))]
9259 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9261 switch (get_attr_type (insn))
9267 gcc_assert (operands[2] == const1_rtx);
9268 return "add{w}\t%0, %0";
9271 if (operands[2] == const1_rtx
9272 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9273 return "sal{w}\t%0";
9275 return "sal{w}\t{%2, %0|%0, %2}";
9279 (cond [(eq_attr "alternative" "1")
9280 (const_string "lea")
9281 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9282 (match_operand 0 "register_operand" ""))
9283 (match_operand 2 "const1_operand" ""))
9284 (const_string "alu")
9286 (const_string "ishift")))
9287 (set (attr "length_immediate")
9289 (ior (eq_attr "type" "alu")
9290 (and (eq_attr "type" "ishift")
9291 (and (match_operand 2 "const1_operand" "")
9292 (ior (match_test "TARGET_SHIFT1")
9293 (match_test "optimize_function_for_size_p (cfun)")))))
9295 (const_string "*")))
9296 (set_attr "mode" "HI,SI")])
9298 ;; %%% Potential partial reg stall on alternative 1. What to do?
9299 (define_insn "*ashlqi3_1"
9300 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9301 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9302 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9303 (clobber (reg:CC FLAGS_REG))]
9304 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9306 switch (get_attr_type (insn))
9312 gcc_assert (operands[2] == const1_rtx);
9313 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9314 return "add{l}\t%k0, %k0";
9316 return "add{b}\t%0, %0";
9319 if (operands[2] == const1_rtx
9320 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9322 if (get_attr_mode (insn) == MODE_SI)
9323 return "sal{l}\t%k0";
9325 return "sal{b}\t%0";
9329 if (get_attr_mode (insn) == MODE_SI)
9330 return "sal{l}\t{%2, %k0|%k0, %2}";
9332 return "sal{b}\t{%2, %0|%0, %2}";
9337 (cond [(eq_attr "alternative" "2")
9338 (const_string "lea")
9339 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9340 (match_operand 0 "register_operand" ""))
9341 (match_operand 2 "const1_operand" ""))
9342 (const_string "alu")
9344 (const_string "ishift")))
9345 (set (attr "length_immediate")
9347 (ior (eq_attr "type" "alu")
9348 (and (eq_attr "type" "ishift")
9349 (and (match_operand 2 "const1_operand" "")
9350 (ior (match_test "TARGET_SHIFT1")
9351 (match_test "optimize_function_for_size_p (cfun)")))))
9353 (const_string "*")))
9354 (set_attr "mode" "QI,SI,SI")])
9356 (define_insn "*ashlqi3_1_slp"
9357 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9358 (ashift:QI (match_dup 0)
9359 (match_operand:QI 1 "nonmemory_operand" "cI")))
9360 (clobber (reg:CC FLAGS_REG))]
9361 "(optimize_function_for_size_p (cfun)
9362 || !TARGET_PARTIAL_FLAG_REG_STALL
9363 || (operands[1] == const1_rtx
9365 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9367 switch (get_attr_type (insn))
9370 gcc_assert (operands[1] == const1_rtx);
9371 return "add{b}\t%0, %0";
9374 if (operands[1] == const1_rtx
9375 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9376 return "sal{b}\t%0";
9378 return "sal{b}\t{%1, %0|%0, %1}";
9382 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9383 (match_operand 0 "register_operand" ""))
9384 (match_operand 1 "const1_operand" ""))
9385 (const_string "alu")
9387 (const_string "ishift1")))
9388 (set (attr "length_immediate")
9390 (ior (eq_attr "type" "alu")
9391 (and (eq_attr "type" "ishift1")
9392 (and (match_operand 1 "const1_operand" "")
9393 (ior (match_test "TARGET_SHIFT1")
9394 (match_test "optimize_function_for_size_p (cfun)")))))
9396 (const_string "*")))
9397 (set_attr "mode" "QI")])
9399 ;; Convert ashift to the lea pattern to avoid flags dependency.
9401 [(set (match_operand 0 "register_operand" "")
9402 (ashift (match_operand 1 "index_register_operand" "")
9403 (match_operand:QI 2 "const_int_operand" "")))
9404 (clobber (reg:CC FLAGS_REG))]
9405 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9407 && true_regnum (operands[0]) != true_regnum (operands[1])"
9410 enum machine_mode mode = GET_MODE (operands[0]);
9413 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9416 operands[0] = gen_lowpart (mode, operands[0]);
9417 operands[1] = gen_lowpart (mode, operands[1]);
9420 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9422 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9424 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9428 ;; Convert ashift to the lea pattern to avoid flags dependency.
9430 [(set (match_operand:DI 0 "register_operand" "")
9432 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9433 (match_operand:QI 2 "const_int_operand" ""))))
9434 (clobber (reg:CC FLAGS_REG))]
9435 "TARGET_64BIT && reload_completed
9436 && true_regnum (operands[0]) != true_regnum (operands[1])"
9438 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9440 operands[1] = gen_lowpart (DImode, operands[1]);
9441 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9444 ;; This pattern can't accept a variable shift count, since shifts by
9445 ;; zero don't affect the flags. We assume that shifts by constant
9446 ;; zero are optimized away.
9447 (define_insn "*ashl<mode>3_cmp"
9448 [(set (reg FLAGS_REG)
9450 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9451 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9453 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9454 (ashift:SWI (match_dup 1) (match_dup 2)))]
9455 "(optimize_function_for_size_p (cfun)
9456 || !TARGET_PARTIAL_FLAG_REG_STALL
9457 || (operands[2] == const1_rtx
9459 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9460 && ix86_match_ccmode (insn, CCGOCmode)
9461 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9463 switch (get_attr_type (insn))
9466 gcc_assert (operands[2] == const1_rtx);
9467 return "add{<imodesuffix>}\t%0, %0";
9470 if (operands[2] == const1_rtx
9471 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9472 return "sal{<imodesuffix>}\t%0";
9474 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9478 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9479 (match_operand 0 "register_operand" ""))
9480 (match_operand 2 "const1_operand" ""))
9481 (const_string "alu")
9483 (const_string "ishift")))
9484 (set (attr "length_immediate")
9486 (ior (eq_attr "type" "alu")
9487 (and (eq_attr "type" "ishift")
9488 (and (match_operand 2 "const1_operand" "")
9489 (ior (match_test "TARGET_SHIFT1")
9490 (match_test "optimize_function_for_size_p (cfun)")))))
9492 (const_string "*")))
9493 (set_attr "mode" "<MODE>")])
9495 (define_insn "*ashlsi3_cmp_zext"
9496 [(set (reg FLAGS_REG)
9498 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9499 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9501 (set (match_operand:DI 0 "register_operand" "=r")
9502 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9504 && (optimize_function_for_size_p (cfun)
9505 || !TARGET_PARTIAL_FLAG_REG_STALL
9506 || (operands[2] == const1_rtx
9508 || TARGET_DOUBLE_WITH_ADD)))
9509 && ix86_match_ccmode (insn, CCGOCmode)
9510 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9512 switch (get_attr_type (insn))
9515 gcc_assert (operands[2] == const1_rtx);
9516 return "add{l}\t%k0, %k0";
9519 if (operands[2] == const1_rtx
9520 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9521 return "sal{l}\t%k0";
9523 return "sal{l}\t{%2, %k0|%k0, %2}";
9527 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9528 (match_operand 2 "const1_operand" ""))
9529 (const_string "alu")
9531 (const_string "ishift")))
9532 (set (attr "length_immediate")
9534 (ior (eq_attr "type" "alu")
9535 (and (eq_attr "type" "ishift")
9536 (and (match_operand 2 "const1_operand" "")
9537 (ior (match_test "TARGET_SHIFT1")
9538 (match_test "optimize_function_for_size_p (cfun)")))))
9540 (const_string "*")))
9541 (set_attr "mode" "SI")])
9543 (define_insn "*ashl<mode>3_cconly"
9544 [(set (reg FLAGS_REG)
9546 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9547 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9549 (clobber (match_scratch:SWI 0 "=<r>"))]
9550 "(optimize_function_for_size_p (cfun)
9551 || !TARGET_PARTIAL_FLAG_REG_STALL
9552 || (operands[2] == const1_rtx
9554 || TARGET_DOUBLE_WITH_ADD)))
9555 && ix86_match_ccmode (insn, CCGOCmode)"
9557 switch (get_attr_type (insn))
9560 gcc_assert (operands[2] == const1_rtx);
9561 return "add{<imodesuffix>}\t%0, %0";
9564 if (operands[2] == const1_rtx
9565 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9566 return "sal{<imodesuffix>}\t%0";
9568 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9572 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9573 (match_operand 0 "register_operand" ""))
9574 (match_operand 2 "const1_operand" ""))
9575 (const_string "alu")
9577 (const_string "ishift")))
9578 (set (attr "length_immediate")
9580 (ior (eq_attr "type" "alu")
9581 (and (eq_attr "type" "ishift")
9582 (and (match_operand 2 "const1_operand" "")
9583 (ior (match_test "TARGET_SHIFT1")
9584 (match_test "optimize_function_for_size_p (cfun)")))))
9586 (const_string "*")))
9587 (set_attr "mode" "<MODE>")])
9589 ;; See comment above `ashl<mode>3' about how this works.
9591 (define_expand "<shift_insn><mode>3"
9592 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9593 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9594 (match_operand:QI 2 "nonmemory_operand" "")))]
9596 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9598 ;; Avoid useless masking of count operand.
9599 (define_insn_and_split "*<shift_insn><mode>3_mask"
9600 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9602 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9605 (match_operand:SI 2 "nonimmediate_operand" "c")
9606 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9607 (clobber (reg:CC FLAGS_REG))]
9608 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9609 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9610 == GET_MODE_BITSIZE (<MODE>mode)-1"
9613 [(parallel [(set (match_dup 0)
9614 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9615 (clobber (reg:CC FLAGS_REG))])]
9617 if (can_create_pseudo_p ())
9618 operands [2] = force_reg (SImode, operands[2]);
9620 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9622 [(set_attr "type" "ishift")
9623 (set_attr "mode" "<MODE>")])
9625 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9626 [(set (match_operand:DWI 0 "register_operand" "=r")
9627 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9628 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9629 (clobber (reg:CC FLAGS_REG))]
9632 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9634 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9635 [(set_attr "type" "multi")])
9637 ;; By default we don't ask for a scratch register, because when DWImode
9638 ;; values are manipulated, registers are already at a premium. But if
9639 ;; we have one handy, we won't turn it away.
9642 [(match_scratch:DWIH 3 "r")
9643 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9645 (match_operand:<DWI> 1 "register_operand" "")
9646 (match_operand:QI 2 "nonmemory_operand" "")))
9647 (clobber (reg:CC FLAGS_REG))])
9651 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9653 (define_insn "x86_64_shrd"
9654 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9655 (ior:DI (ashiftrt:DI (match_dup 0)
9656 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9657 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9658 (minus:QI (const_int 64) (match_dup 2)))))
9659 (clobber (reg:CC FLAGS_REG))]
9661 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9662 [(set_attr "type" "ishift")
9663 (set_attr "prefix_0f" "1")
9664 (set_attr "mode" "DI")
9665 (set_attr "athlon_decode" "vector")
9666 (set_attr "amdfam10_decode" "vector")
9667 (set_attr "bdver1_decode" "vector")])
9669 (define_insn "x86_shrd"
9670 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9671 (ior:SI (ashiftrt:SI (match_dup 0)
9672 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9673 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9674 (minus:QI (const_int 32) (match_dup 2)))))
9675 (clobber (reg:CC FLAGS_REG))]
9677 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9678 [(set_attr "type" "ishift")
9679 (set_attr "prefix_0f" "1")
9680 (set_attr "mode" "SI")
9681 (set_attr "pent_pair" "np")
9682 (set_attr "athlon_decode" "vector")
9683 (set_attr "amdfam10_decode" "vector")
9684 (set_attr "bdver1_decode" "vector")])
9686 (define_insn "ashrdi3_cvt"
9687 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9688 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9689 (match_operand:QI 2 "const_int_operand" "")))
9690 (clobber (reg:CC FLAGS_REG))]
9691 "TARGET_64BIT && INTVAL (operands[2]) == 63
9692 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9693 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9696 sar{q}\t{%2, %0|%0, %2}"
9697 [(set_attr "type" "imovx,ishift")
9698 (set_attr "prefix_0f" "0,*")
9699 (set_attr "length_immediate" "0,*")
9700 (set_attr "modrm" "0,1")
9701 (set_attr "mode" "DI")])
9703 (define_insn "ashrsi3_cvt"
9704 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9705 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9706 (match_operand:QI 2 "const_int_operand" "")))
9707 (clobber (reg:CC FLAGS_REG))]
9708 "INTVAL (operands[2]) == 31
9709 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9710 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9713 sar{l}\t{%2, %0|%0, %2}"
9714 [(set_attr "type" "imovx,ishift")
9715 (set_attr "prefix_0f" "0,*")
9716 (set_attr "length_immediate" "0,*")
9717 (set_attr "modrm" "0,1")
9718 (set_attr "mode" "SI")])
9720 (define_insn "*ashrsi3_cvt_zext"
9721 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9723 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9724 (match_operand:QI 2 "const_int_operand" ""))))
9725 (clobber (reg:CC FLAGS_REG))]
9726 "TARGET_64BIT && INTVAL (operands[2]) == 31
9727 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9728 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9731 sar{l}\t{%2, %k0|%k0, %2}"
9732 [(set_attr "type" "imovx,ishift")
9733 (set_attr "prefix_0f" "0,*")
9734 (set_attr "length_immediate" "0,*")
9735 (set_attr "modrm" "0,1")
9736 (set_attr "mode" "SI")])
9738 (define_expand "x86_shift<mode>_adj_3"
9739 [(use (match_operand:SWI48 0 "register_operand" ""))
9740 (use (match_operand:SWI48 1 "register_operand" ""))
9741 (use (match_operand:QI 2 "register_operand" ""))]
9744 rtx label = gen_label_rtx ();
9747 emit_insn (gen_testqi_ccz_1 (operands[2],
9748 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9750 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9751 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9752 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9753 gen_rtx_LABEL_REF (VOIDmode, label),
9755 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9756 JUMP_LABEL (tmp) = label;
9758 emit_move_insn (operands[0], operands[1]);
9759 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9760 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9762 LABEL_NUSES (label) = 1;
9767 (define_insn "*bmi2_<shift_insn><mode>3_1"
9768 [(set (match_operand:SWI48 0 "register_operand" "=r")
9769 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9770 (match_operand:SWI48 2 "register_operand" "r")))]
9772 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9773 [(set_attr "type" "ishiftx")
9774 (set_attr "mode" "<MODE>")])
9776 (define_insn "*<shift_insn><mode>3_1"
9777 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9779 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9780 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9781 (clobber (reg:CC FLAGS_REG))]
9782 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9784 switch (get_attr_type (insn))
9790 if (operands[2] == const1_rtx
9791 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9792 return "<shift>{<imodesuffix>}\t%0";
9794 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9797 [(set_attr "isa" "*,bmi2")
9798 (set_attr "type" "ishift,ishiftx")
9799 (set (attr "length_immediate")
9801 (and (match_operand 2 "const1_operand" "")
9802 (ior (match_test "TARGET_SHIFT1")
9803 (match_test "optimize_function_for_size_p (cfun)")))
9805 (const_string "*")))
9806 (set_attr "mode" "<MODE>")])
9808 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9810 [(set (match_operand:SWI48 0 "register_operand" "")
9811 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9812 (match_operand:QI 2 "register_operand" "")))
9813 (clobber (reg:CC FLAGS_REG))]
9814 "TARGET_BMI2 && reload_completed"
9816 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9817 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9819 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9820 [(set (match_operand:DI 0 "register_operand" "=r")
9822 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9823 (match_operand:SI 2 "register_operand" "r"))))]
9824 "TARGET_64BIT && TARGET_BMI2"
9825 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9826 [(set_attr "type" "ishiftx")
9827 (set_attr "mode" "SI")])
9829 (define_insn "*<shift_insn>si3_1_zext"
9830 [(set (match_operand:DI 0 "register_operand" "=r,r")
9832 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9833 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9834 (clobber (reg:CC FLAGS_REG))]
9835 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9837 switch (get_attr_type (insn))
9843 if (operands[2] == const1_rtx
9844 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9845 return "<shift>{l}\t%k0";
9847 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9850 [(set_attr "isa" "*,bmi2")
9851 (set_attr "type" "ishift,ishiftx")
9852 (set (attr "length_immediate")
9854 (and (match_operand 2 "const1_operand" "")
9855 (ior (match_test "TARGET_SHIFT1")
9856 (match_test "optimize_function_for_size_p (cfun)")))
9858 (const_string "*")))
9859 (set_attr "mode" "SI")])
9861 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9863 [(set (match_operand:DI 0 "register_operand" "")
9865 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9866 (match_operand:QI 2 "register_operand" ""))))
9867 (clobber (reg:CC FLAGS_REG))]
9868 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9870 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9871 "operands[2] = gen_lowpart (SImode, operands[2]);")
9873 (define_insn "*<shift_insn><mode>3_1"
9874 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9876 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9877 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9878 (clobber (reg:CC FLAGS_REG))]
9879 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9881 if (operands[2] == const1_rtx
9882 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9883 return "<shift>{<imodesuffix>}\t%0";
9885 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9887 [(set_attr "type" "ishift")
9888 (set (attr "length_immediate")
9890 (and (match_operand 2 "const1_operand" "")
9891 (ior (match_test "TARGET_SHIFT1")
9892 (match_test "optimize_function_for_size_p (cfun)")))
9894 (const_string "*")))
9895 (set_attr "mode" "<MODE>")])
9897 (define_insn "*<shift_insn>qi3_1_slp"
9898 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9899 (any_shiftrt:QI (match_dup 0)
9900 (match_operand:QI 1 "nonmemory_operand" "cI")))
9901 (clobber (reg:CC FLAGS_REG))]
9902 "(optimize_function_for_size_p (cfun)
9903 || !TARGET_PARTIAL_REG_STALL
9904 || (operands[1] == const1_rtx
9907 if (operands[1] == const1_rtx
9908 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9909 return "<shift>{b}\t%0";
9911 return "<shift>{b}\t{%1, %0|%0, %1}";
9913 [(set_attr "type" "ishift1")
9914 (set (attr "length_immediate")
9916 (and (match_operand 1 "const1_operand" "")
9917 (ior (match_test "TARGET_SHIFT1")
9918 (match_test "optimize_function_for_size_p (cfun)")))
9920 (const_string "*")))
9921 (set_attr "mode" "QI")])
9923 ;; This pattern can't accept a variable shift count, since shifts by
9924 ;; zero don't affect the flags. We assume that shifts by constant
9925 ;; zero are optimized away.
9926 (define_insn "*<shift_insn><mode>3_cmp"
9927 [(set (reg FLAGS_REG)
9930 (match_operand:SWI 1 "nonimmediate_operand" "0")
9931 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9933 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9934 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9935 "(optimize_function_for_size_p (cfun)
9936 || !TARGET_PARTIAL_FLAG_REG_STALL
9937 || (operands[2] == const1_rtx
9939 && ix86_match_ccmode (insn, CCGOCmode)
9940 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9942 if (operands[2] == const1_rtx
9943 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9944 return "<shift>{<imodesuffix>}\t%0";
9946 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9948 [(set_attr "type" "ishift")
9949 (set (attr "length_immediate")
9951 (and (match_operand 2 "const1_operand" "")
9952 (ior (match_test "TARGET_SHIFT1")
9953 (match_test "optimize_function_for_size_p (cfun)")))
9955 (const_string "*")))
9956 (set_attr "mode" "<MODE>")])
9958 (define_insn "*<shift_insn>si3_cmp_zext"
9959 [(set (reg FLAGS_REG)
9961 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9962 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9964 (set (match_operand:DI 0 "register_operand" "=r")
9965 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9967 && (optimize_function_for_size_p (cfun)
9968 || !TARGET_PARTIAL_FLAG_REG_STALL
9969 || (operands[2] == const1_rtx
9971 && ix86_match_ccmode (insn, CCGOCmode)
9972 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9974 if (operands[2] == const1_rtx
9975 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9976 return "<shift>{l}\t%k0";
9978 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9980 [(set_attr "type" "ishift")
9981 (set (attr "length_immediate")
9983 (and (match_operand 2 "const1_operand" "")
9984 (ior (match_test "TARGET_SHIFT1")
9985 (match_test "optimize_function_for_size_p (cfun)")))
9987 (const_string "*")))
9988 (set_attr "mode" "SI")])
9990 (define_insn "*<shift_insn><mode>3_cconly"
9991 [(set (reg FLAGS_REG)
9994 (match_operand:SWI 1 "register_operand" "0")
9995 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9997 (clobber (match_scratch:SWI 0 "=<r>"))]
9998 "(optimize_function_for_size_p (cfun)
9999 || !TARGET_PARTIAL_FLAG_REG_STALL
10000 || (operands[2] == const1_rtx
10002 && ix86_match_ccmode (insn, CCGOCmode)"
10004 if (operands[2] == const1_rtx
10005 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10006 return "<shift>{<imodesuffix>}\t%0";
10008 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10010 [(set_attr "type" "ishift")
10011 (set (attr "length_immediate")
10013 (and (match_operand 2 "const1_operand" "")
10014 (ior (match_test "TARGET_SHIFT1")
10015 (match_test "optimize_function_for_size_p (cfun)")))
10017 (const_string "*")))
10018 (set_attr "mode" "<MODE>")])
10020 ;; Rotate instructions
10022 (define_expand "<rotate_insn>ti3"
10023 [(set (match_operand:TI 0 "register_operand" "")
10024 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10025 (match_operand:QI 2 "nonmemory_operand" "")))]
10028 if (const_1_to_63_operand (operands[2], VOIDmode))
10029 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10030 (operands[0], operands[1], operands[2]));
10037 (define_expand "<rotate_insn>di3"
10038 [(set (match_operand:DI 0 "shiftdi_operand" "")
10039 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10040 (match_operand:QI 2 "nonmemory_operand" "")))]
10044 ix86_expand_binary_operator (<CODE>, DImode, operands);
10045 else if (const_1_to_31_operand (operands[2], VOIDmode))
10046 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10047 (operands[0], operands[1], operands[2]));
10054 (define_expand "<rotate_insn><mode>3"
10055 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10056 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10057 (match_operand:QI 2 "nonmemory_operand" "")))]
10059 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10061 ;; Avoid useless masking of count operand.
10062 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10063 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10065 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10068 (match_operand:SI 2 "nonimmediate_operand" "c")
10069 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10070 (clobber (reg:CC FLAGS_REG))]
10071 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10072 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10073 == GET_MODE_BITSIZE (<MODE>mode)-1"
10076 [(parallel [(set (match_dup 0)
10077 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10078 (clobber (reg:CC FLAGS_REG))])]
10080 if (can_create_pseudo_p ())
10081 operands [2] = force_reg (SImode, operands[2]);
10083 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10085 [(set_attr "type" "rotate")
10086 (set_attr "mode" "<MODE>")])
10088 ;; Implement rotation using two double-precision
10089 ;; shift instructions and a scratch register.
10091 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10092 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10093 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10094 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10095 (clobber (reg:CC FLAGS_REG))
10096 (clobber (match_scratch:DWIH 3 "=&r"))]
10100 [(set (match_dup 3) (match_dup 4))
10102 [(set (match_dup 4)
10103 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10104 (lshiftrt:DWIH (match_dup 5)
10105 (minus:QI (match_dup 6) (match_dup 2)))))
10106 (clobber (reg:CC FLAGS_REG))])
10108 [(set (match_dup 5)
10109 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10110 (lshiftrt:DWIH (match_dup 3)
10111 (minus:QI (match_dup 6) (match_dup 2)))))
10112 (clobber (reg:CC FLAGS_REG))])]
10114 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10116 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10119 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10120 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10121 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10122 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10123 (clobber (reg:CC FLAGS_REG))
10124 (clobber (match_scratch:DWIH 3 "=&r"))]
10128 [(set (match_dup 3) (match_dup 4))
10130 [(set (match_dup 4)
10131 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10132 (ashift:DWIH (match_dup 5)
10133 (minus:QI (match_dup 6) (match_dup 2)))))
10134 (clobber (reg:CC FLAGS_REG))])
10136 [(set (match_dup 5)
10137 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10138 (ashift:DWIH (match_dup 3)
10139 (minus:QI (match_dup 6) (match_dup 2)))))
10140 (clobber (reg:CC FLAGS_REG))])]
10142 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10144 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10147 (define_insn "*bmi2_rorx<mode>3_1"
10148 [(set (match_operand:SWI48 0 "register_operand" "=r")
10149 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10150 (match_operand:QI 2 "immediate_operand" "<S>")))]
10152 "rorx\t{%2, %1, %0|%0, %1, %2}"
10153 [(set_attr "type" "rotatex")
10154 (set_attr "mode" "<MODE>")])
10156 (define_insn "*<rotate_insn><mode>3_1"
10157 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10159 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10160 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10161 (clobber (reg:CC FLAGS_REG))]
10162 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10164 switch (get_attr_type (insn))
10170 if (operands[2] == const1_rtx
10171 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10172 return "<rotate>{<imodesuffix>}\t%0";
10174 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10177 [(set_attr "isa" "*,bmi2")
10178 (set_attr "type" "rotate,rotatex")
10179 (set (attr "length_immediate")
10181 (and (eq_attr "type" "rotate")
10182 (and (match_operand 2 "const1_operand" "")
10183 (ior (match_test "TARGET_SHIFT1")
10184 (match_test "optimize_function_for_size_p (cfun)"))))
10186 (const_string "*")))
10187 (set_attr "mode" "<MODE>")])
10189 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10191 [(set (match_operand:SWI48 0 "register_operand" "")
10192 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10193 (match_operand:QI 2 "immediate_operand" "")))
10194 (clobber (reg:CC FLAGS_REG))]
10195 "TARGET_BMI2 && reload_completed"
10196 [(set (match_dup 0)
10197 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10200 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10204 [(set (match_operand:SWI48 0 "register_operand" "")
10205 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10206 (match_operand:QI 2 "immediate_operand" "")))
10207 (clobber (reg:CC FLAGS_REG))]
10208 "TARGET_BMI2 && reload_completed"
10209 [(set (match_dup 0)
10210 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10212 (define_insn "*bmi2_rorxsi3_1_zext"
10213 [(set (match_operand:DI 0 "register_operand" "=r")
10215 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10216 (match_operand:QI 2 "immediate_operand" "I"))))]
10217 "TARGET_64BIT && TARGET_BMI2"
10218 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10219 [(set_attr "type" "rotatex")
10220 (set_attr "mode" "SI")])
10222 (define_insn "*<rotate_insn>si3_1_zext"
10223 [(set (match_operand:DI 0 "register_operand" "=r,r")
10225 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10226 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10227 (clobber (reg:CC FLAGS_REG))]
10228 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10230 switch (get_attr_type (insn))
10236 if (operands[2] == const1_rtx
10237 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10238 return "<rotate>{l}\t%k0";
10240 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10243 [(set_attr "isa" "*,bmi2")
10244 (set_attr "type" "rotate,rotatex")
10245 (set (attr "length_immediate")
10247 (and (eq_attr "type" "rotate")
10248 (and (match_operand 2 "const1_operand" "")
10249 (ior (match_test "TARGET_SHIFT1")
10250 (match_test "optimize_function_for_size_p (cfun)"))))
10252 (const_string "*")))
10253 (set_attr "mode" "SI")])
10255 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10257 [(set (match_operand:DI 0 "register_operand" "")
10259 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10260 (match_operand:QI 2 "immediate_operand" ""))))
10261 (clobber (reg:CC FLAGS_REG))]
10262 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10263 [(set (match_dup 0)
10264 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10267 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10271 [(set (match_operand:DI 0 "register_operand" "")
10273 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10274 (match_operand:QI 2 "immediate_operand" ""))))
10275 (clobber (reg:CC FLAGS_REG))]
10276 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10277 [(set (match_dup 0)
10278 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10280 (define_insn "*<rotate_insn><mode>3_1"
10281 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10282 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10283 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10284 (clobber (reg:CC FLAGS_REG))]
10285 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10287 if (operands[2] == const1_rtx
10288 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10289 return "<rotate>{<imodesuffix>}\t%0";
10291 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10293 [(set_attr "type" "rotate")
10294 (set (attr "length_immediate")
10296 (and (match_operand 2 "const1_operand" "")
10297 (ior (match_test "TARGET_SHIFT1")
10298 (match_test "optimize_function_for_size_p (cfun)")))
10300 (const_string "*")))
10301 (set_attr "mode" "<MODE>")])
10303 (define_insn "*<rotate_insn>qi3_1_slp"
10304 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10305 (any_rotate:QI (match_dup 0)
10306 (match_operand:QI 1 "nonmemory_operand" "cI")))
10307 (clobber (reg:CC FLAGS_REG))]
10308 "(optimize_function_for_size_p (cfun)
10309 || !TARGET_PARTIAL_REG_STALL
10310 || (operands[1] == const1_rtx
10311 && TARGET_SHIFT1))"
10313 if (operands[1] == const1_rtx
10314 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10315 return "<rotate>{b}\t%0";
10317 return "<rotate>{b}\t{%1, %0|%0, %1}";
10319 [(set_attr "type" "rotate1")
10320 (set (attr "length_immediate")
10322 (and (match_operand 1 "const1_operand" "")
10323 (ior (match_test "TARGET_SHIFT1")
10324 (match_test "optimize_function_for_size_p (cfun)")))
10326 (const_string "*")))
10327 (set_attr "mode" "QI")])
10330 [(set (match_operand:HI 0 "register_operand" "")
10331 (any_rotate:HI (match_dup 0) (const_int 8)))
10332 (clobber (reg:CC FLAGS_REG))]
10334 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10335 [(parallel [(set (strict_low_part (match_dup 0))
10336 (bswap:HI (match_dup 0)))
10337 (clobber (reg:CC FLAGS_REG))])])
10339 ;; Bit set / bit test instructions
10341 (define_expand "extv"
10342 [(set (match_operand:SI 0 "register_operand" "")
10343 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10344 (match_operand:SI 2 "const8_operand" "")
10345 (match_operand:SI 3 "const8_operand" "")))]
10348 /* Handle extractions from %ah et al. */
10349 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10352 /* From mips.md: extract_bit_field doesn't verify that our source
10353 matches the predicate, so check it again here. */
10354 if (! ext_register_operand (operands[1], VOIDmode))
10358 (define_expand "extzv"
10359 [(set (match_operand:SI 0 "register_operand" "")
10360 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10361 (match_operand:SI 2 "const8_operand" "")
10362 (match_operand:SI 3 "const8_operand" "")))]
10365 /* Handle extractions from %ah et al. */
10366 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10369 /* From mips.md: extract_bit_field doesn't verify that our source
10370 matches the predicate, so check it again here. */
10371 if (! ext_register_operand (operands[1], VOIDmode))
10375 (define_expand "insv"
10376 [(set (zero_extract (match_operand 0 "register_operand" "")
10377 (match_operand 1 "const_int_operand" "")
10378 (match_operand 2 "const_int_operand" ""))
10379 (match_operand 3 "register_operand" ""))]
10382 rtx (*gen_mov_insv_1) (rtx, rtx);
10384 if (ix86_expand_pinsr (operands))
10387 /* Handle insertions to %ah et al. */
10388 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10391 /* From mips.md: insert_bit_field doesn't verify that our source
10392 matches the predicate, so check it again here. */
10393 if (! ext_register_operand (operands[0], VOIDmode))
10396 gen_mov_insv_1 = (TARGET_64BIT
10397 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10399 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10403 ;; %%% bts, btr, btc, bt.
10404 ;; In general these instructions are *slow* when applied to memory,
10405 ;; since they enforce atomic operation. When applied to registers,
10406 ;; it depends on the cpu implementation. They're never faster than
10407 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10408 ;; no point. But in 64-bit, we can't hold the relevant immediates
10409 ;; within the instruction itself, so operating on bits in the high
10410 ;; 32-bits of a register becomes easier.
10412 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10413 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10414 ;; negdf respectively, so they can never be disabled entirely.
10416 (define_insn "*btsq"
10417 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10419 (match_operand:DI 1 "const_0_to_63_operand" ""))
10421 (clobber (reg:CC FLAGS_REG))]
10422 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10423 "bts{q}\t{%1, %0|%0, %1}"
10424 [(set_attr "type" "alu1")
10425 (set_attr "prefix_0f" "1")
10426 (set_attr "mode" "DI")])
10428 (define_insn "*btrq"
10429 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10431 (match_operand:DI 1 "const_0_to_63_operand" ""))
10433 (clobber (reg:CC FLAGS_REG))]
10434 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10435 "btr{q}\t{%1, %0|%0, %1}"
10436 [(set_attr "type" "alu1")
10437 (set_attr "prefix_0f" "1")
10438 (set_attr "mode" "DI")])
10440 (define_insn "*btcq"
10441 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10443 (match_operand:DI 1 "const_0_to_63_operand" ""))
10444 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10445 (clobber (reg:CC FLAGS_REG))]
10446 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10447 "btc{q}\t{%1, %0|%0, %1}"
10448 [(set_attr "type" "alu1")
10449 (set_attr "prefix_0f" "1")
10450 (set_attr "mode" "DI")])
10452 ;; Allow Nocona to avoid these instructions if a register is available.
10455 [(match_scratch:DI 2 "r")
10456 (parallel [(set (zero_extract:DI
10457 (match_operand:DI 0 "register_operand" "")
10459 (match_operand:DI 1 "const_0_to_63_operand" ""))
10461 (clobber (reg:CC FLAGS_REG))])]
10462 "TARGET_64BIT && !TARGET_USE_BT"
10465 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10468 if (HOST_BITS_PER_WIDE_INT >= 64)
10469 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10470 else if (i < HOST_BITS_PER_WIDE_INT)
10471 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10473 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10475 op1 = immed_double_const (lo, hi, DImode);
10478 emit_move_insn (operands[2], op1);
10482 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10487 [(match_scratch:DI 2 "r")
10488 (parallel [(set (zero_extract:DI
10489 (match_operand:DI 0 "register_operand" "")
10491 (match_operand:DI 1 "const_0_to_63_operand" ""))
10493 (clobber (reg:CC FLAGS_REG))])]
10494 "TARGET_64BIT && !TARGET_USE_BT"
10497 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10500 if (HOST_BITS_PER_WIDE_INT >= 64)
10501 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10502 else if (i < HOST_BITS_PER_WIDE_INT)
10503 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10505 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10507 op1 = immed_double_const (~lo, ~hi, DImode);
10510 emit_move_insn (operands[2], op1);
10514 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10519 [(match_scratch:DI 2 "r")
10520 (parallel [(set (zero_extract:DI
10521 (match_operand:DI 0 "register_operand" "")
10523 (match_operand:DI 1 "const_0_to_63_operand" ""))
10524 (not:DI (zero_extract:DI
10525 (match_dup 0) (const_int 1) (match_dup 1))))
10526 (clobber (reg:CC FLAGS_REG))])]
10527 "TARGET_64BIT && !TARGET_USE_BT"
10530 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10533 if (HOST_BITS_PER_WIDE_INT >= 64)
10534 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10535 else if (i < HOST_BITS_PER_WIDE_INT)
10536 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10538 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10540 op1 = immed_double_const (lo, hi, DImode);
10543 emit_move_insn (operands[2], op1);
10547 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10551 (define_insn "*bt<mode>"
10552 [(set (reg:CCC FLAGS_REG)
10554 (zero_extract:SWI48
10555 (match_operand:SWI48 0 "register_operand" "r")
10557 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10559 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10560 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10561 [(set_attr "type" "alu1")
10562 (set_attr "prefix_0f" "1")
10563 (set_attr "mode" "<MODE>")])
10565 ;; Store-flag instructions.
10567 ;; For all sCOND expanders, also expand the compare or test insn that
10568 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10570 (define_insn_and_split "*setcc_di_1"
10571 [(set (match_operand:DI 0 "register_operand" "=q")
10572 (match_operator:DI 1 "ix86_comparison_operator"
10573 [(reg FLAGS_REG) (const_int 0)]))]
10574 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10576 "&& reload_completed"
10577 [(set (match_dup 2) (match_dup 1))
10578 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10580 PUT_MODE (operands[1], QImode);
10581 operands[2] = gen_lowpart (QImode, operands[0]);
10584 (define_insn_and_split "*setcc_si_1_and"
10585 [(set (match_operand:SI 0 "register_operand" "=q")
10586 (match_operator:SI 1 "ix86_comparison_operator"
10587 [(reg FLAGS_REG) (const_int 0)]))
10588 (clobber (reg:CC FLAGS_REG))]
10589 "!TARGET_PARTIAL_REG_STALL
10590 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10592 "&& reload_completed"
10593 [(set (match_dup 2) (match_dup 1))
10594 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10595 (clobber (reg:CC FLAGS_REG))])]
10597 PUT_MODE (operands[1], QImode);
10598 operands[2] = gen_lowpart (QImode, operands[0]);
10601 (define_insn_and_split "*setcc_si_1_movzbl"
10602 [(set (match_operand:SI 0 "register_operand" "=q")
10603 (match_operator:SI 1 "ix86_comparison_operator"
10604 [(reg FLAGS_REG) (const_int 0)]))]
10605 "!TARGET_PARTIAL_REG_STALL
10606 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10608 "&& reload_completed"
10609 [(set (match_dup 2) (match_dup 1))
10610 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10612 PUT_MODE (operands[1], QImode);
10613 operands[2] = gen_lowpart (QImode, operands[0]);
10616 (define_insn "*setcc_qi"
10617 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10618 (match_operator:QI 1 "ix86_comparison_operator"
10619 [(reg FLAGS_REG) (const_int 0)]))]
10622 [(set_attr "type" "setcc")
10623 (set_attr "mode" "QI")])
10625 (define_insn "*setcc_qi_slp"
10626 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10627 (match_operator:QI 1 "ix86_comparison_operator"
10628 [(reg FLAGS_REG) (const_int 0)]))]
10631 [(set_attr "type" "setcc")
10632 (set_attr "mode" "QI")])
10634 ;; In general it is not safe to assume too much about CCmode registers,
10635 ;; so simplify-rtx stops when it sees a second one. Under certain
10636 ;; conditions this is safe on x86, so help combine not create
10643 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10644 (ne:QI (match_operator 1 "ix86_comparison_operator"
10645 [(reg FLAGS_REG) (const_int 0)])
10648 [(set (match_dup 0) (match_dup 1))]
10649 "PUT_MODE (operands[1], QImode);")
10652 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10653 (ne:QI (match_operator 1 "ix86_comparison_operator"
10654 [(reg FLAGS_REG) (const_int 0)])
10657 [(set (match_dup 0) (match_dup 1))]
10658 "PUT_MODE (operands[1], QImode);")
10661 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10662 (eq:QI (match_operator 1 "ix86_comparison_operator"
10663 [(reg FLAGS_REG) (const_int 0)])
10666 [(set (match_dup 0) (match_dup 1))]
10668 rtx new_op1 = copy_rtx (operands[1]);
10669 operands[1] = new_op1;
10670 PUT_MODE (new_op1, QImode);
10671 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10672 GET_MODE (XEXP (new_op1, 0))));
10674 /* Make sure that (a) the CCmode we have for the flags is strong
10675 enough for the reversed compare or (b) we have a valid FP compare. */
10676 if (! ix86_comparison_operator (new_op1, VOIDmode))
10681 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10682 (eq:QI (match_operator 1 "ix86_comparison_operator"
10683 [(reg FLAGS_REG) (const_int 0)])
10686 [(set (match_dup 0) (match_dup 1))]
10688 rtx new_op1 = copy_rtx (operands[1]);
10689 operands[1] = new_op1;
10690 PUT_MODE (new_op1, QImode);
10691 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10692 GET_MODE (XEXP (new_op1, 0))));
10694 /* Make sure that (a) the CCmode we have for the flags is strong
10695 enough for the reversed compare or (b) we have a valid FP compare. */
10696 if (! ix86_comparison_operator (new_op1, VOIDmode))
10700 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10701 ;; subsequent logical operations are used to imitate conditional moves.
10702 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10705 (define_insn "setcc_<mode>_sse"
10706 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10707 (match_operator:MODEF 3 "sse_comparison_operator"
10708 [(match_operand:MODEF 1 "register_operand" "0,x")
10709 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10710 "SSE_FLOAT_MODE_P (<MODE>mode)"
10712 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10713 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10714 [(set_attr "isa" "noavx,avx")
10715 (set_attr "type" "ssecmp")
10716 (set_attr "length_immediate" "1")
10717 (set_attr "prefix" "orig,vex")
10718 (set_attr "mode" "<MODE>")])
10720 ;; Basic conditional jump instructions.
10721 ;; We ignore the overflow flag for signed branch instructions.
10723 (define_insn "*jcc_1"
10725 (if_then_else (match_operator 1 "ix86_comparison_operator"
10726 [(reg FLAGS_REG) (const_int 0)])
10727 (label_ref (match_operand 0 "" ""))
10731 [(set_attr "type" "ibr")
10732 (set_attr "modrm" "0")
10733 (set (attr "length")
10734 (if_then_else (and (ge (minus (match_dup 0) (pc))
10736 (lt (minus (match_dup 0) (pc))
10741 (define_insn "*jcc_2"
10743 (if_then_else (match_operator 1 "ix86_comparison_operator"
10744 [(reg FLAGS_REG) (const_int 0)])
10746 (label_ref (match_operand 0 "" ""))))]
10749 [(set_attr "type" "ibr")
10750 (set_attr "modrm" "0")
10751 (set (attr "length")
10752 (if_then_else (and (ge (minus (match_dup 0) (pc))
10754 (lt (minus (match_dup 0) (pc))
10759 ;; In general it is not safe to assume too much about CCmode registers,
10760 ;; so simplify-rtx stops when it sees a second one. Under certain
10761 ;; conditions this is safe on x86, so help combine not create
10769 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10770 [(reg FLAGS_REG) (const_int 0)])
10772 (label_ref (match_operand 1 "" ""))
10776 (if_then_else (match_dup 0)
10777 (label_ref (match_dup 1))
10779 "PUT_MODE (operands[0], VOIDmode);")
10783 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10784 [(reg FLAGS_REG) (const_int 0)])
10786 (label_ref (match_operand 1 "" ""))
10790 (if_then_else (match_dup 0)
10791 (label_ref (match_dup 1))
10794 rtx new_op0 = copy_rtx (operands[0]);
10795 operands[0] = new_op0;
10796 PUT_MODE (new_op0, VOIDmode);
10797 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10798 GET_MODE (XEXP (new_op0, 0))));
10800 /* Make sure that (a) the CCmode we have for the flags is strong
10801 enough for the reversed compare or (b) we have a valid FP compare. */
10802 if (! ix86_comparison_operator (new_op0, VOIDmode))
10806 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10807 ;; pass generates from shift insn with QImode operand. Actually, the mode
10808 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10809 ;; appropriate modulo of the bit offset value.
10811 (define_insn_and_split "*jcc_bt<mode>"
10813 (if_then_else (match_operator 0 "bt_comparison_operator"
10814 [(zero_extract:SWI48
10815 (match_operand:SWI48 1 "register_operand" "r")
10818 (match_operand:QI 2 "register_operand" "r")))
10820 (label_ref (match_operand 3 "" ""))
10822 (clobber (reg:CC FLAGS_REG))]
10823 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10826 [(set (reg:CCC FLAGS_REG)
10828 (zero_extract:SWI48
10834 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10835 (label_ref (match_dup 3))
10838 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10840 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10843 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10844 ;; also for DImode, this is what combine produces.
10845 (define_insn_and_split "*jcc_bt<mode>_mask"
10847 (if_then_else (match_operator 0 "bt_comparison_operator"
10848 [(zero_extract:SWI48
10849 (match_operand:SWI48 1 "register_operand" "r")
10852 (match_operand:SI 2 "register_operand" "r")
10853 (match_operand:SI 3 "const_int_operand" "n")))])
10854 (label_ref (match_operand 4 "" ""))
10856 (clobber (reg:CC FLAGS_REG))]
10857 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10858 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10859 == GET_MODE_BITSIZE (<MODE>mode)-1"
10862 [(set (reg:CCC FLAGS_REG)
10864 (zero_extract:SWI48
10870 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10871 (label_ref (match_dup 4))
10874 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10876 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10879 (define_insn_and_split "*jcc_btsi_1"
10881 (if_then_else (match_operator 0 "bt_comparison_operator"
10884 (match_operand:SI 1 "register_operand" "r")
10885 (match_operand:QI 2 "register_operand" "r"))
10888 (label_ref (match_operand 3 "" ""))
10890 (clobber (reg:CC FLAGS_REG))]
10891 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10894 [(set (reg:CCC FLAGS_REG)
10902 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10903 (label_ref (match_dup 3))
10906 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10908 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10911 ;; avoid useless masking of bit offset operand
10912 (define_insn_and_split "*jcc_btsi_mask_1"
10915 (match_operator 0 "bt_comparison_operator"
10918 (match_operand:SI 1 "register_operand" "r")
10921 (match_operand:SI 2 "register_operand" "r")
10922 (match_operand:SI 3 "const_int_operand" "n")) 0))
10925 (label_ref (match_operand 4 "" ""))
10927 (clobber (reg:CC FLAGS_REG))]
10928 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10929 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10932 [(set (reg:CCC FLAGS_REG)
10940 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10941 (label_ref (match_dup 4))
10943 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10945 ;; Define combination compare-and-branch fp compare instructions to help
10948 (define_insn "*fp_jcc_1_387"
10950 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10951 [(match_operand 1 "register_operand" "f")
10952 (match_operand 2 "nonimmediate_operand" "fm")])
10953 (label_ref (match_operand 3 "" ""))
10955 (clobber (reg:CCFP FPSR_REG))
10956 (clobber (reg:CCFP FLAGS_REG))
10957 (clobber (match_scratch:HI 4 "=a"))]
10959 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10960 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10961 && SELECT_CC_MODE (GET_CODE (operands[0]),
10962 operands[1], operands[2]) == CCFPmode
10966 (define_insn "*fp_jcc_1r_387"
10968 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10969 [(match_operand 1 "register_operand" "f")
10970 (match_operand 2 "nonimmediate_operand" "fm")])
10972 (label_ref (match_operand 3 "" ""))))
10973 (clobber (reg:CCFP FPSR_REG))
10974 (clobber (reg:CCFP FLAGS_REG))
10975 (clobber (match_scratch:HI 4 "=a"))]
10977 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10978 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10979 && SELECT_CC_MODE (GET_CODE (operands[0]),
10980 operands[1], operands[2]) == CCFPmode
10984 (define_insn "*fp_jcc_2_387"
10986 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10987 [(match_operand 1 "register_operand" "f")
10988 (match_operand 2 "register_operand" "f")])
10989 (label_ref (match_operand 3 "" ""))
10991 (clobber (reg:CCFP FPSR_REG))
10992 (clobber (reg:CCFP FLAGS_REG))
10993 (clobber (match_scratch:HI 4 "=a"))]
10994 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10995 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10999 (define_insn "*fp_jcc_2r_387"
11001 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11002 [(match_operand 1 "register_operand" "f")
11003 (match_operand 2 "register_operand" "f")])
11005 (label_ref (match_operand 3 "" ""))))
11006 (clobber (reg:CCFP FPSR_REG))
11007 (clobber (reg:CCFP FLAGS_REG))
11008 (clobber (match_scratch:HI 4 "=a"))]
11009 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11010 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11014 (define_insn "*fp_jcc_3_387"
11016 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11017 [(match_operand 1 "register_operand" "f")
11018 (match_operand 2 "const0_operand" "")])
11019 (label_ref (match_operand 3 "" ""))
11021 (clobber (reg:CCFP FPSR_REG))
11022 (clobber (reg:CCFP FLAGS_REG))
11023 (clobber (match_scratch:HI 4 "=a"))]
11024 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11025 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11026 && SELECT_CC_MODE (GET_CODE (operands[0]),
11027 operands[1], operands[2]) == CCFPmode
11033 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11034 [(match_operand 1 "register_operand" "")
11035 (match_operand 2 "nonimmediate_operand" "")])
11036 (match_operand 3 "" "")
11037 (match_operand 4 "" "")))
11038 (clobber (reg:CCFP FPSR_REG))
11039 (clobber (reg:CCFP FLAGS_REG))]
11043 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11044 operands[3], operands[4], NULL_RTX, NULL_RTX);
11050 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11051 [(match_operand 1 "register_operand" "")
11052 (match_operand 2 "general_operand" "")])
11053 (match_operand 3 "" "")
11054 (match_operand 4 "" "")))
11055 (clobber (reg:CCFP FPSR_REG))
11056 (clobber (reg:CCFP FLAGS_REG))
11057 (clobber (match_scratch:HI 5 "=a"))]
11061 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11062 operands[3], operands[4], operands[5], NULL_RTX);
11066 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11067 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11068 ;; with a precedence over other operators and is always put in the first
11069 ;; place. Swap condition and operands to match ficom instruction.
11071 (define_insn "*fp_jcc_4_<mode>_387"
11074 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11075 [(match_operator 1 "float_operator"
11076 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11077 (match_operand 3 "register_operand" "f,f")])
11078 (label_ref (match_operand 4 "" ""))
11080 (clobber (reg:CCFP FPSR_REG))
11081 (clobber (reg:CCFP FLAGS_REG))
11082 (clobber (match_scratch:HI 5 "=a,a"))]
11083 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11084 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11085 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11086 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11093 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11094 [(match_operator 1 "float_operator"
11095 [(match_operand:SWI24 2 "memory_operand" "")])
11096 (match_operand 3 "register_operand" "")])
11097 (match_operand 4 "" "")
11098 (match_operand 5 "" "")))
11099 (clobber (reg:CCFP FPSR_REG))
11100 (clobber (reg:CCFP FLAGS_REG))
11101 (clobber (match_scratch:HI 6 "=a"))]
11105 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11107 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11108 operands[3], operands[7],
11109 operands[4], operands[5], operands[6], NULL_RTX);
11113 ;; %%% Kill this when reload knows how to do it.
11117 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11118 [(match_operator 1 "float_operator"
11119 [(match_operand:SWI24 2 "register_operand" "")])
11120 (match_operand 3 "register_operand" "")])
11121 (match_operand 4 "" "")
11122 (match_operand 5 "" "")))
11123 (clobber (reg:CCFP FPSR_REG))
11124 (clobber (reg:CCFP FLAGS_REG))
11125 (clobber (match_scratch:HI 6 "=a"))]
11129 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11130 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11132 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11133 operands[3], operands[7],
11134 operands[4], operands[5], operands[6], operands[2]);
11138 ;; Unconditional and other jump instructions
11140 (define_insn "jump"
11142 (label_ref (match_operand 0 "" "")))]
11145 [(set_attr "type" "ibr")
11146 (set (attr "length")
11147 (if_then_else (and (ge (minus (match_dup 0) (pc))
11149 (lt (minus (match_dup 0) (pc))
11153 (set_attr "modrm" "0")])
11155 (define_expand "indirect_jump"
11156 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11158 (define_insn "*indirect_jump"
11159 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11162 [(set_attr "type" "ibr")
11163 (set_attr "length_immediate" "0")])
11165 (define_expand "tablejump"
11166 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11167 (use (label_ref (match_operand 1 "" "")))])]
11170 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11171 relative. Convert the relative address to an absolute address. */
11175 enum rtx_code code;
11177 /* We can't use @GOTOFF for text labels on VxWorks;
11178 see gotoff_operand. */
11179 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11183 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11185 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11189 op1 = pic_offset_table_rtx;
11194 op0 = pic_offset_table_rtx;
11198 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11201 else if (TARGET_X32)
11202 operands[0] = convert_memory_address (Pmode, operands[0]);
11205 (define_insn "*tablejump_1"
11206 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11207 (use (label_ref (match_operand 1 "" "")))]
11210 [(set_attr "type" "ibr")
11211 (set_attr "length_immediate" "0")])
11213 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11216 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11217 (set (match_operand:QI 1 "register_operand" "")
11218 (match_operator:QI 2 "ix86_comparison_operator"
11219 [(reg FLAGS_REG) (const_int 0)]))
11220 (set (match_operand 3 "q_regs_operand" "")
11221 (zero_extend (match_dup 1)))]
11222 "(peep2_reg_dead_p (3, operands[1])
11223 || operands_match_p (operands[1], operands[3]))
11224 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11225 [(set (match_dup 4) (match_dup 0))
11226 (set (strict_low_part (match_dup 5))
11229 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11230 operands[5] = gen_lowpart (QImode, operands[3]);
11231 ix86_expand_clear (operands[3]);
11234 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11237 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11238 (set (match_operand:QI 1 "register_operand" "")
11239 (match_operator:QI 2 "ix86_comparison_operator"
11240 [(reg FLAGS_REG) (const_int 0)]))
11241 (parallel [(set (match_operand 3 "q_regs_operand" "")
11242 (zero_extend (match_dup 1)))
11243 (clobber (reg:CC FLAGS_REG))])]
11244 "(peep2_reg_dead_p (3, operands[1])
11245 || operands_match_p (operands[1], operands[3]))
11246 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11247 [(set (match_dup 4) (match_dup 0))
11248 (set (strict_low_part (match_dup 5))
11251 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11252 operands[5] = gen_lowpart (QImode, operands[3]);
11253 ix86_expand_clear (operands[3]);
11256 ;; Call instructions.
11258 ;; The predicates normally associated with named expanders are not properly
11259 ;; checked for calls. This is a bug in the generic code, but it isn't that
11260 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11262 ;; P6 processors will jump to the address after the decrement when %esp
11263 ;; is used as a call operand, so they will execute return address as a code.
11264 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11266 ;; Register constraint for call instruction.
11267 (define_mode_attr c [(SI "l") (DI "r")])
11269 ;; Call subroutine returning no value.
11271 (define_expand "call"
11272 [(call (match_operand:QI 0 "" "")
11273 (match_operand 1 "" ""))
11274 (use (match_operand 2 "" ""))]
11277 ix86_expand_call (NULL, operands[0], operands[1],
11278 operands[2], NULL, false);
11282 (define_expand "sibcall"
11283 [(call (match_operand:QI 0 "" "")
11284 (match_operand 1 "" ""))
11285 (use (match_operand 2 "" ""))]
11288 ix86_expand_call (NULL, operands[0], operands[1],
11289 operands[2], NULL, true);
11293 (define_insn_and_split "*call_vzeroupper"
11294 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11295 (match_operand 1 "" ""))
11296 (unspec [(match_operand 2 "const_int_operand" "")]
11297 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11298 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11300 "&& reload_completed"
11302 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11303 [(set_attr "type" "call")])
11305 (define_insn "*call"
11306 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11307 (match_operand 1 "" ""))]
11308 "!SIBLING_CALL_P (insn)"
11309 "* return ix86_output_call_insn (insn, operands[0]);"
11310 [(set_attr "type" "call")])
11312 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11313 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11314 (match_operand 1 "" ""))
11315 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11316 (clobber (reg:TI XMM6_REG))
11317 (clobber (reg:TI XMM7_REG))
11318 (clobber (reg:TI XMM8_REG))
11319 (clobber (reg:TI XMM9_REG))
11320 (clobber (reg:TI XMM10_REG))
11321 (clobber (reg:TI XMM11_REG))
11322 (clobber (reg:TI XMM12_REG))
11323 (clobber (reg:TI XMM13_REG))
11324 (clobber (reg:TI XMM14_REG))
11325 (clobber (reg:TI XMM15_REG))
11326 (clobber (reg:DI SI_REG))
11327 (clobber (reg:DI DI_REG))
11328 (unspec [(match_operand 2 "const_int_operand" "")]
11329 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11330 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11332 "&& reload_completed"
11334 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11335 [(set_attr "type" "call")])
11337 (define_insn "*call_rex64_ms_sysv"
11338 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11339 (match_operand 1 "" ""))
11340 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11341 (clobber (reg:TI XMM6_REG))
11342 (clobber (reg:TI XMM7_REG))
11343 (clobber (reg:TI XMM8_REG))
11344 (clobber (reg:TI XMM9_REG))
11345 (clobber (reg:TI XMM10_REG))
11346 (clobber (reg:TI XMM11_REG))
11347 (clobber (reg:TI XMM12_REG))
11348 (clobber (reg:TI XMM13_REG))
11349 (clobber (reg:TI XMM14_REG))
11350 (clobber (reg:TI XMM15_REG))
11351 (clobber (reg:DI SI_REG))
11352 (clobber (reg:DI DI_REG))]
11353 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11354 "* return ix86_output_call_insn (insn, operands[0]);"
11355 [(set_attr "type" "call")])
11357 (define_insn_and_split "*sibcall_vzeroupper"
11358 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11359 (match_operand 1 "" ""))
11360 (unspec [(match_operand 2 "const_int_operand" "")]
11361 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11362 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11364 "&& reload_completed"
11366 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11367 [(set_attr "type" "call")])
11369 (define_insn "*sibcall"
11370 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11371 (match_operand 1 "" ""))]
11372 "SIBLING_CALL_P (insn)"
11373 "* return ix86_output_call_insn (insn, operands[0]);"
11374 [(set_attr "type" "call")])
11376 (define_expand "call_pop"
11377 [(parallel [(call (match_operand:QI 0 "" "")
11378 (match_operand:SI 1 "" ""))
11379 (set (reg:SI SP_REG)
11380 (plus:SI (reg:SI SP_REG)
11381 (match_operand:SI 3 "" "")))])]
11384 ix86_expand_call (NULL, operands[0], operands[1],
11385 operands[2], operands[3], false);
11389 (define_insn_and_split "*call_pop_vzeroupper"
11390 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11391 (match_operand:SI 1 "" ""))
11392 (set (reg:SI SP_REG)
11393 (plus:SI (reg:SI SP_REG)
11394 (match_operand:SI 2 "immediate_operand" "i")))
11395 (unspec [(match_operand 3 "const_int_operand" "")]
11396 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11397 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11399 "&& reload_completed"
11401 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11402 [(set_attr "type" "call")])
11404 (define_insn "*call_pop"
11405 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11406 (match_operand 1 "" ""))
11407 (set (reg:SI SP_REG)
11408 (plus:SI (reg:SI SP_REG)
11409 (match_operand:SI 2 "immediate_operand" "i")))]
11410 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11411 "* return ix86_output_call_insn (insn, operands[0]);"
11412 [(set_attr "type" "call")])
11414 (define_insn_and_split "*sibcall_pop_vzeroupper"
11415 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11416 (match_operand 1 "" ""))
11417 (set (reg:SI SP_REG)
11418 (plus:SI (reg:SI SP_REG)
11419 (match_operand:SI 2 "immediate_operand" "i")))
11420 (unspec [(match_operand 3 "const_int_operand" "")]
11421 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11422 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11424 "&& reload_completed"
11426 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11427 [(set_attr "type" "call")])
11429 (define_insn "*sibcall_pop"
11430 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11431 (match_operand 1 "" ""))
11432 (set (reg:SI SP_REG)
11433 (plus:SI (reg:SI SP_REG)
11434 (match_operand:SI 2 "immediate_operand" "i")))]
11435 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11436 "* return ix86_output_call_insn (insn, operands[0]);"
11437 [(set_attr "type" "call")])
11439 ;; Call subroutine, returning value in operand 0
11441 (define_expand "call_value"
11442 [(set (match_operand 0 "" "")
11443 (call (match_operand:QI 1 "" "")
11444 (match_operand 2 "" "")))
11445 (use (match_operand 3 "" ""))]
11448 ix86_expand_call (operands[0], operands[1], operands[2],
11449 operands[3], NULL, false);
11453 (define_expand "sibcall_value"
11454 [(set (match_operand 0 "" "")
11455 (call (match_operand:QI 1 "" "")
11456 (match_operand 2 "" "")))
11457 (use (match_operand 3 "" ""))]
11460 ix86_expand_call (operands[0], operands[1], operands[2],
11461 operands[3], NULL, true);
11465 (define_insn_and_split "*call_value_vzeroupper"
11466 [(set (match_operand 0 "" "")
11467 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11468 (match_operand 2 "" "")))
11469 (unspec [(match_operand 3 "const_int_operand" "")]
11470 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11471 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11473 "&& reload_completed"
11475 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11476 [(set_attr "type" "callv")])
11478 (define_insn "*call_value"
11479 [(set (match_operand 0 "" "")
11480 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11481 (match_operand 2 "" "")))]
11482 "!SIBLING_CALL_P (insn)"
11483 "* return ix86_output_call_insn (insn, operands[1]);"
11484 [(set_attr "type" "callv")])
11486 (define_insn_and_split "*sibcall_value_vzeroupper"
11487 [(set (match_operand 0 "" "")
11488 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11489 (match_operand 2 "" "")))
11490 (unspec [(match_operand 3 "const_int_operand" "")]
11491 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11492 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11494 "&& reload_completed"
11496 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11497 [(set_attr "type" "callv")])
11499 (define_insn "*sibcall_value"
11500 [(set (match_operand 0 "" "")
11501 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11502 (match_operand 2 "" "")))]
11503 "SIBLING_CALL_P (insn)"
11504 "* return ix86_output_call_insn (insn, operands[1]);"
11505 [(set_attr "type" "callv")])
11507 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11508 [(set (match_operand 0 "" "")
11509 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11510 (match_operand 2 "" "")))
11511 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11512 (clobber (reg:TI XMM6_REG))
11513 (clobber (reg:TI XMM7_REG))
11514 (clobber (reg:TI XMM8_REG))
11515 (clobber (reg:TI XMM9_REG))
11516 (clobber (reg:TI XMM10_REG))
11517 (clobber (reg:TI XMM11_REG))
11518 (clobber (reg:TI XMM12_REG))
11519 (clobber (reg:TI XMM13_REG))
11520 (clobber (reg:TI XMM14_REG))
11521 (clobber (reg:TI XMM15_REG))
11522 (clobber (reg:DI SI_REG))
11523 (clobber (reg:DI DI_REG))
11524 (unspec [(match_operand 3 "const_int_operand" "")]
11525 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11526 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11528 "&& reload_completed"
11530 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11531 [(set_attr "type" "callv")])
11533 (define_insn "*call_value_rex64_ms_sysv"
11534 [(set (match_operand 0 "" "")
11535 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11536 (match_operand 2 "" "")))
11537 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11538 (clobber (reg:TI XMM6_REG))
11539 (clobber (reg:TI XMM7_REG))
11540 (clobber (reg:TI XMM8_REG))
11541 (clobber (reg:TI XMM9_REG))
11542 (clobber (reg:TI XMM10_REG))
11543 (clobber (reg:TI XMM11_REG))
11544 (clobber (reg:TI XMM12_REG))
11545 (clobber (reg:TI XMM13_REG))
11546 (clobber (reg:TI XMM14_REG))
11547 (clobber (reg:TI XMM15_REG))
11548 (clobber (reg:DI SI_REG))
11549 (clobber (reg:DI DI_REG))]
11550 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11551 "* return ix86_output_call_insn (insn, operands[1]);"
11552 [(set_attr "type" "callv")])
11554 (define_expand "call_value_pop"
11555 [(parallel [(set (match_operand 0 "" "")
11556 (call (match_operand:QI 1 "" "")
11557 (match_operand:SI 2 "" "")))
11558 (set (reg:SI SP_REG)
11559 (plus:SI (reg:SI SP_REG)
11560 (match_operand:SI 4 "" "")))])]
11563 ix86_expand_call (operands[0], operands[1], operands[2],
11564 operands[3], operands[4], false);
11568 (define_insn_and_split "*call_value_pop_vzeroupper"
11569 [(set (match_operand 0 "" "")
11570 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11571 (match_operand 2 "" "")))
11572 (set (reg:SI SP_REG)
11573 (plus:SI (reg:SI SP_REG)
11574 (match_operand:SI 3 "immediate_operand" "i")))
11575 (unspec [(match_operand 4 "const_int_operand" "")]
11576 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11577 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11579 "&& reload_completed"
11581 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11582 [(set_attr "type" "callv")])
11584 (define_insn "*call_value_pop"
11585 [(set (match_operand 0 "" "")
11586 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11587 (match_operand 2 "" "")))
11588 (set (reg:SI SP_REG)
11589 (plus:SI (reg:SI SP_REG)
11590 (match_operand:SI 3 "immediate_operand" "i")))]
11591 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11592 "* return ix86_output_call_insn (insn, operands[1]);"
11593 [(set_attr "type" "callv")])
11595 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11596 [(set (match_operand 0 "" "")
11597 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11598 (match_operand 2 "" "")))
11599 (set (reg:SI SP_REG)
11600 (plus:SI (reg:SI SP_REG)
11601 (match_operand:SI 3 "immediate_operand" "i")))
11602 (unspec [(match_operand 4 "const_int_operand" "")]
11603 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11604 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11606 "&& reload_completed"
11608 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11609 [(set_attr "type" "callv")])
11611 (define_insn "*sibcall_value_pop"
11612 [(set (match_operand 0 "" "")
11613 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11614 (match_operand 2 "" "")))
11615 (set (reg:SI SP_REG)
11616 (plus:SI (reg:SI SP_REG)
11617 (match_operand:SI 3 "immediate_operand" "i")))]
11618 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11619 "* return ix86_output_call_insn (insn, operands[1]);"
11620 [(set_attr "type" "callv")])
11622 ;; Call subroutine returning any type.
11624 (define_expand "untyped_call"
11625 [(parallel [(call (match_operand 0 "" "")
11627 (match_operand 1 "" "")
11628 (match_operand 2 "" "")])]
11633 /* In order to give reg-stack an easier job in validating two
11634 coprocessor registers as containing a possible return value,
11635 simply pretend the untyped call returns a complex long double
11638 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11639 and should have the default ABI. */
11641 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11642 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11643 operands[0], const0_rtx,
11644 GEN_INT ((TARGET_64BIT
11645 ? (ix86_abi == SYSV_ABI
11646 ? X86_64_SSE_REGPARM_MAX
11647 : X86_64_MS_SSE_REGPARM_MAX)
11648 : X86_32_SSE_REGPARM_MAX)
11652 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11654 rtx set = XVECEXP (operands[2], 0, i);
11655 emit_move_insn (SET_DEST (set), SET_SRC (set));
11658 /* The optimizer does not know that the call sets the function value
11659 registers we stored in the result block. We avoid problems by
11660 claiming that all hard registers are used and clobbered at this
11662 emit_insn (gen_blockage ());
11667 ;; Prologue and epilogue instructions
11669 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11670 ;; all of memory. This blocks insns from being moved across this point.
11672 (define_insn "blockage"
11673 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11676 [(set_attr "length" "0")])
11678 ;; Do not schedule instructions accessing memory across this point.
11680 (define_expand "memory_blockage"
11681 [(set (match_dup 0)
11682 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11685 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11686 MEM_VOLATILE_P (operands[0]) = 1;
11689 (define_insn "*memory_blockage"
11690 [(set (match_operand:BLK 0 "" "")
11691 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11694 [(set_attr "length" "0")])
11696 ;; As USE insns aren't meaningful after reload, this is used instead
11697 ;; to prevent deleting instructions setting registers for PIC code
11698 (define_insn "prologue_use"
11699 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11702 [(set_attr "length" "0")])
11704 ;; Insn emitted into the body of a function to return from a function.
11705 ;; This is only done if the function's epilogue is known to be simple.
11706 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11708 (define_expand "return"
11710 "ix86_can_use_return_insn_p ()"
11712 ix86_maybe_emit_epilogue_vzeroupper ();
11713 if (crtl->args.pops_args)
11715 rtx popc = GEN_INT (crtl->args.pops_args);
11716 emit_jump_insn (gen_simple_return_pop_internal (popc));
11721 ;; We need to disable this for TARGET_SEH, as otherwise
11722 ;; shrink-wrapped prologue gets enabled too. This might exceed
11723 ;; the maximum size of prologue in unwind information.
11725 (define_expand "simple_return"
11729 ix86_maybe_emit_epilogue_vzeroupper ();
11730 if (crtl->args.pops_args)
11732 rtx popc = GEN_INT (crtl->args.pops_args);
11733 emit_jump_insn (gen_simple_return_pop_internal (popc));
11738 (define_insn "simple_return_internal"
11742 [(set_attr "length" "1")
11743 (set_attr "atom_unit" "jeu")
11744 (set_attr "length_immediate" "0")
11745 (set_attr "modrm" "0")])
11747 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11748 ;; instruction Athlon and K8 have.
11750 (define_insn "simple_return_internal_long"
11752 (unspec [(const_int 0)] UNSPEC_REP)]
11755 [(set_attr "length" "2")
11756 (set_attr "atom_unit" "jeu")
11757 (set_attr "length_immediate" "0")
11758 (set_attr "prefix_rep" "1")
11759 (set_attr "modrm" "0")])
11761 (define_insn "simple_return_pop_internal"
11763 (use (match_operand:SI 0 "const_int_operand" ""))]
11766 [(set_attr "length" "3")
11767 (set_attr "atom_unit" "jeu")
11768 (set_attr "length_immediate" "2")
11769 (set_attr "modrm" "0")])
11771 (define_insn "simple_return_indirect_internal"
11773 (use (match_operand:SI 0 "register_operand" "r"))]
11776 [(set_attr "type" "ibr")
11777 (set_attr "length_immediate" "0")])
11783 [(set_attr "length" "1")
11784 (set_attr "length_immediate" "0")
11785 (set_attr "modrm" "0")])
11787 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11788 (define_insn "nops"
11789 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11793 int num = INTVAL (operands[0]);
11795 gcc_assert (num >= 1 && num <= 8);
11798 fputs ("\tnop\n", asm_out_file);
11802 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11803 (set_attr "length_immediate" "0")
11804 (set_attr "modrm" "0")])
11806 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11807 ;; branch prediction penalty for the third jump in a 16-byte
11811 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11814 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11815 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11817 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11818 The align insn is used to avoid 3 jump instructions in the row to improve
11819 branch prediction and the benefits hardly outweigh the cost of extra 8
11820 nops on the average inserted by full alignment pseudo operation. */
11824 [(set_attr "length" "16")])
11826 (define_expand "prologue"
11829 "ix86_expand_prologue (); DONE;")
11831 (define_insn "set_got"
11832 [(set (match_operand:SI 0 "register_operand" "=r")
11833 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11834 (clobber (reg:CC FLAGS_REG))]
11836 "* return output_set_got (operands[0], NULL_RTX);"
11837 [(set_attr "type" "multi")
11838 (set_attr "length" "12")])
11840 (define_insn "set_got_labelled"
11841 [(set (match_operand:SI 0 "register_operand" "=r")
11842 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11844 (clobber (reg:CC FLAGS_REG))]
11846 "* return output_set_got (operands[0], operands[1]);"
11847 [(set_attr "type" "multi")
11848 (set_attr "length" "12")])
11850 (define_insn "set_got_rex64"
11851 [(set (match_operand:DI 0 "register_operand" "=r")
11852 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11854 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11855 [(set_attr "type" "lea")
11856 (set_attr "length_address" "4")
11857 (set_attr "mode" "DI")])
11859 (define_insn "set_rip_rex64"
11860 [(set (match_operand:DI 0 "register_operand" "=r")
11861 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11863 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11864 [(set_attr "type" "lea")
11865 (set_attr "length_address" "4")
11866 (set_attr "mode" "DI")])
11868 (define_insn "set_got_offset_rex64"
11869 [(set (match_operand:DI 0 "register_operand" "=r")
11871 [(label_ref (match_operand 1 "" ""))]
11872 UNSPEC_SET_GOT_OFFSET))]
11874 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11875 [(set_attr "type" "imov")
11876 (set_attr "length_immediate" "0")
11877 (set_attr "length_address" "8")
11878 (set_attr "mode" "DI")])
11880 (define_expand "epilogue"
11883 "ix86_expand_epilogue (1); DONE;")
11885 (define_expand "sibcall_epilogue"
11888 "ix86_expand_epilogue (0); DONE;")
11890 (define_expand "eh_return"
11891 [(use (match_operand 0 "register_operand" ""))]
11894 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11896 /* Tricky bit: we write the address of the handler to which we will
11897 be returning into someone else's stack frame, one word below the
11898 stack address we wish to restore. */
11899 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11900 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11901 tmp = gen_rtx_MEM (Pmode, tmp);
11902 emit_move_insn (tmp, ra);
11904 emit_jump_insn (gen_eh_return_internal ());
11909 (define_insn_and_split "eh_return_internal"
11913 "epilogue_completed"
11915 "ix86_expand_epilogue (2); DONE;")
11917 (define_insn "leave"
11918 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11919 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11920 (clobber (mem:BLK (scratch)))]
11923 [(set_attr "type" "leave")])
11925 (define_insn "leave_rex64"
11926 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11927 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11928 (clobber (mem:BLK (scratch)))]
11931 [(set_attr "type" "leave")])
11933 ;; Handle -fsplit-stack.
11935 (define_expand "split_stack_prologue"
11939 ix86_expand_split_stack_prologue ();
11943 ;; In order to support the call/return predictor, we use a return
11944 ;; instruction which the middle-end doesn't see.
11945 (define_insn "split_stack_return"
11946 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11947 UNSPECV_SPLIT_STACK_RETURN)]
11950 if (operands[0] == const0_rtx)
11955 [(set_attr "atom_unit" "jeu")
11956 (set_attr "modrm" "0")
11957 (set (attr "length")
11958 (if_then_else (match_operand:SI 0 "const0_operand" "")
11961 (set (attr "length_immediate")
11962 (if_then_else (match_operand:SI 0 "const0_operand" "")
11966 ;; If there are operand 0 bytes available on the stack, jump to
11969 (define_expand "split_stack_space_check"
11970 [(set (pc) (if_then_else
11971 (ltu (minus (reg SP_REG)
11972 (match_operand 0 "register_operand" ""))
11973 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11974 (label_ref (match_operand 1 "" ""))
11978 rtx reg, size, limit;
11980 reg = gen_reg_rtx (Pmode);
11981 size = force_reg (Pmode, operands[0]);
11982 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11983 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11984 UNSPEC_STACK_CHECK);
11985 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11986 ix86_expand_branch (GEU, reg, limit, operands[1]);
11991 ;; Bit manipulation instructions.
11993 (define_expand "ffs<mode>2"
11994 [(set (match_dup 2) (const_int -1))
11995 (parallel [(set (reg:CCZ FLAGS_REG)
11997 (match_operand:SWI48 1 "nonimmediate_operand" "")
11999 (set (match_operand:SWI48 0 "register_operand" "")
12000 (ctz:SWI48 (match_dup 1)))])
12001 (set (match_dup 0) (if_then_else:SWI48
12002 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12005 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12006 (clobber (reg:CC FLAGS_REG))])]
12009 if (<MODE>mode == SImode && !TARGET_CMOVE)
12011 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12014 operands[2] = gen_reg_rtx (<MODE>mode);
12017 (define_insn_and_split "ffssi2_no_cmove"
12018 [(set (match_operand:SI 0 "register_operand" "=r")
12019 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12020 (clobber (match_scratch:SI 2 "=&q"))
12021 (clobber (reg:CC FLAGS_REG))]
12024 "&& reload_completed"
12025 [(parallel [(set (reg:CCZ FLAGS_REG)
12026 (compare:CCZ (match_dup 1) (const_int 0)))
12027 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12028 (set (strict_low_part (match_dup 3))
12029 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12030 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12031 (clobber (reg:CC FLAGS_REG))])
12032 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12033 (clobber (reg:CC FLAGS_REG))])
12034 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12035 (clobber (reg:CC FLAGS_REG))])]
12037 operands[3] = gen_lowpart (QImode, operands[2]);
12038 ix86_expand_clear (operands[2]);
12041 (define_insn "*ffs<mode>_1"
12042 [(set (reg:CCZ FLAGS_REG)
12043 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12045 (set (match_operand:SWI48 0 "register_operand" "=r")
12046 (ctz:SWI48 (match_dup 1)))]
12048 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12049 [(set_attr "type" "alu1")
12050 (set_attr "prefix_0f" "1")
12051 (set_attr "mode" "<MODE>")])
12053 (define_insn "ctz<mode>2"
12054 [(set (match_operand:SWI248 0 "register_operand" "=r")
12055 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12056 (clobber (reg:CC FLAGS_REG))]
12060 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12062 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12064 [(set_attr "type" "alu1")
12065 (set_attr "prefix_0f" "1")
12066 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12067 (set_attr "mode" "<MODE>")])
12069 (define_expand "clz<mode>2"
12071 [(set (match_operand:SWI248 0 "register_operand" "")
12074 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12075 (clobber (reg:CC FLAGS_REG))])
12077 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12078 (clobber (reg:CC FLAGS_REG))])]
12083 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12086 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12089 (define_insn "clz<mode>2_lzcnt"
12090 [(set (match_operand:SWI248 0 "register_operand" "=r")
12091 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12092 (clobber (reg:CC FLAGS_REG))]
12094 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12095 [(set_attr "prefix_rep" "1")
12096 (set_attr "type" "bitmanip")
12097 (set_attr "mode" "<MODE>")])
12099 ;; BMI instructions.
12100 (define_insn "*bmi_andn_<mode>"
12101 [(set (match_operand:SWI48 0 "register_operand" "=r")
12104 (match_operand:SWI48 1 "register_operand" "r"))
12105 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12106 (clobber (reg:CC FLAGS_REG))]
12108 "andn\t{%2, %1, %0|%0, %1, %2}"
12109 [(set_attr "type" "bitmanip")
12110 (set_attr "mode" "<MODE>")])
12112 (define_insn "bmi_bextr_<mode>"
12113 [(set (match_operand:SWI48 0 "register_operand" "=r")
12114 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12115 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12117 (clobber (reg:CC FLAGS_REG))]
12119 "bextr\t{%2, %1, %0|%0, %1, %2}"
12120 [(set_attr "type" "bitmanip")
12121 (set_attr "mode" "<MODE>")])
12123 (define_insn "*bmi_blsi_<mode>"
12124 [(set (match_operand:SWI48 0 "register_operand" "=r")
12127 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12129 (clobber (reg:CC FLAGS_REG))]
12131 "blsi\t{%1, %0|%0, %1}"
12132 [(set_attr "type" "bitmanip")
12133 (set_attr "mode" "<MODE>")])
12135 (define_insn "*bmi_blsmsk_<mode>"
12136 [(set (match_operand:SWI48 0 "register_operand" "=r")
12139 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12142 (clobber (reg:CC FLAGS_REG))]
12144 "blsmsk\t{%1, %0|%0, %1}"
12145 [(set_attr "type" "bitmanip")
12146 (set_attr "mode" "<MODE>")])
12148 (define_insn "*bmi_blsr_<mode>"
12149 [(set (match_operand:SWI48 0 "register_operand" "=r")
12152 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12155 (clobber (reg:CC FLAGS_REG))]
12157 "blsr\t{%1, %0|%0, %1}"
12158 [(set_attr "type" "bitmanip")
12159 (set_attr "mode" "<MODE>")])
12161 ;; BMI2 instructions.
12162 (define_insn "bmi2_bzhi_<mode>3"
12163 [(set (match_operand:SWI48 0 "register_operand" "=r")
12164 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12165 (lshiftrt:SWI48 (const_int -1)
12166 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12167 (clobber (reg:CC FLAGS_REG))]
12169 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12170 [(set_attr "type" "bitmanip")
12171 (set_attr "prefix" "vex")
12172 (set_attr "mode" "<MODE>")])
12174 (define_insn "bmi2_pdep_<mode>3"
12175 [(set (match_operand:SWI48 0 "register_operand" "=r")
12176 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12177 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12180 "pdep\t{%2, %1, %0|%0, %1, %2}"
12181 [(set_attr "type" "bitmanip")
12182 (set_attr "prefix" "vex")
12183 (set_attr "mode" "<MODE>")])
12185 (define_insn "bmi2_pext_<mode>3"
12186 [(set (match_operand:SWI48 0 "register_operand" "=r")
12187 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12188 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12191 "pext\t{%2, %1, %0|%0, %1, %2}"
12192 [(set_attr "type" "bitmanip")
12193 (set_attr "prefix" "vex")
12194 (set_attr "mode" "<MODE>")])
12196 ;; TBM instructions.
12197 (define_insn "tbm_bextri_<mode>"
12198 [(set (match_operand:SWI48 0 "register_operand" "=r")
12199 (zero_extract:SWI48
12200 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12201 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12202 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12203 (clobber (reg:CC FLAGS_REG))]
12206 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12207 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12209 [(set_attr "type" "bitmanip")
12210 (set_attr "mode" "<MODE>")])
12212 (define_insn "*tbm_blcfill_<mode>"
12213 [(set (match_operand:SWI48 0 "register_operand" "=r")
12216 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12219 (clobber (reg:CC FLAGS_REG))]
12221 "blcfill\t{%1, %0|%0, %1}"
12222 [(set_attr "type" "bitmanip")
12223 (set_attr "mode" "<MODE>")])
12225 (define_insn "*tbm_blci_<mode>"
12226 [(set (match_operand:SWI48 0 "register_operand" "=r")
12230 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12233 (clobber (reg:CC FLAGS_REG))]
12235 "blci\t{%1, %0|%0, %1}"
12236 [(set_attr "type" "bitmanip")
12237 (set_attr "mode" "<MODE>")])
12239 (define_insn "*tbm_blcic_<mode>"
12240 [(set (match_operand:SWI48 0 "register_operand" "=r")
12243 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12247 (clobber (reg:CC FLAGS_REG))]
12249 "blcic\t{%1, %0|%0, %1}"
12250 [(set_attr "type" "bitmanip")
12251 (set_attr "mode" "<MODE>")])
12253 (define_insn "*tbm_blcmsk_<mode>"
12254 [(set (match_operand:SWI48 0 "register_operand" "=r")
12257 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12260 (clobber (reg:CC FLAGS_REG))]
12262 "blcmsk\t{%1, %0|%0, %1}"
12263 [(set_attr "type" "bitmanip")
12264 (set_attr "mode" "<MODE>")])
12266 (define_insn "*tbm_blcs_<mode>"
12267 [(set (match_operand:SWI48 0 "register_operand" "=r")
12270 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12273 (clobber (reg:CC FLAGS_REG))]
12275 "blcs\t{%1, %0|%0, %1}"
12276 [(set_attr "type" "bitmanip")
12277 (set_attr "mode" "<MODE>")])
12279 (define_insn "*tbm_blsfill_<mode>"
12280 [(set (match_operand:SWI48 0 "register_operand" "=r")
12283 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12286 (clobber (reg:CC FLAGS_REG))]
12288 "blsfill\t{%1, %0|%0, %1}"
12289 [(set_attr "type" "bitmanip")
12290 (set_attr "mode" "<MODE>")])
12292 (define_insn "*tbm_blsic_<mode>"
12293 [(set (match_operand:SWI48 0 "register_operand" "=r")
12296 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12300 (clobber (reg:CC FLAGS_REG))]
12302 "blsic\t{%1, %0|%0, %1}"
12303 [(set_attr "type" "bitmanip")
12304 (set_attr "mode" "<MODE>")])
12306 (define_insn "*tbm_t1mskc_<mode>"
12307 [(set (match_operand:SWI48 0 "register_operand" "=r")
12310 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12314 (clobber (reg:CC FLAGS_REG))]
12316 "t1mskc\t{%1, %0|%0, %1}"
12317 [(set_attr "type" "bitmanip")
12318 (set_attr "mode" "<MODE>")])
12320 (define_insn "*tbm_tzmsk_<mode>"
12321 [(set (match_operand:SWI48 0 "register_operand" "=r")
12324 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12328 (clobber (reg:CC FLAGS_REG))]
12330 "tzmsk\t{%1, %0|%0, %1}"
12331 [(set_attr "type" "bitmanip")
12332 (set_attr "mode" "<MODE>")])
12334 (define_insn "bsr_rex64"
12335 [(set (match_operand:DI 0 "register_operand" "=r")
12336 (minus:DI (const_int 63)
12337 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12338 (clobber (reg:CC FLAGS_REG))]
12340 "bsr{q}\t{%1, %0|%0, %1}"
12341 [(set_attr "type" "alu1")
12342 (set_attr "prefix_0f" "1")
12343 (set_attr "mode" "DI")])
12346 [(set (match_operand:SI 0 "register_operand" "=r")
12347 (minus:SI (const_int 31)
12348 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12349 (clobber (reg:CC FLAGS_REG))]
12351 "bsr{l}\t{%1, %0|%0, %1}"
12352 [(set_attr "type" "alu1")
12353 (set_attr "prefix_0f" "1")
12354 (set_attr "mode" "SI")])
12356 (define_insn "*bsrhi"
12357 [(set (match_operand:HI 0 "register_operand" "=r")
12358 (minus:HI (const_int 15)
12359 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12360 (clobber (reg:CC FLAGS_REG))]
12362 "bsr{w}\t{%1, %0|%0, %1}"
12363 [(set_attr "type" "alu1")
12364 (set_attr "prefix_0f" "1")
12365 (set_attr "mode" "HI")])
12367 (define_insn "popcount<mode>2"
12368 [(set (match_operand:SWI248 0 "register_operand" "=r")
12370 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12371 (clobber (reg:CC FLAGS_REG))]
12375 return "popcnt\t{%1, %0|%0, %1}";
12377 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12380 [(set_attr "prefix_rep" "1")
12381 (set_attr "type" "bitmanip")
12382 (set_attr "mode" "<MODE>")])
12384 (define_insn "*popcount<mode>2_cmp"
12385 [(set (reg FLAGS_REG)
12388 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12390 (set (match_operand:SWI248 0 "register_operand" "=r")
12391 (popcount:SWI248 (match_dup 1)))]
12392 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12395 return "popcnt\t{%1, %0|%0, %1}";
12397 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12400 [(set_attr "prefix_rep" "1")
12401 (set_attr "type" "bitmanip")
12402 (set_attr "mode" "<MODE>")])
12404 (define_insn "*popcountsi2_cmp_zext"
12405 [(set (reg FLAGS_REG)
12407 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12409 (set (match_operand:DI 0 "register_operand" "=r")
12410 (zero_extend:DI(popcount:SI (match_dup 1))))]
12411 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12414 return "popcnt\t{%1, %0|%0, %1}";
12416 return "popcnt{l}\t{%1, %0|%0, %1}";
12419 [(set_attr "prefix_rep" "1")
12420 (set_attr "type" "bitmanip")
12421 (set_attr "mode" "SI")])
12423 (define_expand "bswap<mode>2"
12424 [(set (match_operand:SWI48 0 "register_operand" "")
12425 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12428 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12430 rtx x = operands[0];
12432 emit_move_insn (x, operands[1]);
12433 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12434 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12435 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12440 (define_insn "*bswap<mode>2_movbe"
12441 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12442 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12444 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12447 movbe\t{%1, %0|%0, %1}
12448 movbe\t{%1, %0|%0, %1}"
12449 [(set_attr "type" "bitmanip,imov,imov")
12450 (set_attr "modrm" "0,1,1")
12451 (set_attr "prefix_0f" "*,1,1")
12452 (set_attr "prefix_extra" "*,1,1")
12453 (set_attr "mode" "<MODE>")])
12455 (define_insn "*bswap<mode>2_1"
12456 [(set (match_operand:SWI48 0 "register_operand" "=r")
12457 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12460 [(set_attr "type" "bitmanip")
12461 (set_attr "modrm" "0")
12462 (set_attr "mode" "<MODE>")])
12464 (define_insn "*bswaphi_lowpart_1"
12465 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12466 (bswap:HI (match_dup 0)))
12467 (clobber (reg:CC FLAGS_REG))]
12468 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12470 xchg{b}\t{%h0, %b0|%b0, %h0}
12471 rol{w}\t{$8, %0|%0, 8}"
12472 [(set_attr "length" "2,4")
12473 (set_attr "mode" "QI,HI")])
12475 (define_insn "bswaphi_lowpart"
12476 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12477 (bswap:HI (match_dup 0)))
12478 (clobber (reg:CC FLAGS_REG))]
12480 "rol{w}\t{$8, %0|%0, 8}"
12481 [(set_attr "length" "4")
12482 (set_attr "mode" "HI")])
12484 (define_expand "paritydi2"
12485 [(set (match_operand:DI 0 "register_operand" "")
12486 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12489 rtx scratch = gen_reg_rtx (QImode);
12492 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12493 NULL_RTX, operands[1]));
12495 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12496 gen_rtx_REG (CCmode, FLAGS_REG),
12498 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12501 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12504 rtx tmp = gen_reg_rtx (SImode);
12506 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12507 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12512 (define_expand "paritysi2"
12513 [(set (match_operand:SI 0 "register_operand" "")
12514 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12517 rtx scratch = gen_reg_rtx (QImode);
12520 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12522 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12523 gen_rtx_REG (CCmode, FLAGS_REG),
12525 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12527 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12531 (define_insn_and_split "paritydi2_cmp"
12532 [(set (reg:CC FLAGS_REG)
12533 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12535 (clobber (match_scratch:DI 0 "=r"))
12536 (clobber (match_scratch:SI 1 "=&r"))
12537 (clobber (match_scratch:HI 2 "=Q"))]
12540 "&& reload_completed"
12542 [(set (match_dup 1)
12543 (xor:SI (match_dup 1) (match_dup 4)))
12544 (clobber (reg:CC FLAGS_REG))])
12546 [(set (reg:CC FLAGS_REG)
12547 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12548 (clobber (match_dup 1))
12549 (clobber (match_dup 2))])]
12551 operands[4] = gen_lowpart (SImode, operands[3]);
12555 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12556 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12559 operands[1] = gen_highpart (SImode, operands[3]);
12562 (define_insn_and_split "paritysi2_cmp"
12563 [(set (reg:CC FLAGS_REG)
12564 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12566 (clobber (match_scratch:SI 0 "=r"))
12567 (clobber (match_scratch:HI 1 "=&Q"))]
12570 "&& reload_completed"
12572 [(set (match_dup 1)
12573 (xor:HI (match_dup 1) (match_dup 3)))
12574 (clobber (reg:CC FLAGS_REG))])
12576 [(set (reg:CC FLAGS_REG)
12577 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12578 (clobber (match_dup 1))])]
12580 operands[3] = gen_lowpart (HImode, operands[2]);
12582 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12583 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12586 (define_insn "*parityhi2_cmp"
12587 [(set (reg:CC FLAGS_REG)
12588 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12590 (clobber (match_scratch:HI 0 "=Q"))]
12592 "xor{b}\t{%h0, %b0|%b0, %h0}"
12593 [(set_attr "length" "2")
12594 (set_attr "mode" "HI")])
12597 ;; Thread-local storage patterns for ELF.
12599 ;; Note that these code sequences must appear exactly as shown
12600 ;; in order to allow linker relaxation.
12602 (define_insn "*tls_global_dynamic_32_gnu"
12603 [(set (match_operand:SI 0 "register_operand" "=a")
12605 [(match_operand:SI 1 "register_operand" "b")
12606 (match_operand:SI 2 "tls_symbolic_operand" "")
12607 (match_operand:SI 3 "constant_call_address_operand" "z")]
12609 (clobber (match_scratch:SI 4 "=d"))
12610 (clobber (match_scratch:SI 5 "=c"))
12611 (clobber (reg:CC FLAGS_REG))]
12612 "!TARGET_64BIT && TARGET_GNU_TLS"
12615 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12616 if (TARGET_SUN_TLS)
12617 #ifdef HAVE_AS_IX86_TLSGDPLT
12618 return "call\t%a2@tlsgdplt";
12620 return "call\t%p3@plt";
12622 return "call\t%P3";
12624 [(set_attr "type" "multi")
12625 (set_attr "length" "12")])
12627 (define_expand "tls_global_dynamic_32"
12629 [(set (match_operand:SI 0 "register_operand" "")
12630 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12631 (match_operand:SI 1 "tls_symbolic_operand" "")
12632 (match_operand:SI 3 "constant_call_address_operand" "")]
12634 (clobber (match_scratch:SI 4 ""))
12635 (clobber (match_scratch:SI 5 ""))
12636 (clobber (reg:CC FLAGS_REG))])])
12638 (define_insn "*tls_global_dynamic_64"
12639 [(set (match_operand:DI 0 "register_operand" "=a")
12641 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12642 (match_operand:DI 3 "" "")))
12643 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12648 fputs (ASM_BYTE "0x66\n", asm_out_file);
12650 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12651 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12652 fputs ("\trex64\n", asm_out_file);
12653 if (TARGET_SUN_TLS)
12654 return "call\t%p2@plt";
12655 return "call\t%P2";
12657 [(set_attr "type" "multi")
12658 (set (attr "length")
12659 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12661 (define_expand "tls_global_dynamic_64"
12663 [(set (match_operand:DI 0 "register_operand" "")
12665 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12667 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12670 (define_insn "*tls_local_dynamic_base_32_gnu"
12671 [(set (match_operand:SI 0 "register_operand" "=a")
12673 [(match_operand:SI 1 "register_operand" "b")
12674 (match_operand:SI 2 "constant_call_address_operand" "z")]
12675 UNSPEC_TLS_LD_BASE))
12676 (clobber (match_scratch:SI 3 "=d"))
12677 (clobber (match_scratch:SI 4 "=c"))
12678 (clobber (reg:CC FLAGS_REG))]
12679 "!TARGET_64BIT && TARGET_GNU_TLS"
12682 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12683 if (TARGET_SUN_TLS)
12684 #ifdef HAVE_AS_IX86_TLSLDMPLT
12685 return "call\t%&@tlsldmplt";
12687 return "call\t%p2@plt";
12689 return "call\t%P2";
12691 [(set_attr "type" "multi")
12692 (set_attr "length" "11")])
12694 (define_expand "tls_local_dynamic_base_32"
12696 [(set (match_operand:SI 0 "register_operand" "")
12698 [(match_operand:SI 1 "register_operand" "")
12699 (match_operand:SI 2 "constant_call_address_operand" "")]
12700 UNSPEC_TLS_LD_BASE))
12701 (clobber (match_scratch:SI 3 ""))
12702 (clobber (match_scratch:SI 4 ""))
12703 (clobber (reg:CC FLAGS_REG))])])
12705 (define_insn "*tls_local_dynamic_base_64"
12706 [(set (match_operand:DI 0 "register_operand" "=a")
12708 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12709 (match_operand:DI 2 "" "")))
12710 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12714 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12715 if (TARGET_SUN_TLS)
12716 return "call\t%p1@plt";
12717 return "call\t%P1";
12719 [(set_attr "type" "multi")
12720 (set_attr "length" "12")])
12722 (define_expand "tls_local_dynamic_base_64"
12724 [(set (match_operand:DI 0 "register_operand" "")
12726 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12728 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12730 ;; Local dynamic of a single variable is a lose. Show combine how
12731 ;; to convert that back to global dynamic.
12733 (define_insn_and_split "*tls_local_dynamic_32_once"
12734 [(set (match_operand:SI 0 "register_operand" "=a")
12736 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12737 (match_operand:SI 2 "constant_call_address_operand" "z")]
12738 UNSPEC_TLS_LD_BASE)
12739 (const:SI (unspec:SI
12740 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12742 (clobber (match_scratch:SI 4 "=d"))
12743 (clobber (match_scratch:SI 5 "=c"))
12744 (clobber (reg:CC FLAGS_REG))]
12749 [(set (match_dup 0)
12750 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12752 (clobber (match_dup 4))
12753 (clobber (match_dup 5))
12754 (clobber (reg:CC FLAGS_REG))])])
12756 ;; Segment register for the thread base ptr load
12757 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12759 ;; Load and add the thread base pointer from %<tp_seg>:0.
12760 (define_insn "*load_tp_x32"
12761 [(set (match_operand:SI 0 "register_operand" "=r")
12762 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12764 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12765 [(set_attr "type" "imov")
12766 (set_attr "modrm" "0")
12767 (set_attr "length" "7")
12768 (set_attr "memory" "load")
12769 (set_attr "imm_disp" "false")])
12771 (define_insn "*load_tp_x32_zext"
12772 [(set (match_operand:DI 0 "register_operand" "=r")
12773 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12775 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12776 [(set_attr "type" "imov")
12777 (set_attr "modrm" "0")
12778 (set_attr "length" "7")
12779 (set_attr "memory" "load")
12780 (set_attr "imm_disp" "false")])
12782 (define_insn "*load_tp_<mode>"
12783 [(set (match_operand:P 0 "register_operand" "=r")
12784 (unspec:P [(const_int 0)] UNSPEC_TP))]
12786 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12787 [(set_attr "type" "imov")
12788 (set_attr "modrm" "0")
12789 (set_attr "length" "7")
12790 (set_attr "memory" "load")
12791 (set_attr "imm_disp" "false")])
12793 (define_insn "*add_tp_x32"
12794 [(set (match_operand:SI 0 "register_operand" "=r")
12795 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12796 (match_operand:SI 1 "register_operand" "0")))
12797 (clobber (reg:CC FLAGS_REG))]
12799 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12800 [(set_attr "type" "alu")
12801 (set_attr "modrm" "0")
12802 (set_attr "length" "7")
12803 (set_attr "memory" "load")
12804 (set_attr "imm_disp" "false")])
12806 (define_insn "*add_tp_x32_zext"
12807 [(set (match_operand:DI 0 "register_operand" "=r")
12809 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12810 (match_operand:SI 1 "register_operand" "0"))))
12811 (clobber (reg:CC FLAGS_REG))]
12813 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12814 [(set_attr "type" "alu")
12815 (set_attr "modrm" "0")
12816 (set_attr "length" "7")
12817 (set_attr "memory" "load")
12818 (set_attr "imm_disp" "false")])
12820 (define_insn "*add_tp_<mode>"
12821 [(set (match_operand:P 0 "register_operand" "=r")
12822 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12823 (match_operand:P 1 "register_operand" "0")))
12824 (clobber (reg:CC FLAGS_REG))]
12826 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12827 [(set_attr "type" "alu")
12828 (set_attr "modrm" "0")
12829 (set_attr "length" "7")
12830 (set_attr "memory" "load")
12831 (set_attr "imm_disp" "false")])
12833 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12834 ;; %rax as destination of the initial executable code sequence.
12835 (define_insn "tls_initial_exec_64_sun"
12836 [(set (match_operand:DI 0 "register_operand" "=a")
12838 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12839 UNSPEC_TLS_IE_SUN))
12840 (clobber (reg:CC FLAGS_REG))]
12841 "TARGET_64BIT && TARGET_SUN_TLS"
12844 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12845 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12847 [(set_attr "type" "multi")])
12849 ;; GNU2 TLS patterns can be split.
12851 (define_expand "tls_dynamic_gnu2_32"
12852 [(set (match_dup 3)
12853 (plus:SI (match_operand:SI 2 "register_operand" "")
12855 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12858 [(set (match_operand:SI 0 "register_operand" "")
12859 (unspec:SI [(match_dup 1) (match_dup 3)
12860 (match_dup 2) (reg:SI SP_REG)]
12862 (clobber (reg:CC FLAGS_REG))])]
12863 "!TARGET_64BIT && TARGET_GNU2_TLS"
12865 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12866 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12869 (define_insn "*tls_dynamic_gnu2_lea_32"
12870 [(set (match_operand:SI 0 "register_operand" "=r")
12871 (plus:SI (match_operand:SI 1 "register_operand" "b")
12873 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12874 UNSPEC_TLSDESC))))]
12875 "!TARGET_64BIT && TARGET_GNU2_TLS"
12876 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12877 [(set_attr "type" "lea")
12878 (set_attr "mode" "SI")
12879 (set_attr "length" "6")
12880 (set_attr "length_address" "4")])
12882 (define_insn "*tls_dynamic_gnu2_call_32"
12883 [(set (match_operand:SI 0 "register_operand" "=a")
12884 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12885 (match_operand:SI 2 "register_operand" "0")
12886 ;; we have to make sure %ebx still points to the GOT
12887 (match_operand:SI 3 "register_operand" "b")
12890 (clobber (reg:CC FLAGS_REG))]
12891 "!TARGET_64BIT && TARGET_GNU2_TLS"
12892 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12893 [(set_attr "type" "call")
12894 (set_attr "length" "2")
12895 (set_attr "length_address" "0")])
12897 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12898 [(set (match_operand:SI 0 "register_operand" "=&a")
12900 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12901 (match_operand:SI 4 "" "")
12902 (match_operand:SI 2 "register_operand" "b")
12905 (const:SI (unspec:SI
12906 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12908 (clobber (reg:CC FLAGS_REG))]
12909 "!TARGET_64BIT && TARGET_GNU2_TLS"
12912 [(set (match_dup 0) (match_dup 5))]
12914 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12915 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12918 (define_expand "tls_dynamic_gnu2_64"
12919 [(set (match_dup 2)
12920 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12923 [(set (match_operand:DI 0 "register_operand" "")
12924 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12926 (clobber (reg:CC FLAGS_REG))])]
12927 "TARGET_64BIT && TARGET_GNU2_TLS"
12929 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12930 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12933 (define_insn "*tls_dynamic_gnu2_lea_64"
12934 [(set (match_operand:DI 0 "register_operand" "=r")
12935 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12937 "TARGET_64BIT && TARGET_GNU2_TLS"
12938 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12939 [(set_attr "type" "lea")
12940 (set_attr "mode" "DI")
12941 (set_attr "length" "7")
12942 (set_attr "length_address" "4")])
12944 (define_insn "*tls_dynamic_gnu2_call_64"
12945 [(set (match_operand:DI 0 "register_operand" "=a")
12946 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12947 (match_operand:DI 2 "register_operand" "0")
12950 (clobber (reg:CC FLAGS_REG))]
12951 "TARGET_64BIT && TARGET_GNU2_TLS"
12952 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12953 [(set_attr "type" "call")
12954 (set_attr "length" "2")
12955 (set_attr "length_address" "0")])
12957 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12958 [(set (match_operand:DI 0 "register_operand" "=&a")
12960 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12961 (match_operand:DI 3 "" "")
12964 (const:DI (unspec:DI
12965 [(match_operand 1 "tls_symbolic_operand" "")]
12967 (clobber (reg:CC FLAGS_REG))]
12968 "TARGET_64BIT && TARGET_GNU2_TLS"
12971 [(set (match_dup 0) (match_dup 4))]
12973 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12974 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12977 ;; These patterns match the binary 387 instructions for addM3, subM3,
12978 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12979 ;; SFmode. The first is the normal insn, the second the same insn but
12980 ;; with one operand a conversion, and the third the same insn but with
12981 ;; the other operand a conversion. The conversion may be SFmode or
12982 ;; SImode if the target mode DFmode, but only SImode if the target mode
12985 ;; Gcc is slightly more smart about handling normal two address instructions
12986 ;; so use special patterns for add and mull.
12988 (define_insn "*fop_<mode>_comm_mixed"
12989 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12990 (match_operator:MODEF 3 "binary_fp_operator"
12991 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12992 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12993 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12994 && COMMUTATIVE_ARITH_P (operands[3])
12995 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12996 "* return output_387_binary_op (insn, operands);"
12997 [(set (attr "type")
12998 (if_then_else (eq_attr "alternative" "1,2")
12999 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13000 (const_string "ssemul")
13001 (const_string "sseadd"))
13002 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13003 (const_string "fmul")
13004 (const_string "fop"))))
13005 (set_attr "isa" "*,noavx,avx")
13006 (set_attr "prefix" "orig,orig,vex")
13007 (set_attr "mode" "<MODE>")])
13009 (define_insn "*fop_<mode>_comm_sse"
13010 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13011 (match_operator:MODEF 3 "binary_fp_operator"
13012 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13013 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13014 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13015 && COMMUTATIVE_ARITH_P (operands[3])
13016 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13017 "* return output_387_binary_op (insn, operands);"
13018 [(set (attr "type")
13019 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13020 (const_string "ssemul")
13021 (const_string "sseadd")))
13022 (set_attr "isa" "noavx,avx")
13023 (set_attr "prefix" "orig,vex")
13024 (set_attr "mode" "<MODE>")])
13026 (define_insn "*fop_<mode>_comm_i387"
13027 [(set (match_operand:MODEF 0 "register_operand" "=f")
13028 (match_operator:MODEF 3 "binary_fp_operator"
13029 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13030 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13031 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13032 && COMMUTATIVE_ARITH_P (operands[3])
13033 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13034 "* return output_387_binary_op (insn, operands);"
13035 [(set (attr "type")
13036 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13037 (const_string "fmul")
13038 (const_string "fop")))
13039 (set_attr "mode" "<MODE>")])
13041 (define_insn "*fop_<mode>_1_mixed"
13042 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13043 (match_operator:MODEF 3 "binary_fp_operator"
13044 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13045 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13046 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13047 && !COMMUTATIVE_ARITH_P (operands[3])
13048 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13049 "* return output_387_binary_op (insn, operands);"
13050 [(set (attr "type")
13051 (cond [(and (eq_attr "alternative" "2,3")
13052 (match_operand:MODEF 3 "mult_operator" ""))
13053 (const_string "ssemul")
13054 (and (eq_attr "alternative" "2,3")
13055 (match_operand:MODEF 3 "div_operator" ""))
13056 (const_string "ssediv")
13057 (eq_attr "alternative" "2,3")
13058 (const_string "sseadd")
13059 (match_operand:MODEF 3 "mult_operator" "")
13060 (const_string "fmul")
13061 (match_operand:MODEF 3 "div_operator" "")
13062 (const_string "fdiv")
13064 (const_string "fop")))
13065 (set_attr "isa" "*,*,noavx,avx")
13066 (set_attr "prefix" "orig,orig,orig,vex")
13067 (set_attr "mode" "<MODE>")])
13069 (define_insn "*rcpsf2_sse"
13070 [(set (match_operand:SF 0 "register_operand" "=x")
13071 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13074 "%vrcpss\t{%1, %d0|%d0, %1}"
13075 [(set_attr "type" "sse")
13076 (set_attr "atom_sse_attr" "rcp")
13077 (set_attr "prefix" "maybe_vex")
13078 (set_attr "mode" "SF")])
13080 (define_insn "*fop_<mode>_1_sse"
13081 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13082 (match_operator:MODEF 3 "binary_fp_operator"
13083 [(match_operand:MODEF 1 "register_operand" "0,x")
13084 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13085 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13086 && !COMMUTATIVE_ARITH_P (operands[3])"
13087 "* return output_387_binary_op (insn, operands);"
13088 [(set (attr "type")
13089 (cond [(match_operand:MODEF 3 "mult_operator" "")
13090 (const_string "ssemul")
13091 (match_operand:MODEF 3 "div_operator" "")
13092 (const_string "ssediv")
13094 (const_string "sseadd")))
13095 (set_attr "isa" "noavx,avx")
13096 (set_attr "prefix" "orig,vex")
13097 (set_attr "mode" "<MODE>")])
13099 ;; This pattern is not fully shadowed by the pattern above.
13100 (define_insn "*fop_<mode>_1_i387"
13101 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13102 (match_operator:MODEF 3 "binary_fp_operator"
13103 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13104 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13105 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13106 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13107 && !COMMUTATIVE_ARITH_P (operands[3])
13108 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13109 "* return output_387_binary_op (insn, operands);"
13110 [(set (attr "type")
13111 (cond [(match_operand:MODEF 3 "mult_operator" "")
13112 (const_string "fmul")
13113 (match_operand:MODEF 3 "div_operator" "")
13114 (const_string "fdiv")
13116 (const_string "fop")))
13117 (set_attr "mode" "<MODE>")])
13119 ;; ??? Add SSE splitters for these!
13120 (define_insn "*fop_<MODEF:mode>_2_i387"
13121 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13122 (match_operator:MODEF 3 "binary_fp_operator"
13124 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13125 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13126 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13127 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13128 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13129 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13130 [(set (attr "type")
13131 (cond [(match_operand:MODEF 3 "mult_operator" "")
13132 (const_string "fmul")
13133 (match_operand:MODEF 3 "div_operator" "")
13134 (const_string "fdiv")
13136 (const_string "fop")))
13137 (set_attr "fp_int_src" "true")
13138 (set_attr "mode" "<SWI24:MODE>")])
13140 (define_insn "*fop_<MODEF:mode>_3_i387"
13141 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13142 (match_operator:MODEF 3 "binary_fp_operator"
13143 [(match_operand:MODEF 1 "register_operand" "0,0")
13145 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13146 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13147 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13148 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13149 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13150 [(set (attr "type")
13151 (cond [(match_operand:MODEF 3 "mult_operator" "")
13152 (const_string "fmul")
13153 (match_operand:MODEF 3 "div_operator" "")
13154 (const_string "fdiv")
13156 (const_string "fop")))
13157 (set_attr "fp_int_src" "true")
13158 (set_attr "mode" "<MODE>")])
13160 (define_insn "*fop_df_4_i387"
13161 [(set (match_operand:DF 0 "register_operand" "=f,f")
13162 (match_operator:DF 3 "binary_fp_operator"
13164 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13165 (match_operand:DF 2 "register_operand" "0,f")]))]
13166 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13167 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13168 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13169 "* return output_387_binary_op (insn, operands);"
13170 [(set (attr "type")
13171 (cond [(match_operand:DF 3 "mult_operator" "")
13172 (const_string "fmul")
13173 (match_operand:DF 3 "div_operator" "")
13174 (const_string "fdiv")
13176 (const_string "fop")))
13177 (set_attr "mode" "SF")])
13179 (define_insn "*fop_df_5_i387"
13180 [(set (match_operand:DF 0 "register_operand" "=f,f")
13181 (match_operator:DF 3 "binary_fp_operator"
13182 [(match_operand:DF 1 "register_operand" "0,f")
13184 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13185 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13186 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13187 "* return output_387_binary_op (insn, operands);"
13188 [(set (attr "type")
13189 (cond [(match_operand:DF 3 "mult_operator" "")
13190 (const_string "fmul")
13191 (match_operand:DF 3 "div_operator" "")
13192 (const_string "fdiv")
13194 (const_string "fop")))
13195 (set_attr "mode" "SF")])
13197 (define_insn "*fop_df_6_i387"
13198 [(set (match_operand:DF 0 "register_operand" "=f,f")
13199 (match_operator:DF 3 "binary_fp_operator"
13201 (match_operand:SF 1 "register_operand" "0,f"))
13203 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13204 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13205 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13206 "* return output_387_binary_op (insn, operands);"
13207 [(set (attr "type")
13208 (cond [(match_operand:DF 3 "mult_operator" "")
13209 (const_string "fmul")
13210 (match_operand:DF 3 "div_operator" "")
13211 (const_string "fdiv")
13213 (const_string "fop")))
13214 (set_attr "mode" "SF")])
13216 (define_insn "*fop_xf_comm_i387"
13217 [(set (match_operand:XF 0 "register_operand" "=f")
13218 (match_operator:XF 3 "binary_fp_operator"
13219 [(match_operand:XF 1 "register_operand" "%0")
13220 (match_operand:XF 2 "register_operand" "f")]))]
13222 && COMMUTATIVE_ARITH_P (operands[3])"
13223 "* return output_387_binary_op (insn, operands);"
13224 [(set (attr "type")
13225 (if_then_else (match_operand:XF 3 "mult_operator" "")
13226 (const_string "fmul")
13227 (const_string "fop")))
13228 (set_attr "mode" "XF")])
13230 (define_insn "*fop_xf_1_i387"
13231 [(set (match_operand:XF 0 "register_operand" "=f,f")
13232 (match_operator:XF 3 "binary_fp_operator"
13233 [(match_operand:XF 1 "register_operand" "0,f")
13234 (match_operand:XF 2 "register_operand" "f,0")]))]
13236 && !COMMUTATIVE_ARITH_P (operands[3])"
13237 "* return output_387_binary_op (insn, operands);"
13238 [(set (attr "type")
13239 (cond [(match_operand:XF 3 "mult_operator" "")
13240 (const_string "fmul")
13241 (match_operand:XF 3 "div_operator" "")
13242 (const_string "fdiv")
13244 (const_string "fop")))
13245 (set_attr "mode" "XF")])
13247 (define_insn "*fop_xf_2_i387"
13248 [(set (match_operand:XF 0 "register_operand" "=f,f")
13249 (match_operator:XF 3 "binary_fp_operator"
13251 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13252 (match_operand:XF 2 "register_operand" "0,0")]))]
13253 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13254 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13255 [(set (attr "type")
13256 (cond [(match_operand:XF 3 "mult_operator" "")
13257 (const_string "fmul")
13258 (match_operand:XF 3 "div_operator" "")
13259 (const_string "fdiv")
13261 (const_string "fop")))
13262 (set_attr "fp_int_src" "true")
13263 (set_attr "mode" "<MODE>")])
13265 (define_insn "*fop_xf_3_i387"
13266 [(set (match_operand:XF 0 "register_operand" "=f,f")
13267 (match_operator:XF 3 "binary_fp_operator"
13268 [(match_operand:XF 1 "register_operand" "0,0")
13270 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13271 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13272 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13273 [(set (attr "type")
13274 (cond [(match_operand:XF 3 "mult_operator" "")
13275 (const_string "fmul")
13276 (match_operand:XF 3 "div_operator" "")
13277 (const_string "fdiv")
13279 (const_string "fop")))
13280 (set_attr "fp_int_src" "true")
13281 (set_attr "mode" "<MODE>")])
13283 (define_insn "*fop_xf_4_i387"
13284 [(set (match_operand:XF 0 "register_operand" "=f,f")
13285 (match_operator:XF 3 "binary_fp_operator"
13287 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13288 (match_operand:XF 2 "register_operand" "0,f")]))]
13290 "* return output_387_binary_op (insn, operands);"
13291 [(set (attr "type")
13292 (cond [(match_operand:XF 3 "mult_operator" "")
13293 (const_string "fmul")
13294 (match_operand:XF 3 "div_operator" "")
13295 (const_string "fdiv")
13297 (const_string "fop")))
13298 (set_attr "mode" "<MODE>")])
13300 (define_insn "*fop_xf_5_i387"
13301 [(set (match_operand:XF 0 "register_operand" "=f,f")
13302 (match_operator:XF 3 "binary_fp_operator"
13303 [(match_operand:XF 1 "register_operand" "0,f")
13305 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13307 "* return output_387_binary_op (insn, operands);"
13308 [(set (attr "type")
13309 (cond [(match_operand:XF 3 "mult_operator" "")
13310 (const_string "fmul")
13311 (match_operand:XF 3 "div_operator" "")
13312 (const_string "fdiv")
13314 (const_string "fop")))
13315 (set_attr "mode" "<MODE>")])
13317 (define_insn "*fop_xf_6_i387"
13318 [(set (match_operand:XF 0 "register_operand" "=f,f")
13319 (match_operator:XF 3 "binary_fp_operator"
13321 (match_operand:MODEF 1 "register_operand" "0,f"))
13323 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13325 "* return output_387_binary_op (insn, operands);"
13326 [(set (attr "type")
13327 (cond [(match_operand:XF 3 "mult_operator" "")
13328 (const_string "fmul")
13329 (match_operand:XF 3 "div_operator" "")
13330 (const_string "fdiv")
13332 (const_string "fop")))
13333 (set_attr "mode" "<MODE>")])
13336 [(set (match_operand 0 "register_operand" "")
13337 (match_operator 3 "binary_fp_operator"
13338 [(float (match_operand:SWI24 1 "register_operand" ""))
13339 (match_operand 2 "register_operand" "")]))]
13341 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13342 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13345 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13346 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13347 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13348 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13349 GET_MODE (operands[3]),
13352 ix86_free_from_memory (GET_MODE (operands[1]));
13357 [(set (match_operand 0 "register_operand" "")
13358 (match_operator 3 "binary_fp_operator"
13359 [(match_operand 1 "register_operand" "")
13360 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13362 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13363 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13366 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13367 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13368 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13369 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13370 GET_MODE (operands[3]),
13373 ix86_free_from_memory (GET_MODE (operands[2]));
13377 ;; FPU special functions.
13379 ;; This pattern implements a no-op XFmode truncation for
13380 ;; all fancy i386 XFmode math functions.
13382 (define_insn "truncxf<mode>2_i387_noop_unspec"
13383 [(set (match_operand:MODEF 0 "register_operand" "=f")
13384 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13385 UNSPEC_TRUNC_NOOP))]
13386 "TARGET_USE_FANCY_MATH_387"
13387 "* return output_387_reg_move (insn, operands);"
13388 [(set_attr "type" "fmov")
13389 (set_attr "mode" "<MODE>")])
13391 (define_insn "sqrtxf2"
13392 [(set (match_operand:XF 0 "register_operand" "=f")
13393 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13394 "TARGET_USE_FANCY_MATH_387"
13396 [(set_attr "type" "fpspc")
13397 (set_attr "mode" "XF")
13398 (set_attr "athlon_decode" "direct")
13399 (set_attr "amdfam10_decode" "direct")
13400 (set_attr "bdver1_decode" "direct")])
13402 (define_insn "sqrt_extend<mode>xf2_i387"
13403 [(set (match_operand:XF 0 "register_operand" "=f")
13406 (match_operand:MODEF 1 "register_operand" "0"))))]
13407 "TARGET_USE_FANCY_MATH_387"
13409 [(set_attr "type" "fpspc")
13410 (set_attr "mode" "XF")
13411 (set_attr "athlon_decode" "direct")
13412 (set_attr "amdfam10_decode" "direct")
13413 (set_attr "bdver1_decode" "direct")])
13415 (define_insn "*rsqrtsf2_sse"
13416 [(set (match_operand:SF 0 "register_operand" "=x")
13417 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13420 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13421 [(set_attr "type" "sse")
13422 (set_attr "atom_sse_attr" "rcp")
13423 (set_attr "prefix" "maybe_vex")
13424 (set_attr "mode" "SF")])
13426 (define_expand "rsqrtsf2"
13427 [(set (match_operand:SF 0 "register_operand" "")
13428 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13432 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13436 (define_insn "*sqrt<mode>2_sse"
13437 [(set (match_operand:MODEF 0 "register_operand" "=x")
13439 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13440 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13441 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13442 [(set_attr "type" "sse")
13443 (set_attr "atom_sse_attr" "sqrt")
13444 (set_attr "prefix" "maybe_vex")
13445 (set_attr "mode" "<MODE>")
13446 (set_attr "athlon_decode" "*")
13447 (set_attr "amdfam10_decode" "*")
13448 (set_attr "bdver1_decode" "*")])
13450 (define_expand "sqrt<mode>2"
13451 [(set (match_operand:MODEF 0 "register_operand" "")
13453 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13454 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13455 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13457 if (<MODE>mode == SFmode
13459 && TARGET_RECIP_SQRT
13460 && !optimize_function_for_size_p (cfun)
13461 && flag_finite_math_only && !flag_trapping_math
13462 && flag_unsafe_math_optimizations)
13464 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13468 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13470 rtx op0 = gen_reg_rtx (XFmode);
13471 rtx op1 = force_reg (<MODE>mode, operands[1]);
13473 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13474 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13479 (define_insn "fpremxf4_i387"
13480 [(set (match_operand:XF 0 "register_operand" "=f")
13481 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13482 (match_operand:XF 3 "register_operand" "1")]
13484 (set (match_operand:XF 1 "register_operand" "=u")
13485 (unspec:XF [(match_dup 2) (match_dup 3)]
13487 (set (reg:CCFP FPSR_REG)
13488 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13490 "TARGET_USE_FANCY_MATH_387"
13492 [(set_attr "type" "fpspc")
13493 (set_attr "mode" "XF")])
13495 (define_expand "fmodxf3"
13496 [(use (match_operand:XF 0 "register_operand" ""))
13497 (use (match_operand:XF 1 "general_operand" ""))
13498 (use (match_operand:XF 2 "general_operand" ""))]
13499 "TARGET_USE_FANCY_MATH_387"
13501 rtx label = gen_label_rtx ();
13503 rtx op1 = gen_reg_rtx (XFmode);
13504 rtx op2 = gen_reg_rtx (XFmode);
13506 emit_move_insn (op2, operands[2]);
13507 emit_move_insn (op1, operands[1]);
13509 emit_label (label);
13510 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13511 ix86_emit_fp_unordered_jump (label);
13512 LABEL_NUSES (label) = 1;
13514 emit_move_insn (operands[0], op1);
13518 (define_expand "fmod<mode>3"
13519 [(use (match_operand:MODEF 0 "register_operand" ""))
13520 (use (match_operand:MODEF 1 "general_operand" ""))
13521 (use (match_operand:MODEF 2 "general_operand" ""))]
13522 "TARGET_USE_FANCY_MATH_387"
13524 rtx (*gen_truncxf) (rtx, rtx);
13526 rtx label = gen_label_rtx ();
13528 rtx op1 = gen_reg_rtx (XFmode);
13529 rtx op2 = gen_reg_rtx (XFmode);
13531 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13532 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13534 emit_label (label);
13535 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13536 ix86_emit_fp_unordered_jump (label);
13537 LABEL_NUSES (label) = 1;
13539 /* Truncate the result properly for strict SSE math. */
13540 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13541 && !TARGET_MIX_SSE_I387)
13542 gen_truncxf = gen_truncxf<mode>2;
13544 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13546 emit_insn (gen_truncxf (operands[0], op1));
13550 (define_insn "fprem1xf4_i387"
13551 [(set (match_operand:XF 0 "register_operand" "=f")
13552 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13553 (match_operand:XF 3 "register_operand" "1")]
13555 (set (match_operand:XF 1 "register_operand" "=u")
13556 (unspec:XF [(match_dup 2) (match_dup 3)]
13558 (set (reg:CCFP FPSR_REG)
13559 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13561 "TARGET_USE_FANCY_MATH_387"
13563 [(set_attr "type" "fpspc")
13564 (set_attr "mode" "XF")])
13566 (define_expand "remainderxf3"
13567 [(use (match_operand:XF 0 "register_operand" ""))
13568 (use (match_operand:XF 1 "general_operand" ""))
13569 (use (match_operand:XF 2 "general_operand" ""))]
13570 "TARGET_USE_FANCY_MATH_387"
13572 rtx label = gen_label_rtx ();
13574 rtx op1 = gen_reg_rtx (XFmode);
13575 rtx op2 = gen_reg_rtx (XFmode);
13577 emit_move_insn (op2, operands[2]);
13578 emit_move_insn (op1, operands[1]);
13580 emit_label (label);
13581 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13582 ix86_emit_fp_unordered_jump (label);
13583 LABEL_NUSES (label) = 1;
13585 emit_move_insn (operands[0], op1);
13589 (define_expand "remainder<mode>3"
13590 [(use (match_operand:MODEF 0 "register_operand" ""))
13591 (use (match_operand:MODEF 1 "general_operand" ""))
13592 (use (match_operand:MODEF 2 "general_operand" ""))]
13593 "TARGET_USE_FANCY_MATH_387"
13595 rtx (*gen_truncxf) (rtx, rtx);
13597 rtx label = gen_label_rtx ();
13599 rtx op1 = gen_reg_rtx (XFmode);
13600 rtx op2 = gen_reg_rtx (XFmode);
13602 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13603 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13605 emit_label (label);
13607 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13608 ix86_emit_fp_unordered_jump (label);
13609 LABEL_NUSES (label) = 1;
13611 /* Truncate the result properly for strict SSE math. */
13612 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13613 && !TARGET_MIX_SSE_I387)
13614 gen_truncxf = gen_truncxf<mode>2;
13616 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13618 emit_insn (gen_truncxf (operands[0], op1));
13622 (define_insn "*sinxf2_i387"
13623 [(set (match_operand:XF 0 "register_operand" "=f")
13624 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13625 "TARGET_USE_FANCY_MATH_387
13626 && flag_unsafe_math_optimizations"
13628 [(set_attr "type" "fpspc")
13629 (set_attr "mode" "XF")])
13631 (define_insn "*sin_extend<mode>xf2_i387"
13632 [(set (match_operand:XF 0 "register_operand" "=f")
13633 (unspec:XF [(float_extend:XF
13634 (match_operand:MODEF 1 "register_operand" "0"))]
13636 "TARGET_USE_FANCY_MATH_387
13637 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13638 || TARGET_MIX_SSE_I387)
13639 && flag_unsafe_math_optimizations"
13641 [(set_attr "type" "fpspc")
13642 (set_attr "mode" "XF")])
13644 (define_insn "*cosxf2_i387"
13645 [(set (match_operand:XF 0 "register_operand" "=f")
13646 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13647 "TARGET_USE_FANCY_MATH_387
13648 && flag_unsafe_math_optimizations"
13650 [(set_attr "type" "fpspc")
13651 (set_attr "mode" "XF")])
13653 (define_insn "*cos_extend<mode>xf2_i387"
13654 [(set (match_operand:XF 0 "register_operand" "=f")
13655 (unspec:XF [(float_extend:XF
13656 (match_operand:MODEF 1 "register_operand" "0"))]
13658 "TARGET_USE_FANCY_MATH_387
13659 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13660 || TARGET_MIX_SSE_I387)
13661 && flag_unsafe_math_optimizations"
13663 [(set_attr "type" "fpspc")
13664 (set_attr "mode" "XF")])
13666 ;; When sincos pattern is defined, sin and cos builtin functions will be
13667 ;; expanded to sincos pattern with one of its outputs left unused.
13668 ;; CSE pass will figure out if two sincos patterns can be combined,
13669 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13670 ;; depending on the unused output.
13672 (define_insn "sincosxf3"
13673 [(set (match_operand:XF 0 "register_operand" "=f")
13674 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13675 UNSPEC_SINCOS_COS))
13676 (set (match_operand:XF 1 "register_operand" "=u")
13677 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13678 "TARGET_USE_FANCY_MATH_387
13679 && flag_unsafe_math_optimizations"
13681 [(set_attr "type" "fpspc")
13682 (set_attr "mode" "XF")])
13685 [(set (match_operand:XF 0 "register_operand" "")
13686 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13687 UNSPEC_SINCOS_COS))
13688 (set (match_operand:XF 1 "register_operand" "")
13689 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13690 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13691 && can_create_pseudo_p ()"
13692 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13695 [(set (match_operand:XF 0 "register_operand" "")
13696 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13697 UNSPEC_SINCOS_COS))
13698 (set (match_operand:XF 1 "register_operand" "")
13699 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13700 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13701 && can_create_pseudo_p ()"
13702 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13704 (define_insn "sincos_extend<mode>xf3_i387"
13705 [(set (match_operand:XF 0 "register_operand" "=f")
13706 (unspec:XF [(float_extend:XF
13707 (match_operand:MODEF 2 "register_operand" "0"))]
13708 UNSPEC_SINCOS_COS))
13709 (set (match_operand:XF 1 "register_operand" "=u")
13710 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13711 "TARGET_USE_FANCY_MATH_387
13712 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13713 || TARGET_MIX_SSE_I387)
13714 && flag_unsafe_math_optimizations"
13716 [(set_attr "type" "fpspc")
13717 (set_attr "mode" "XF")])
13720 [(set (match_operand:XF 0 "register_operand" "")
13721 (unspec:XF [(float_extend:XF
13722 (match_operand:MODEF 2 "register_operand" ""))]
13723 UNSPEC_SINCOS_COS))
13724 (set (match_operand:XF 1 "register_operand" "")
13725 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13726 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13727 && can_create_pseudo_p ()"
13728 [(set (match_dup 1)
13729 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13732 [(set (match_operand:XF 0 "register_operand" "")
13733 (unspec:XF [(float_extend:XF
13734 (match_operand:MODEF 2 "register_operand" ""))]
13735 UNSPEC_SINCOS_COS))
13736 (set (match_operand:XF 1 "register_operand" "")
13737 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13738 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13739 && can_create_pseudo_p ()"
13740 [(set (match_dup 0)
13741 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13743 (define_expand "sincos<mode>3"
13744 [(use (match_operand:MODEF 0 "register_operand" ""))
13745 (use (match_operand:MODEF 1 "register_operand" ""))
13746 (use (match_operand:MODEF 2 "register_operand" ""))]
13747 "TARGET_USE_FANCY_MATH_387
13748 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13749 || TARGET_MIX_SSE_I387)
13750 && flag_unsafe_math_optimizations"
13752 rtx op0 = gen_reg_rtx (XFmode);
13753 rtx op1 = gen_reg_rtx (XFmode);
13755 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13756 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13757 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13761 (define_insn "fptanxf4_i387"
13762 [(set (match_operand:XF 0 "register_operand" "=f")
13763 (match_operand:XF 3 "const_double_operand" "F"))
13764 (set (match_operand:XF 1 "register_operand" "=u")
13765 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13767 "TARGET_USE_FANCY_MATH_387
13768 && flag_unsafe_math_optimizations
13769 && standard_80387_constant_p (operands[3]) == 2"
13771 [(set_attr "type" "fpspc")
13772 (set_attr "mode" "XF")])
13774 (define_insn "fptan_extend<mode>xf4_i387"
13775 [(set (match_operand:MODEF 0 "register_operand" "=f")
13776 (match_operand:MODEF 3 "const_double_operand" "F"))
13777 (set (match_operand:XF 1 "register_operand" "=u")
13778 (unspec:XF [(float_extend:XF
13779 (match_operand:MODEF 2 "register_operand" "0"))]
13781 "TARGET_USE_FANCY_MATH_387
13782 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13783 || TARGET_MIX_SSE_I387)
13784 && flag_unsafe_math_optimizations
13785 && standard_80387_constant_p (operands[3]) == 2"
13787 [(set_attr "type" "fpspc")
13788 (set_attr "mode" "XF")])
13790 (define_expand "tanxf2"
13791 [(use (match_operand:XF 0 "register_operand" ""))
13792 (use (match_operand:XF 1 "register_operand" ""))]
13793 "TARGET_USE_FANCY_MATH_387
13794 && flag_unsafe_math_optimizations"
13796 rtx one = gen_reg_rtx (XFmode);
13797 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13799 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13803 (define_expand "tan<mode>2"
13804 [(use (match_operand:MODEF 0 "register_operand" ""))
13805 (use (match_operand:MODEF 1 "register_operand" ""))]
13806 "TARGET_USE_FANCY_MATH_387
13807 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13808 || TARGET_MIX_SSE_I387)
13809 && flag_unsafe_math_optimizations"
13811 rtx op0 = gen_reg_rtx (XFmode);
13813 rtx one = gen_reg_rtx (<MODE>mode);
13814 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13816 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13817 operands[1], op2));
13818 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13822 (define_insn "*fpatanxf3_i387"
13823 [(set (match_operand:XF 0 "register_operand" "=f")
13824 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13825 (match_operand:XF 2 "register_operand" "u")]
13827 (clobber (match_scratch:XF 3 "=2"))]
13828 "TARGET_USE_FANCY_MATH_387
13829 && flag_unsafe_math_optimizations"
13831 [(set_attr "type" "fpspc")
13832 (set_attr "mode" "XF")])
13834 (define_insn "fpatan_extend<mode>xf3_i387"
13835 [(set (match_operand:XF 0 "register_operand" "=f")
13836 (unspec:XF [(float_extend:XF
13837 (match_operand:MODEF 1 "register_operand" "0"))
13839 (match_operand:MODEF 2 "register_operand" "u"))]
13841 (clobber (match_scratch:XF 3 "=2"))]
13842 "TARGET_USE_FANCY_MATH_387
13843 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13844 || TARGET_MIX_SSE_I387)
13845 && flag_unsafe_math_optimizations"
13847 [(set_attr "type" "fpspc")
13848 (set_attr "mode" "XF")])
13850 (define_expand "atan2xf3"
13851 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13852 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13853 (match_operand:XF 1 "register_operand" "")]
13855 (clobber (match_scratch:XF 3 ""))])]
13856 "TARGET_USE_FANCY_MATH_387
13857 && flag_unsafe_math_optimizations")
13859 (define_expand "atan2<mode>3"
13860 [(use (match_operand:MODEF 0 "register_operand" ""))
13861 (use (match_operand:MODEF 1 "register_operand" ""))
13862 (use (match_operand:MODEF 2 "register_operand" ""))]
13863 "TARGET_USE_FANCY_MATH_387
13864 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13865 || TARGET_MIX_SSE_I387)
13866 && flag_unsafe_math_optimizations"
13868 rtx op0 = gen_reg_rtx (XFmode);
13870 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13871 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13875 (define_expand "atanxf2"
13876 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13877 (unspec:XF [(match_dup 2)
13878 (match_operand:XF 1 "register_operand" "")]
13880 (clobber (match_scratch:XF 3 ""))])]
13881 "TARGET_USE_FANCY_MATH_387
13882 && flag_unsafe_math_optimizations"
13884 operands[2] = gen_reg_rtx (XFmode);
13885 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13888 (define_expand "atan<mode>2"
13889 [(use (match_operand:MODEF 0 "register_operand" ""))
13890 (use (match_operand:MODEF 1 "register_operand" ""))]
13891 "TARGET_USE_FANCY_MATH_387
13892 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13893 || TARGET_MIX_SSE_I387)
13894 && flag_unsafe_math_optimizations"
13896 rtx op0 = gen_reg_rtx (XFmode);
13898 rtx op2 = gen_reg_rtx (<MODE>mode);
13899 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13901 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13902 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13906 (define_expand "asinxf2"
13907 [(set (match_dup 2)
13908 (mult:XF (match_operand:XF 1 "register_operand" "")
13910 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13911 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13912 (parallel [(set (match_operand:XF 0 "register_operand" "")
13913 (unspec:XF [(match_dup 5) (match_dup 1)]
13915 (clobber (match_scratch:XF 6 ""))])]
13916 "TARGET_USE_FANCY_MATH_387
13917 && flag_unsafe_math_optimizations"
13921 if (optimize_insn_for_size_p ())
13924 for (i = 2; i < 6; i++)
13925 operands[i] = gen_reg_rtx (XFmode);
13927 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13930 (define_expand "asin<mode>2"
13931 [(use (match_operand:MODEF 0 "register_operand" ""))
13932 (use (match_operand:MODEF 1 "general_operand" ""))]
13933 "TARGET_USE_FANCY_MATH_387
13934 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13935 || TARGET_MIX_SSE_I387)
13936 && flag_unsafe_math_optimizations"
13938 rtx op0 = gen_reg_rtx (XFmode);
13939 rtx op1 = gen_reg_rtx (XFmode);
13941 if (optimize_insn_for_size_p ())
13944 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13945 emit_insn (gen_asinxf2 (op0, op1));
13946 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13950 (define_expand "acosxf2"
13951 [(set (match_dup 2)
13952 (mult:XF (match_operand:XF 1 "register_operand" "")
13954 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13955 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13956 (parallel [(set (match_operand:XF 0 "register_operand" "")
13957 (unspec:XF [(match_dup 1) (match_dup 5)]
13959 (clobber (match_scratch:XF 6 ""))])]
13960 "TARGET_USE_FANCY_MATH_387
13961 && flag_unsafe_math_optimizations"
13965 if (optimize_insn_for_size_p ())
13968 for (i = 2; i < 6; i++)
13969 operands[i] = gen_reg_rtx (XFmode);
13971 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13974 (define_expand "acos<mode>2"
13975 [(use (match_operand:MODEF 0 "register_operand" ""))
13976 (use (match_operand:MODEF 1 "general_operand" ""))]
13977 "TARGET_USE_FANCY_MATH_387
13978 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13979 || TARGET_MIX_SSE_I387)
13980 && flag_unsafe_math_optimizations"
13982 rtx op0 = gen_reg_rtx (XFmode);
13983 rtx op1 = gen_reg_rtx (XFmode);
13985 if (optimize_insn_for_size_p ())
13988 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13989 emit_insn (gen_acosxf2 (op0, op1));
13990 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13994 (define_insn "fyl2xxf3_i387"
13995 [(set (match_operand:XF 0 "register_operand" "=f")
13996 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13997 (match_operand:XF 2 "register_operand" "u")]
13999 (clobber (match_scratch:XF 3 "=2"))]
14000 "TARGET_USE_FANCY_MATH_387
14001 && flag_unsafe_math_optimizations"
14003 [(set_attr "type" "fpspc")
14004 (set_attr "mode" "XF")])
14006 (define_insn "fyl2x_extend<mode>xf3_i387"
14007 [(set (match_operand:XF 0 "register_operand" "=f")
14008 (unspec:XF [(float_extend:XF
14009 (match_operand:MODEF 1 "register_operand" "0"))
14010 (match_operand:XF 2 "register_operand" "u")]
14012 (clobber (match_scratch:XF 3 "=2"))]
14013 "TARGET_USE_FANCY_MATH_387
14014 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14015 || TARGET_MIX_SSE_I387)
14016 && flag_unsafe_math_optimizations"
14018 [(set_attr "type" "fpspc")
14019 (set_attr "mode" "XF")])
14021 (define_expand "logxf2"
14022 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14023 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14024 (match_dup 2)] UNSPEC_FYL2X))
14025 (clobber (match_scratch:XF 3 ""))])]
14026 "TARGET_USE_FANCY_MATH_387
14027 && flag_unsafe_math_optimizations"
14029 operands[2] = gen_reg_rtx (XFmode);
14030 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14033 (define_expand "log<mode>2"
14034 [(use (match_operand:MODEF 0 "register_operand" ""))
14035 (use (match_operand:MODEF 1 "register_operand" ""))]
14036 "TARGET_USE_FANCY_MATH_387
14037 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14038 || TARGET_MIX_SSE_I387)
14039 && flag_unsafe_math_optimizations"
14041 rtx op0 = gen_reg_rtx (XFmode);
14043 rtx op2 = gen_reg_rtx (XFmode);
14044 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14046 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14047 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14051 (define_expand "log10xf2"
14052 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14053 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14054 (match_dup 2)] UNSPEC_FYL2X))
14055 (clobber (match_scratch:XF 3 ""))])]
14056 "TARGET_USE_FANCY_MATH_387
14057 && flag_unsafe_math_optimizations"
14059 operands[2] = gen_reg_rtx (XFmode);
14060 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14063 (define_expand "log10<mode>2"
14064 [(use (match_operand:MODEF 0 "register_operand" ""))
14065 (use (match_operand:MODEF 1 "register_operand" ""))]
14066 "TARGET_USE_FANCY_MATH_387
14067 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14068 || TARGET_MIX_SSE_I387)
14069 && flag_unsafe_math_optimizations"
14071 rtx op0 = gen_reg_rtx (XFmode);
14073 rtx op2 = gen_reg_rtx (XFmode);
14074 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14076 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14077 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14081 (define_expand "log2xf2"
14082 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14083 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14084 (match_dup 2)] UNSPEC_FYL2X))
14085 (clobber (match_scratch:XF 3 ""))])]
14086 "TARGET_USE_FANCY_MATH_387
14087 && flag_unsafe_math_optimizations"
14089 operands[2] = gen_reg_rtx (XFmode);
14090 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14093 (define_expand "log2<mode>2"
14094 [(use (match_operand:MODEF 0 "register_operand" ""))
14095 (use (match_operand:MODEF 1 "register_operand" ""))]
14096 "TARGET_USE_FANCY_MATH_387
14097 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14098 || TARGET_MIX_SSE_I387)
14099 && flag_unsafe_math_optimizations"
14101 rtx op0 = gen_reg_rtx (XFmode);
14103 rtx op2 = gen_reg_rtx (XFmode);
14104 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14106 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14107 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14111 (define_insn "fyl2xp1xf3_i387"
14112 [(set (match_operand:XF 0 "register_operand" "=f")
14113 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14114 (match_operand:XF 2 "register_operand" "u")]
14116 (clobber (match_scratch:XF 3 "=2"))]
14117 "TARGET_USE_FANCY_MATH_387
14118 && flag_unsafe_math_optimizations"
14120 [(set_attr "type" "fpspc")
14121 (set_attr "mode" "XF")])
14123 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14124 [(set (match_operand:XF 0 "register_operand" "=f")
14125 (unspec:XF [(float_extend:XF
14126 (match_operand:MODEF 1 "register_operand" "0"))
14127 (match_operand:XF 2 "register_operand" "u")]
14129 (clobber (match_scratch:XF 3 "=2"))]
14130 "TARGET_USE_FANCY_MATH_387
14131 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14132 || TARGET_MIX_SSE_I387)
14133 && flag_unsafe_math_optimizations"
14135 [(set_attr "type" "fpspc")
14136 (set_attr "mode" "XF")])
14138 (define_expand "log1pxf2"
14139 [(use (match_operand:XF 0 "register_operand" ""))
14140 (use (match_operand:XF 1 "register_operand" ""))]
14141 "TARGET_USE_FANCY_MATH_387
14142 && flag_unsafe_math_optimizations"
14144 if (optimize_insn_for_size_p ())
14147 ix86_emit_i387_log1p (operands[0], operands[1]);
14151 (define_expand "log1p<mode>2"
14152 [(use (match_operand:MODEF 0 "register_operand" ""))
14153 (use (match_operand:MODEF 1 "register_operand" ""))]
14154 "TARGET_USE_FANCY_MATH_387
14155 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14156 || TARGET_MIX_SSE_I387)
14157 && flag_unsafe_math_optimizations"
14161 if (optimize_insn_for_size_p ())
14164 op0 = gen_reg_rtx (XFmode);
14166 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14168 ix86_emit_i387_log1p (op0, operands[1]);
14169 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14173 (define_insn "fxtractxf3_i387"
14174 [(set (match_operand:XF 0 "register_operand" "=f")
14175 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14176 UNSPEC_XTRACT_FRACT))
14177 (set (match_operand:XF 1 "register_operand" "=u")
14178 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14179 "TARGET_USE_FANCY_MATH_387
14180 && flag_unsafe_math_optimizations"
14182 [(set_attr "type" "fpspc")
14183 (set_attr "mode" "XF")])
14185 (define_insn "fxtract_extend<mode>xf3_i387"
14186 [(set (match_operand:XF 0 "register_operand" "=f")
14187 (unspec:XF [(float_extend:XF
14188 (match_operand:MODEF 2 "register_operand" "0"))]
14189 UNSPEC_XTRACT_FRACT))
14190 (set (match_operand:XF 1 "register_operand" "=u")
14191 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
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"
14197 [(set_attr "type" "fpspc")
14198 (set_attr "mode" "XF")])
14200 (define_expand "logbxf2"
14201 [(parallel [(set (match_dup 2)
14202 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14203 UNSPEC_XTRACT_FRACT))
14204 (set (match_operand:XF 0 "register_operand" "")
14205 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14206 "TARGET_USE_FANCY_MATH_387
14207 && flag_unsafe_math_optimizations"
14208 "operands[2] = gen_reg_rtx (XFmode);")
14210 (define_expand "logb<mode>2"
14211 [(use (match_operand:MODEF 0 "register_operand" ""))
14212 (use (match_operand:MODEF 1 "register_operand" ""))]
14213 "TARGET_USE_FANCY_MATH_387
14214 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14215 || TARGET_MIX_SSE_I387)
14216 && flag_unsafe_math_optimizations"
14218 rtx op0 = gen_reg_rtx (XFmode);
14219 rtx op1 = gen_reg_rtx (XFmode);
14221 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14222 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14226 (define_expand "ilogbxf2"
14227 [(use (match_operand:SI 0 "register_operand" ""))
14228 (use (match_operand:XF 1 "register_operand" ""))]
14229 "TARGET_USE_FANCY_MATH_387
14230 && flag_unsafe_math_optimizations"
14234 if (optimize_insn_for_size_p ())
14237 op0 = gen_reg_rtx (XFmode);
14238 op1 = gen_reg_rtx (XFmode);
14240 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14241 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14245 (define_expand "ilogb<mode>2"
14246 [(use (match_operand:SI 0 "register_operand" ""))
14247 (use (match_operand:MODEF 1 "register_operand" ""))]
14248 "TARGET_USE_FANCY_MATH_387
14249 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14250 || TARGET_MIX_SSE_I387)
14251 && flag_unsafe_math_optimizations"
14255 if (optimize_insn_for_size_p ())
14258 op0 = gen_reg_rtx (XFmode);
14259 op1 = gen_reg_rtx (XFmode);
14261 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14262 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14266 (define_insn "*f2xm1xf2_i387"
14267 [(set (match_operand:XF 0 "register_operand" "=f")
14268 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14270 "TARGET_USE_FANCY_MATH_387
14271 && flag_unsafe_math_optimizations"
14273 [(set_attr "type" "fpspc")
14274 (set_attr "mode" "XF")])
14276 (define_insn "*fscalexf4_i387"
14277 [(set (match_operand:XF 0 "register_operand" "=f")
14278 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14279 (match_operand:XF 3 "register_operand" "1")]
14280 UNSPEC_FSCALE_FRACT))
14281 (set (match_operand:XF 1 "register_operand" "=u")
14282 (unspec:XF [(match_dup 2) (match_dup 3)]
14283 UNSPEC_FSCALE_EXP))]
14284 "TARGET_USE_FANCY_MATH_387
14285 && flag_unsafe_math_optimizations"
14287 [(set_attr "type" "fpspc")
14288 (set_attr "mode" "XF")])
14290 (define_expand "expNcorexf3"
14291 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14292 (match_operand:XF 2 "register_operand" "")))
14293 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14294 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14295 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14296 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14297 (parallel [(set (match_operand:XF 0 "register_operand" "")
14298 (unspec:XF [(match_dup 8) (match_dup 4)]
14299 UNSPEC_FSCALE_FRACT))
14301 (unspec:XF [(match_dup 8) (match_dup 4)]
14302 UNSPEC_FSCALE_EXP))])]
14303 "TARGET_USE_FANCY_MATH_387
14304 && flag_unsafe_math_optimizations"
14308 if (optimize_insn_for_size_p ())
14311 for (i = 3; i < 10; i++)
14312 operands[i] = gen_reg_rtx (XFmode);
14314 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14317 (define_expand "expxf2"
14318 [(use (match_operand:XF 0 "register_operand" ""))
14319 (use (match_operand:XF 1 "register_operand" ""))]
14320 "TARGET_USE_FANCY_MATH_387
14321 && flag_unsafe_math_optimizations"
14325 if (optimize_insn_for_size_p ())
14328 op2 = gen_reg_rtx (XFmode);
14329 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14331 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14335 (define_expand "exp<mode>2"
14336 [(use (match_operand:MODEF 0 "register_operand" ""))
14337 (use (match_operand:MODEF 1 "general_operand" ""))]
14338 "TARGET_USE_FANCY_MATH_387
14339 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14340 || TARGET_MIX_SSE_I387)
14341 && flag_unsafe_math_optimizations"
14345 if (optimize_insn_for_size_p ())
14348 op0 = gen_reg_rtx (XFmode);
14349 op1 = gen_reg_rtx (XFmode);
14351 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14352 emit_insn (gen_expxf2 (op0, op1));
14353 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14357 (define_expand "exp10xf2"
14358 [(use (match_operand:XF 0 "register_operand" ""))
14359 (use (match_operand:XF 1 "register_operand" ""))]
14360 "TARGET_USE_FANCY_MATH_387
14361 && flag_unsafe_math_optimizations"
14365 if (optimize_insn_for_size_p ())
14368 op2 = gen_reg_rtx (XFmode);
14369 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14371 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14375 (define_expand "exp10<mode>2"
14376 [(use (match_operand:MODEF 0 "register_operand" ""))
14377 (use (match_operand:MODEF 1 "general_operand" ""))]
14378 "TARGET_USE_FANCY_MATH_387
14379 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14380 || TARGET_MIX_SSE_I387)
14381 && flag_unsafe_math_optimizations"
14385 if (optimize_insn_for_size_p ())
14388 op0 = gen_reg_rtx (XFmode);
14389 op1 = gen_reg_rtx (XFmode);
14391 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14392 emit_insn (gen_exp10xf2 (op0, op1));
14393 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14397 (define_expand "exp2xf2"
14398 [(use (match_operand:XF 0 "register_operand" ""))
14399 (use (match_operand:XF 1 "register_operand" ""))]
14400 "TARGET_USE_FANCY_MATH_387
14401 && flag_unsafe_math_optimizations"
14405 if (optimize_insn_for_size_p ())
14408 op2 = gen_reg_rtx (XFmode);
14409 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14411 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14415 (define_expand "exp2<mode>2"
14416 [(use (match_operand:MODEF 0 "register_operand" ""))
14417 (use (match_operand:MODEF 1 "general_operand" ""))]
14418 "TARGET_USE_FANCY_MATH_387
14419 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14420 || TARGET_MIX_SSE_I387)
14421 && flag_unsafe_math_optimizations"
14425 if (optimize_insn_for_size_p ())
14428 op0 = gen_reg_rtx (XFmode);
14429 op1 = gen_reg_rtx (XFmode);
14431 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14432 emit_insn (gen_exp2xf2 (op0, op1));
14433 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14437 (define_expand "expm1xf2"
14438 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14440 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14441 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14442 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14443 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14444 (parallel [(set (match_dup 7)
14445 (unspec:XF [(match_dup 6) (match_dup 4)]
14446 UNSPEC_FSCALE_FRACT))
14448 (unspec:XF [(match_dup 6) (match_dup 4)]
14449 UNSPEC_FSCALE_EXP))])
14450 (parallel [(set (match_dup 10)
14451 (unspec:XF [(match_dup 9) (match_dup 8)]
14452 UNSPEC_FSCALE_FRACT))
14453 (set (match_dup 11)
14454 (unspec:XF [(match_dup 9) (match_dup 8)]
14455 UNSPEC_FSCALE_EXP))])
14456 (set (match_dup 12) (minus:XF (match_dup 10)
14457 (float_extend:XF (match_dup 13))))
14458 (set (match_operand:XF 0 "register_operand" "")
14459 (plus:XF (match_dup 12) (match_dup 7)))]
14460 "TARGET_USE_FANCY_MATH_387
14461 && flag_unsafe_math_optimizations"
14465 if (optimize_insn_for_size_p ())
14468 for (i = 2; i < 13; i++)
14469 operands[i] = gen_reg_rtx (XFmode);
14472 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14474 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14477 (define_expand "expm1<mode>2"
14478 [(use (match_operand:MODEF 0 "register_operand" ""))
14479 (use (match_operand:MODEF 1 "general_operand" ""))]
14480 "TARGET_USE_FANCY_MATH_387
14481 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14482 || TARGET_MIX_SSE_I387)
14483 && flag_unsafe_math_optimizations"
14487 if (optimize_insn_for_size_p ())
14490 op0 = gen_reg_rtx (XFmode);
14491 op1 = gen_reg_rtx (XFmode);
14493 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14494 emit_insn (gen_expm1xf2 (op0, op1));
14495 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14499 (define_expand "ldexpxf3"
14500 [(set (match_dup 3)
14501 (float:XF (match_operand:SI 2 "register_operand" "")))
14502 (parallel [(set (match_operand:XF 0 " register_operand" "")
14503 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14505 UNSPEC_FSCALE_FRACT))
14507 (unspec:XF [(match_dup 1) (match_dup 3)]
14508 UNSPEC_FSCALE_EXP))])]
14509 "TARGET_USE_FANCY_MATH_387
14510 && flag_unsafe_math_optimizations"
14512 if (optimize_insn_for_size_p ())
14515 operands[3] = gen_reg_rtx (XFmode);
14516 operands[4] = gen_reg_rtx (XFmode);
14519 (define_expand "ldexp<mode>3"
14520 [(use (match_operand:MODEF 0 "register_operand" ""))
14521 (use (match_operand:MODEF 1 "general_operand" ""))
14522 (use (match_operand:SI 2 "register_operand" ""))]
14523 "TARGET_USE_FANCY_MATH_387
14524 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14525 || TARGET_MIX_SSE_I387)
14526 && flag_unsafe_math_optimizations"
14530 if (optimize_insn_for_size_p ())
14533 op0 = gen_reg_rtx (XFmode);
14534 op1 = gen_reg_rtx (XFmode);
14536 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14537 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14538 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14542 (define_expand "scalbxf3"
14543 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14544 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14545 (match_operand:XF 2 "register_operand" "")]
14546 UNSPEC_FSCALE_FRACT))
14548 (unspec:XF [(match_dup 1) (match_dup 2)]
14549 UNSPEC_FSCALE_EXP))])]
14550 "TARGET_USE_FANCY_MATH_387
14551 && flag_unsafe_math_optimizations"
14553 if (optimize_insn_for_size_p ())
14556 operands[3] = gen_reg_rtx (XFmode);
14559 (define_expand "scalb<mode>3"
14560 [(use (match_operand:MODEF 0 "register_operand" ""))
14561 (use (match_operand:MODEF 1 "general_operand" ""))
14562 (use (match_operand:MODEF 2 "general_operand" ""))]
14563 "TARGET_USE_FANCY_MATH_387
14564 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14565 || TARGET_MIX_SSE_I387)
14566 && flag_unsafe_math_optimizations"
14570 if (optimize_insn_for_size_p ())
14573 op0 = gen_reg_rtx (XFmode);
14574 op1 = gen_reg_rtx (XFmode);
14575 op2 = gen_reg_rtx (XFmode);
14577 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14578 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14579 emit_insn (gen_scalbxf3 (op0, op1, op2));
14580 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14584 (define_expand "significandxf2"
14585 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14586 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14587 UNSPEC_XTRACT_FRACT))
14589 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14590 "TARGET_USE_FANCY_MATH_387
14591 && flag_unsafe_math_optimizations"
14592 "operands[2] = gen_reg_rtx (XFmode);")
14594 (define_expand "significand<mode>2"
14595 [(use (match_operand:MODEF 0 "register_operand" ""))
14596 (use (match_operand:MODEF 1 "register_operand" ""))]
14597 "TARGET_USE_FANCY_MATH_387
14598 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14599 || TARGET_MIX_SSE_I387)
14600 && flag_unsafe_math_optimizations"
14602 rtx op0 = gen_reg_rtx (XFmode);
14603 rtx op1 = gen_reg_rtx (XFmode);
14605 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14606 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14611 (define_insn "sse4_1_round<mode>2"
14612 [(set (match_operand:MODEF 0 "register_operand" "=x")
14613 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14614 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14617 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14618 [(set_attr "type" "ssecvt")
14619 (set_attr "prefix_extra" "1")
14620 (set_attr "prefix" "maybe_vex")
14621 (set_attr "mode" "<MODE>")])
14623 (define_insn "rintxf2"
14624 [(set (match_operand:XF 0 "register_operand" "=f")
14625 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14627 "TARGET_USE_FANCY_MATH_387
14628 && flag_unsafe_math_optimizations"
14630 [(set_attr "type" "fpspc")
14631 (set_attr "mode" "XF")])
14633 (define_expand "rint<mode>2"
14634 [(use (match_operand:MODEF 0 "register_operand" ""))
14635 (use (match_operand:MODEF 1 "register_operand" ""))]
14636 "(TARGET_USE_FANCY_MATH_387
14637 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14638 || TARGET_MIX_SSE_I387)
14639 && flag_unsafe_math_optimizations)
14640 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14641 && !flag_trapping_math)"
14643 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14644 && !flag_trapping_math)
14647 emit_insn (gen_sse4_1_round<mode>2
14648 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14649 else if (optimize_insn_for_size_p ())
14652 ix86_expand_rint (operands[0], operands[1]);
14656 rtx op0 = gen_reg_rtx (XFmode);
14657 rtx op1 = gen_reg_rtx (XFmode);
14659 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14660 emit_insn (gen_rintxf2 (op0, op1));
14662 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14667 (define_expand "round<mode>2"
14668 [(match_operand:X87MODEF 0 "register_operand" "")
14669 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14670 "(TARGET_USE_FANCY_MATH_387
14671 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14672 || TARGET_MIX_SSE_I387)
14673 && flag_unsafe_math_optimizations)
14674 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14675 && !flag_trapping_math && !flag_rounding_math)"
14677 if (optimize_insn_for_size_p ())
14680 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14681 && !flag_trapping_math && !flag_rounding_math)
14685 operands[1] = force_reg (<MODE>mode, operands[1]);
14686 ix86_expand_round_sse4 (operands[0], operands[1]);
14688 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14689 ix86_expand_round (operands[0], operands[1]);
14691 ix86_expand_rounddf_32 (operands[0], operands[1]);
14695 operands[1] = force_reg (<MODE>mode, operands[1]);
14696 ix86_emit_i387_round (operands[0], operands[1]);
14701 (define_insn_and_split "*fistdi2_1"
14702 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14703 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14705 "TARGET_USE_FANCY_MATH_387
14706 && can_create_pseudo_p ()"
14711 if (memory_operand (operands[0], VOIDmode))
14712 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14715 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14716 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14721 [(set_attr "type" "fpspc")
14722 (set_attr "mode" "DI")])
14724 (define_insn "fistdi2"
14725 [(set (match_operand:DI 0 "memory_operand" "=m")
14726 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14728 (clobber (match_scratch:XF 2 "=&1f"))]
14729 "TARGET_USE_FANCY_MATH_387"
14730 "* return output_fix_trunc (insn, operands, false);"
14731 [(set_attr "type" "fpspc")
14732 (set_attr "mode" "DI")])
14734 (define_insn "fistdi2_with_temp"
14735 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14736 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14738 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14739 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14740 "TARGET_USE_FANCY_MATH_387"
14742 [(set_attr "type" "fpspc")
14743 (set_attr "mode" "DI")])
14746 [(set (match_operand:DI 0 "register_operand" "")
14747 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14749 (clobber (match_operand:DI 2 "memory_operand" ""))
14750 (clobber (match_scratch 3 ""))]
14752 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14753 (clobber (match_dup 3))])
14754 (set (match_dup 0) (match_dup 2))])
14757 [(set (match_operand:DI 0 "memory_operand" "")
14758 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14760 (clobber (match_operand:DI 2 "memory_operand" ""))
14761 (clobber (match_scratch 3 ""))]
14763 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14764 (clobber (match_dup 3))])])
14766 (define_insn_and_split "*fist<mode>2_1"
14767 [(set (match_operand:SWI24 0 "register_operand" "")
14768 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14770 "TARGET_USE_FANCY_MATH_387
14771 && can_create_pseudo_p ()"
14776 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14777 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14781 [(set_attr "type" "fpspc")
14782 (set_attr "mode" "<MODE>")])
14784 (define_insn "fist<mode>2"
14785 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14786 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14788 "TARGET_USE_FANCY_MATH_387"
14789 "* return output_fix_trunc (insn, operands, false);"
14790 [(set_attr "type" "fpspc")
14791 (set_attr "mode" "<MODE>")])
14793 (define_insn "fist<mode>2_with_temp"
14794 [(set (match_operand:SWI24 0 "register_operand" "=r")
14795 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14797 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14798 "TARGET_USE_FANCY_MATH_387"
14800 [(set_attr "type" "fpspc")
14801 (set_attr "mode" "<MODE>")])
14804 [(set (match_operand:SWI24 0 "register_operand" "")
14805 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14807 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14809 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14810 (set (match_dup 0) (match_dup 2))])
14813 [(set (match_operand:SWI24 0 "memory_operand" "")
14814 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14816 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14818 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14820 (define_expand "lrintxf<mode>2"
14821 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14822 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14824 "TARGET_USE_FANCY_MATH_387")
14826 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14827 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14828 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14829 UNSPEC_FIX_NOTRUNC))]
14830 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14831 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14833 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14834 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14835 (match_operand:X87MODEF 1 "register_operand" "")]
14836 "(TARGET_USE_FANCY_MATH_387
14837 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14838 || TARGET_MIX_SSE_I387)
14839 && flag_unsafe_math_optimizations)
14840 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14841 && <SWI248x:MODE>mode != HImode
14842 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14843 && !flag_trapping_math && !flag_rounding_math)"
14845 if (optimize_insn_for_size_p ())
14848 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14849 && <SWI248x:MODE>mode != HImode
14850 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14851 && !flag_trapping_math && !flag_rounding_math)
14852 ix86_expand_lround (operands[0], operands[1]);
14854 ix86_emit_i387_round (operands[0], operands[1]);
14858 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14859 (define_insn_and_split "frndintxf2_floor"
14860 [(set (match_operand:XF 0 "register_operand" "")
14861 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14862 UNSPEC_FRNDINT_FLOOR))
14863 (clobber (reg:CC FLAGS_REG))]
14864 "TARGET_USE_FANCY_MATH_387
14865 && flag_unsafe_math_optimizations
14866 && can_create_pseudo_p ()"
14871 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14873 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14874 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14876 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14877 operands[2], operands[3]));
14880 [(set_attr "type" "frndint")
14881 (set_attr "i387_cw" "floor")
14882 (set_attr "mode" "XF")])
14884 (define_insn "frndintxf2_floor_i387"
14885 [(set (match_operand:XF 0 "register_operand" "=f")
14886 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14887 UNSPEC_FRNDINT_FLOOR))
14888 (use (match_operand:HI 2 "memory_operand" "m"))
14889 (use (match_operand:HI 3 "memory_operand" "m"))]
14890 "TARGET_USE_FANCY_MATH_387
14891 && flag_unsafe_math_optimizations"
14892 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14893 [(set_attr "type" "frndint")
14894 (set_attr "i387_cw" "floor")
14895 (set_attr "mode" "XF")])
14897 (define_expand "floorxf2"
14898 [(use (match_operand:XF 0 "register_operand" ""))
14899 (use (match_operand:XF 1 "register_operand" ""))]
14900 "TARGET_USE_FANCY_MATH_387
14901 && flag_unsafe_math_optimizations"
14903 if (optimize_insn_for_size_p ())
14905 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14909 (define_expand "floor<mode>2"
14910 [(use (match_operand:MODEF 0 "register_operand" ""))
14911 (use (match_operand:MODEF 1 "register_operand" ""))]
14912 "(TARGET_USE_FANCY_MATH_387
14913 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14914 || TARGET_MIX_SSE_I387)
14915 && flag_unsafe_math_optimizations)
14916 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14917 && !flag_trapping_math)"
14919 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14920 && !flag_trapping_math)
14923 emit_insn (gen_sse4_1_round<mode>2
14924 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14925 else if (optimize_insn_for_size_p ())
14927 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14928 ix86_expand_floorceil (operands[0], operands[1], true);
14930 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14936 if (optimize_insn_for_size_p ())
14939 op0 = gen_reg_rtx (XFmode);
14940 op1 = gen_reg_rtx (XFmode);
14941 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14942 emit_insn (gen_frndintxf2_floor (op0, op1));
14944 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14949 (define_insn_and_split "*fist<mode>2_floor_1"
14950 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14951 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14952 UNSPEC_FIST_FLOOR))
14953 (clobber (reg:CC FLAGS_REG))]
14954 "TARGET_USE_FANCY_MATH_387
14955 && flag_unsafe_math_optimizations
14956 && can_create_pseudo_p ()"
14961 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14963 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14964 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14965 if (memory_operand (operands[0], VOIDmode))
14966 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14967 operands[2], operands[3]));
14970 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14971 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14972 operands[2], operands[3],
14977 [(set_attr "type" "fistp")
14978 (set_attr "i387_cw" "floor")
14979 (set_attr "mode" "<MODE>")])
14981 (define_insn "fistdi2_floor"
14982 [(set (match_operand:DI 0 "memory_operand" "=m")
14983 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14984 UNSPEC_FIST_FLOOR))
14985 (use (match_operand:HI 2 "memory_operand" "m"))
14986 (use (match_operand:HI 3 "memory_operand" "m"))
14987 (clobber (match_scratch:XF 4 "=&1f"))]
14988 "TARGET_USE_FANCY_MATH_387
14989 && flag_unsafe_math_optimizations"
14990 "* return output_fix_trunc (insn, operands, false);"
14991 [(set_attr "type" "fistp")
14992 (set_attr "i387_cw" "floor")
14993 (set_attr "mode" "DI")])
14995 (define_insn "fistdi2_floor_with_temp"
14996 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14997 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14998 UNSPEC_FIST_FLOOR))
14999 (use (match_operand:HI 2 "memory_operand" "m,m"))
15000 (use (match_operand:HI 3 "memory_operand" "m,m"))
15001 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15002 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15003 "TARGET_USE_FANCY_MATH_387
15004 && flag_unsafe_math_optimizations"
15006 [(set_attr "type" "fistp")
15007 (set_attr "i387_cw" "floor")
15008 (set_attr "mode" "DI")])
15011 [(set (match_operand:DI 0 "register_operand" "")
15012 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15013 UNSPEC_FIST_FLOOR))
15014 (use (match_operand:HI 2 "memory_operand" ""))
15015 (use (match_operand:HI 3 "memory_operand" ""))
15016 (clobber (match_operand:DI 4 "memory_operand" ""))
15017 (clobber (match_scratch 5 ""))]
15019 [(parallel [(set (match_dup 4)
15020 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15021 (use (match_dup 2))
15022 (use (match_dup 3))
15023 (clobber (match_dup 5))])
15024 (set (match_dup 0) (match_dup 4))])
15027 [(set (match_operand:DI 0 "memory_operand" "")
15028 (unspec:DI [(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:DI 4 "memory_operand" ""))
15033 (clobber (match_scratch 5 ""))]
15035 [(parallel [(set (match_dup 0)
15036 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15037 (use (match_dup 2))
15038 (use (match_dup 3))
15039 (clobber (match_dup 5))])])
15041 (define_insn "fist<mode>2_floor"
15042 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15043 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15044 UNSPEC_FIST_FLOOR))
15045 (use (match_operand:HI 2 "memory_operand" "m"))
15046 (use (match_operand:HI 3 "memory_operand" "m"))]
15047 "TARGET_USE_FANCY_MATH_387
15048 && flag_unsafe_math_optimizations"
15049 "* return output_fix_trunc (insn, operands, false);"
15050 [(set_attr "type" "fistp")
15051 (set_attr "i387_cw" "floor")
15052 (set_attr "mode" "<MODE>")])
15054 (define_insn "fist<mode>2_floor_with_temp"
15055 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15056 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15057 UNSPEC_FIST_FLOOR))
15058 (use (match_operand:HI 2 "memory_operand" "m,m"))
15059 (use (match_operand:HI 3 "memory_operand" "m,m"))
15060 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15061 "TARGET_USE_FANCY_MATH_387
15062 && flag_unsafe_math_optimizations"
15064 [(set_attr "type" "fistp")
15065 (set_attr "i387_cw" "floor")
15066 (set_attr "mode" "<MODE>")])
15069 [(set (match_operand:SWI24 0 "register_operand" "")
15070 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15071 UNSPEC_FIST_FLOOR))
15072 (use (match_operand:HI 2 "memory_operand" ""))
15073 (use (match_operand:HI 3 "memory_operand" ""))
15074 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15076 [(parallel [(set (match_dup 4)
15077 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15078 (use (match_dup 2))
15079 (use (match_dup 3))])
15080 (set (match_dup 0) (match_dup 4))])
15083 [(set (match_operand:SWI24 0 "memory_operand" "")
15084 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15085 UNSPEC_FIST_FLOOR))
15086 (use (match_operand:HI 2 "memory_operand" ""))
15087 (use (match_operand:HI 3 "memory_operand" ""))
15088 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15090 [(parallel [(set (match_dup 0)
15091 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15092 (use (match_dup 2))
15093 (use (match_dup 3))])])
15095 (define_expand "lfloorxf<mode>2"
15096 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15097 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15098 UNSPEC_FIST_FLOOR))
15099 (clobber (reg:CC FLAGS_REG))])]
15100 "TARGET_USE_FANCY_MATH_387
15101 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15102 && flag_unsafe_math_optimizations")
15104 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15105 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15106 (match_operand:MODEF 1 "register_operand" "")]
15107 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15108 && !flag_trapping_math"
15110 if (TARGET_64BIT && optimize_insn_for_size_p ())
15112 ix86_expand_lfloorceil (operands[0], operands[1], true);
15116 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15117 (define_insn_and_split "frndintxf2_ceil"
15118 [(set (match_operand:XF 0 "register_operand" "")
15119 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15120 UNSPEC_FRNDINT_CEIL))
15121 (clobber (reg:CC FLAGS_REG))]
15122 "TARGET_USE_FANCY_MATH_387
15123 && flag_unsafe_math_optimizations
15124 && can_create_pseudo_p ()"
15129 ix86_optimize_mode_switching[I387_CEIL] = 1;
15131 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15132 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15134 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15135 operands[2], operands[3]));
15138 [(set_attr "type" "frndint")
15139 (set_attr "i387_cw" "ceil")
15140 (set_attr "mode" "XF")])
15142 (define_insn "frndintxf2_ceil_i387"
15143 [(set (match_operand:XF 0 "register_operand" "=f")
15144 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15145 UNSPEC_FRNDINT_CEIL))
15146 (use (match_operand:HI 2 "memory_operand" "m"))
15147 (use (match_operand:HI 3 "memory_operand" "m"))]
15148 "TARGET_USE_FANCY_MATH_387
15149 && flag_unsafe_math_optimizations"
15150 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15151 [(set_attr "type" "frndint")
15152 (set_attr "i387_cw" "ceil")
15153 (set_attr "mode" "XF")])
15155 (define_expand "ceilxf2"
15156 [(use (match_operand:XF 0 "register_operand" ""))
15157 (use (match_operand:XF 1 "register_operand" ""))]
15158 "TARGET_USE_FANCY_MATH_387
15159 && flag_unsafe_math_optimizations"
15161 if (optimize_insn_for_size_p ())
15163 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15167 (define_expand "ceil<mode>2"
15168 [(use (match_operand:MODEF 0 "register_operand" ""))
15169 (use (match_operand:MODEF 1 "register_operand" ""))]
15170 "(TARGET_USE_FANCY_MATH_387
15171 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15172 || TARGET_MIX_SSE_I387)
15173 && flag_unsafe_math_optimizations)
15174 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15175 && !flag_trapping_math)"
15177 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15178 && !flag_trapping_math)
15181 emit_insn (gen_sse4_1_round<mode>2
15182 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15183 else if (optimize_insn_for_size_p ())
15185 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15186 ix86_expand_floorceil (operands[0], operands[1], false);
15188 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15194 if (optimize_insn_for_size_p ())
15197 op0 = gen_reg_rtx (XFmode);
15198 op1 = gen_reg_rtx (XFmode);
15199 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15200 emit_insn (gen_frndintxf2_ceil (op0, op1));
15202 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15207 (define_insn_and_split "*fist<mode>2_ceil_1"
15208 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15209 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15211 (clobber (reg:CC FLAGS_REG))]
15212 "TARGET_USE_FANCY_MATH_387
15213 && flag_unsafe_math_optimizations
15214 && can_create_pseudo_p ()"
15219 ix86_optimize_mode_switching[I387_CEIL] = 1;
15221 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15222 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15223 if (memory_operand (operands[0], VOIDmode))
15224 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15225 operands[2], operands[3]));
15228 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15229 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15230 operands[2], operands[3],
15235 [(set_attr "type" "fistp")
15236 (set_attr "i387_cw" "ceil")
15237 (set_attr "mode" "<MODE>")])
15239 (define_insn "fistdi2_ceil"
15240 [(set (match_operand:DI 0 "memory_operand" "=m")
15241 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15243 (use (match_operand:HI 2 "memory_operand" "m"))
15244 (use (match_operand:HI 3 "memory_operand" "m"))
15245 (clobber (match_scratch:XF 4 "=&1f"))]
15246 "TARGET_USE_FANCY_MATH_387
15247 && flag_unsafe_math_optimizations"
15248 "* return output_fix_trunc (insn, operands, false);"
15249 [(set_attr "type" "fistp")
15250 (set_attr "i387_cw" "ceil")
15251 (set_attr "mode" "DI")])
15253 (define_insn "fistdi2_ceil_with_temp"
15254 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15255 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15257 (use (match_operand:HI 2 "memory_operand" "m,m"))
15258 (use (match_operand:HI 3 "memory_operand" "m,m"))
15259 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15260 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15261 "TARGET_USE_FANCY_MATH_387
15262 && flag_unsafe_math_optimizations"
15264 [(set_attr "type" "fistp")
15265 (set_attr "i387_cw" "ceil")
15266 (set_attr "mode" "DI")])
15269 [(set (match_operand:DI 0 "register_operand" "")
15270 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15272 (use (match_operand:HI 2 "memory_operand" ""))
15273 (use (match_operand:HI 3 "memory_operand" ""))
15274 (clobber (match_operand:DI 4 "memory_operand" ""))
15275 (clobber (match_scratch 5 ""))]
15277 [(parallel [(set (match_dup 4)
15278 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15279 (use (match_dup 2))
15280 (use (match_dup 3))
15281 (clobber (match_dup 5))])
15282 (set (match_dup 0) (match_dup 4))])
15285 [(set (match_operand:DI 0 "memory_operand" "")
15286 (unspec:DI [(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:DI 4 "memory_operand" ""))
15291 (clobber (match_scratch 5 ""))]
15293 [(parallel [(set (match_dup 0)
15294 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15295 (use (match_dup 2))
15296 (use (match_dup 3))
15297 (clobber (match_dup 5))])])
15299 (define_insn "fist<mode>2_ceil"
15300 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15301 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15303 (use (match_operand:HI 2 "memory_operand" "m"))
15304 (use (match_operand:HI 3 "memory_operand" "m"))]
15305 "TARGET_USE_FANCY_MATH_387
15306 && flag_unsafe_math_optimizations"
15307 "* return output_fix_trunc (insn, operands, false);"
15308 [(set_attr "type" "fistp")
15309 (set_attr "i387_cw" "ceil")
15310 (set_attr "mode" "<MODE>")])
15312 (define_insn "fist<mode>2_ceil_with_temp"
15313 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15314 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15316 (use (match_operand:HI 2 "memory_operand" "m,m"))
15317 (use (match_operand:HI 3 "memory_operand" "m,m"))
15318 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15319 "TARGET_USE_FANCY_MATH_387
15320 && flag_unsafe_math_optimizations"
15322 [(set_attr "type" "fistp")
15323 (set_attr "i387_cw" "ceil")
15324 (set_attr "mode" "<MODE>")])
15327 [(set (match_operand:SWI24 0 "register_operand" "")
15328 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15330 (use (match_operand:HI 2 "memory_operand" ""))
15331 (use (match_operand:HI 3 "memory_operand" ""))
15332 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15334 [(parallel [(set (match_dup 4)
15335 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15336 (use (match_dup 2))
15337 (use (match_dup 3))])
15338 (set (match_dup 0) (match_dup 4))])
15341 [(set (match_operand:SWI24 0 "memory_operand" "")
15342 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15344 (use (match_operand:HI 2 "memory_operand" ""))
15345 (use (match_operand:HI 3 "memory_operand" ""))
15346 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15348 [(parallel [(set (match_dup 0)
15349 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15350 (use (match_dup 2))
15351 (use (match_dup 3))])])
15353 (define_expand "lceilxf<mode>2"
15354 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15355 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15357 (clobber (reg:CC FLAGS_REG))])]
15358 "TARGET_USE_FANCY_MATH_387
15359 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15360 && flag_unsafe_math_optimizations")
15362 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15363 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15364 (match_operand:MODEF 1 "register_operand" "")]
15365 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15366 && !flag_trapping_math"
15368 ix86_expand_lfloorceil (operands[0], operands[1], false);
15372 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15373 (define_insn_and_split "frndintxf2_trunc"
15374 [(set (match_operand:XF 0 "register_operand" "")
15375 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15376 UNSPEC_FRNDINT_TRUNC))
15377 (clobber (reg:CC FLAGS_REG))]
15378 "TARGET_USE_FANCY_MATH_387
15379 && flag_unsafe_math_optimizations
15380 && can_create_pseudo_p ()"
15385 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15387 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15388 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15390 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15391 operands[2], operands[3]));
15394 [(set_attr "type" "frndint")
15395 (set_attr "i387_cw" "trunc")
15396 (set_attr "mode" "XF")])
15398 (define_insn "frndintxf2_trunc_i387"
15399 [(set (match_operand:XF 0 "register_operand" "=f")
15400 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15401 UNSPEC_FRNDINT_TRUNC))
15402 (use (match_operand:HI 2 "memory_operand" "m"))
15403 (use (match_operand:HI 3 "memory_operand" "m"))]
15404 "TARGET_USE_FANCY_MATH_387
15405 && flag_unsafe_math_optimizations"
15406 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15407 [(set_attr "type" "frndint")
15408 (set_attr "i387_cw" "trunc")
15409 (set_attr "mode" "XF")])
15411 (define_expand "btruncxf2"
15412 [(use (match_operand:XF 0 "register_operand" ""))
15413 (use (match_operand:XF 1 "register_operand" ""))]
15414 "TARGET_USE_FANCY_MATH_387
15415 && flag_unsafe_math_optimizations"
15417 if (optimize_insn_for_size_p ())
15419 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15423 (define_expand "btrunc<mode>2"
15424 [(use (match_operand:MODEF 0 "register_operand" ""))
15425 (use (match_operand:MODEF 1 "register_operand" ""))]
15426 "(TARGET_USE_FANCY_MATH_387
15427 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15428 || TARGET_MIX_SSE_I387)
15429 && flag_unsafe_math_optimizations)
15430 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15431 && !flag_trapping_math)"
15433 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15434 && !flag_trapping_math)
15437 emit_insn (gen_sse4_1_round<mode>2
15438 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15439 else if (optimize_insn_for_size_p ())
15441 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15442 ix86_expand_trunc (operands[0], operands[1]);
15444 ix86_expand_truncdf_32 (operands[0], operands[1]);
15450 if (optimize_insn_for_size_p ())
15453 op0 = gen_reg_rtx (XFmode);
15454 op1 = gen_reg_rtx (XFmode);
15455 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15456 emit_insn (gen_frndintxf2_trunc (op0, op1));
15458 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15463 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15464 (define_insn_and_split "frndintxf2_mask_pm"
15465 [(set (match_operand:XF 0 "register_operand" "")
15466 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15467 UNSPEC_FRNDINT_MASK_PM))
15468 (clobber (reg:CC FLAGS_REG))]
15469 "TARGET_USE_FANCY_MATH_387
15470 && flag_unsafe_math_optimizations
15471 && can_create_pseudo_p ()"
15476 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15478 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15479 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15481 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15482 operands[2], operands[3]));
15485 [(set_attr "type" "frndint")
15486 (set_attr "i387_cw" "mask_pm")
15487 (set_attr "mode" "XF")])
15489 (define_insn "frndintxf2_mask_pm_i387"
15490 [(set (match_operand:XF 0 "register_operand" "=f")
15491 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15492 UNSPEC_FRNDINT_MASK_PM))
15493 (use (match_operand:HI 2 "memory_operand" "m"))
15494 (use (match_operand:HI 3 "memory_operand" "m"))]
15495 "TARGET_USE_FANCY_MATH_387
15496 && flag_unsafe_math_optimizations"
15497 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15498 [(set_attr "type" "frndint")
15499 (set_attr "i387_cw" "mask_pm")
15500 (set_attr "mode" "XF")])
15502 (define_expand "nearbyintxf2"
15503 [(use (match_operand:XF 0 "register_operand" ""))
15504 (use (match_operand:XF 1 "register_operand" ""))]
15505 "TARGET_USE_FANCY_MATH_387
15506 && flag_unsafe_math_optimizations"
15508 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15512 (define_expand "nearbyint<mode>2"
15513 [(use (match_operand:MODEF 0 "register_operand" ""))
15514 (use (match_operand:MODEF 1 "register_operand" ""))]
15515 "TARGET_USE_FANCY_MATH_387
15516 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15517 || TARGET_MIX_SSE_I387)
15518 && flag_unsafe_math_optimizations"
15520 rtx op0 = gen_reg_rtx (XFmode);
15521 rtx op1 = gen_reg_rtx (XFmode);
15523 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15524 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15526 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15530 (define_insn "fxam<mode>2_i387"
15531 [(set (match_operand:HI 0 "register_operand" "=a")
15533 [(match_operand:X87MODEF 1 "register_operand" "f")]
15535 "TARGET_USE_FANCY_MATH_387"
15536 "fxam\n\tfnstsw\t%0"
15537 [(set_attr "type" "multi")
15538 (set_attr "length" "4")
15539 (set_attr "unit" "i387")
15540 (set_attr "mode" "<MODE>")])
15542 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15543 [(set (match_operand:HI 0 "register_operand" "")
15545 [(match_operand:MODEF 1 "memory_operand" "")]
15547 "TARGET_USE_FANCY_MATH_387
15548 && can_create_pseudo_p ()"
15551 [(set (match_dup 2)(match_dup 1))
15553 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15555 operands[2] = gen_reg_rtx (<MODE>mode);
15557 MEM_VOLATILE_P (operands[1]) = 1;
15559 [(set_attr "type" "multi")
15560 (set_attr "unit" "i387")
15561 (set_attr "mode" "<MODE>")])
15563 (define_expand "isinfxf2"
15564 [(use (match_operand:SI 0 "register_operand" ""))
15565 (use (match_operand:XF 1 "register_operand" ""))]
15566 "TARGET_USE_FANCY_MATH_387
15567 && TARGET_C99_FUNCTIONS"
15569 rtx mask = GEN_INT (0x45);
15570 rtx val = GEN_INT (0x05);
15574 rtx scratch = gen_reg_rtx (HImode);
15575 rtx res = gen_reg_rtx (QImode);
15577 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15579 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15580 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15581 cond = gen_rtx_fmt_ee (EQ, QImode,
15582 gen_rtx_REG (CCmode, FLAGS_REG),
15584 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15585 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15589 (define_expand "isinf<mode>2"
15590 [(use (match_operand:SI 0 "register_operand" ""))
15591 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15592 "TARGET_USE_FANCY_MATH_387
15593 && TARGET_C99_FUNCTIONS
15594 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15596 rtx mask = GEN_INT (0x45);
15597 rtx val = GEN_INT (0x05);
15601 rtx scratch = gen_reg_rtx (HImode);
15602 rtx res = gen_reg_rtx (QImode);
15604 /* Remove excess precision by forcing value through memory. */
15605 if (memory_operand (operands[1], VOIDmode))
15606 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15609 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15611 emit_move_insn (temp, operands[1]);
15612 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15615 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15616 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15617 cond = gen_rtx_fmt_ee (EQ, QImode,
15618 gen_rtx_REG (CCmode, FLAGS_REG),
15620 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15621 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15625 (define_expand "signbitxf2"
15626 [(use (match_operand:SI 0 "register_operand" ""))
15627 (use (match_operand:XF 1 "register_operand" ""))]
15628 "TARGET_USE_FANCY_MATH_387"
15630 rtx scratch = gen_reg_rtx (HImode);
15632 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15633 emit_insn (gen_andsi3 (operands[0],
15634 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15638 (define_insn "movmsk_df"
15639 [(set (match_operand:SI 0 "register_operand" "=r")
15641 [(match_operand:DF 1 "register_operand" "x")]
15643 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15644 "%vmovmskpd\t{%1, %0|%0, %1}"
15645 [(set_attr "type" "ssemov")
15646 (set_attr "prefix" "maybe_vex")
15647 (set_attr "mode" "DF")])
15649 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15650 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15651 (define_expand "signbitdf2"
15652 [(use (match_operand:SI 0 "register_operand" ""))
15653 (use (match_operand:DF 1 "register_operand" ""))]
15654 "TARGET_USE_FANCY_MATH_387
15655 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15657 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15659 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15660 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15664 rtx scratch = gen_reg_rtx (HImode);
15666 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15667 emit_insn (gen_andsi3 (operands[0],
15668 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15673 (define_expand "signbitsf2"
15674 [(use (match_operand:SI 0 "register_operand" ""))
15675 (use (match_operand:SF 1 "register_operand" ""))]
15676 "TARGET_USE_FANCY_MATH_387
15677 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15679 rtx scratch = gen_reg_rtx (HImode);
15681 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15682 emit_insn (gen_andsi3 (operands[0],
15683 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15687 ;; Block operation instructions
15690 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15693 [(set_attr "length" "1")
15694 (set_attr "length_immediate" "0")
15695 (set_attr "modrm" "0")])
15697 (define_expand "movmem<mode>"
15698 [(use (match_operand:BLK 0 "memory_operand" ""))
15699 (use (match_operand:BLK 1 "memory_operand" ""))
15700 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15701 (use (match_operand:SWI48 3 "const_int_operand" ""))
15702 (use (match_operand:SI 4 "const_int_operand" ""))
15703 (use (match_operand:SI 5 "const_int_operand" ""))]
15706 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15707 operands[4], operands[5]))
15713 ;; Most CPUs don't like single string operations
15714 ;; Handle this case here to simplify previous expander.
15716 (define_expand "strmov"
15717 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15718 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15719 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15720 (clobber (reg:CC FLAGS_REG))])
15721 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15722 (clobber (reg:CC FLAGS_REG))])]
15725 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15727 /* If .md ever supports :P for Pmode, these can be directly
15728 in the pattern above. */
15729 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15730 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15732 /* Can't use this if the user has appropriated esi or edi. */
15733 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15734 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15736 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15737 operands[2], operands[3],
15738 operands[5], operands[6]));
15742 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15745 (define_expand "strmov_singleop"
15746 [(parallel [(set (match_operand 1 "memory_operand" "")
15747 (match_operand 3 "memory_operand" ""))
15748 (set (match_operand 0 "register_operand" "")
15749 (match_operand 4 "" ""))
15750 (set (match_operand 2 "register_operand" "")
15751 (match_operand 5 "" ""))])]
15753 "ix86_current_function_needs_cld = 1;")
15755 (define_insn "*strmovdi_rex_1"
15756 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15757 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15758 (set (match_operand:DI 0 "register_operand" "=D")
15759 (plus:DI (match_dup 2)
15761 (set (match_operand:DI 1 "register_operand" "=S")
15762 (plus:DI (match_dup 3)
15765 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15767 [(set_attr "type" "str")
15768 (set_attr "memory" "both")
15769 (set_attr "mode" "DI")])
15771 (define_insn "*strmovsi_1"
15772 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15773 (mem:SI (match_operand:P 3 "register_operand" "1")))
15774 (set (match_operand:P 0 "register_operand" "=D")
15775 (plus:P (match_dup 2)
15777 (set (match_operand:P 1 "register_operand" "=S")
15778 (plus:P (match_dup 3)
15780 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15782 [(set_attr "type" "str")
15783 (set_attr "memory" "both")
15784 (set_attr "mode" "SI")])
15786 (define_insn "*strmovhi_1"
15787 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15788 (mem:HI (match_operand:P 3 "register_operand" "1")))
15789 (set (match_operand:P 0 "register_operand" "=D")
15790 (plus:P (match_dup 2)
15792 (set (match_operand:P 1 "register_operand" "=S")
15793 (plus:P (match_dup 3)
15795 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15797 [(set_attr "type" "str")
15798 (set_attr "memory" "both")
15799 (set_attr "mode" "HI")])
15801 (define_insn "*strmovqi_1"
15802 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15803 (mem:QI (match_operand:P 3 "register_operand" "1")))
15804 (set (match_operand:P 0 "register_operand" "=D")
15805 (plus:P (match_dup 2)
15807 (set (match_operand:P 1 "register_operand" "=S")
15808 (plus:P (match_dup 3)
15810 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15812 [(set_attr "type" "str")
15813 (set_attr "memory" "both")
15814 (set (attr "prefix_rex")
15816 (match_test "<P:MODE>mode == DImode")
15818 (const_string "*")))
15819 (set_attr "mode" "QI")])
15821 (define_expand "rep_mov"
15822 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15823 (set (match_operand 0 "register_operand" "")
15824 (match_operand 5 "" ""))
15825 (set (match_operand 2 "register_operand" "")
15826 (match_operand 6 "" ""))
15827 (set (match_operand 1 "memory_operand" "")
15828 (match_operand 3 "memory_operand" ""))
15829 (use (match_dup 4))])]
15831 "ix86_current_function_needs_cld = 1;")
15833 (define_insn "*rep_movdi_rex64"
15834 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15835 (set (match_operand:DI 0 "register_operand" "=D")
15836 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15838 (match_operand:DI 3 "register_operand" "0")))
15839 (set (match_operand:DI 1 "register_operand" "=S")
15840 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15841 (match_operand:DI 4 "register_operand" "1")))
15842 (set (mem:BLK (match_dup 3))
15843 (mem:BLK (match_dup 4)))
15844 (use (match_dup 5))]
15846 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15848 [(set_attr "type" "str")
15849 (set_attr "prefix_rep" "1")
15850 (set_attr "memory" "both")
15851 (set_attr "mode" "DI")])
15853 (define_insn "*rep_movsi"
15854 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15855 (set (match_operand:P 0 "register_operand" "=D")
15856 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15858 (match_operand:P 3 "register_operand" "0")))
15859 (set (match_operand:P 1 "register_operand" "=S")
15860 (plus:P (ashift:P (match_dup 5) (const_int 2))
15861 (match_operand:P 4 "register_operand" "1")))
15862 (set (mem:BLK (match_dup 3))
15863 (mem:BLK (match_dup 4)))
15864 (use (match_dup 5))]
15865 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15866 "rep{%;} movs{l|d}"
15867 [(set_attr "type" "str")
15868 (set_attr "prefix_rep" "1")
15869 (set_attr "memory" "both")
15870 (set_attr "mode" "SI")])
15872 (define_insn "*rep_movqi"
15873 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15874 (set (match_operand:P 0 "register_operand" "=D")
15875 (plus:P (match_operand:P 3 "register_operand" "0")
15876 (match_operand:P 5 "register_operand" "2")))
15877 (set (match_operand:P 1 "register_operand" "=S")
15878 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15879 (set (mem:BLK (match_dup 3))
15880 (mem:BLK (match_dup 4)))
15881 (use (match_dup 5))]
15882 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15884 [(set_attr "type" "str")
15885 (set_attr "prefix_rep" "1")
15886 (set_attr "memory" "both")
15887 (set_attr "mode" "QI")])
15889 (define_expand "setmem<mode>"
15890 [(use (match_operand:BLK 0 "memory_operand" ""))
15891 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15892 (use (match_operand:QI 2 "nonmemory_operand" ""))
15893 (use (match_operand 3 "const_int_operand" ""))
15894 (use (match_operand:SI 4 "const_int_operand" ""))
15895 (use (match_operand:SI 5 "const_int_operand" ""))]
15898 if (ix86_expand_setmem (operands[0], operands[1],
15899 operands[2], operands[3],
15900 operands[4], operands[5]))
15906 ;; Most CPUs don't like single string operations
15907 ;; Handle this case here to simplify previous expander.
15909 (define_expand "strset"
15910 [(set (match_operand 1 "memory_operand" "")
15911 (match_operand 2 "register_operand" ""))
15912 (parallel [(set (match_operand 0 "register_operand" "")
15914 (clobber (reg:CC FLAGS_REG))])]
15917 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15918 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15920 /* If .md ever supports :P for Pmode, this can be directly
15921 in the pattern above. */
15922 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15923 GEN_INT (GET_MODE_SIZE (GET_MODE
15925 /* Can't use this if the user has appropriated eax or edi. */
15926 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15927 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15929 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15935 (define_expand "strset_singleop"
15936 [(parallel [(set (match_operand 1 "memory_operand" "")
15937 (match_operand 2 "register_operand" ""))
15938 (set (match_operand 0 "register_operand" "")
15939 (match_operand 3 "" ""))])]
15941 "ix86_current_function_needs_cld = 1;")
15943 (define_insn "*strsetdi_rex_1"
15944 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15945 (match_operand:DI 2 "register_operand" "a"))
15946 (set (match_operand:DI 0 "register_operand" "=D")
15947 (plus:DI (match_dup 1)
15950 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15952 [(set_attr "type" "str")
15953 (set_attr "memory" "store")
15954 (set_attr "mode" "DI")])
15956 (define_insn "*strsetsi_1"
15957 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15958 (match_operand:SI 2 "register_operand" "a"))
15959 (set (match_operand:P 0 "register_operand" "=D")
15960 (plus:P (match_dup 1)
15962 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15964 [(set_attr "type" "str")
15965 (set_attr "memory" "store")
15966 (set_attr "mode" "SI")])
15968 (define_insn "*strsethi_1"
15969 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15970 (match_operand:HI 2 "register_operand" "a"))
15971 (set (match_operand:P 0 "register_operand" "=D")
15972 (plus:P (match_dup 1)
15974 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15976 [(set_attr "type" "str")
15977 (set_attr "memory" "store")
15978 (set_attr "mode" "HI")])
15980 (define_insn "*strsetqi_1"
15981 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15982 (match_operand:QI 2 "register_operand" "a"))
15983 (set (match_operand:P 0 "register_operand" "=D")
15984 (plus:P (match_dup 1)
15986 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15988 [(set_attr "type" "str")
15989 (set_attr "memory" "store")
15990 (set (attr "prefix_rex")
15992 (match_test "<P:MODE>mode == DImode")
15994 (const_string "*")))
15995 (set_attr "mode" "QI")])
15997 (define_expand "rep_stos"
15998 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15999 (set (match_operand 0 "register_operand" "")
16000 (match_operand 4 "" ""))
16001 (set (match_operand 2 "memory_operand" "") (const_int 0))
16002 (use (match_operand 3 "register_operand" ""))
16003 (use (match_dup 1))])]
16005 "ix86_current_function_needs_cld = 1;")
16007 (define_insn "*rep_stosdi_rex64"
16008 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16009 (set (match_operand:DI 0 "register_operand" "=D")
16010 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16012 (match_operand:DI 3 "register_operand" "0")))
16013 (set (mem:BLK (match_dup 3))
16015 (use (match_operand:DI 2 "register_operand" "a"))
16016 (use (match_dup 4))]
16018 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16020 [(set_attr "type" "str")
16021 (set_attr "prefix_rep" "1")
16022 (set_attr "memory" "store")
16023 (set_attr "mode" "DI")])
16025 (define_insn "*rep_stossi"
16026 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16027 (set (match_operand:P 0 "register_operand" "=D")
16028 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16030 (match_operand:P 3 "register_operand" "0")))
16031 (set (mem:BLK (match_dup 3))
16033 (use (match_operand:SI 2 "register_operand" "a"))
16034 (use (match_dup 4))]
16035 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16036 "rep{%;} stos{l|d}"
16037 [(set_attr "type" "str")
16038 (set_attr "prefix_rep" "1")
16039 (set_attr "memory" "store")
16040 (set_attr "mode" "SI")])
16042 (define_insn "*rep_stosqi"
16043 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16044 (set (match_operand:P 0 "register_operand" "=D")
16045 (plus:P (match_operand:P 3 "register_operand" "0")
16046 (match_operand:P 4 "register_operand" "1")))
16047 (set (mem:BLK (match_dup 3))
16049 (use (match_operand:QI 2 "register_operand" "a"))
16050 (use (match_dup 4))]
16051 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16053 [(set_attr "type" "str")
16054 (set_attr "prefix_rep" "1")
16055 (set_attr "memory" "store")
16056 (set (attr "prefix_rex")
16058 (match_test "<P:MODE>mode == DImode")
16060 (const_string "*")))
16061 (set_attr "mode" "QI")])
16063 (define_expand "cmpstrnsi"
16064 [(set (match_operand:SI 0 "register_operand" "")
16065 (compare:SI (match_operand:BLK 1 "general_operand" "")
16066 (match_operand:BLK 2 "general_operand" "")))
16067 (use (match_operand 3 "general_operand" ""))
16068 (use (match_operand 4 "immediate_operand" ""))]
16071 rtx addr1, addr2, out, outlow, count, countreg, align;
16073 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16076 /* Can't use this if the user has appropriated ecx, esi or edi. */
16077 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16082 out = gen_reg_rtx (SImode);
16084 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16085 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16086 if (addr1 != XEXP (operands[1], 0))
16087 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16088 if (addr2 != XEXP (operands[2], 0))
16089 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16091 count = operands[3];
16092 countreg = ix86_zero_extend_to_Pmode (count);
16094 /* %%% Iff we are testing strict equality, we can use known alignment
16095 to good advantage. This may be possible with combine, particularly
16096 once cc0 is dead. */
16097 align = operands[4];
16099 if (CONST_INT_P (count))
16101 if (INTVAL (count) == 0)
16103 emit_move_insn (operands[0], const0_rtx);
16106 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16107 operands[1], operands[2]));
16111 rtx (*gen_cmp) (rtx, rtx);
16113 gen_cmp = (TARGET_64BIT
16114 ? gen_cmpdi_1 : gen_cmpsi_1);
16116 emit_insn (gen_cmp (countreg, countreg));
16117 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16118 operands[1], operands[2]));
16121 outlow = gen_lowpart (QImode, out);
16122 emit_insn (gen_cmpintqi (outlow));
16123 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16125 if (operands[0] != out)
16126 emit_move_insn (operands[0], out);
16131 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16133 (define_expand "cmpintqi"
16134 [(set (match_dup 1)
16135 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16137 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16138 (parallel [(set (match_operand:QI 0 "register_operand" "")
16139 (minus:QI (match_dup 1)
16141 (clobber (reg:CC FLAGS_REG))])]
16144 operands[1] = gen_reg_rtx (QImode);
16145 operands[2] = gen_reg_rtx (QImode);
16148 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16149 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16151 (define_expand "cmpstrnqi_nz_1"
16152 [(parallel [(set (reg:CC FLAGS_REG)
16153 (compare:CC (match_operand 4 "memory_operand" "")
16154 (match_operand 5 "memory_operand" "")))
16155 (use (match_operand 2 "register_operand" ""))
16156 (use (match_operand:SI 3 "immediate_operand" ""))
16157 (clobber (match_operand 0 "register_operand" ""))
16158 (clobber (match_operand 1 "register_operand" ""))
16159 (clobber (match_dup 2))])]
16161 "ix86_current_function_needs_cld = 1;")
16163 (define_insn "*cmpstrnqi_nz_1"
16164 [(set (reg:CC FLAGS_REG)
16165 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16166 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16167 (use (match_operand:P 6 "register_operand" "2"))
16168 (use (match_operand:SI 3 "immediate_operand" "i"))
16169 (clobber (match_operand:P 0 "register_operand" "=S"))
16170 (clobber (match_operand:P 1 "register_operand" "=D"))
16171 (clobber (match_operand:P 2 "register_operand" "=c"))]
16172 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16174 [(set_attr "type" "str")
16175 (set_attr "mode" "QI")
16176 (set (attr "prefix_rex")
16178 (match_test "<P:MODE>mode == DImode")
16180 (const_string "*")))
16181 (set_attr "prefix_rep" "1")])
16183 ;; The same, but the count is not known to not be zero.
16185 (define_expand "cmpstrnqi_1"
16186 [(parallel [(set (reg:CC FLAGS_REG)
16187 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16189 (compare:CC (match_operand 4 "memory_operand" "")
16190 (match_operand 5 "memory_operand" ""))
16192 (use (match_operand:SI 3 "immediate_operand" ""))
16193 (use (reg:CC FLAGS_REG))
16194 (clobber (match_operand 0 "register_operand" ""))
16195 (clobber (match_operand 1 "register_operand" ""))
16196 (clobber (match_dup 2))])]
16198 "ix86_current_function_needs_cld = 1;")
16200 (define_insn "*cmpstrnqi_1"
16201 [(set (reg:CC FLAGS_REG)
16202 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16204 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16205 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16207 (use (match_operand:SI 3 "immediate_operand" "i"))
16208 (use (reg:CC FLAGS_REG))
16209 (clobber (match_operand:P 0 "register_operand" "=S"))
16210 (clobber (match_operand:P 1 "register_operand" "=D"))
16211 (clobber (match_operand:P 2 "register_operand" "=c"))]
16212 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16214 [(set_attr "type" "str")
16215 (set_attr "mode" "QI")
16216 (set (attr "prefix_rex")
16218 (match_test "<P:MODE>mode == DImode")
16220 (const_string "*")))
16221 (set_attr "prefix_rep" "1")])
16223 (define_expand "strlen<mode>"
16224 [(set (match_operand:P 0 "register_operand" "")
16225 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16226 (match_operand:QI 2 "immediate_operand" "")
16227 (match_operand 3 "immediate_operand" "")]
16231 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16237 (define_expand "strlenqi_1"
16238 [(parallel [(set (match_operand 0 "register_operand" "")
16239 (match_operand 2 "" ""))
16240 (clobber (match_operand 1 "register_operand" ""))
16241 (clobber (reg:CC FLAGS_REG))])]
16243 "ix86_current_function_needs_cld = 1;")
16245 (define_insn "*strlenqi_1"
16246 [(set (match_operand:P 0 "register_operand" "=&c")
16247 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16248 (match_operand:QI 2 "register_operand" "a")
16249 (match_operand:P 3 "immediate_operand" "i")
16250 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16251 (clobber (match_operand:P 1 "register_operand" "=D"))
16252 (clobber (reg:CC FLAGS_REG))]
16253 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16255 [(set_attr "type" "str")
16256 (set_attr "mode" "QI")
16257 (set (attr "prefix_rex")
16259 (match_test "<P:MODE>mode == DImode")
16261 (const_string "*")))
16262 (set_attr "prefix_rep" "1")])
16264 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16265 ;; handled in combine, but it is not currently up to the task.
16266 ;; When used for their truth value, the cmpstrn* expanders generate
16275 ;; The intermediate three instructions are unnecessary.
16277 ;; This one handles cmpstrn*_nz_1...
16280 (set (reg:CC FLAGS_REG)
16281 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16282 (mem:BLK (match_operand 5 "register_operand" ""))))
16283 (use (match_operand 6 "register_operand" ""))
16284 (use (match_operand:SI 3 "immediate_operand" ""))
16285 (clobber (match_operand 0 "register_operand" ""))
16286 (clobber (match_operand 1 "register_operand" ""))
16287 (clobber (match_operand 2 "register_operand" ""))])
16288 (set (match_operand:QI 7 "register_operand" "")
16289 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16290 (set (match_operand:QI 8 "register_operand" "")
16291 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16292 (set (reg FLAGS_REG)
16293 (compare (match_dup 7) (match_dup 8)))
16295 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16297 (set (reg:CC FLAGS_REG)
16298 (compare:CC (mem:BLK (match_dup 4))
16299 (mem:BLK (match_dup 5))))
16300 (use (match_dup 6))
16301 (use (match_dup 3))
16302 (clobber (match_dup 0))
16303 (clobber (match_dup 1))
16304 (clobber (match_dup 2))])])
16306 ;; ...and this one handles cmpstrn*_1.
16309 (set (reg:CC FLAGS_REG)
16310 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16312 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16313 (mem:BLK (match_operand 5 "register_operand" "")))
16315 (use (match_operand:SI 3 "immediate_operand" ""))
16316 (use (reg:CC FLAGS_REG))
16317 (clobber (match_operand 0 "register_operand" ""))
16318 (clobber (match_operand 1 "register_operand" ""))
16319 (clobber (match_operand 2 "register_operand" ""))])
16320 (set (match_operand:QI 7 "register_operand" "")
16321 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16322 (set (match_operand:QI 8 "register_operand" "")
16323 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16324 (set (reg FLAGS_REG)
16325 (compare (match_dup 7) (match_dup 8)))
16327 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16329 (set (reg:CC FLAGS_REG)
16330 (if_then_else:CC (ne (match_dup 6)
16332 (compare:CC (mem:BLK (match_dup 4))
16333 (mem:BLK (match_dup 5)))
16335 (use (match_dup 3))
16336 (use (reg:CC FLAGS_REG))
16337 (clobber (match_dup 0))
16338 (clobber (match_dup 1))
16339 (clobber (match_dup 2))])])
16341 ;; Conditional move instructions.
16343 (define_expand "mov<mode>cc"
16344 [(set (match_operand:SWIM 0 "register_operand" "")
16345 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16346 (match_operand:SWIM 2 "<general_operand>" "")
16347 (match_operand:SWIM 3 "<general_operand>" "")))]
16349 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16351 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16352 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16353 ;; So just document what we're doing explicitly.
16355 (define_expand "x86_mov<mode>cc_0_m1"
16357 [(set (match_operand:SWI48 0 "register_operand" "")
16358 (if_then_else:SWI48
16359 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16360 [(match_operand 1 "flags_reg_operand" "")
16364 (clobber (reg:CC FLAGS_REG))])])
16366 (define_insn "*x86_mov<mode>cc_0_m1"
16367 [(set (match_operand:SWI48 0 "register_operand" "=r")
16368 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16369 [(reg FLAGS_REG) (const_int 0)])
16372 (clobber (reg:CC FLAGS_REG))]
16374 "sbb{<imodesuffix>}\t%0, %0"
16375 ; Since we don't have the proper number of operands for an alu insn,
16376 ; fill in all the blanks.
16377 [(set_attr "type" "alu")
16378 (set_attr "use_carry" "1")
16379 (set_attr "pent_pair" "pu")
16380 (set_attr "memory" "none")
16381 (set_attr "imm_disp" "false")
16382 (set_attr "mode" "<MODE>")
16383 (set_attr "length_immediate" "0")])
16385 (define_insn "*x86_mov<mode>cc_0_m1_se"
16386 [(set (match_operand:SWI48 0 "register_operand" "=r")
16387 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16388 [(reg FLAGS_REG) (const_int 0)])
16391 (clobber (reg:CC FLAGS_REG))]
16393 "sbb{<imodesuffix>}\t%0, %0"
16394 [(set_attr "type" "alu")
16395 (set_attr "use_carry" "1")
16396 (set_attr "pent_pair" "pu")
16397 (set_attr "memory" "none")
16398 (set_attr "imm_disp" "false")
16399 (set_attr "mode" "<MODE>")
16400 (set_attr "length_immediate" "0")])
16402 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16403 [(set (match_operand:SWI48 0 "register_operand" "=r")
16404 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16405 [(reg FLAGS_REG) (const_int 0)])))
16406 (clobber (reg:CC FLAGS_REG))]
16408 "sbb{<imodesuffix>}\t%0, %0"
16409 [(set_attr "type" "alu")
16410 (set_attr "use_carry" "1")
16411 (set_attr "pent_pair" "pu")
16412 (set_attr "memory" "none")
16413 (set_attr "imm_disp" "false")
16414 (set_attr "mode" "<MODE>")
16415 (set_attr "length_immediate" "0")])
16417 (define_insn "*mov<mode>cc_noc"
16418 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16419 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16420 [(reg FLAGS_REG) (const_int 0)])
16421 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16422 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16423 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16425 cmov%O2%C1\t{%2, %0|%0, %2}
16426 cmov%O2%c1\t{%3, %0|%0, %3}"
16427 [(set_attr "type" "icmov")
16428 (set_attr "mode" "<MODE>")])
16430 (define_insn "*movqicc_noc"
16431 [(set (match_operand:QI 0 "register_operand" "=r,r")
16432 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16433 [(reg FLAGS_REG) (const_int 0)])
16434 (match_operand:QI 2 "register_operand" "r,0")
16435 (match_operand:QI 3 "register_operand" "0,r")))]
16436 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16438 [(set_attr "type" "icmov")
16439 (set_attr "mode" "QI")])
16442 [(set (match_operand 0 "register_operand")
16443 (if_then_else (match_operator 1 "ix86_comparison_operator"
16444 [(reg FLAGS_REG) (const_int 0)])
16445 (match_operand 2 "register_operand")
16446 (match_operand 3 "register_operand")))]
16447 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16448 && (GET_MODE (operands[0]) == QImode
16449 || GET_MODE (operands[0]) == HImode)
16450 && reload_completed"
16451 [(set (match_dup 0)
16452 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16454 operands[0] = gen_lowpart (SImode, operands[0]);
16455 operands[2] = gen_lowpart (SImode, operands[2]);
16456 operands[3] = gen_lowpart (SImode, operands[3]);
16459 (define_expand "mov<mode>cc"
16460 [(set (match_operand:X87MODEF 0 "register_operand" "")
16461 (if_then_else:X87MODEF
16462 (match_operand 1 "ix86_fp_comparison_operator" "")
16463 (match_operand:X87MODEF 2 "register_operand" "")
16464 (match_operand:X87MODEF 3 "register_operand" "")))]
16465 "(TARGET_80387 && TARGET_CMOVE)
16466 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16467 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16469 (define_insn "*movxfcc_1"
16470 [(set (match_operand:XF 0 "register_operand" "=f,f")
16471 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16472 [(reg FLAGS_REG) (const_int 0)])
16473 (match_operand:XF 2 "register_operand" "f,0")
16474 (match_operand:XF 3 "register_operand" "0,f")))]
16475 "TARGET_80387 && TARGET_CMOVE"
16477 fcmov%F1\t{%2, %0|%0, %2}
16478 fcmov%f1\t{%3, %0|%0, %3}"
16479 [(set_attr "type" "fcmov")
16480 (set_attr "mode" "XF")])
16482 (define_insn "*movdfcc_1_rex64"
16483 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16484 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16485 [(reg FLAGS_REG) (const_int 0)])
16486 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16487 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16488 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16489 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16491 fcmov%F1\t{%2, %0|%0, %2}
16492 fcmov%f1\t{%3, %0|%0, %3}
16493 cmov%O2%C1\t{%2, %0|%0, %2}
16494 cmov%O2%c1\t{%3, %0|%0, %3}"
16495 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16496 (set_attr "mode" "DF,DF,DI,DI")])
16498 (define_insn "*movdfcc_1"
16499 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16500 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16501 [(reg FLAGS_REG) (const_int 0)])
16502 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16503 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16504 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16505 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16507 fcmov%F1\t{%2, %0|%0, %2}
16508 fcmov%f1\t{%3, %0|%0, %3}
16511 [(set_attr "type" "fcmov,fcmov,multi,multi")
16512 (set_attr "mode" "DF,DF,DI,DI")])
16515 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16516 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16517 [(reg FLAGS_REG) (const_int 0)])
16518 (match_operand:DF 2 "nonimmediate_operand")
16519 (match_operand:DF 3 "nonimmediate_operand")))]
16520 "!TARGET_64BIT && reload_completed"
16521 [(set (match_dup 2)
16522 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16524 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16526 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16527 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16530 (define_insn "*movsfcc_1_387"
16531 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16532 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16533 [(reg FLAGS_REG) (const_int 0)])
16534 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16535 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16536 "TARGET_80387 && TARGET_CMOVE
16537 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16539 fcmov%F1\t{%2, %0|%0, %2}
16540 fcmov%f1\t{%3, %0|%0, %3}
16541 cmov%O2%C1\t{%2, %0|%0, %2}
16542 cmov%O2%c1\t{%3, %0|%0, %3}"
16543 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16544 (set_attr "mode" "SF,SF,SI,SI")])
16546 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16547 ;; the scalar versions to have only XMM registers as operands.
16549 ;; XOP conditional move
16550 (define_insn "*xop_pcmov_<mode>"
16551 [(set (match_operand:MODEF 0 "register_operand" "=x")
16552 (if_then_else:MODEF
16553 (match_operand:MODEF 1 "register_operand" "x")
16554 (match_operand:MODEF 2 "register_operand" "x")
16555 (match_operand:MODEF 3 "register_operand" "x")))]
16557 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16558 [(set_attr "type" "sse4arg")])
16560 ;; These versions of the min/max patterns are intentionally ignorant of
16561 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16562 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16563 ;; are undefined in this condition, we're certain this is correct.
16565 (define_insn "<code><mode>3"
16566 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16568 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16569 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16570 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16572 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16573 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16574 [(set_attr "isa" "noavx,avx")
16575 (set_attr "prefix" "orig,vex")
16576 (set_attr "type" "sseadd")
16577 (set_attr "mode" "<MODE>")])
16579 ;; These versions of the min/max patterns implement exactly the operations
16580 ;; min = (op1 < op2 ? op1 : op2)
16581 ;; max = (!(op1 < op2) ? op1 : op2)
16582 ;; Their operands are not commutative, and thus they may be used in the
16583 ;; presence of -0.0 and NaN.
16585 (define_insn "*ieee_smin<mode>3"
16586 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16588 [(match_operand:MODEF 1 "register_operand" "0,x")
16589 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16591 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16593 min<ssemodesuffix>\t{%2, %0|%0, %2}
16594 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16595 [(set_attr "isa" "noavx,avx")
16596 (set_attr "prefix" "orig,vex")
16597 (set_attr "type" "sseadd")
16598 (set_attr "mode" "<MODE>")])
16600 (define_insn "*ieee_smax<mode>3"
16601 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16603 [(match_operand:MODEF 1 "register_operand" "0,x")
16604 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16606 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16608 max<ssemodesuffix>\t{%2, %0|%0, %2}
16609 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16610 [(set_attr "isa" "noavx,avx")
16611 (set_attr "prefix" "orig,vex")
16612 (set_attr "type" "sseadd")
16613 (set_attr "mode" "<MODE>")])
16615 ;; Make two stack loads independent:
16617 ;; fld %st(0) -> fld bb
16618 ;; fmul bb fmul %st(1), %st
16620 ;; Actually we only match the last two instructions for simplicity.
16622 [(set (match_operand 0 "fp_register_operand" "")
16623 (match_operand 1 "fp_register_operand" ""))
16625 (match_operator 2 "binary_fp_operator"
16627 (match_operand 3 "memory_operand" "")]))]
16628 "REGNO (operands[0]) != REGNO (operands[1])"
16629 [(set (match_dup 0) (match_dup 3))
16630 (set (match_dup 0) (match_dup 4))]
16632 ;; The % modifier is not operational anymore in peephole2's, so we have to
16633 ;; swap the operands manually in the case of addition and multiplication.
16637 if (COMMUTATIVE_ARITH_P (operands[2]))
16638 op0 = operands[0], op1 = operands[1];
16640 op0 = operands[1], op1 = operands[0];
16642 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16643 GET_MODE (operands[2]),
16647 ;; Conditional addition patterns
16648 (define_expand "add<mode>cc"
16649 [(match_operand:SWI 0 "register_operand" "")
16650 (match_operand 1 "ordered_comparison_operator" "")
16651 (match_operand:SWI 2 "register_operand" "")
16652 (match_operand:SWI 3 "const_int_operand" "")]
16654 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16656 ;; Misc patterns (?)
16658 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16659 ;; Otherwise there will be nothing to keep
16661 ;; [(set (reg ebp) (reg esp))]
16662 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16663 ;; (clobber (eflags)]
16664 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16666 ;; in proper program order.
16668 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16669 [(set (match_operand:P 0 "register_operand" "=r,r")
16670 (plus:P (match_operand:P 1 "register_operand" "0,r")
16671 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16672 (clobber (reg:CC FLAGS_REG))
16673 (clobber (mem:BLK (scratch)))]
16676 switch (get_attr_type (insn))
16679 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16682 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16683 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16684 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16686 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16689 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16690 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16693 [(set (attr "type")
16694 (cond [(and (eq_attr "alternative" "0")
16695 (not (match_test "TARGET_OPT_AGU")))
16696 (const_string "alu")
16697 (match_operand:<MODE> 2 "const0_operand" "")
16698 (const_string "imov")
16700 (const_string "lea")))
16701 (set (attr "length_immediate")
16702 (cond [(eq_attr "type" "imov")
16704 (and (eq_attr "type" "alu")
16705 (match_operand 2 "const128_operand" ""))
16708 (const_string "*")))
16709 (set_attr "mode" "<MODE>")])
16711 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16712 [(set (match_operand:P 0 "register_operand" "=r")
16713 (minus:P (match_operand:P 1 "register_operand" "0")
16714 (match_operand:P 2 "register_operand" "r")))
16715 (clobber (reg:CC FLAGS_REG))
16716 (clobber (mem:BLK (scratch)))]
16718 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16719 [(set_attr "type" "alu")
16720 (set_attr "mode" "<MODE>")])
16722 (define_insn "allocate_stack_worker_probe_<mode>"
16723 [(set (match_operand:P 0 "register_operand" "=a")
16724 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16725 UNSPECV_STACK_PROBE))
16726 (clobber (reg:CC FLAGS_REG))]
16727 "ix86_target_stack_probe ()"
16728 "call\t___chkstk_ms"
16729 [(set_attr "type" "multi")
16730 (set_attr "length" "5")])
16732 (define_expand "allocate_stack"
16733 [(match_operand 0 "register_operand" "")
16734 (match_operand 1 "general_operand" "")]
16735 "ix86_target_stack_probe ()"
16739 #ifndef CHECK_STACK_LIMIT
16740 #define CHECK_STACK_LIMIT 0
16743 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16744 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16746 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16747 stack_pointer_rtx, 0, OPTAB_DIRECT);
16748 if (x != stack_pointer_rtx)
16749 emit_move_insn (stack_pointer_rtx, x);
16753 x = copy_to_mode_reg (Pmode, operands[1]);
16755 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16757 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16758 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16759 stack_pointer_rtx, 0, OPTAB_DIRECT);
16760 if (x != stack_pointer_rtx)
16761 emit_move_insn (stack_pointer_rtx, x);
16764 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16768 ;; Use IOR for stack probes, this is shorter.
16769 (define_expand "probe_stack"
16770 [(match_operand 0 "memory_operand" "")]
16773 rtx (*gen_ior3) (rtx, rtx, rtx);
16775 gen_ior3 = (GET_MODE (operands[0]) == DImode
16776 ? gen_iordi3 : gen_iorsi3);
16778 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16782 (define_insn "adjust_stack_and_probe<mode>"
16783 [(set (match_operand:P 0 "register_operand" "=r")
16784 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16785 UNSPECV_PROBE_STACK_RANGE))
16786 (set (reg:P SP_REG)
16787 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16788 (clobber (reg:CC FLAGS_REG))
16789 (clobber (mem:BLK (scratch)))]
16791 "* return output_adjust_stack_and_probe (operands[0]);"
16792 [(set_attr "type" "multi")])
16794 (define_insn "probe_stack_range<mode>"
16795 [(set (match_operand:P 0 "register_operand" "=r")
16796 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16797 (match_operand:P 2 "const_int_operand" "n")]
16798 UNSPECV_PROBE_STACK_RANGE))
16799 (clobber (reg:CC FLAGS_REG))]
16801 "* return output_probe_stack_range (operands[0], operands[2]);"
16802 [(set_attr "type" "multi")])
16804 (define_expand "builtin_setjmp_receiver"
16805 [(label_ref (match_operand 0 "" ""))]
16806 "!TARGET_64BIT && flag_pic"
16812 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16813 rtx label_rtx = gen_label_rtx ();
16814 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16815 xops[0] = xops[1] = picreg;
16816 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16817 ix86_expand_binary_operator (MINUS, SImode, xops);
16821 emit_insn (gen_set_got (pic_offset_table_rtx));
16825 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16828 [(set (match_operand 0 "register_operand" "")
16829 (match_operator 3 "promotable_binary_operator"
16830 [(match_operand 1 "register_operand" "")
16831 (match_operand 2 "aligned_operand" "")]))
16832 (clobber (reg:CC FLAGS_REG))]
16833 "! TARGET_PARTIAL_REG_STALL && reload_completed
16834 && ((GET_MODE (operands[0]) == HImode
16835 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16836 /* ??? next two lines just !satisfies_constraint_K (...) */
16837 || !CONST_INT_P (operands[2])
16838 || satisfies_constraint_K (operands[2])))
16839 || (GET_MODE (operands[0]) == QImode
16840 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16841 [(parallel [(set (match_dup 0)
16842 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16843 (clobber (reg:CC FLAGS_REG))])]
16845 operands[0] = gen_lowpart (SImode, operands[0]);
16846 operands[1] = gen_lowpart (SImode, operands[1]);
16847 if (GET_CODE (operands[3]) != ASHIFT)
16848 operands[2] = gen_lowpart (SImode, operands[2]);
16849 PUT_MODE (operands[3], SImode);
16852 ; Promote the QImode tests, as i386 has encoding of the AND
16853 ; instruction with 32-bit sign-extended immediate and thus the
16854 ; instruction size is unchanged, except in the %eax case for
16855 ; which it is increased by one byte, hence the ! optimize_size.
16857 [(set (match_operand 0 "flags_reg_operand" "")
16858 (match_operator 2 "compare_operator"
16859 [(and (match_operand 3 "aligned_operand" "")
16860 (match_operand 4 "const_int_operand" ""))
16862 (set (match_operand 1 "register_operand" "")
16863 (and (match_dup 3) (match_dup 4)))]
16864 "! TARGET_PARTIAL_REG_STALL && reload_completed
16865 && optimize_insn_for_speed_p ()
16866 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16867 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16868 /* Ensure that the operand will remain sign-extended immediate. */
16869 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16870 [(parallel [(set (match_dup 0)
16871 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16874 (and:SI (match_dup 3) (match_dup 4)))])]
16877 = gen_int_mode (INTVAL (operands[4])
16878 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16879 operands[1] = gen_lowpart (SImode, operands[1]);
16880 operands[3] = gen_lowpart (SImode, operands[3]);
16883 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16884 ; the TEST instruction with 32-bit sign-extended immediate and thus
16885 ; the instruction size would at least double, which is not what we
16886 ; want even with ! optimize_size.
16888 [(set (match_operand 0 "flags_reg_operand" "")
16889 (match_operator 1 "compare_operator"
16890 [(and (match_operand:HI 2 "aligned_operand" "")
16891 (match_operand:HI 3 "const_int_operand" ""))
16893 "! TARGET_PARTIAL_REG_STALL && reload_completed
16894 && ! TARGET_FAST_PREFIX
16895 && optimize_insn_for_speed_p ()
16896 /* Ensure that the operand will remain sign-extended immediate. */
16897 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16898 [(set (match_dup 0)
16899 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16903 = gen_int_mode (INTVAL (operands[3])
16904 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16905 operands[2] = gen_lowpart (SImode, operands[2]);
16909 [(set (match_operand 0 "register_operand" "")
16910 (neg (match_operand 1 "register_operand" "")))
16911 (clobber (reg:CC FLAGS_REG))]
16912 "! TARGET_PARTIAL_REG_STALL && reload_completed
16913 && (GET_MODE (operands[0]) == HImode
16914 || (GET_MODE (operands[0]) == QImode
16915 && (TARGET_PROMOTE_QImode
16916 || optimize_insn_for_size_p ())))"
16917 [(parallel [(set (match_dup 0)
16918 (neg:SI (match_dup 1)))
16919 (clobber (reg:CC FLAGS_REG))])]
16921 operands[0] = gen_lowpart (SImode, operands[0]);
16922 operands[1] = gen_lowpart (SImode, operands[1]);
16926 [(set (match_operand 0 "register_operand" "")
16927 (not (match_operand 1 "register_operand" "")))]
16928 "! TARGET_PARTIAL_REG_STALL && reload_completed
16929 && (GET_MODE (operands[0]) == HImode
16930 || (GET_MODE (operands[0]) == QImode
16931 && (TARGET_PROMOTE_QImode
16932 || optimize_insn_for_size_p ())))"
16933 [(set (match_dup 0)
16934 (not:SI (match_dup 1)))]
16936 operands[0] = gen_lowpart (SImode, operands[0]);
16937 operands[1] = gen_lowpart (SImode, operands[1]);
16940 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16941 ;; transform a complex memory operation into two memory to register operations.
16943 ;; Don't push memory operands
16945 [(set (match_operand:SWI 0 "push_operand" "")
16946 (match_operand:SWI 1 "memory_operand" ""))
16947 (match_scratch:SWI 2 "<r>")]
16948 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16949 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16950 [(set (match_dup 2) (match_dup 1))
16951 (set (match_dup 0) (match_dup 2))])
16953 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16956 [(set (match_operand:SF 0 "push_operand" "")
16957 (match_operand:SF 1 "memory_operand" ""))
16958 (match_scratch:SF 2 "r")]
16959 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16960 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16961 [(set (match_dup 2) (match_dup 1))
16962 (set (match_dup 0) (match_dup 2))])
16964 ;; Don't move an immediate directly to memory when the instruction
16967 [(match_scratch:SWI124 1 "<r>")
16968 (set (match_operand:SWI124 0 "memory_operand" "")
16970 "optimize_insn_for_speed_p ()
16971 && !TARGET_USE_MOV0
16972 && TARGET_SPLIT_LONG_MOVES
16973 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16974 && peep2_regno_dead_p (0, FLAGS_REG)"
16975 [(parallel [(set (match_dup 2) (const_int 0))
16976 (clobber (reg:CC FLAGS_REG))])
16977 (set (match_dup 0) (match_dup 1))]
16978 "operands[2] = gen_lowpart (SImode, operands[1]);")
16981 [(match_scratch:SWI124 2 "<r>")
16982 (set (match_operand:SWI124 0 "memory_operand" "")
16983 (match_operand:SWI124 1 "immediate_operand" ""))]
16984 "optimize_insn_for_speed_p ()
16985 && TARGET_SPLIT_LONG_MOVES
16986 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16987 [(set (match_dup 2) (match_dup 1))
16988 (set (match_dup 0) (match_dup 2))])
16990 ;; Don't compare memory with zero, load and use a test instead.
16992 [(set (match_operand 0 "flags_reg_operand" "")
16993 (match_operator 1 "compare_operator"
16994 [(match_operand:SI 2 "memory_operand" "")
16996 (match_scratch:SI 3 "r")]
16997 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16998 [(set (match_dup 3) (match_dup 2))
16999 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17001 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17002 ;; Don't split NOTs with a displacement operand, because resulting XOR
17003 ;; will not be pairable anyway.
17005 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17006 ;; represented using a modRM byte. The XOR replacement is long decoded,
17007 ;; so this split helps here as well.
17009 ;; Note: Can't do this as a regular split because we can't get proper
17010 ;; lifetime information then.
17013 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17014 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17015 "optimize_insn_for_speed_p ()
17016 && ((TARGET_NOT_UNPAIRABLE
17017 && (!MEM_P (operands[0])
17018 || !memory_displacement_operand (operands[0], <MODE>mode)))
17019 || (TARGET_NOT_VECTORMODE
17020 && long_memory_operand (operands[0], <MODE>mode)))
17021 && peep2_regno_dead_p (0, FLAGS_REG)"
17022 [(parallel [(set (match_dup 0)
17023 (xor:SWI124 (match_dup 1) (const_int -1)))
17024 (clobber (reg:CC FLAGS_REG))])])
17026 ;; Non pairable "test imm, reg" instructions can be translated to
17027 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17028 ;; byte opcode instead of two, have a short form for byte operands),
17029 ;; so do it for other CPUs as well. Given that the value was dead,
17030 ;; this should not create any new dependencies. Pass on the sub-word
17031 ;; versions if we're concerned about partial register stalls.
17034 [(set (match_operand 0 "flags_reg_operand" "")
17035 (match_operator 1 "compare_operator"
17036 [(and:SI (match_operand:SI 2 "register_operand" "")
17037 (match_operand:SI 3 "immediate_operand" ""))
17039 "ix86_match_ccmode (insn, CCNOmode)
17040 && (true_regnum (operands[2]) != AX_REG
17041 || satisfies_constraint_K (operands[3]))
17042 && peep2_reg_dead_p (1, operands[2])"
17044 [(set (match_dup 0)
17045 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17048 (and:SI (match_dup 2) (match_dup 3)))])])
17050 ;; We don't need to handle HImode case, because it will be promoted to SImode
17051 ;; on ! TARGET_PARTIAL_REG_STALL
17054 [(set (match_operand 0 "flags_reg_operand" "")
17055 (match_operator 1 "compare_operator"
17056 [(and:QI (match_operand:QI 2 "register_operand" "")
17057 (match_operand:QI 3 "immediate_operand" ""))
17059 "! TARGET_PARTIAL_REG_STALL
17060 && ix86_match_ccmode (insn, CCNOmode)
17061 && true_regnum (operands[2]) != AX_REG
17062 && peep2_reg_dead_p (1, operands[2])"
17064 [(set (match_dup 0)
17065 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17068 (and:QI (match_dup 2) (match_dup 3)))])])
17071 [(set (match_operand 0 "flags_reg_operand" "")
17072 (match_operator 1 "compare_operator"
17075 (match_operand 2 "ext_register_operand" "")
17078 (match_operand 3 "const_int_operand" ""))
17080 "! TARGET_PARTIAL_REG_STALL
17081 && ix86_match_ccmode (insn, CCNOmode)
17082 && true_regnum (operands[2]) != AX_REG
17083 && peep2_reg_dead_p (1, operands[2])"
17084 [(parallel [(set (match_dup 0)
17093 (set (zero_extract:SI (match_dup 2)
17101 (match_dup 3)))])])
17103 ;; Don't do logical operations with memory inputs.
17105 [(match_scratch:SI 2 "r")
17106 (parallel [(set (match_operand:SI 0 "register_operand" "")
17107 (match_operator:SI 3 "arith_or_logical_operator"
17109 (match_operand:SI 1 "memory_operand" "")]))
17110 (clobber (reg:CC FLAGS_REG))])]
17111 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17112 [(set (match_dup 2) (match_dup 1))
17113 (parallel [(set (match_dup 0)
17114 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17115 (clobber (reg:CC FLAGS_REG))])])
17118 [(match_scratch:SI 2 "r")
17119 (parallel [(set (match_operand:SI 0 "register_operand" "")
17120 (match_operator:SI 3 "arith_or_logical_operator"
17121 [(match_operand:SI 1 "memory_operand" "")
17123 (clobber (reg:CC FLAGS_REG))])]
17124 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17125 [(set (match_dup 2) (match_dup 1))
17126 (parallel [(set (match_dup 0)
17127 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17128 (clobber (reg:CC FLAGS_REG))])])
17130 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17131 ;; refers to the destination of the load!
17134 [(set (match_operand:SI 0 "register_operand" "")
17135 (match_operand:SI 1 "register_operand" ""))
17136 (parallel [(set (match_dup 0)
17137 (match_operator:SI 3 "commutative_operator"
17139 (match_operand:SI 2 "memory_operand" "")]))
17140 (clobber (reg:CC FLAGS_REG))])]
17141 "REGNO (operands[0]) != REGNO (operands[1])
17142 && GENERAL_REGNO_P (REGNO (operands[0]))
17143 && GENERAL_REGNO_P (REGNO (operands[1]))"
17144 [(set (match_dup 0) (match_dup 4))
17145 (parallel [(set (match_dup 0)
17146 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17147 (clobber (reg:CC FLAGS_REG))])]
17148 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17151 [(set (match_operand 0 "register_operand" "")
17152 (match_operand 1 "register_operand" ""))
17154 (match_operator 3 "commutative_operator"
17156 (match_operand 2 "memory_operand" "")]))]
17157 "REGNO (operands[0]) != REGNO (operands[1])
17158 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17159 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17160 [(set (match_dup 0) (match_dup 2))
17162 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17164 ; Don't do logical operations with memory outputs
17166 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17167 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17168 ; the same decoder scheduling characteristics as the original.
17171 [(match_scratch:SI 2 "r")
17172 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17173 (match_operator:SI 3 "arith_or_logical_operator"
17175 (match_operand:SI 1 "nonmemory_operand" "")]))
17176 (clobber (reg:CC FLAGS_REG))])]
17177 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17178 /* Do not split stack checking probes. */
17179 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17180 [(set (match_dup 2) (match_dup 0))
17181 (parallel [(set (match_dup 2)
17182 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17183 (clobber (reg:CC FLAGS_REG))])
17184 (set (match_dup 0) (match_dup 2))])
17187 [(match_scratch:SI 2 "r")
17188 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17189 (match_operator:SI 3 "arith_or_logical_operator"
17190 [(match_operand:SI 1 "nonmemory_operand" "")
17192 (clobber (reg:CC FLAGS_REG))])]
17193 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17194 /* Do not split stack checking probes. */
17195 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17196 [(set (match_dup 2) (match_dup 0))
17197 (parallel [(set (match_dup 2)
17198 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17199 (clobber (reg:CC FLAGS_REG))])
17200 (set (match_dup 0) (match_dup 2))])
17202 ;; Attempt to use arith or logical operations with memory outputs with
17203 ;; setting of flags.
17205 [(set (match_operand:SWI 0 "register_operand" "")
17206 (match_operand:SWI 1 "memory_operand" ""))
17207 (parallel [(set (match_dup 0)
17208 (match_operator:SWI 3 "plusminuslogic_operator"
17210 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17211 (clobber (reg:CC FLAGS_REG))])
17212 (set (match_dup 1) (match_dup 0))
17213 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17214 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17215 && peep2_reg_dead_p (4, operands[0])
17216 && !reg_overlap_mentioned_p (operands[0], operands[1])
17217 && (<MODE>mode != QImode
17218 || immediate_operand (operands[2], QImode)
17219 || q_regs_operand (operands[2], QImode))
17220 && ix86_match_ccmode (peep2_next_insn (3),
17221 (GET_CODE (operands[3]) == PLUS
17222 || GET_CODE (operands[3]) == MINUS)
17223 ? CCGOCmode : CCNOmode)"
17224 [(parallel [(set (match_dup 4) (match_dup 5))
17225 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17226 (match_dup 2)]))])]
17228 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17229 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17230 copy_rtx (operands[1]),
17231 copy_rtx (operands[2]));
17232 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17233 operands[5], const0_rtx);
17237 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17238 (match_operator:SWI 2 "plusminuslogic_operator"
17240 (match_operand:SWI 1 "memory_operand" "")]))
17241 (clobber (reg:CC FLAGS_REG))])
17242 (set (match_dup 1) (match_dup 0))
17243 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17244 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17245 && GET_CODE (operands[2]) != MINUS
17246 && peep2_reg_dead_p (3, operands[0])
17247 && !reg_overlap_mentioned_p (operands[0], operands[1])
17248 && ix86_match_ccmode (peep2_next_insn (2),
17249 GET_CODE (operands[2]) == PLUS
17250 ? CCGOCmode : CCNOmode)"
17251 [(parallel [(set (match_dup 3) (match_dup 4))
17252 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17253 (match_dup 0)]))])]
17255 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17256 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17257 copy_rtx (operands[1]),
17258 copy_rtx (operands[0]));
17259 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17260 operands[4], const0_rtx);
17264 [(set (match_operand:SWI12 0 "register_operand" "")
17265 (match_operand:SWI12 1 "memory_operand" ""))
17266 (parallel [(set (match_operand:SI 4 "register_operand" "")
17267 (match_operator:SI 3 "plusminuslogic_operator"
17269 (match_operand:SI 2 "nonmemory_operand" "")]))
17270 (clobber (reg:CC FLAGS_REG))])
17271 (set (match_dup 1) (match_dup 0))
17272 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17273 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17274 && REG_P (operands[0]) && REG_P (operands[4])
17275 && REGNO (operands[0]) == REGNO (operands[4])
17276 && peep2_reg_dead_p (4, operands[0])
17277 && (<MODE>mode != QImode
17278 || immediate_operand (operands[2], SImode)
17279 || q_regs_operand (operands[2], SImode))
17280 && !reg_overlap_mentioned_p (operands[0], operands[1])
17281 && ix86_match_ccmode (peep2_next_insn (3),
17282 (GET_CODE (operands[3]) == PLUS
17283 || GET_CODE (operands[3]) == MINUS)
17284 ? CCGOCmode : CCNOmode)"
17285 [(parallel [(set (match_dup 4) (match_dup 5))
17286 (set (match_dup 1) (match_dup 6))])]
17288 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17289 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17290 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17291 copy_rtx (operands[1]), operands[2]);
17292 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17293 operands[5], const0_rtx);
17294 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17295 copy_rtx (operands[1]),
17296 copy_rtx (operands[2]));
17299 ;; Attempt to always use XOR for zeroing registers.
17301 [(set (match_operand 0 "register_operand" "")
17302 (match_operand 1 "const0_operand" ""))]
17303 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17304 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17305 && GENERAL_REG_P (operands[0])
17306 && peep2_regno_dead_p (0, FLAGS_REG)"
17307 [(parallel [(set (match_dup 0) (const_int 0))
17308 (clobber (reg:CC FLAGS_REG))])]
17309 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17312 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17314 "(GET_MODE (operands[0]) == QImode
17315 || GET_MODE (operands[0]) == HImode)
17316 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17317 && peep2_regno_dead_p (0, FLAGS_REG)"
17318 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17319 (clobber (reg:CC FLAGS_REG))])])
17321 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17323 [(set (match_operand:SWI248 0 "register_operand" "")
17325 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17326 && peep2_regno_dead_p (0, FLAGS_REG)"
17327 [(parallel [(set (match_dup 0) (const_int -1))
17328 (clobber (reg:CC FLAGS_REG))])]
17330 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17331 operands[0] = gen_lowpart (SImode, operands[0]);
17334 ;; Attempt to convert simple lea to add/shift.
17335 ;; These can be created by move expanders.
17338 [(set (match_operand:SWI48 0 "register_operand" "")
17339 (plus:SWI48 (match_dup 0)
17340 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17341 "peep2_regno_dead_p (0, FLAGS_REG)"
17342 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17343 (clobber (reg:CC FLAGS_REG))])])
17346 [(set (match_operand:SI 0 "register_operand" "")
17347 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17348 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17350 && peep2_regno_dead_p (0, FLAGS_REG)
17351 && REGNO (operands[0]) == REGNO (operands[1])"
17352 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17353 (clobber (reg:CC FLAGS_REG))])]
17354 "operands[2] = gen_lowpart (SImode, operands[2]);")
17357 [(set (match_operand:SWI48 0 "register_operand" "")
17358 (mult:SWI48 (match_dup 0)
17359 (match_operand:SWI48 1 "const_int_operand" "")))]
17360 "exact_log2 (INTVAL (operands[1])) >= 0
17361 && peep2_regno_dead_p (0, FLAGS_REG)"
17362 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17363 (clobber (reg:CC FLAGS_REG))])]
17364 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17367 [(set (match_operand:SI 0 "register_operand" "")
17368 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17369 (match_operand:DI 2 "const_int_operand" "")) 0))]
17371 && exact_log2 (INTVAL (operands[2])) >= 0
17372 && REGNO (operands[0]) == REGNO (operands[1])
17373 && peep2_regno_dead_p (0, FLAGS_REG)"
17374 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17375 (clobber (reg:CC FLAGS_REG))])]
17376 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17378 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17379 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17380 ;; On many CPUs it is also faster, since special hardware to avoid esp
17381 ;; dependencies is present.
17383 ;; While some of these conversions may be done using splitters, we use
17384 ;; peepholes in order to allow combine_stack_adjustments pass to see
17385 ;; nonobfuscated RTL.
17387 ;; Convert prologue esp subtractions to push.
17388 ;; We need register to push. In order to keep verify_flow_info happy we have
17390 ;; - use scratch and clobber it in order to avoid dependencies
17391 ;; - use already live register
17392 ;; We can't use the second way right now, since there is no reliable way how to
17393 ;; verify that given register is live. First choice will also most likely in
17394 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17395 ;; call clobbered registers are dead. We may want to use base pointer as an
17396 ;; alternative when no register is available later.
17399 [(match_scratch:P 1 "r")
17400 (parallel [(set (reg:P SP_REG)
17401 (plus:P (reg:P SP_REG)
17402 (match_operand:P 0 "const_int_operand" "")))
17403 (clobber (reg:CC FLAGS_REG))
17404 (clobber (mem:BLK (scratch)))])]
17405 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17406 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17407 [(clobber (match_dup 1))
17408 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17409 (clobber (mem:BLK (scratch)))])])
17412 [(match_scratch:P 1 "r")
17413 (parallel [(set (reg:P SP_REG)
17414 (plus:P (reg:P SP_REG)
17415 (match_operand:P 0 "const_int_operand" "")))
17416 (clobber (reg:CC FLAGS_REG))
17417 (clobber (mem:BLK (scratch)))])]
17418 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17419 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17420 [(clobber (match_dup 1))
17421 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17422 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17423 (clobber (mem:BLK (scratch)))])])
17425 ;; Convert esp subtractions to push.
17427 [(match_scratch:P 1 "r")
17428 (parallel [(set (reg:P SP_REG)
17429 (plus:P (reg:P SP_REG)
17430 (match_operand:P 0 "const_int_operand" "")))
17431 (clobber (reg:CC FLAGS_REG))])]
17432 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17433 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17434 [(clobber (match_dup 1))
17435 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17438 [(match_scratch:P 1 "r")
17439 (parallel [(set (reg:P SP_REG)
17440 (plus:P (reg:P SP_REG)
17441 (match_operand:P 0 "const_int_operand" "")))
17442 (clobber (reg:CC FLAGS_REG))])]
17443 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17444 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17445 [(clobber (match_dup 1))
17446 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17447 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17449 ;; Convert epilogue deallocator 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 (clobber (mem:BLK (scratch)))])]
17457 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17458 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17459 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17460 (clobber (mem:BLK (scratch)))])])
17462 ;; Two pops case is tricky, since pop causes dependency
17463 ;; on destination register. We use two registers if available.
17465 [(match_scratch:P 1 "r")
17466 (match_scratch:P 2 "r")
17467 (parallel [(set (reg:P SP_REG)
17468 (plus:P (reg:P SP_REG)
17469 (match_operand:P 0 "const_int_operand" "")))
17470 (clobber (reg:CC FLAGS_REG))
17471 (clobber (mem:BLK (scratch)))])]
17472 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17473 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17474 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17475 (clobber (mem:BLK (scratch)))])
17476 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17479 [(match_scratch:P 1 "r")
17480 (parallel [(set (reg:P SP_REG)
17481 (plus:P (reg:P SP_REG)
17482 (match_operand:P 0 "const_int_operand" "")))
17483 (clobber (reg:CC FLAGS_REG))
17484 (clobber (mem:BLK (scratch)))])]
17485 "optimize_insn_for_size_p ()
17486 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17487 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17488 (clobber (mem:BLK (scratch)))])
17489 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17491 ;; Convert esp additions to pop.
17493 [(match_scratch:P 1 "r")
17494 (parallel [(set (reg:P SP_REG)
17495 (plus:P (reg:P SP_REG)
17496 (match_operand:P 0 "const_int_operand" "")))
17497 (clobber (reg:CC FLAGS_REG))])]
17498 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17499 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17501 ;; Two pops case is tricky, since pop causes dependency
17502 ;; on destination register. We use two registers if available.
17504 [(match_scratch:P 1 "r")
17505 (match_scratch:P 2 "r")
17506 (parallel [(set (reg:P SP_REG)
17507 (plus:P (reg:P SP_REG)
17508 (match_operand:P 0 "const_int_operand" "")))
17509 (clobber (reg:CC FLAGS_REG))])]
17510 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17511 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17512 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17515 [(match_scratch:P 1 "r")
17516 (parallel [(set (reg:P SP_REG)
17517 (plus:P (reg:P SP_REG)
17518 (match_operand:P 0 "const_int_operand" "")))
17519 (clobber (reg:CC FLAGS_REG))])]
17520 "optimize_insn_for_size_p ()
17521 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17522 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17523 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17525 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17526 ;; required and register dies. Similarly for 128 to -128.
17528 [(set (match_operand 0 "flags_reg_operand" "")
17529 (match_operator 1 "compare_operator"
17530 [(match_operand 2 "register_operand" "")
17531 (match_operand 3 "const_int_operand" "")]))]
17532 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17533 && incdec_operand (operands[3], GET_MODE (operands[3])))
17534 || (!TARGET_FUSE_CMP_AND_BRANCH
17535 && INTVAL (operands[3]) == 128))
17536 && ix86_match_ccmode (insn, CCGCmode)
17537 && peep2_reg_dead_p (1, operands[2])"
17538 [(parallel [(set (match_dup 0)
17539 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17540 (clobber (match_dup 2))])])
17542 ;; Convert imul by three, five and nine into lea
17545 [(set (match_operand:SWI48 0 "register_operand" "")
17546 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17547 (match_operand:SWI48 2 "const359_operand" "")))
17548 (clobber (reg:CC FLAGS_REG))])]
17549 "!TARGET_PARTIAL_REG_STALL
17550 || <MODE>mode == SImode
17551 || optimize_function_for_size_p (cfun)"
17552 [(set (match_dup 0)
17553 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17555 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17559 [(set (match_operand:SWI48 0 "register_operand" "")
17560 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17561 (match_operand:SWI48 2 "const359_operand" "")))
17562 (clobber (reg:CC FLAGS_REG))])]
17563 "optimize_insn_for_speed_p ()
17564 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17565 [(set (match_dup 0) (match_dup 1))
17567 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17569 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17571 ;; imul $32bit_imm, mem, reg is vector decoded, while
17572 ;; imul $32bit_imm, reg, reg is direct decoded.
17574 [(match_scratch:SWI48 3 "r")
17575 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17576 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17577 (match_operand:SWI48 2 "immediate_operand" "")))
17578 (clobber (reg:CC FLAGS_REG))])]
17579 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17580 && !satisfies_constraint_K (operands[2])"
17581 [(set (match_dup 3) (match_dup 1))
17582 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17583 (clobber (reg:CC FLAGS_REG))])])
17586 [(match_scratch:SI 3 "r")
17587 (parallel [(set (match_operand:DI 0 "register_operand" "")
17589 (mult:SI (match_operand:SI 1 "memory_operand" "")
17590 (match_operand:SI 2 "immediate_operand" ""))))
17591 (clobber (reg:CC FLAGS_REG))])]
17593 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17594 && !satisfies_constraint_K (operands[2])"
17595 [(set (match_dup 3) (match_dup 1))
17596 (parallel [(set (match_dup 0)
17597 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17598 (clobber (reg:CC FLAGS_REG))])])
17600 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17601 ;; Convert it into imul reg, reg
17602 ;; It would be better to force assembler to encode instruction using long
17603 ;; immediate, but there is apparently no way to do so.
17605 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17607 (match_operand:SWI248 1 "nonimmediate_operand" "")
17608 (match_operand:SWI248 2 "const_int_operand" "")))
17609 (clobber (reg:CC FLAGS_REG))])
17610 (match_scratch:SWI248 3 "r")]
17611 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17612 && satisfies_constraint_K (operands[2])"
17613 [(set (match_dup 3) (match_dup 2))
17614 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17615 (clobber (reg:CC FLAGS_REG))])]
17617 if (!rtx_equal_p (operands[0], operands[1]))
17618 emit_move_insn (operands[0], operands[1]);
17621 ;; After splitting up read-modify operations, array accesses with memory
17622 ;; operands might end up in form:
17624 ;; movl 4(%esp), %edx
17626 ;; instead of pre-splitting:
17628 ;; addl 4(%esp), %eax
17630 ;; movl 4(%esp), %edx
17631 ;; leal (%edx,%eax,4), %eax
17634 [(match_scratch:P 5 "r")
17635 (parallel [(set (match_operand 0 "register_operand" "")
17636 (ashift (match_operand 1 "register_operand" "")
17637 (match_operand 2 "const_int_operand" "")))
17638 (clobber (reg:CC FLAGS_REG))])
17639 (parallel [(set (match_operand 3 "register_operand" "")
17640 (plus (match_dup 0)
17641 (match_operand 4 "x86_64_general_operand" "")))
17642 (clobber (reg:CC FLAGS_REG))])]
17643 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17644 /* Validate MODE for lea. */
17645 && ((!TARGET_PARTIAL_REG_STALL
17646 && (GET_MODE (operands[0]) == QImode
17647 || GET_MODE (operands[0]) == HImode))
17648 || GET_MODE (operands[0]) == SImode
17649 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17650 && (rtx_equal_p (operands[0], operands[3])
17651 || peep2_reg_dead_p (2, operands[0]))
17652 /* We reorder load and the shift. */
17653 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17654 [(set (match_dup 5) (match_dup 4))
17655 (set (match_dup 0) (match_dup 1))]
17657 enum machine_mode op1mode = GET_MODE (operands[1]);
17658 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17659 int scale = 1 << INTVAL (operands[2]);
17660 rtx index = gen_lowpart (Pmode, operands[1]);
17661 rtx base = gen_lowpart (Pmode, operands[5]);
17662 rtx dest = gen_lowpart (mode, operands[3]);
17664 operands[1] = gen_rtx_PLUS (Pmode, base,
17665 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17666 operands[5] = base;
17668 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17669 if (op1mode != Pmode)
17670 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17671 operands[0] = dest;
17674 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17675 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17676 ;; caught for use by garbage collectors and the like. Using an insn that
17677 ;; maps to SIGILL makes it more likely the program will rightfully die.
17678 ;; Keeping with tradition, "6" is in honor of #UD.
17679 (define_insn "trap"
17680 [(trap_if (const_int 1) (const_int 6))]
17682 { return ASM_SHORT "0x0b0f"; }
17683 [(set_attr "length" "2")])
17685 (define_expand "prefetch"
17686 [(prefetch (match_operand 0 "address_operand" "")
17687 (match_operand:SI 1 "const_int_operand" "")
17688 (match_operand:SI 2 "const_int_operand" ""))]
17689 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17691 int rw = INTVAL (operands[1]);
17692 int locality = INTVAL (operands[2]);
17694 gcc_assert (rw == 0 || rw == 1);
17695 gcc_assert (IN_RANGE (locality, 0, 3));
17697 if (TARGET_PREFETCHW && rw)
17698 operands[2] = GEN_INT (3);
17699 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17700 supported by SSE counterpart or the SSE prefetch is not available
17701 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17703 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17704 operands[2] = GEN_INT (3);
17706 operands[1] = const0_rtx;
17709 (define_insn "*prefetch_sse"
17710 [(prefetch (match_operand 0 "address_operand" "p")
17712 (match_operand:SI 1 "const_int_operand" ""))]
17713 "TARGET_PREFETCH_SSE"
17715 static const char * const patterns[4] = {
17716 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17719 int locality = INTVAL (operands[1]);
17720 gcc_assert (IN_RANGE (locality, 0, 3));
17722 return patterns[locality];
17724 [(set_attr "type" "sse")
17725 (set_attr "atom_sse_attr" "prefetch")
17726 (set (attr "length_address")
17727 (symbol_ref "memory_address_length (operands[0], false)"))
17728 (set_attr "memory" "none")])
17730 (define_insn "*prefetch_3dnow"
17731 [(prefetch (match_operand 0 "address_operand" "p")
17732 (match_operand:SI 1 "const_int_operand" "n")
17734 "TARGET_3DNOW || TARGET_PREFETCHW"
17736 if (INTVAL (operands[1]) == 0)
17737 return "prefetch\t%a0";
17739 return "prefetchw\t%a0";
17741 [(set_attr "type" "mmx")
17742 (set (attr "length_address")
17743 (symbol_ref "memory_address_length (operands[0], false)"))
17744 (set_attr "memory" "none")])
17746 (define_expand "stack_protect_set"
17747 [(match_operand 0 "memory_operand" "")
17748 (match_operand 1 "memory_operand" "")]
17749 "!TARGET_HAS_BIONIC"
17751 rtx (*insn)(rtx, rtx);
17753 #ifdef TARGET_THREAD_SSP_OFFSET
17754 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17755 insn = (TARGET_LP64
17756 ? gen_stack_tls_protect_set_di
17757 : gen_stack_tls_protect_set_si);
17759 insn = (TARGET_LP64
17760 ? gen_stack_protect_set_di
17761 : gen_stack_protect_set_si);
17764 emit_insn (insn (operands[0], operands[1]));
17768 (define_insn "stack_protect_set_<mode>"
17769 [(set (match_operand:PTR 0 "memory_operand" "=m")
17770 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17772 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17773 (clobber (reg:CC FLAGS_REG))]
17774 "!TARGET_HAS_BIONIC"
17775 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17776 [(set_attr "type" "multi")])
17778 (define_insn "stack_tls_protect_set_<mode>"
17779 [(set (match_operand:PTR 0 "memory_operand" "=m")
17780 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17781 UNSPEC_SP_TLS_SET))
17782 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17783 (clobber (reg:CC FLAGS_REG))]
17785 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17786 [(set_attr "type" "multi")])
17788 (define_expand "stack_protect_test"
17789 [(match_operand 0 "memory_operand" "")
17790 (match_operand 1 "memory_operand" "")
17791 (match_operand 2 "" "")]
17792 "!TARGET_HAS_BIONIC"
17794 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17796 rtx (*insn)(rtx, rtx, rtx);
17798 #ifdef TARGET_THREAD_SSP_OFFSET
17799 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17800 insn = (TARGET_LP64
17801 ? gen_stack_tls_protect_test_di
17802 : gen_stack_tls_protect_test_si);
17804 insn = (TARGET_LP64
17805 ? gen_stack_protect_test_di
17806 : gen_stack_protect_test_si);
17809 emit_insn (insn (flags, operands[0], operands[1]));
17811 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17812 flags, const0_rtx, operands[2]));
17816 (define_insn "stack_protect_test_<mode>"
17817 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17818 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17819 (match_operand:PTR 2 "memory_operand" "m")]
17821 (clobber (match_scratch:PTR 3 "=&r"))]
17822 "!TARGET_HAS_BIONIC"
17823 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17824 [(set_attr "type" "multi")])
17826 (define_insn "stack_tls_protect_test_<mode>"
17827 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17828 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17829 (match_operand:PTR 2 "const_int_operand" "i")]
17830 UNSPEC_SP_TLS_TEST))
17831 (clobber (match_scratch:PTR 3 "=r"))]
17833 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17834 [(set_attr "type" "multi")])
17836 (define_insn "sse4_2_crc32<mode>"
17837 [(set (match_operand:SI 0 "register_operand" "=r")
17839 [(match_operand:SI 1 "register_operand" "0")
17840 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17842 "TARGET_SSE4_2 || TARGET_CRC32"
17843 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17844 [(set_attr "type" "sselog1")
17845 (set_attr "prefix_rep" "1")
17846 (set_attr "prefix_extra" "1")
17847 (set (attr "prefix_data16")
17848 (if_then_else (match_operand:HI 2 "" "")
17850 (const_string "*")))
17851 (set (attr "prefix_rex")
17852 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17854 (const_string "*")))
17855 (set_attr "mode" "SI")])
17857 (define_insn "sse4_2_crc32di"
17858 [(set (match_operand:DI 0 "register_operand" "=r")
17860 [(match_operand:DI 1 "register_operand" "0")
17861 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17863 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17864 "crc32{q}\t{%2, %0|%0, %2}"
17865 [(set_attr "type" "sselog1")
17866 (set_attr "prefix_rep" "1")
17867 (set_attr "prefix_extra" "1")
17868 (set_attr "mode" "DI")])
17870 (define_expand "rdpmc"
17871 [(match_operand:DI 0 "register_operand" "")
17872 (match_operand:SI 1 "register_operand" "")]
17875 rtx reg = gen_reg_rtx (DImode);
17878 /* Force operand 1 into ECX. */
17879 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17880 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17881 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17886 rtvec vec = rtvec_alloc (2);
17887 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17888 rtx upper = gen_reg_rtx (DImode);
17889 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17890 gen_rtvec (1, const0_rtx),
17892 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17893 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17895 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17896 NULL, 1, OPTAB_DIRECT);
17897 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17901 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17902 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17906 (define_insn "*rdpmc"
17907 [(set (match_operand:DI 0 "register_operand" "=A")
17908 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17912 [(set_attr "type" "other")
17913 (set_attr "length" "2")])
17915 (define_insn "*rdpmc_rex64"
17916 [(set (match_operand:DI 0 "register_operand" "=a")
17917 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17919 (set (match_operand:DI 1 "register_operand" "=d")
17920 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17923 [(set_attr "type" "other")
17924 (set_attr "length" "2")])
17926 (define_expand "rdtsc"
17927 [(set (match_operand:DI 0 "register_operand" "")
17928 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17933 rtvec vec = rtvec_alloc (2);
17934 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17935 rtx upper = gen_reg_rtx (DImode);
17936 rtx lower = gen_reg_rtx (DImode);
17937 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17938 gen_rtvec (1, const0_rtx),
17940 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17941 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17943 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17944 NULL, 1, OPTAB_DIRECT);
17945 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17947 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17952 (define_insn "*rdtsc"
17953 [(set (match_operand:DI 0 "register_operand" "=A")
17954 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17957 [(set_attr "type" "other")
17958 (set_attr "length" "2")])
17960 (define_insn "*rdtsc_rex64"
17961 [(set (match_operand:DI 0 "register_operand" "=a")
17962 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17963 (set (match_operand:DI 1 "register_operand" "=d")
17964 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17967 [(set_attr "type" "other")
17968 (set_attr "length" "2")])
17970 (define_expand "rdtscp"
17971 [(match_operand:DI 0 "register_operand" "")
17972 (match_operand:SI 1 "memory_operand" "")]
17975 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17976 gen_rtvec (1, const0_rtx),
17978 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17979 gen_rtvec (1, const0_rtx),
17981 rtx reg = gen_reg_rtx (DImode);
17982 rtx tmp = gen_reg_rtx (SImode);
17986 rtvec vec = rtvec_alloc (3);
17987 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17988 rtx upper = gen_reg_rtx (DImode);
17989 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17990 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17991 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17993 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17994 NULL, 1, OPTAB_DIRECT);
17995 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18000 rtvec vec = rtvec_alloc (2);
18001 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18002 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18003 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18006 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18007 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18011 (define_insn "*rdtscp"
18012 [(set (match_operand:DI 0 "register_operand" "=A")
18013 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18014 (set (match_operand:SI 1 "register_operand" "=c")
18015 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18018 [(set_attr "type" "other")
18019 (set_attr "length" "3")])
18021 (define_insn "*rdtscp_rex64"
18022 [(set (match_operand:DI 0 "register_operand" "=a")
18023 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18024 (set (match_operand:DI 1 "register_operand" "=d")
18025 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18026 (set (match_operand:SI 2 "register_operand" "=c")
18027 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18030 [(set_attr "type" "other")
18031 (set_attr "length" "3")])
18033 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18035 ;; LWP instructions
18037 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18039 (define_expand "lwp_llwpcb"
18040 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18041 UNSPECV_LLWP_INTRINSIC)]
18044 (define_insn "*lwp_llwpcb<mode>1"
18045 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18046 UNSPECV_LLWP_INTRINSIC)]
18049 [(set_attr "type" "lwp")
18050 (set_attr "mode" "<MODE>")
18051 (set_attr "length" "5")])
18053 (define_expand "lwp_slwpcb"
18054 [(set (match_operand 0 "register_operand" "=r")
18055 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18060 insn = (TARGET_64BIT
18062 : gen_lwp_slwpcbsi);
18064 emit_insn (insn (operands[0]));
18068 (define_insn "lwp_slwpcb<mode>"
18069 [(set (match_operand:P 0 "register_operand" "=r")
18070 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18073 [(set_attr "type" "lwp")
18074 (set_attr "mode" "<MODE>")
18075 (set_attr "length" "5")])
18077 (define_expand "lwp_lwpval<mode>3"
18078 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18079 (match_operand:SI 2 "nonimmediate_operand" "rm")
18080 (match_operand:SI 3 "const_int_operand" "i")]
18081 UNSPECV_LWPVAL_INTRINSIC)]
18083 ;; Avoid unused variable warning.
18084 "(void) operands[0];")
18086 (define_insn "*lwp_lwpval<mode>3_1"
18087 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18088 (match_operand:SI 1 "nonimmediate_operand" "rm")
18089 (match_operand:SI 2 "const_int_operand" "i")]
18090 UNSPECV_LWPVAL_INTRINSIC)]
18092 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18093 [(set_attr "type" "lwp")
18094 (set_attr "mode" "<MODE>")
18095 (set (attr "length")
18096 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18098 (define_expand "lwp_lwpins<mode>3"
18099 [(set (reg:CCC FLAGS_REG)
18100 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18101 (match_operand:SI 2 "nonimmediate_operand" "rm")
18102 (match_operand:SI 3 "const_int_operand" "i")]
18103 UNSPECV_LWPINS_INTRINSIC))
18104 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18105 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18108 (define_insn "*lwp_lwpins<mode>3_1"
18109 [(set (reg:CCC FLAGS_REG)
18110 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18111 (match_operand:SI 1 "nonimmediate_operand" "rm")
18112 (match_operand:SI 2 "const_int_operand" "i")]
18113 UNSPECV_LWPINS_INTRINSIC))]
18115 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18116 [(set_attr "type" "lwp")
18117 (set_attr "mode" "<MODE>")
18118 (set (attr "length")
18119 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18121 (define_insn "rdfsbase<mode>"
18122 [(set (match_operand:SWI48 0 "register_operand" "=r")
18123 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18124 "TARGET_64BIT && TARGET_FSGSBASE"
18126 [(set_attr "type" "other")
18127 (set_attr "prefix_extra" "2")])
18129 (define_insn "rdgsbase<mode>"
18130 [(set (match_operand:SWI48 0 "register_operand" "=r")
18131 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18132 "TARGET_64BIT && TARGET_FSGSBASE"
18134 [(set_attr "type" "other")
18135 (set_attr "prefix_extra" "2")])
18137 (define_insn "wrfsbase<mode>"
18138 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18140 "TARGET_64BIT && TARGET_FSGSBASE"
18142 [(set_attr "type" "other")
18143 (set_attr "prefix_extra" "2")])
18145 (define_insn "wrgsbase<mode>"
18146 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18148 "TARGET_64BIT && TARGET_FSGSBASE"
18150 [(set_attr "type" "other")
18151 (set_attr "prefix_extra" "2")])
18153 (define_insn "rdrand<mode>_1"
18154 [(set (match_operand:SWI248 0 "register_operand" "=r")
18155 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18156 (set (reg:CCC FLAGS_REG)
18157 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18160 [(set_attr "type" "other")
18161 (set_attr "prefix_extra" "1")])
18163 (define_expand "pause"
18164 [(set (match_dup 0)
18165 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18168 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18169 MEM_VOLATILE_P (operands[0]) = 1;
18172 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18173 ;; They have the same encoding.
18174 (define_insn "*pause"
18175 [(set (match_operand:BLK 0 "" "")
18176 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18179 [(set_attr "length" "2")
18180 (set_attr "memory" "unknown")])
18184 (include "sync.md")