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" "fma") (symbol_ref "TARGET_FMA")
647 ;; Fma instruction selection has to be done based on
648 ;; register pressure. For generating fma4, a cost model
649 ;; based on register pressure is required. Till then,
650 ;; fma4 instruction is disabled for targets that implement
651 ;; both fma and fma4 instruction sets.
652 (eq_attr "isa" "fma4")
653 (symbol_ref "TARGET_FMA4 && !TARGET_FMA")
657 ;; Describe a user's asm statement.
658 (define_asm_attributes
659 [(set_attr "length" "128")
660 (set_attr "type" "multi")])
662 (define_code_iterator plusminus [plus minus])
664 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
666 ;; Base name for define_insn
667 (define_code_attr plusminus_insn
668 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
669 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
671 ;; Base name for insn mnemonic.
672 (define_code_attr plusminus_mnemonic
673 [(plus "add") (ss_plus "adds") (us_plus "addus")
674 (minus "sub") (ss_minus "subs") (us_minus "subus")])
675 (define_code_attr plusminus_carry_mnemonic
676 [(plus "adc") (minus "sbb")])
678 ;; Mark commutative operators as such in constraints.
679 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
680 (minus "") (ss_minus "") (us_minus "")])
682 ;; Mapping of max and min
683 (define_code_iterator maxmin [smax smin umax umin])
685 ;; Mapping of signed max and min
686 (define_code_iterator smaxmin [smax smin])
688 ;; Mapping of unsigned max and min
689 (define_code_iterator umaxmin [umax umin])
691 ;; Base name for integer and FP insn mnemonic
692 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
693 (umax "maxu") (umin "minu")])
694 (define_code_attr maxmin_float [(smax "max") (smin "min")])
696 ;; Mapping of logic operators
697 (define_code_iterator any_logic [and ior xor])
698 (define_code_iterator any_or [ior xor])
700 ;; Base name for insn mnemonic.
701 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
703 ;; Mapping of logic-shift operators
704 (define_code_iterator any_lshift [ashift lshiftrt])
706 ;; Mapping of shift-right operators
707 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
709 ;; Base name for define_insn
710 (define_code_attr shift_insn
711 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
713 ;; Base name for insn mnemonic.
714 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
715 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
717 ;; Mapping of rotate operators
718 (define_code_iterator any_rotate [rotate rotatert])
720 ;; Base name for define_insn
721 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
723 ;; Base name for insn mnemonic.
724 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
726 ;; Mapping of abs neg operators
727 (define_code_iterator absneg [abs neg])
729 ;; Base name for x87 insn mnemonic.
730 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
732 ;; Used in signed and unsigned widening multiplications.
733 (define_code_iterator any_extend [sign_extend zero_extend])
735 ;; Prefix for insn menmonic.
736 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
738 ;; Prefix for define_insn
739 (define_code_attr u [(sign_extend "") (zero_extend "u")])
740 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
742 ;; All integer modes.
743 (define_mode_iterator SWI1248x [QI HI SI DI])
745 ;; All integer modes without QImode.
746 (define_mode_iterator SWI248x [HI SI DI])
748 ;; All integer modes without QImode and HImode.
749 (define_mode_iterator SWI48x [SI DI])
751 ;; All integer modes without SImode and DImode.
752 (define_mode_iterator SWI12 [QI HI])
754 ;; All integer modes without DImode.
755 (define_mode_iterator SWI124 [QI HI SI])
757 ;; All integer modes without QImode and DImode.
758 (define_mode_iterator SWI24 [HI SI])
760 ;; Single word integer modes.
761 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
763 ;; Single word integer modes without QImode.
764 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
766 ;; Single word integer modes without QImode and HImode.
767 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
769 ;; All math-dependant single and double word integer modes.
770 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
771 (HI "TARGET_HIMODE_MATH")
772 SI DI (TI "TARGET_64BIT")])
774 ;; Math-dependant single word integer modes.
775 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
776 (HI "TARGET_HIMODE_MATH")
777 SI (DI "TARGET_64BIT")])
779 ;; Math-dependant integer modes without DImode.
780 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
781 (HI "TARGET_HIMODE_MATH")
784 ;; Math-dependant single word integer modes without QImode.
785 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
786 SI (DI "TARGET_64BIT")])
788 ;; Double word integer modes.
789 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
790 (TI "TARGET_64BIT")])
792 ;; Double word integer modes as mode attribute.
793 (define_mode_attr DWI [(SI "DI") (DI "TI")])
794 (define_mode_attr dwi [(SI "di") (DI "ti")])
796 ;; Half mode for double word integer modes.
797 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
798 (DI "TARGET_64BIT")])
800 ;; Instruction suffix for integer modes.
801 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
803 ;; Pointer size prefix for integer modes (Intel asm dialect)
804 (define_mode_attr iptrsize [(QI "BYTE")
809 ;; Register class for integer modes.
810 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
812 ;; Immediate operand constraint for integer modes.
813 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
815 ;; General operand constraint for word modes.
816 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
818 ;; Immediate operand constraint for double integer modes.
819 (define_mode_attr di [(SI "nF") (DI "e")])
821 ;; Immediate operand constraint for shifts.
822 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
824 ;; General operand predicate for integer modes.
825 (define_mode_attr general_operand
826 [(QI "general_operand")
827 (HI "general_operand")
828 (SI "x86_64_general_operand")
829 (DI "x86_64_general_operand")
830 (TI "x86_64_general_operand")])
832 ;; General sign/zero extend operand predicate for integer modes.
833 (define_mode_attr general_szext_operand
834 [(QI "general_operand")
835 (HI "general_operand")
836 (SI "x86_64_szext_general_operand")
837 (DI "x86_64_szext_general_operand")])
839 ;; Immediate operand predicate for integer modes.
840 (define_mode_attr immediate_operand
841 [(QI "immediate_operand")
842 (HI "immediate_operand")
843 (SI "x86_64_immediate_operand")
844 (DI "x86_64_immediate_operand")])
846 ;; Nonmemory operand predicate for integer modes.
847 (define_mode_attr nonmemory_operand
848 [(QI "nonmemory_operand")
849 (HI "nonmemory_operand")
850 (SI "x86_64_nonmemory_operand")
851 (DI "x86_64_nonmemory_operand")])
853 ;; Operand predicate for shifts.
854 (define_mode_attr shift_operand
855 [(QI "nonimmediate_operand")
856 (HI "nonimmediate_operand")
857 (SI "nonimmediate_operand")
858 (DI "shiftdi_operand")
859 (TI "register_operand")])
861 ;; Operand predicate for shift argument.
862 (define_mode_attr shift_immediate_operand
863 [(QI "const_1_to_31_operand")
864 (HI "const_1_to_31_operand")
865 (SI "const_1_to_31_operand")
866 (DI "const_1_to_63_operand")])
868 ;; Input operand predicate for arithmetic left shifts.
869 (define_mode_attr ashl_input_operand
870 [(QI "nonimmediate_operand")
871 (HI "nonimmediate_operand")
872 (SI "nonimmediate_operand")
873 (DI "ashldi_input_operand")
874 (TI "reg_or_pm1_operand")])
876 ;; SSE and x87 SFmode and DFmode floating point modes
877 (define_mode_iterator MODEF [SF DF])
879 ;; All x87 floating point modes
880 (define_mode_iterator X87MODEF [SF DF XF])
882 ;; SSE instruction suffix for various modes
883 (define_mode_attr ssemodesuffix
885 (V8SF "ps") (V4DF "pd")
886 (V4SF "ps") (V2DF "pd")
887 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
888 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
890 ;; SSE vector suffix for floating point modes
891 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
893 ;; SSE vector mode corresponding to a scalar mode
894 (define_mode_attr ssevecmode
895 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
897 ;; Instruction suffix for REX 64bit operators.
898 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
900 ;; This mode iterator allows :P to be used for patterns that operate on
901 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
902 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
904 ;; This mode iterator allows :PTR to be used for patterns that operate on
905 ;; ptr_mode sized quantities.
906 (define_mode_iterator PTR
907 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
909 ;; Scheduling descriptions
911 (include "pentium.md")
914 (include "athlon.md")
915 (include "bdver1.md")
921 ;; Operand and operator predicates and constraints
923 (include "predicates.md")
924 (include "constraints.md")
927 ;; Compare and branch/compare and store instructions.
929 (define_expand "cbranch<mode>4"
930 [(set (reg:CC FLAGS_REG)
931 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
932 (match_operand:SDWIM 2 "<general_operand>" "")))
933 (set (pc) (if_then_else
934 (match_operator 0 "ordered_comparison_operator"
935 [(reg:CC FLAGS_REG) (const_int 0)])
936 (label_ref (match_operand 3 "" ""))
940 if (MEM_P (operands[1]) && MEM_P (operands[2]))
941 operands[1] = force_reg (<MODE>mode, operands[1]);
942 ix86_expand_branch (GET_CODE (operands[0]),
943 operands[1], operands[2], operands[3]);
947 (define_expand "cstore<mode>4"
948 [(set (reg:CC FLAGS_REG)
949 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
950 (match_operand:SWIM 3 "<general_operand>" "")))
951 (set (match_operand:QI 0 "register_operand" "")
952 (match_operator 1 "ordered_comparison_operator"
953 [(reg:CC FLAGS_REG) (const_int 0)]))]
956 if (MEM_P (operands[2]) && MEM_P (operands[3]))
957 operands[2] = force_reg (<MODE>mode, operands[2]);
958 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
959 operands[2], operands[3]);
963 (define_expand "cmp<mode>_1"
964 [(set (reg:CC FLAGS_REG)
965 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
966 (match_operand:SWI48 1 "<general_operand>" "")))])
968 (define_insn "*cmp<mode>_ccno_1"
969 [(set (reg FLAGS_REG)
970 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
971 (match_operand:SWI 1 "const0_operand" "")))]
972 "ix86_match_ccmode (insn, CCNOmode)"
974 test{<imodesuffix>}\t%0, %0
975 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
976 [(set_attr "type" "test,icmp")
977 (set_attr "length_immediate" "0,1")
978 (set_attr "mode" "<MODE>")])
980 (define_insn "*cmp<mode>_1"
981 [(set (reg FLAGS_REG)
982 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
983 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
984 "ix86_match_ccmode (insn, CCmode)"
985 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
986 [(set_attr "type" "icmp")
987 (set_attr "mode" "<MODE>")])
989 (define_insn "*cmp<mode>_minus_1"
990 [(set (reg FLAGS_REG)
992 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
993 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
995 "ix86_match_ccmode (insn, CCGOCmode)"
996 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
997 [(set_attr "type" "icmp")
998 (set_attr "mode" "<MODE>")])
1000 (define_insn "*cmpqi_ext_1"
1001 [(set (reg FLAGS_REG)
1003 (match_operand:QI 0 "general_operand" "Qm")
1006 (match_operand 1 "ext_register_operand" "Q")
1008 (const_int 8)) 0)))]
1009 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1010 "cmp{b}\t{%h1, %0|%0, %h1}"
1011 [(set_attr "type" "icmp")
1012 (set_attr "mode" "QI")])
1014 (define_insn "*cmpqi_ext_1_rex64"
1015 [(set (reg FLAGS_REG)
1017 (match_operand:QI 0 "register_operand" "Q")
1020 (match_operand 1 "ext_register_operand" "Q")
1022 (const_int 8)) 0)))]
1023 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1024 "cmp{b}\t{%h1, %0|%0, %h1}"
1025 [(set_attr "type" "icmp")
1026 (set_attr "mode" "QI")])
1028 (define_insn "*cmpqi_ext_2"
1029 [(set (reg FLAGS_REG)
1033 (match_operand 0 "ext_register_operand" "Q")
1036 (match_operand:QI 1 "const0_operand" "")))]
1037 "ix86_match_ccmode (insn, CCNOmode)"
1039 [(set_attr "type" "test")
1040 (set_attr "length_immediate" "0")
1041 (set_attr "mode" "QI")])
1043 (define_expand "cmpqi_ext_3"
1044 [(set (reg:CC FLAGS_REG)
1048 (match_operand 0 "ext_register_operand" "")
1051 (match_operand:QI 1 "immediate_operand" "")))])
1053 (define_insn "*cmpqi_ext_3_insn"
1054 [(set (reg FLAGS_REG)
1058 (match_operand 0 "ext_register_operand" "Q")
1061 (match_operand:QI 1 "general_operand" "Qmn")))]
1062 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1063 "cmp{b}\t{%1, %h0|%h0, %1}"
1064 [(set_attr "type" "icmp")
1065 (set_attr "modrm" "1")
1066 (set_attr "mode" "QI")])
1068 (define_insn "*cmpqi_ext_3_insn_rex64"
1069 [(set (reg FLAGS_REG)
1073 (match_operand 0 "ext_register_operand" "Q")
1076 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1077 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1078 "cmp{b}\t{%1, %h0|%h0, %1}"
1079 [(set_attr "type" "icmp")
1080 (set_attr "modrm" "1")
1081 (set_attr "mode" "QI")])
1083 (define_insn "*cmpqi_ext_4"
1084 [(set (reg FLAGS_REG)
1088 (match_operand 0 "ext_register_operand" "Q")
1093 (match_operand 1 "ext_register_operand" "Q")
1095 (const_int 8)) 0)))]
1096 "ix86_match_ccmode (insn, CCmode)"
1097 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1098 [(set_attr "type" "icmp")
1099 (set_attr "mode" "QI")])
1101 ;; These implement float point compares.
1102 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1103 ;; which would allow mix and match FP modes on the compares. Which is what
1104 ;; the old patterns did, but with many more of them.
1106 (define_expand "cbranchxf4"
1107 [(set (reg:CC FLAGS_REG)
1108 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1109 (match_operand:XF 2 "nonmemory_operand" "")))
1110 (set (pc) (if_then_else
1111 (match_operator 0 "ix86_fp_comparison_operator"
1114 (label_ref (match_operand 3 "" ""))
1118 ix86_expand_branch (GET_CODE (operands[0]),
1119 operands[1], operands[2], operands[3]);
1123 (define_expand "cstorexf4"
1124 [(set (reg:CC FLAGS_REG)
1125 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1126 (match_operand:XF 3 "nonmemory_operand" "")))
1127 (set (match_operand:QI 0 "register_operand" "")
1128 (match_operator 1 "ix86_fp_comparison_operator"
1133 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1134 operands[2], operands[3]);
1138 (define_expand "cbranch<mode>4"
1139 [(set (reg:CC FLAGS_REG)
1140 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1141 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1142 (set (pc) (if_then_else
1143 (match_operator 0 "ix86_fp_comparison_operator"
1146 (label_ref (match_operand 3 "" ""))
1148 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1150 ix86_expand_branch (GET_CODE (operands[0]),
1151 operands[1], operands[2], operands[3]);
1155 (define_expand "cstore<mode>4"
1156 [(set (reg:CC FLAGS_REG)
1157 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1158 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1159 (set (match_operand:QI 0 "register_operand" "")
1160 (match_operator 1 "ix86_fp_comparison_operator"
1163 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1165 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1166 operands[2], operands[3]);
1170 (define_expand "cbranchcc4"
1171 [(set (pc) (if_then_else
1172 (match_operator 0 "comparison_operator"
1173 [(match_operand 1 "flags_reg_operand" "")
1174 (match_operand 2 "const0_operand" "")])
1175 (label_ref (match_operand 3 "" ""))
1179 ix86_expand_branch (GET_CODE (operands[0]),
1180 operands[1], operands[2], operands[3]);
1184 (define_expand "cstorecc4"
1185 [(set (match_operand:QI 0 "register_operand" "")
1186 (match_operator 1 "comparison_operator"
1187 [(match_operand 2 "flags_reg_operand" "")
1188 (match_operand 3 "const0_operand" "")]))]
1191 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1192 operands[2], operands[3]);
1197 ;; FP compares, step 1:
1198 ;; Set the FP condition codes.
1200 ;; CCFPmode compare with exceptions
1201 ;; CCFPUmode compare with no exceptions
1203 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1204 ;; used to manage the reg stack popping would not be preserved.
1206 (define_insn "*cmpfp_0"
1207 [(set (match_operand:HI 0 "register_operand" "=a")
1210 (match_operand 1 "register_operand" "f")
1211 (match_operand 2 "const0_operand" ""))]
1213 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1214 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1215 "* return output_fp_compare (insn, operands, false, false);"
1216 [(set_attr "type" "multi")
1217 (set_attr "unit" "i387")
1219 (cond [(match_operand:SF 1 "" "")
1221 (match_operand:DF 1 "" "")
1224 (const_string "XF")))])
1226 (define_insn_and_split "*cmpfp_0_cc"
1227 [(set (reg:CCFP FLAGS_REG)
1229 (match_operand 1 "register_operand" "f")
1230 (match_operand 2 "const0_operand" "")))
1231 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1232 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1233 && TARGET_SAHF && !TARGET_CMOVE
1234 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1236 "&& reload_completed"
1239 [(compare:CCFP (match_dup 1)(match_dup 2))]
1241 (set (reg:CC FLAGS_REG)
1242 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1244 [(set_attr "type" "multi")
1245 (set_attr "unit" "i387")
1247 (cond [(match_operand:SF 1 "" "")
1249 (match_operand:DF 1 "" "")
1252 (const_string "XF")))])
1254 (define_insn "*cmpfp_xf"
1255 [(set (match_operand:HI 0 "register_operand" "=a")
1258 (match_operand:XF 1 "register_operand" "f")
1259 (match_operand:XF 2 "register_operand" "f"))]
1262 "* return output_fp_compare (insn, operands, false, false);"
1263 [(set_attr "type" "multi")
1264 (set_attr "unit" "i387")
1265 (set_attr "mode" "XF")])
1267 (define_insn_and_split "*cmpfp_xf_cc"
1268 [(set (reg:CCFP FLAGS_REG)
1270 (match_operand:XF 1 "register_operand" "f")
1271 (match_operand:XF 2 "register_operand" "f")))
1272 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1274 && TARGET_SAHF && !TARGET_CMOVE"
1276 "&& reload_completed"
1279 [(compare:CCFP (match_dup 1)(match_dup 2))]
1281 (set (reg:CC FLAGS_REG)
1282 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1284 [(set_attr "type" "multi")
1285 (set_attr "unit" "i387")
1286 (set_attr "mode" "XF")])
1288 (define_insn "*cmpfp_<mode>"
1289 [(set (match_operand:HI 0 "register_operand" "=a")
1292 (match_operand:MODEF 1 "register_operand" "f")
1293 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1296 "* return output_fp_compare (insn, operands, false, false);"
1297 [(set_attr "type" "multi")
1298 (set_attr "unit" "i387")
1299 (set_attr "mode" "<MODE>")])
1301 (define_insn_and_split "*cmpfp_<mode>_cc"
1302 [(set (reg:CCFP FLAGS_REG)
1304 (match_operand:MODEF 1 "register_operand" "f")
1305 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1306 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1308 && TARGET_SAHF && !TARGET_CMOVE"
1310 "&& reload_completed"
1313 [(compare:CCFP (match_dup 1)(match_dup 2))]
1315 (set (reg:CC FLAGS_REG)
1316 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1318 [(set_attr "type" "multi")
1319 (set_attr "unit" "i387")
1320 (set_attr "mode" "<MODE>")])
1322 (define_insn "*cmpfp_u"
1323 [(set (match_operand:HI 0 "register_operand" "=a")
1326 (match_operand 1 "register_operand" "f")
1327 (match_operand 2 "register_operand" "f"))]
1329 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1330 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1331 "* return output_fp_compare (insn, operands, false, true);"
1332 [(set_attr "type" "multi")
1333 (set_attr "unit" "i387")
1335 (cond [(match_operand:SF 1 "" "")
1337 (match_operand:DF 1 "" "")
1340 (const_string "XF")))])
1342 (define_insn_and_split "*cmpfp_u_cc"
1343 [(set (reg:CCFPU FLAGS_REG)
1345 (match_operand 1 "register_operand" "f")
1346 (match_operand 2 "register_operand" "f")))
1347 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1348 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1349 && TARGET_SAHF && !TARGET_CMOVE
1350 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1352 "&& reload_completed"
1355 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1357 (set (reg:CC FLAGS_REG)
1358 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1360 [(set_attr "type" "multi")
1361 (set_attr "unit" "i387")
1363 (cond [(match_operand:SF 1 "" "")
1365 (match_operand:DF 1 "" "")
1368 (const_string "XF")))])
1370 (define_insn "*cmpfp_<mode>"
1371 [(set (match_operand:HI 0 "register_operand" "=a")
1374 (match_operand 1 "register_operand" "f")
1375 (match_operator 3 "float_operator"
1376 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1378 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1379 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1380 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1381 "* return output_fp_compare (insn, operands, false, false);"
1382 [(set_attr "type" "multi")
1383 (set_attr "unit" "i387")
1384 (set_attr "fp_int_src" "true")
1385 (set_attr "mode" "<MODE>")])
1387 (define_insn_and_split "*cmpfp_<mode>_cc"
1388 [(set (reg:CCFP FLAGS_REG)
1390 (match_operand 1 "register_operand" "f")
1391 (match_operator 3 "float_operator"
1392 [(match_operand:SWI24 2 "memory_operand" "m")])))
1393 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1394 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1395 && TARGET_SAHF && !TARGET_CMOVE
1396 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1397 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1399 "&& reload_completed"
1404 (match_op_dup 3 [(match_dup 2)]))]
1406 (set (reg:CC FLAGS_REG)
1407 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1409 [(set_attr "type" "multi")
1410 (set_attr "unit" "i387")
1411 (set_attr "fp_int_src" "true")
1412 (set_attr "mode" "<MODE>")])
1414 ;; FP compares, step 2
1415 ;; Move the fpsw to ax.
1417 (define_insn "x86_fnstsw_1"
1418 [(set (match_operand:HI 0 "register_operand" "=a")
1419 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1422 [(set (attr "length")
1423 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1424 (set_attr "mode" "SI")
1425 (set_attr "unit" "i387")])
1427 ;; FP compares, step 3
1428 ;; Get ax into flags, general case.
1430 (define_insn "x86_sahf_1"
1431 [(set (reg:CC FLAGS_REG)
1432 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1436 #ifndef HAVE_AS_IX86_SAHF
1438 return ASM_BYTE "0x9e";
1443 [(set_attr "length" "1")
1444 (set_attr "athlon_decode" "vector")
1445 (set_attr "amdfam10_decode" "direct")
1446 (set_attr "bdver1_decode" "direct")
1447 (set_attr "mode" "SI")])
1449 ;; Pentium Pro can do steps 1 through 3 in one go.
1450 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1451 ;; (these i387 instructions set flags directly)
1452 (define_insn "*cmpfp_i_mixed"
1453 [(set (reg:CCFP FLAGS_REG)
1454 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1455 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1456 "TARGET_MIX_SSE_I387
1457 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1458 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1459 "* return output_fp_compare (insn, operands, true, false);"
1460 [(set_attr "type" "fcmp,ssecomi")
1461 (set_attr "prefix" "orig,maybe_vex")
1463 (if_then_else (match_operand:SF 1 "" "")
1465 (const_string "DF")))
1466 (set (attr "prefix_rep")
1467 (if_then_else (eq_attr "type" "ssecomi")
1469 (const_string "*")))
1470 (set (attr "prefix_data16")
1471 (cond [(eq_attr "type" "fcmp")
1473 (eq_attr "mode" "DF")
1476 (const_string "0")))
1477 (set_attr "athlon_decode" "vector")
1478 (set_attr "amdfam10_decode" "direct")
1479 (set_attr "bdver1_decode" "double")])
1481 (define_insn "*cmpfp_i_sse"
1482 [(set (reg:CCFP FLAGS_REG)
1483 (compare:CCFP (match_operand 0 "register_operand" "x")
1484 (match_operand 1 "nonimmediate_operand" "xm")))]
1486 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1487 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1488 "* return output_fp_compare (insn, operands, true, false);"
1489 [(set_attr "type" "ssecomi")
1490 (set_attr "prefix" "maybe_vex")
1492 (if_then_else (match_operand:SF 1 "" "")
1494 (const_string "DF")))
1495 (set_attr "prefix_rep" "0")
1496 (set (attr "prefix_data16")
1497 (if_then_else (eq_attr "mode" "DF")
1499 (const_string "0")))
1500 (set_attr "athlon_decode" "vector")
1501 (set_attr "amdfam10_decode" "direct")
1502 (set_attr "bdver1_decode" "double")])
1504 (define_insn "*cmpfp_i_i387"
1505 [(set (reg:CCFP FLAGS_REG)
1506 (compare:CCFP (match_operand 0 "register_operand" "f")
1507 (match_operand 1 "register_operand" "f")))]
1508 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1510 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1511 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1512 "* return output_fp_compare (insn, operands, true, false);"
1513 [(set_attr "type" "fcmp")
1515 (cond [(match_operand:SF 1 "" "")
1517 (match_operand:DF 1 "" "")
1520 (const_string "XF")))
1521 (set_attr "athlon_decode" "vector")
1522 (set_attr "amdfam10_decode" "direct")
1523 (set_attr "bdver1_decode" "double")])
1525 (define_insn "*cmpfp_iu_mixed"
1526 [(set (reg:CCFPU FLAGS_REG)
1527 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1528 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1529 "TARGET_MIX_SSE_I387
1530 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1531 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1532 "* return output_fp_compare (insn, operands, true, true);"
1533 [(set_attr "type" "fcmp,ssecomi")
1534 (set_attr "prefix" "orig,maybe_vex")
1536 (if_then_else (match_operand:SF 1 "" "")
1538 (const_string "DF")))
1539 (set (attr "prefix_rep")
1540 (if_then_else (eq_attr "type" "ssecomi")
1542 (const_string "*")))
1543 (set (attr "prefix_data16")
1544 (cond [(eq_attr "type" "fcmp")
1546 (eq_attr "mode" "DF")
1549 (const_string "0")))
1550 (set_attr "athlon_decode" "vector")
1551 (set_attr "amdfam10_decode" "direct")
1552 (set_attr "bdver1_decode" "double")])
1554 (define_insn "*cmpfp_iu_sse"
1555 [(set (reg:CCFPU FLAGS_REG)
1556 (compare:CCFPU (match_operand 0 "register_operand" "x")
1557 (match_operand 1 "nonimmediate_operand" "xm")))]
1559 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1560 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1561 "* return output_fp_compare (insn, operands, true, true);"
1562 [(set_attr "type" "ssecomi")
1563 (set_attr "prefix" "maybe_vex")
1565 (if_then_else (match_operand:SF 1 "" "")
1567 (const_string "DF")))
1568 (set_attr "prefix_rep" "0")
1569 (set (attr "prefix_data16")
1570 (if_then_else (eq_attr "mode" "DF")
1572 (const_string "0")))
1573 (set_attr "athlon_decode" "vector")
1574 (set_attr "amdfam10_decode" "direct")
1575 (set_attr "bdver1_decode" "double")])
1577 (define_insn "*cmpfp_iu_387"
1578 [(set (reg:CCFPU FLAGS_REG)
1579 (compare:CCFPU (match_operand 0 "register_operand" "f")
1580 (match_operand 1 "register_operand" "f")))]
1581 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1583 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1584 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1585 "* return output_fp_compare (insn, operands, true, true);"
1586 [(set_attr "type" "fcmp")
1588 (cond [(match_operand:SF 1 "" "")
1590 (match_operand:DF 1 "" "")
1593 (const_string "XF")))
1594 (set_attr "athlon_decode" "vector")
1595 (set_attr "amdfam10_decode" "direct")
1596 (set_attr "bdver1_decode" "direct")])
1598 ;; Push/pop instructions.
1600 (define_insn "*push<mode>2"
1601 [(set (match_operand:DWI 0 "push_operand" "=<")
1602 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1605 [(set_attr "type" "multi")
1606 (set_attr "mode" "<MODE>")])
1609 [(set (match_operand:TI 0 "push_operand" "")
1610 (match_operand:TI 1 "general_operand" ""))]
1611 "TARGET_64BIT && reload_completed
1612 && !SSE_REG_P (operands[1])"
1614 "ix86_split_long_move (operands); DONE;")
1616 (define_insn "*pushdi2_rex64"
1617 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1618 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1623 [(set_attr "type" "push,multi")
1624 (set_attr "mode" "DI")])
1626 ;; Convert impossible pushes of immediate to existing instructions.
1627 ;; First try to get scratch register and go through it. In case this
1628 ;; fails, push sign extended lower part first and then overwrite
1629 ;; upper part by 32bit move.
1631 [(match_scratch:DI 2 "r")
1632 (set (match_operand:DI 0 "push_operand" "")
1633 (match_operand:DI 1 "immediate_operand" ""))]
1634 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1635 && !x86_64_immediate_operand (operands[1], DImode)"
1636 [(set (match_dup 2) (match_dup 1))
1637 (set (match_dup 0) (match_dup 2))])
1639 ;; We need to define this as both peepholer and splitter for case
1640 ;; peephole2 pass is not run.
1641 ;; "&& 1" is needed to keep it from matching the previous pattern.
1643 [(set (match_operand:DI 0 "push_operand" "")
1644 (match_operand:DI 1 "immediate_operand" ""))]
1645 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1646 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1647 [(set (match_dup 0) (match_dup 1))
1648 (set (match_dup 2) (match_dup 3))]
1650 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1652 operands[1] = gen_lowpart (DImode, operands[2]);
1653 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1658 [(set (match_operand:DI 0 "push_operand" "")
1659 (match_operand:DI 1 "immediate_operand" ""))]
1660 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1661 ? epilogue_completed : reload_completed)
1662 && !symbolic_operand (operands[1], DImode)
1663 && !x86_64_immediate_operand (operands[1], DImode)"
1664 [(set (match_dup 0) (match_dup 1))
1665 (set (match_dup 2) (match_dup 3))]
1667 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1669 operands[1] = gen_lowpart (DImode, operands[2]);
1670 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1675 [(set (match_operand:DI 0 "push_operand" "")
1676 (match_operand:DI 1 "general_operand" ""))]
1677 "!TARGET_64BIT && reload_completed
1678 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1680 "ix86_split_long_move (operands); DONE;")
1682 (define_insn "*pushsi2"
1683 [(set (match_operand:SI 0 "push_operand" "=<")
1684 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1687 [(set_attr "type" "push")
1688 (set_attr "mode" "SI")])
1690 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1691 ;; "push a byte/word". But actually we use pushl, which has the effect
1692 ;; of rounding the amount pushed up to a word.
1694 ;; For TARGET_64BIT we always round up to 8 bytes.
1695 (define_insn "*push<mode>2_rex64"
1696 [(set (match_operand:SWI124 0 "push_operand" "=X")
1697 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1700 [(set_attr "type" "push")
1701 (set_attr "mode" "DI")])
1703 (define_insn "*push<mode>2"
1704 [(set (match_operand:SWI12 0 "push_operand" "=X")
1705 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1708 [(set_attr "type" "push")
1709 (set_attr "mode" "SI")])
1711 (define_insn "*push<mode>2_prologue"
1712 [(set (match_operand:P 0 "push_operand" "=<")
1713 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1714 (clobber (mem:BLK (scratch)))]
1716 "push{<imodesuffix>}\t%1"
1717 [(set_attr "type" "push")
1718 (set_attr "mode" "<MODE>")])
1720 (define_insn "*pop<mode>1"
1721 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1722 (match_operand:P 1 "pop_operand" ">"))]
1724 "pop{<imodesuffix>}\t%0"
1725 [(set_attr "type" "pop")
1726 (set_attr "mode" "<MODE>")])
1728 (define_insn "*pop<mode>1_epilogue"
1729 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1730 (match_operand:P 1 "pop_operand" ">"))
1731 (clobber (mem:BLK (scratch)))]
1733 "pop{<imodesuffix>}\t%0"
1734 [(set_attr "type" "pop")
1735 (set_attr "mode" "<MODE>")])
1737 ;; Move instructions.
1739 (define_expand "movoi"
1740 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1741 (match_operand:OI 1 "general_operand" ""))]
1743 "ix86_expand_move (OImode, operands); DONE;")
1745 (define_expand "movti"
1746 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1747 (match_operand:TI 1 "nonimmediate_operand" ""))]
1748 "TARGET_64BIT || TARGET_SSE"
1751 ix86_expand_move (TImode, operands);
1752 else if (push_operand (operands[0], TImode))
1753 ix86_expand_push (TImode, operands[1]);
1755 ix86_expand_vector_move (TImode, operands);
1759 ;; This expands to what emit_move_complex would generate if we didn't
1760 ;; have a movti pattern. Having this avoids problems with reload on
1761 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1762 ;; to have around all the time.
1763 (define_expand "movcdi"
1764 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1765 (match_operand:CDI 1 "general_operand" ""))]
1768 if (push_operand (operands[0], CDImode))
1769 emit_move_complex_push (CDImode, operands[0], operands[1]);
1771 emit_move_complex_parts (operands[0], operands[1]);
1775 (define_expand "mov<mode>"
1776 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1777 (match_operand:SWI1248x 1 "general_operand" ""))]
1779 "ix86_expand_move (<MODE>mode, operands); DONE;")
1781 (define_insn "*mov<mode>_xor"
1782 [(set (match_operand:SWI48 0 "register_operand" "=r")
1783 (match_operand:SWI48 1 "const0_operand" ""))
1784 (clobber (reg:CC FLAGS_REG))]
1787 [(set_attr "type" "alu1")
1788 (set_attr "mode" "SI")
1789 (set_attr "length_immediate" "0")])
1791 (define_insn "*mov<mode>_or"
1792 [(set (match_operand:SWI48 0 "register_operand" "=r")
1793 (match_operand:SWI48 1 "const_int_operand" ""))
1794 (clobber (reg:CC FLAGS_REG))]
1796 && operands[1] == constm1_rtx"
1797 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1798 [(set_attr "type" "alu1")
1799 (set_attr "mode" "<MODE>")
1800 (set_attr "length_immediate" "1")])
1802 (define_insn "*movoi_internal_avx"
1803 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1804 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1805 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1807 switch (which_alternative)
1810 return standard_sse_constant_opcode (insn, operands[1]);
1813 if (misaligned_operand (operands[0], OImode)
1814 || misaligned_operand (operands[1], OImode))
1815 return "vmovdqu\t{%1, %0|%0, %1}";
1817 return "vmovdqa\t{%1, %0|%0, %1}";
1822 [(set_attr "type" "sselog1,ssemov,ssemov")
1823 (set_attr "prefix" "vex")
1824 (set_attr "mode" "OI")])
1826 (define_insn "*movti_internal_rex64"
1827 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1828 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1829 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1831 switch (which_alternative)
1837 return standard_sse_constant_opcode (insn, operands[1]);
1840 /* TDmode values are passed as TImode on the stack. Moving them
1841 to stack may result in unaligned memory access. */
1842 if (misaligned_operand (operands[0], TImode)
1843 || misaligned_operand (operands[1], TImode))
1845 if (get_attr_mode (insn) == MODE_V4SF)
1846 return "%vmovups\t{%1, %0|%0, %1}";
1848 return "%vmovdqu\t{%1, %0|%0, %1}";
1852 if (get_attr_mode (insn) == MODE_V4SF)
1853 return "%vmovaps\t{%1, %0|%0, %1}";
1855 return "%vmovdqa\t{%1, %0|%0, %1}";
1861 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1862 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1864 (cond [(eq_attr "alternative" "2,3")
1866 (match_test "optimize_function_for_size_p (cfun)")
1867 (const_string "V4SF")
1868 (const_string "TI"))
1869 (eq_attr "alternative" "4")
1871 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1872 (match_test "optimize_function_for_size_p (cfun)"))
1873 (const_string "V4SF")
1874 (const_string "TI"))]
1875 (const_string "DI")))])
1878 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1879 (match_operand:TI 1 "general_operand" ""))]
1881 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1883 "ix86_split_long_move (operands); DONE;")
1885 (define_insn "*movti_internal_sse"
1886 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1887 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1888 "TARGET_SSE && !TARGET_64BIT
1889 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1891 switch (which_alternative)
1894 return standard_sse_constant_opcode (insn, operands[1]);
1897 /* TDmode values are passed as TImode on the stack. Moving them
1898 to stack may result in unaligned memory access. */
1899 if (misaligned_operand (operands[0], TImode)
1900 || misaligned_operand (operands[1], TImode))
1902 if (get_attr_mode (insn) == MODE_V4SF)
1903 return "%vmovups\t{%1, %0|%0, %1}";
1905 return "%vmovdqu\t{%1, %0|%0, %1}";
1909 if (get_attr_mode (insn) == MODE_V4SF)
1910 return "%vmovaps\t{%1, %0|%0, %1}";
1912 return "%vmovdqa\t{%1, %0|%0, %1}";
1918 [(set_attr "type" "sselog1,ssemov,ssemov")
1919 (set_attr "prefix" "maybe_vex")
1921 (cond [(ior (not (match_test "TARGET_SSE2"))
1922 (match_test "optimize_function_for_size_p (cfun)"))
1923 (const_string "V4SF")
1924 (and (eq_attr "alternative" "2")
1925 (match_test "TARGET_SSE_TYPELESS_STORES"))
1926 (const_string "V4SF")]
1927 (const_string "TI")))])
1929 (define_insn "*movdi_internal_rex64"
1930 [(set (match_operand:DI 0 "nonimmediate_operand"
1931 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1932 (match_operand:DI 1 "general_operand"
1933 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1934 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1936 switch (get_attr_type (insn))
1939 if (SSE_REG_P (operands[0]))
1940 return "movq2dq\t{%1, %0|%0, %1}";
1942 return "movdq2q\t{%1, %0|%0, %1}";
1945 if (get_attr_mode (insn) == MODE_TI)
1946 return "%vmovdqa\t{%1, %0|%0, %1}";
1947 /* Handle broken assemblers that require movd instead of movq. */
1948 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1949 return "%vmovd\t{%1, %0|%0, %1}";
1951 return "%vmovq\t{%1, %0|%0, %1}";
1954 /* Handle broken assemblers that require movd instead of movq. */
1955 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1956 return "movd\t{%1, %0|%0, %1}";
1958 return "movq\t{%1, %0|%0, %1}";
1961 return standard_sse_constant_opcode (insn, operands[1]);
1964 return "pxor\t%0, %0";
1970 return "lea{q}\t{%E1, %0|%0, %E1}";
1973 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1974 if (get_attr_mode (insn) == MODE_SI)
1975 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1976 else if (which_alternative == 2)
1977 return "movabs{q}\t{%1, %0|%0, %1}";
1978 else if (ix86_use_lea_for_mov (insn, operands))
1979 return "lea{q}\t{%E1, %0|%0, %E1}";
1981 return "mov{q}\t{%1, %0|%0, %1}";
1985 (cond [(eq_attr "alternative" "4")
1986 (const_string "multi")
1987 (eq_attr "alternative" "5")
1988 (const_string "mmx")
1989 (eq_attr "alternative" "6,7,8,9")
1990 (const_string "mmxmov")
1991 (eq_attr "alternative" "10")
1992 (const_string "sselog1")
1993 (eq_attr "alternative" "11,12,13,14,15")
1994 (const_string "ssemov")
1995 (eq_attr "alternative" "16,17")
1996 (const_string "ssecvt")
1997 (match_operand 1 "pic_32bit_operand" "")
1998 (const_string "lea")
2000 (const_string "imov")))
2003 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2005 (const_string "*")))
2006 (set (attr "length_immediate")
2008 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2010 (const_string "*")))
2011 (set (attr "prefix_rex")
2012 (if_then_else (eq_attr "alternative" "8,9")
2014 (const_string "*")))
2015 (set (attr "prefix_data16")
2016 (if_then_else (eq_attr "alternative" "11")
2018 (const_string "*")))
2019 (set (attr "prefix")
2020 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2021 (const_string "maybe_vex")
2022 (const_string "orig")))
2023 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2025 ;; Reload patterns to support multi-word load/store
2026 ;; with non-offsetable address.
2027 (define_expand "reload_noff_store"
2028 [(parallel [(match_operand 0 "memory_operand" "=m")
2029 (match_operand 1 "register_operand" "r")
2030 (match_operand:DI 2 "register_operand" "=&r")])]
2033 rtx mem = operands[0];
2034 rtx addr = XEXP (mem, 0);
2036 emit_move_insn (operands[2], addr);
2037 mem = replace_equiv_address_nv (mem, operands[2]);
2039 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2043 (define_expand "reload_noff_load"
2044 [(parallel [(match_operand 0 "register_operand" "=r")
2045 (match_operand 1 "memory_operand" "m")
2046 (match_operand:DI 2 "register_operand" "=r")])]
2049 rtx mem = operands[1];
2050 rtx addr = XEXP (mem, 0);
2052 emit_move_insn (operands[2], addr);
2053 mem = replace_equiv_address_nv (mem, operands[2]);
2055 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2059 ;; Convert impossible stores of immediate to existing instructions.
2060 ;; First try to get scratch register and go through it. In case this
2061 ;; fails, move by 32bit parts.
2063 [(match_scratch:DI 2 "r")
2064 (set (match_operand:DI 0 "memory_operand" "")
2065 (match_operand:DI 1 "immediate_operand" ""))]
2066 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2067 && !x86_64_immediate_operand (operands[1], DImode)"
2068 [(set (match_dup 2) (match_dup 1))
2069 (set (match_dup 0) (match_dup 2))])
2071 ;; We need to define this as both peepholer and splitter for case
2072 ;; peephole2 pass is not run.
2073 ;; "&& 1" is needed to keep it from matching the previous pattern.
2075 [(set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2079 [(set (match_dup 2) (match_dup 3))
2080 (set (match_dup 4) (match_dup 5))]
2081 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2084 [(set (match_operand:DI 0 "memory_operand" "")
2085 (match_operand:DI 1 "immediate_operand" ""))]
2086 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2087 ? epilogue_completed : reload_completed)
2088 && !symbolic_operand (operands[1], DImode)
2089 && !x86_64_immediate_operand (operands[1], DImode)"
2090 [(set (match_dup 2) (match_dup 3))
2091 (set (match_dup 4) (match_dup 5))]
2092 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2094 (define_insn "*movdi_internal"
2095 [(set (match_operand:DI 0 "nonimmediate_operand"
2096 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2097 (match_operand:DI 1 "general_operand"
2098 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2099 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2101 switch (get_attr_type (insn))
2104 if (SSE_REG_P (operands[0]))
2105 return "movq2dq\t{%1, %0|%0, %1}";
2107 return "movdq2q\t{%1, %0|%0, %1}";
2110 switch (get_attr_mode (insn))
2113 return "%vmovdqa\t{%1, %0|%0, %1}";
2115 return "%vmovq\t{%1, %0|%0, %1}";
2117 return "movaps\t{%1, %0|%0, %1}";
2119 return "movlps\t{%1, %0|%0, %1}";
2125 return "movq\t{%1, %0|%0, %1}";
2128 return standard_sse_constant_opcode (insn, operands[1]);
2131 return "pxor\t%0, %0";
2141 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2142 (const_string "sse2")
2143 (eq_attr "alternative" "9,10,11,12")
2144 (const_string "noavx")
2146 (const_string "*")))
2148 (cond [(eq_attr "alternative" "0,1")
2149 (const_string "multi")
2150 (eq_attr "alternative" "2")
2151 (const_string "mmx")
2152 (eq_attr "alternative" "3,4")
2153 (const_string "mmxmov")
2154 (eq_attr "alternative" "5,9")
2155 (const_string "sselog1")
2156 (eq_attr "alternative" "13,14")
2157 (const_string "ssecvt")
2159 (const_string "ssemov")))
2160 (set (attr "prefix")
2161 (if_then_else (eq_attr "alternative" "5,6,7,8")
2162 (const_string "maybe_vex")
2163 (const_string "orig")))
2164 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2167 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2168 (match_operand:DI 1 "general_operand" ""))]
2169 "!TARGET_64BIT && reload_completed
2170 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2171 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2173 "ix86_split_long_move (operands); DONE;")
2175 (define_insn "*movsi_internal"
2176 [(set (match_operand:SI 0 "nonimmediate_operand"
2177 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2178 (match_operand:SI 1 "general_operand"
2179 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2180 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2182 switch (get_attr_type (insn))
2185 return standard_sse_constant_opcode (insn, operands[1]);
2188 switch (get_attr_mode (insn))
2191 return "%vmovdqa\t{%1, %0|%0, %1}";
2193 return "%vmovaps\t{%1, %0|%0, %1}";
2195 return "%vmovd\t{%1, %0|%0, %1}";
2197 return "%vmovss\t{%1, %0|%0, %1}";
2203 return "pxor\t%0, %0";
2206 if (get_attr_mode (insn) == MODE_DI)
2207 return "movq\t{%1, %0|%0, %1}";
2208 return "movd\t{%1, %0|%0, %1}";
2211 return "lea{l}\t{%E1, %0|%0, %E1}";
2214 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2215 if (ix86_use_lea_for_mov (insn, operands))
2216 return "lea{l}\t{%E1, %0|%0, %E1}";
2218 return "mov{l}\t{%1, %0|%0, %1}";
2222 (cond [(eq_attr "alternative" "2")
2223 (const_string "mmx")
2224 (eq_attr "alternative" "3,4,5")
2225 (const_string "mmxmov")
2226 (eq_attr "alternative" "6")
2227 (const_string "sselog1")
2228 (eq_attr "alternative" "7,8,9,10,11")
2229 (const_string "ssemov")
2230 (match_operand 1 "pic_32bit_operand" "")
2231 (const_string "lea")
2233 (const_string "imov")))
2234 (set (attr "prefix")
2235 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2236 (const_string "orig")
2237 (const_string "maybe_vex")))
2238 (set (attr "prefix_data16")
2239 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2241 (const_string "*")))
2243 (cond [(eq_attr "alternative" "2,3")
2245 (eq_attr "alternative" "6,7")
2247 (not (match_test "TARGET_SSE2"))
2248 (const_string "V4SF")
2249 (const_string "TI"))
2250 (and (eq_attr "alternative" "8,9,10,11")
2251 (not (match_test "TARGET_SSE2")))
2254 (const_string "SI")))])
2256 (define_insn "*movhi_internal"
2257 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2258 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2259 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2261 switch (get_attr_type (insn))
2264 /* movzwl is faster than movw on p2 due to partial word stalls,
2265 though not as fast as an aligned movl. */
2266 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2268 if (get_attr_mode (insn) == MODE_SI)
2269 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2271 return "mov{w}\t{%1, %0|%0, %1}";
2275 (cond [(match_test "optimize_function_for_size_p (cfun)")
2276 (const_string "imov")
2277 (and (eq_attr "alternative" "0")
2278 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2279 (not (match_test "TARGET_HIMODE_MATH"))))
2280 (const_string "imov")
2281 (and (eq_attr "alternative" "1,2")
2282 (match_operand:HI 1 "aligned_operand" ""))
2283 (const_string "imov")
2284 (and (match_test "TARGET_MOVX")
2285 (eq_attr "alternative" "0,2"))
2286 (const_string "imovx")
2288 (const_string "imov")))
2290 (cond [(eq_attr "type" "imovx")
2292 (and (eq_attr "alternative" "1,2")
2293 (match_operand:HI 1 "aligned_operand" ""))
2295 (and (eq_attr "alternative" "0")
2296 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2297 (not (match_test "TARGET_HIMODE_MATH"))))
2300 (const_string "HI")))])
2302 ;; Situation is quite tricky about when to choose full sized (SImode) move
2303 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2304 ;; partial register dependency machines (such as AMD Athlon), where QImode
2305 ;; moves issue extra dependency and for partial register stalls machines
2306 ;; that don't use QImode patterns (and QImode move cause stall on the next
2309 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2310 ;; register stall machines with, where we use QImode instructions, since
2311 ;; partial register stall can be caused there. Then we use movzx.
2312 (define_insn "*movqi_internal"
2313 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2314 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2315 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2317 switch (get_attr_type (insn))
2320 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2321 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2323 if (get_attr_mode (insn) == MODE_SI)
2324 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2326 return "mov{b}\t{%1, %0|%0, %1}";
2330 (cond [(and (eq_attr "alternative" "5")
2331 (not (match_operand:QI 1 "aligned_operand" "")))
2332 (const_string "imovx")
2333 (match_test "optimize_function_for_size_p (cfun)")
2334 (const_string "imov")
2335 (and (eq_attr "alternative" "3")
2336 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2337 (not (match_test "TARGET_QIMODE_MATH"))))
2338 (const_string "imov")
2339 (eq_attr "alternative" "3,5")
2340 (const_string "imovx")
2341 (and (match_test "TARGET_MOVX")
2342 (eq_attr "alternative" "2"))
2343 (const_string "imovx")
2345 (const_string "imov")))
2347 (cond [(eq_attr "alternative" "3,4,5")
2349 (eq_attr "alternative" "6")
2351 (eq_attr "type" "imovx")
2353 (and (eq_attr "type" "imov")
2354 (and (eq_attr "alternative" "0,1")
2355 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2356 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2357 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2359 ;; Avoid partial register stalls when not using QImode arithmetic
2360 (and (eq_attr "type" "imov")
2361 (and (eq_attr "alternative" "0,1")
2362 (and (match_test "TARGET_PARTIAL_REG_STALL")
2363 (not (match_test "TARGET_QIMODE_MATH")))))
2366 (const_string "QI")))])
2368 ;; Stores and loads of ax to arbitrary constant address.
2369 ;; We fake an second form of instruction to force reload to load address
2370 ;; into register when rax is not available
2371 (define_insn "*movabs<mode>_1"
2372 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2373 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2374 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2376 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2377 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2378 [(set_attr "type" "imov")
2379 (set_attr "modrm" "0,*")
2380 (set_attr "length_address" "8,0")
2381 (set_attr "length_immediate" "0,*")
2382 (set_attr "memory" "store")
2383 (set_attr "mode" "<MODE>")])
2385 (define_insn "*movabs<mode>_2"
2386 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2387 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2388 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2390 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2391 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2392 [(set_attr "type" "imov")
2393 (set_attr "modrm" "0,*")
2394 (set_attr "length_address" "8,0")
2395 (set_attr "length_immediate" "0")
2396 (set_attr "memory" "load")
2397 (set_attr "mode" "<MODE>")])
2399 (define_insn "*swap<mode>"
2400 [(set (match_operand:SWI48 0 "register_operand" "+r")
2401 (match_operand:SWI48 1 "register_operand" "+r"))
2405 "xchg{<imodesuffix>}\t%1, %0"
2406 [(set_attr "type" "imov")
2407 (set_attr "mode" "<MODE>")
2408 (set_attr "pent_pair" "np")
2409 (set_attr "athlon_decode" "vector")
2410 (set_attr "amdfam10_decode" "double")
2411 (set_attr "bdver1_decode" "double")])
2413 (define_insn "*swap<mode>_1"
2414 [(set (match_operand:SWI12 0 "register_operand" "+r")
2415 (match_operand:SWI12 1 "register_operand" "+r"))
2418 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2420 [(set_attr "type" "imov")
2421 (set_attr "mode" "SI")
2422 (set_attr "pent_pair" "np")
2423 (set_attr "athlon_decode" "vector")
2424 (set_attr "amdfam10_decode" "double")
2425 (set_attr "bdver1_decode" "double")])
2427 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2428 ;; is disabled for AMDFAM10
2429 (define_insn "*swap<mode>_2"
2430 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2431 (match_operand:SWI12 1 "register_operand" "+<r>"))
2434 "TARGET_PARTIAL_REG_STALL"
2435 "xchg{<imodesuffix>}\t%1, %0"
2436 [(set_attr "type" "imov")
2437 (set_attr "mode" "<MODE>")
2438 (set_attr "pent_pair" "np")
2439 (set_attr "athlon_decode" "vector")])
2441 (define_expand "movstrict<mode>"
2442 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2443 (match_operand:SWI12 1 "general_operand" ""))]
2446 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2448 if (GET_CODE (operands[0]) == SUBREG
2449 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2451 /* Don't generate memory->memory moves, go through a register */
2452 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2453 operands[1] = force_reg (<MODE>mode, operands[1]);
2456 (define_insn "*movstrict<mode>_1"
2457 [(set (strict_low_part
2458 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2459 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2460 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2461 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2462 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2463 [(set_attr "type" "imov")
2464 (set_attr "mode" "<MODE>")])
2466 (define_insn "*movstrict<mode>_xor"
2467 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2468 (match_operand:SWI12 1 "const0_operand" ""))
2469 (clobber (reg:CC FLAGS_REG))]
2471 "xor{<imodesuffix>}\t%0, %0"
2472 [(set_attr "type" "alu1")
2473 (set_attr "mode" "<MODE>")
2474 (set_attr "length_immediate" "0")])
2476 (define_insn "*mov<mode>_extv_1"
2477 [(set (match_operand:SWI24 0 "register_operand" "=R")
2478 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2482 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2483 [(set_attr "type" "imovx")
2484 (set_attr "mode" "SI")])
2486 (define_insn "*movqi_extv_1_rex64"
2487 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2488 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2493 switch (get_attr_type (insn))
2496 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2498 return "mov{b}\t{%h1, %0|%0, %h1}";
2502 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2503 (match_test "TARGET_MOVX"))
2504 (const_string "imovx")
2505 (const_string "imov")))
2507 (if_then_else (eq_attr "type" "imovx")
2509 (const_string "QI")))])
2511 (define_insn "*movqi_extv_1"
2512 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2513 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2518 switch (get_attr_type (insn))
2521 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2523 return "mov{b}\t{%h1, %0|%0, %h1}";
2527 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2528 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2529 (match_test "TARGET_MOVX")))
2530 (const_string "imovx")
2531 (const_string "imov")))
2533 (if_then_else (eq_attr "type" "imovx")
2535 (const_string "QI")))])
2537 (define_insn "*mov<mode>_extzv_1"
2538 [(set (match_operand:SWI48 0 "register_operand" "=R")
2539 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2543 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2544 [(set_attr "type" "imovx")
2545 (set_attr "mode" "SI")])
2547 (define_insn "*movqi_extzv_2_rex64"
2548 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2550 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2555 switch (get_attr_type (insn))
2558 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2560 return "mov{b}\t{%h1, %0|%0, %h1}";
2564 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2565 (match_test "TARGET_MOVX"))
2566 (const_string "imovx")
2567 (const_string "imov")))
2569 (if_then_else (eq_attr "type" "imovx")
2571 (const_string "QI")))])
2573 (define_insn "*movqi_extzv_2"
2574 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2576 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2581 switch (get_attr_type (insn))
2584 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2586 return "mov{b}\t{%h1, %0|%0, %h1}";
2590 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2591 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2592 (match_test "TARGET_MOVX")))
2593 (const_string "imovx")
2594 (const_string "imov")))
2596 (if_then_else (eq_attr "type" "imovx")
2598 (const_string "QI")))])
2600 (define_expand "mov<mode>_insv_1"
2601 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2604 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2606 (define_insn "*mov<mode>_insv_1_rex64"
2607 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2610 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2613 if (CONST_INT_P (operands[1]))
2614 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2615 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2617 [(set_attr "type" "imov")
2618 (set_attr "mode" "QI")])
2620 (define_insn "*movsi_insv_1"
2621 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2624 (match_operand:SI 1 "general_operand" "Qmn"))]
2627 if (CONST_INT_P (operands[1]))
2628 operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2629 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2631 [(set_attr "type" "imov")
2632 (set_attr "mode" "QI")])
2634 (define_insn "*movqi_insv_2"
2635 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2638 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2641 "mov{b}\t{%h1, %h0|%h0, %h1}"
2642 [(set_attr "type" "imov")
2643 (set_attr "mode" "QI")])
2645 ;; Floating point push instructions.
2647 (define_insn "*pushtf"
2648 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2649 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2652 /* This insn should be already split before reg-stack. */
2655 [(set_attr "type" "multi")
2656 (set_attr "unit" "sse,*,*")
2657 (set_attr "mode" "TF,SI,SI")])
2659 ;; %%% Kill this when call knows how to work this out.
2661 [(set (match_operand:TF 0 "push_operand" "")
2662 (match_operand:TF 1 "sse_reg_operand" ""))]
2663 "TARGET_SSE2 && reload_completed"
2664 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2665 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2667 (define_insn "*pushxf"
2668 [(set (match_operand:XF 0 "push_operand" "=<,<")
2669 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2670 "optimize_function_for_speed_p (cfun)"
2672 /* This insn should be already split before reg-stack. */
2675 [(set_attr "type" "multi")
2676 (set_attr "unit" "i387,*")
2677 (set_attr "mode" "XF,SI")])
2679 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2680 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2681 ;; Pushing using integer instructions is longer except for constants
2682 ;; and direct memory references (assuming that any given constant is pushed
2683 ;; only once, but this ought to be handled elsewhere).
2685 (define_insn "*pushxf_nointeger"
2686 [(set (match_operand:XF 0 "push_operand" "=<,<")
2687 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2688 "optimize_function_for_size_p (cfun)"
2690 /* This insn should be already split before reg-stack. */
2693 [(set_attr "type" "multi")
2694 (set_attr "unit" "i387,*")
2695 (set_attr "mode" "XF,SI")])
2697 ;; %%% Kill this when call knows how to work this out.
2699 [(set (match_operand:XF 0 "push_operand" "")
2700 (match_operand:XF 1 "fp_register_operand" ""))]
2702 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2703 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2704 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2706 (define_insn "*pushdf_rex64"
2707 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2708 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2711 /* This insn should be already split before reg-stack. */
2714 [(set_attr "type" "multi")
2715 (set_attr "unit" "i387,*,*")
2716 (set_attr "mode" "DF,DI,DF")])
2718 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2719 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2720 ;; On the average, pushdf using integers can be still shorter.
2722 (define_insn "*pushdf"
2723 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2724 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2727 /* This insn should be already split before reg-stack. */
2730 [(set_attr "isa" "*,*,sse2")
2731 (set_attr "type" "multi")
2732 (set_attr "unit" "i387,*,*")
2733 (set_attr "mode" "DF,DI,DF")])
2735 ;; %%% Kill this when call knows how to work this out.
2737 [(set (match_operand:DF 0 "push_operand" "")
2738 (match_operand:DF 1 "any_fp_register_operand" ""))]
2740 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2741 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2743 (define_insn "*pushsf_rex64"
2744 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2745 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2748 /* Anything else should be already split before reg-stack. */
2749 gcc_assert (which_alternative == 1);
2750 return "push{q}\t%q1";
2752 [(set_attr "type" "multi,push,multi")
2753 (set_attr "unit" "i387,*,*")
2754 (set_attr "mode" "SF,DI,SF")])
2756 (define_insn "*pushsf"
2757 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2758 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2761 /* Anything else should be already split before reg-stack. */
2762 gcc_assert (which_alternative == 1);
2763 return "push{l}\t%1";
2765 [(set_attr "type" "multi,push,multi")
2766 (set_attr "unit" "i387,*,*")
2767 (set_attr "mode" "SF,SI,SF")])
2769 ;; %%% Kill this when call knows how to work this out.
2771 [(set (match_operand:SF 0 "push_operand" "")
2772 (match_operand:SF 1 "any_fp_register_operand" ""))]
2774 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2775 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2776 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2779 [(set (match_operand:SF 0 "push_operand" "")
2780 (match_operand:SF 1 "memory_operand" ""))]
2782 && (operands[2] = find_constant_src (insn))"
2783 [(set (match_dup 0) (match_dup 2))])
2786 [(set (match_operand 0 "push_operand" "")
2787 (match_operand 1 "general_operand" ""))]
2789 && (GET_MODE (operands[0]) == TFmode
2790 || GET_MODE (operands[0]) == XFmode
2791 || GET_MODE (operands[0]) == DFmode)
2792 && !ANY_FP_REG_P (operands[1])"
2794 "ix86_split_long_move (operands); DONE;")
2796 ;; Floating point move instructions.
2798 (define_expand "movtf"
2799 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2800 (match_operand:TF 1 "nonimmediate_operand" ""))]
2803 ix86_expand_move (TFmode, operands);
2807 (define_expand "mov<mode>"
2808 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2809 (match_operand:X87MODEF 1 "general_operand" ""))]
2811 "ix86_expand_move (<MODE>mode, operands); DONE;")
2813 (define_insn "*movtf_internal"
2814 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2815 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2817 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2818 && (!can_create_pseudo_p ()
2819 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2820 || GET_CODE (operands[1]) != CONST_DOUBLE
2821 || (optimize_function_for_size_p (cfun)
2822 && standard_sse_constant_p (operands[1])
2823 && !memory_operand (operands[0], TFmode))
2824 || (!TARGET_MEMORY_MISMATCH_STALL
2825 && memory_operand (operands[0], TFmode)))"
2827 switch (which_alternative)
2831 /* Handle misaligned load/store since we
2832 don't have movmisaligntf pattern. */
2833 if (misaligned_operand (operands[0], TFmode)
2834 || misaligned_operand (operands[1], TFmode))
2836 if (get_attr_mode (insn) == MODE_V4SF)
2837 return "%vmovups\t{%1, %0|%0, %1}";
2839 return "%vmovdqu\t{%1, %0|%0, %1}";
2843 if (get_attr_mode (insn) == MODE_V4SF)
2844 return "%vmovaps\t{%1, %0|%0, %1}";
2846 return "%vmovdqa\t{%1, %0|%0, %1}";
2850 return standard_sse_constant_opcode (insn, operands[1]);
2860 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2861 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2863 (cond [(eq_attr "alternative" "0,2")
2865 (match_test "optimize_function_for_size_p (cfun)")
2866 (const_string "V4SF")
2867 (const_string "TI"))
2868 (eq_attr "alternative" "1")
2870 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2871 (match_test "optimize_function_for_size_p (cfun)"))
2872 (const_string "V4SF")
2873 (const_string "TI"))]
2874 (const_string "DI")))])
2876 ;; Possible store forwarding (partial memory) stall in alternative 4.
2877 (define_insn "*movxf_internal"
2878 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2879 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2880 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2881 && (!can_create_pseudo_p ()
2882 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2883 || GET_CODE (operands[1]) != CONST_DOUBLE
2884 || (optimize_function_for_size_p (cfun)
2885 && standard_80387_constant_p (operands[1]) > 0
2886 && !memory_operand (operands[0], XFmode))
2887 || (!TARGET_MEMORY_MISMATCH_STALL
2888 && memory_operand (operands[0], XFmode)))"
2890 switch (which_alternative)
2894 return output_387_reg_move (insn, operands);
2897 return standard_80387_constant_opcode (operands[1]);
2907 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2908 (set_attr "mode" "XF,XF,XF,SI,SI")])
2910 (define_insn "*movdf_internal_rex64"
2911 [(set (match_operand:DF 0 "nonimmediate_operand"
2912 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2913 (match_operand:DF 1 "general_operand"
2914 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2915 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2916 && (!can_create_pseudo_p ()
2917 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2918 || GET_CODE (operands[1]) != CONST_DOUBLE
2919 || (optimize_function_for_size_p (cfun)
2920 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2921 && standard_80387_constant_p (operands[1]) > 0)
2922 || (TARGET_SSE2 && TARGET_SSE_MATH
2923 && standard_sse_constant_p (operands[1]))))
2924 || memory_operand (operands[0], DFmode))"
2926 switch (which_alternative)
2930 return output_387_reg_move (insn, operands);
2933 return standard_80387_constant_opcode (operands[1]);
2937 return "mov{q}\t{%1, %0|%0, %1}";
2940 return "movabs{q}\t{%1, %0|%0, %1}";
2946 return standard_sse_constant_opcode (insn, operands[1]);
2951 switch (get_attr_mode (insn))
2954 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2955 return "%vmovapd\t{%1, %0|%0, %1}";
2957 return "%vmovaps\t{%1, %0|%0, %1}";
2960 return "%vmovq\t{%1, %0|%0, %1}";
2962 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2963 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2964 return "%vmovsd\t{%1, %0|%0, %1}";
2966 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2968 return "%vmovlps\t{%1, %d0|%d0, %1}";
2975 /* Handle broken assemblers that require movd instead of movq. */
2976 return "%vmovd\t{%1, %0|%0, %1}";
2983 (cond [(eq_attr "alternative" "0,1,2")
2984 (const_string "fmov")
2985 (eq_attr "alternative" "3,4,5")
2986 (const_string "imov")
2987 (eq_attr "alternative" "6")
2988 (const_string "multi")
2989 (eq_attr "alternative" "7")
2990 (const_string "sselog1")
2992 (const_string "ssemov")))
2995 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2997 (const_string "*")))
2998 (set (attr "length_immediate")
3000 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3002 (const_string "*")))
3003 (set (attr "prefix")
3004 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3005 (const_string "orig")
3006 (const_string "maybe_vex")))
3007 (set (attr "prefix_data16")
3008 (if_then_else (eq_attr "mode" "V1DF")
3010 (const_string "*")))
3012 (cond [(eq_attr "alternative" "0,1,2")
3014 (eq_attr "alternative" "3,4,5,6,11,12")
3017 /* xorps is one byte shorter. */
3018 (eq_attr "alternative" "7")
3019 (cond [(match_test "optimize_function_for_size_p (cfun)")
3020 (const_string "V4SF")
3021 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3024 (const_string "V2DF"))
3026 /* For architectures resolving dependencies on
3027 whole SSE registers use APD move to break dependency
3028 chains, otherwise use short move to avoid extra work.
3030 movaps encodes one byte shorter. */
3031 (eq_attr "alternative" "8")
3033 [(match_test "optimize_function_for_size_p (cfun)")
3034 (const_string "V4SF")
3035 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3036 (const_string "V2DF")
3038 (const_string "DF"))
3039 /* For architectures resolving dependencies on register
3040 parts we may avoid extra work to zero out upper part
3042 (eq_attr "alternative" "9")
3044 (match_test "TARGET_SSE_SPLIT_REGS")
3045 (const_string "V1DF")
3046 (const_string "DF"))
3048 (const_string "DF")))])
3050 ;; Possible store forwarding (partial memory) stall in alternative 4.
3051 (define_insn "*movdf_internal"
3052 [(set (match_operand:DF 0 "nonimmediate_operand"
3053 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3054 (match_operand:DF 1 "general_operand"
3055 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3056 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3057 && (!can_create_pseudo_p ()
3058 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3059 || GET_CODE (operands[1]) != CONST_DOUBLE
3060 || (optimize_function_for_size_p (cfun)
3061 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3062 && standard_80387_constant_p (operands[1]) > 0)
3063 || (TARGET_SSE2 && TARGET_SSE_MATH
3064 && standard_sse_constant_p (operands[1])))
3065 && !memory_operand (operands[0], DFmode))
3066 || (!TARGET_MEMORY_MISMATCH_STALL
3067 && memory_operand (operands[0], DFmode)))"
3069 switch (which_alternative)
3073 return output_387_reg_move (insn, operands);
3076 return standard_80387_constant_opcode (operands[1]);
3084 return standard_sse_constant_opcode (insn, operands[1]);
3092 switch (get_attr_mode (insn))
3095 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3096 return "%vmovapd\t{%1, %0|%0, %1}";
3098 return "%vmovaps\t{%1, %0|%0, %1}";
3101 return "%vmovq\t{%1, %0|%0, %1}";
3103 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3104 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3105 return "%vmovsd\t{%1, %0|%0, %1}";
3107 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3109 return "%vmovlps\t{%1, %d0|%d0, %1}";
3119 (if_then_else (eq_attr "alternative" "5,6,7,8")
3120 (const_string "sse2")
3121 (const_string "*")))
3123 (cond [(eq_attr "alternative" "0,1,2")
3124 (const_string "fmov")
3125 (eq_attr "alternative" "3,4")
3126 (const_string "multi")
3127 (eq_attr "alternative" "5,9")
3128 (const_string "sselog1")
3130 (const_string "ssemov")))
3131 (set (attr "prefix")
3132 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3133 (const_string "orig")
3134 (const_string "maybe_vex")))
3135 (set (attr "prefix_data16")
3136 (if_then_else (eq_attr "mode" "V1DF")
3138 (const_string "*")))
3140 (cond [(eq_attr "alternative" "0,1,2")
3142 (eq_attr "alternative" "3,4")
3145 /* For SSE1, we have many fewer alternatives. */
3146 (not (match_test "TARGET_SSE2"))
3148 (eq_attr "alternative" "5,6,9,10")
3149 (const_string "V4SF")
3150 (const_string "V2SF"))
3152 /* xorps is one byte shorter. */
3153 (eq_attr "alternative" "5,9")
3154 (cond [(match_test "optimize_function_for_size_p (cfun)")
3155 (const_string "V4SF")
3156 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3159 (const_string "V2DF"))
3161 /* For architectures resolving dependencies on
3162 whole SSE registers use APD move to break dependency
3163 chains, otherwise use short move to avoid extra work.
3165 movaps encodes one byte shorter. */
3166 (eq_attr "alternative" "6,10")
3168 [(match_test "optimize_function_for_size_p (cfun)")
3169 (const_string "V4SF")
3170 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3171 (const_string "V2DF")
3173 (const_string "DF"))
3174 /* For architectures resolving dependencies on register
3175 parts we may avoid extra work to zero out upper part
3177 (eq_attr "alternative" "7,11")
3179 (match_test "TARGET_SSE_SPLIT_REGS")
3180 (const_string "V1DF")
3181 (const_string "DF"))
3183 (const_string "DF")))])
3185 (define_insn "*movsf_internal"
3186 [(set (match_operand:SF 0 "nonimmediate_operand"
3187 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3188 (match_operand:SF 1 "general_operand"
3189 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3190 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3191 && (!can_create_pseudo_p ()
3192 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3193 || GET_CODE (operands[1]) != CONST_DOUBLE
3194 || (optimize_function_for_size_p (cfun)
3195 && ((!TARGET_SSE_MATH
3196 && standard_80387_constant_p (operands[1]) > 0)
3198 && standard_sse_constant_p (operands[1]))))
3199 || memory_operand (operands[0], SFmode))"
3201 switch (which_alternative)
3205 return output_387_reg_move (insn, operands);
3208 return standard_80387_constant_opcode (operands[1]);
3212 return "mov{l}\t{%1, %0|%0, %1}";
3215 return standard_sse_constant_opcode (insn, operands[1]);
3218 if (get_attr_mode (insn) == MODE_V4SF)
3219 return "%vmovaps\t{%1, %0|%0, %1}";
3221 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3225 return "%vmovss\t{%1, %0|%0, %1}";
3231 return "movd\t{%1, %0|%0, %1}";
3234 return "movq\t{%1, %0|%0, %1}";
3238 return "%vmovd\t{%1, %0|%0, %1}";
3245 (cond [(eq_attr "alternative" "0,1,2")
3246 (const_string "fmov")
3247 (eq_attr "alternative" "3,4")
3248 (const_string "multi")
3249 (eq_attr "alternative" "5")
3250 (const_string "sselog1")
3251 (eq_attr "alternative" "9,10,11,14,15")
3252 (const_string "mmxmov")
3254 (const_string "ssemov")))
3255 (set (attr "prefix")
3256 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3257 (const_string "maybe_vex")
3258 (const_string "orig")))
3260 (cond [(eq_attr "alternative" "3,4,9,10")
3262 (eq_attr "alternative" "5")
3264 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3265 (match_test "TARGET_SSE2"))
3266 (not (match_test "optimize_function_for_size_p (cfun)")))
3268 (const_string "V4SF"))
3269 /* For architectures resolving dependencies on
3270 whole SSE registers use APS move to break dependency
3271 chains, otherwise use short move to avoid extra work.
3273 Do the same for architectures resolving dependencies on
3274 the parts. While in DF mode it is better to always handle
3275 just register parts, the SF mode is different due to lack
3276 of instructions to load just part of the register. It is
3277 better to maintain the whole registers in single format
3278 to avoid problems on using packed logical operations. */
3279 (eq_attr "alternative" "6")
3281 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3282 (match_test "TARGET_SSE_SPLIT_REGS"))
3283 (const_string "V4SF")
3284 (const_string "SF"))
3285 (eq_attr "alternative" "11")
3286 (const_string "DI")]
3287 (const_string "SF")))])
3290 [(set (match_operand 0 "any_fp_register_operand" "")
3291 (match_operand 1 "memory_operand" ""))]
3293 && (GET_MODE (operands[0]) == TFmode
3294 || GET_MODE (operands[0]) == XFmode
3295 || GET_MODE (operands[0]) == DFmode
3296 || GET_MODE (operands[0]) == SFmode)
3297 && (operands[2] = find_constant_src (insn))"
3298 [(set (match_dup 0) (match_dup 2))]
3300 rtx c = operands[2];
3301 int r = REGNO (operands[0]);
3303 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3304 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3309 [(set (match_operand 0 "any_fp_register_operand" "")
3310 (float_extend (match_operand 1 "memory_operand" "")))]
3312 && (GET_MODE (operands[0]) == TFmode
3313 || GET_MODE (operands[0]) == XFmode
3314 || GET_MODE (operands[0]) == DFmode)
3315 && (operands[2] = find_constant_src (insn))"
3316 [(set (match_dup 0) (match_dup 2))]
3318 rtx c = operands[2];
3319 int r = REGNO (operands[0]);
3321 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3322 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3326 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3328 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3329 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3331 && (standard_80387_constant_p (operands[1]) == 8
3332 || standard_80387_constant_p (operands[1]) == 9)"
3333 [(set (match_dup 0)(match_dup 1))
3335 (neg:X87MODEF (match_dup 0)))]
3339 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3340 if (real_isnegzero (&r))
3341 operands[1] = CONST0_RTX (<MODE>mode);
3343 operands[1] = CONST1_RTX (<MODE>mode);
3347 [(set (match_operand 0 "nonimmediate_operand" "")
3348 (match_operand 1 "general_operand" ""))]
3350 && (GET_MODE (operands[0]) == TFmode
3351 || GET_MODE (operands[0]) == XFmode
3352 || GET_MODE (operands[0]) == DFmode)
3353 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3355 "ix86_split_long_move (operands); DONE;")
3357 (define_insn "swapxf"
3358 [(set (match_operand:XF 0 "register_operand" "+f")
3359 (match_operand:XF 1 "register_operand" "+f"))
3364 if (STACK_TOP_P (operands[0]))
3369 [(set_attr "type" "fxch")
3370 (set_attr "mode" "XF")])
3372 (define_insn "*swap<mode>"
3373 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3374 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3377 "TARGET_80387 || reload_completed"
3379 if (STACK_TOP_P (operands[0]))
3384 [(set_attr "type" "fxch")
3385 (set_attr "mode" "<MODE>")])
3387 ;; Zero extension instructions
3389 (define_expand "zero_extendsidi2"
3390 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3391 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3396 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3401 (define_insn "*zero_extendsidi2_rex64"
3402 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3404 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3407 mov{l}\t{%1, %k0|%k0, %1}
3409 movd\t{%1, %0|%0, %1}
3410 movd\t{%1, %0|%0, %1}
3411 %vmovd\t{%1, %0|%0, %1}
3412 %vmovd\t{%1, %0|%0, %1}"
3413 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3414 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3415 (set_attr "prefix_0f" "0,*,*,*,*,*")
3416 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3419 [(set (match_operand:DI 0 "memory_operand" "")
3420 (zero_extend:DI (match_dup 0)))]
3422 [(set (match_dup 4) (const_int 0))]
3423 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3425 ;; %%% Kill me once multi-word ops are sane.
3426 (define_insn "zero_extendsidi2_1"
3427 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3429 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3430 (clobber (reg:CC FLAGS_REG))]
3436 movd\t{%1, %0|%0, %1}
3437 movd\t{%1, %0|%0, %1}
3438 %vmovd\t{%1, %0|%0, %1}
3439 %vmovd\t{%1, %0|%0, %1}"
3440 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3441 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3442 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3443 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3446 [(set (match_operand:DI 0 "register_operand" "")
3447 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3448 (clobber (reg:CC FLAGS_REG))]
3449 "!TARGET_64BIT && reload_completed
3450 && true_regnum (operands[0]) == true_regnum (operands[1])"
3451 [(set (match_dup 4) (const_int 0))]
3452 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3455 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3456 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3457 (clobber (reg:CC FLAGS_REG))]
3458 "!TARGET_64BIT && reload_completed
3459 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3460 [(set (match_dup 3) (match_dup 1))
3461 (set (match_dup 4) (const_int 0))]
3462 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3464 (define_insn "zero_extend<mode>di2"
3465 [(set (match_operand:DI 0 "register_operand" "=r")
3467 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3469 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3470 [(set_attr "type" "imovx")
3471 (set_attr "mode" "SI")])
3473 (define_expand "zero_extendhisi2"
3474 [(set (match_operand:SI 0 "register_operand" "")
3475 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3478 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3480 operands[1] = force_reg (HImode, operands[1]);
3481 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3486 (define_insn_and_split "zero_extendhisi2_and"
3487 [(set (match_operand:SI 0 "register_operand" "=r")
3488 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3489 (clobber (reg:CC FLAGS_REG))]
3490 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3492 "&& reload_completed"
3493 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3494 (clobber (reg:CC FLAGS_REG))])]
3496 [(set_attr "type" "alu1")
3497 (set_attr "mode" "SI")])
3499 (define_insn "*zero_extendhisi2_movzwl"
3500 [(set (match_operand:SI 0 "register_operand" "=r")
3501 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3502 "!TARGET_ZERO_EXTEND_WITH_AND
3503 || optimize_function_for_size_p (cfun)"
3504 "movz{wl|x}\t{%1, %0|%0, %1}"
3505 [(set_attr "type" "imovx")
3506 (set_attr "mode" "SI")])
3508 (define_expand "zero_extendqi<mode>2"
3510 [(set (match_operand:SWI24 0 "register_operand" "")
3511 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3512 (clobber (reg:CC FLAGS_REG))])])
3514 (define_insn "*zero_extendqi<mode>2_and"
3515 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3516 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3517 (clobber (reg:CC FLAGS_REG))]
3518 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3520 [(set_attr "type" "alu1")
3521 (set_attr "mode" "<MODE>")])
3523 ;; When source and destination does not overlap, clear destination
3524 ;; first and then do the movb
3526 [(set (match_operand:SWI24 0 "register_operand" "")
3527 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3528 (clobber (reg:CC FLAGS_REG))]
3530 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3531 && ANY_QI_REG_P (operands[0])
3532 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3533 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3534 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3536 operands[2] = gen_lowpart (QImode, operands[0]);
3537 ix86_expand_clear (operands[0]);
3540 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3541 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3542 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3543 (clobber (reg:CC FLAGS_REG))]
3544 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3546 [(set_attr "type" "imovx,alu1")
3547 (set_attr "mode" "<MODE>")])
3549 ;; For the movzbl case strip only the clobber
3551 [(set (match_operand:SWI24 0 "register_operand" "")
3552 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3553 (clobber (reg:CC FLAGS_REG))]
3555 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3556 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3558 (zero_extend:SWI24 (match_dup 1)))])
3560 ; zero extend to SImode to avoid partial register stalls
3561 (define_insn "*zero_extendqi<mode>2_movzbl"
3562 [(set (match_operand:SWI24 0 "register_operand" "=r")
3563 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3565 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3566 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3567 [(set_attr "type" "imovx")
3568 (set_attr "mode" "SI")])
3570 ;; Rest is handled by single and.
3572 [(set (match_operand:SWI24 0 "register_operand" "")
3573 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3574 (clobber (reg:CC FLAGS_REG))]
3576 && true_regnum (operands[0]) == true_regnum (operands[1])"
3577 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3578 (clobber (reg:CC FLAGS_REG))])])
3580 ;; Sign extension instructions
3582 (define_expand "extendsidi2"
3583 [(set (match_operand:DI 0 "register_operand" "")
3584 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3589 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3594 (define_insn "*extendsidi2_rex64"
3595 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3596 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3600 movs{lq|x}\t{%1, %0|%0, %1}"
3601 [(set_attr "type" "imovx")
3602 (set_attr "mode" "DI")
3603 (set_attr "prefix_0f" "0")
3604 (set_attr "modrm" "0,1")])
3606 (define_insn "extendsidi2_1"
3607 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3608 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3609 (clobber (reg:CC FLAGS_REG))
3610 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3614 ;; Extend to memory case when source register does die.
3616 [(set (match_operand:DI 0 "memory_operand" "")
3617 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3618 (clobber (reg:CC FLAGS_REG))
3619 (clobber (match_operand:SI 2 "register_operand" ""))]
3621 && dead_or_set_p (insn, operands[1])
3622 && !reg_mentioned_p (operands[1], operands[0]))"
3623 [(set (match_dup 3) (match_dup 1))
3624 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3625 (clobber (reg:CC FLAGS_REG))])
3626 (set (match_dup 4) (match_dup 1))]
3627 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3629 ;; Extend to memory case when source register does not die.
3631 [(set (match_operand:DI 0 "memory_operand" "")
3632 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3633 (clobber (reg:CC FLAGS_REG))
3634 (clobber (match_operand:SI 2 "register_operand" ""))]
3638 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3640 emit_move_insn (operands[3], operands[1]);
3642 /* Generate a cltd if possible and doing so it profitable. */
3643 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3644 && true_regnum (operands[1]) == AX_REG
3645 && true_regnum (operands[2]) == DX_REG)
3647 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3651 emit_move_insn (operands[2], operands[1]);
3652 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3654 emit_move_insn (operands[4], operands[2]);
3658 ;; Extend to register case. Optimize case where source and destination
3659 ;; registers match and cases where we can use cltd.
3661 [(set (match_operand:DI 0 "register_operand" "")
3662 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3663 (clobber (reg:CC FLAGS_REG))
3664 (clobber (match_scratch:SI 2 ""))]
3668 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3670 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3671 emit_move_insn (operands[3], operands[1]);
3673 /* Generate a cltd if possible and doing so it profitable. */
3674 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3675 && true_regnum (operands[3]) == AX_REG
3676 && true_regnum (operands[4]) == DX_REG)
3678 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3682 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3683 emit_move_insn (operands[4], operands[1]);
3685 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3689 (define_insn "extend<mode>di2"
3690 [(set (match_operand:DI 0 "register_operand" "=r")
3692 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3694 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3695 [(set_attr "type" "imovx")
3696 (set_attr "mode" "DI")])
3698 (define_insn "extendhisi2"
3699 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3700 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3703 switch (get_attr_prefix_0f (insn))
3706 return "{cwtl|cwde}";
3708 return "movs{wl|x}\t{%1, %0|%0, %1}";
3711 [(set_attr "type" "imovx")
3712 (set_attr "mode" "SI")
3713 (set (attr "prefix_0f")
3714 ;; movsx is short decodable while cwtl is vector decoded.
3715 (if_then_else (and (eq_attr "cpu" "!k6")
3716 (eq_attr "alternative" "0"))
3718 (const_string "1")))
3720 (if_then_else (eq_attr "prefix_0f" "0")
3722 (const_string "1")))])
3724 (define_insn "*extendhisi2_zext"
3725 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3728 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3731 switch (get_attr_prefix_0f (insn))
3734 return "{cwtl|cwde}";
3736 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3739 [(set_attr "type" "imovx")
3740 (set_attr "mode" "SI")
3741 (set (attr "prefix_0f")
3742 ;; movsx is short decodable while cwtl is vector decoded.
3743 (if_then_else (and (eq_attr "cpu" "!k6")
3744 (eq_attr "alternative" "0"))
3746 (const_string "1")))
3748 (if_then_else (eq_attr "prefix_0f" "0")
3750 (const_string "1")))])
3752 (define_insn "extendqisi2"
3753 [(set (match_operand:SI 0 "register_operand" "=r")
3754 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3756 "movs{bl|x}\t{%1, %0|%0, %1}"
3757 [(set_attr "type" "imovx")
3758 (set_attr "mode" "SI")])
3760 (define_insn "*extendqisi2_zext"
3761 [(set (match_operand:DI 0 "register_operand" "=r")
3763 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3765 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3766 [(set_attr "type" "imovx")
3767 (set_attr "mode" "SI")])
3769 (define_insn "extendqihi2"
3770 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3771 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3774 switch (get_attr_prefix_0f (insn))
3777 return "{cbtw|cbw}";
3779 return "movs{bw|x}\t{%1, %0|%0, %1}";
3782 [(set_attr "type" "imovx")
3783 (set_attr "mode" "HI")
3784 (set (attr "prefix_0f")
3785 ;; movsx is short decodable while cwtl is vector decoded.
3786 (if_then_else (and (eq_attr "cpu" "!k6")
3787 (eq_attr "alternative" "0"))
3789 (const_string "1")))
3791 (if_then_else (eq_attr "prefix_0f" "0")
3793 (const_string "1")))])
3795 ;; Conversions between float and double.
3797 ;; These are all no-ops in the model used for the 80387.
3798 ;; So just emit moves.
3800 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3802 [(set (match_operand:DF 0 "push_operand" "")
3803 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3805 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3806 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3809 [(set (match_operand:XF 0 "push_operand" "")
3810 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3812 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3813 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3814 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3816 (define_expand "extendsfdf2"
3817 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3818 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3819 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3821 /* ??? Needed for compress_float_constant since all fp constants
3822 are TARGET_LEGITIMATE_CONSTANT_P. */
3823 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3825 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3826 && standard_80387_constant_p (operands[1]) > 0)
3828 operands[1] = simplify_const_unary_operation
3829 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3830 emit_move_insn_1 (operands[0], operands[1]);
3833 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3837 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3839 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3841 We do the conversion post reload to avoid producing of 128bit spills
3842 that might lead to ICE on 32bit target. The sequence unlikely combine
3845 [(set (match_operand:DF 0 "register_operand" "")
3847 (match_operand:SF 1 "nonimmediate_operand" "")))]
3848 "TARGET_USE_VECTOR_FP_CONVERTS
3849 && optimize_insn_for_speed_p ()
3850 && reload_completed && SSE_REG_P (operands[0])"
3855 (parallel [(const_int 0) (const_int 1)]))))]
3857 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3858 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3859 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3860 Try to avoid move when unpacking can be done in source. */
3861 if (REG_P (operands[1]))
3863 /* If it is unsafe to overwrite upper half of source, we need
3864 to move to destination and unpack there. */
3865 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3866 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3867 && true_regnum (operands[0]) != true_regnum (operands[1]))
3869 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3870 emit_move_insn (tmp, operands[1]);
3873 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3874 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3878 emit_insn (gen_vec_setv4sf_0 (operands[3],
3879 CONST0_RTX (V4SFmode), operands[1]));
3882 (define_insn "*extendsfdf2_mixed"
3883 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3885 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3886 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3888 switch (which_alternative)
3892 return output_387_reg_move (insn, operands);
3895 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3901 [(set_attr "type" "fmov,fmov,ssecvt")
3902 (set_attr "prefix" "orig,orig,maybe_vex")
3903 (set_attr "mode" "SF,XF,DF")])
3905 (define_insn "*extendsfdf2_sse"
3906 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3907 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3908 "TARGET_SSE2 && TARGET_SSE_MATH"
3909 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3910 [(set_attr "type" "ssecvt")
3911 (set_attr "prefix" "maybe_vex")
3912 (set_attr "mode" "DF")])
3914 (define_insn "*extendsfdf2_i387"
3915 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3916 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3918 "* return output_387_reg_move (insn, operands);"
3919 [(set_attr "type" "fmov")
3920 (set_attr "mode" "SF,XF")])
3922 (define_expand "extend<mode>xf2"
3923 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3924 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3927 /* ??? Needed for compress_float_constant since all fp constants
3928 are TARGET_LEGITIMATE_CONSTANT_P. */
3929 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3931 if (standard_80387_constant_p (operands[1]) > 0)
3933 operands[1] = simplify_const_unary_operation
3934 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3935 emit_move_insn_1 (operands[0], operands[1]);
3938 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3942 (define_insn "*extend<mode>xf2_i387"
3943 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3945 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3947 "* return output_387_reg_move (insn, operands);"
3948 [(set_attr "type" "fmov")
3949 (set_attr "mode" "<MODE>,XF")])
3951 ;; %%% This seems bad bad news.
3952 ;; This cannot output into an f-reg because there is no way to be sure
3953 ;; of truncating in that case. Otherwise this is just like a simple move
3954 ;; insn. So we pretend we can output to a reg in order to get better
3955 ;; register preferencing, but we really use a stack slot.
3957 ;; Conversion from DFmode to SFmode.
3959 (define_expand "truncdfsf2"
3960 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3962 (match_operand:DF 1 "nonimmediate_operand" "")))]
3963 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3965 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3967 else if (flag_unsafe_math_optimizations)
3971 enum ix86_stack_slot slot = (virtuals_instantiated
3974 rtx temp = assign_386_stack_local (SFmode, slot);
3975 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3980 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3982 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3984 We do the conversion post reload to avoid producing of 128bit spills
3985 that might lead to ICE on 32bit target. The sequence unlikely combine
3988 [(set (match_operand:SF 0 "register_operand" "")
3990 (match_operand:DF 1 "nonimmediate_operand" "")))]
3991 "TARGET_USE_VECTOR_FP_CONVERTS
3992 && optimize_insn_for_speed_p ()
3993 && reload_completed && SSE_REG_P (operands[0])"
3996 (float_truncate:V2SF
4000 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4001 operands[3] = CONST0_RTX (V2SFmode);
4002 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4003 /* Use movsd for loading from memory, unpcklpd for registers.
4004 Try to avoid move when unpacking can be done in source, or SSE3
4005 movddup is available. */
4006 if (REG_P (operands[1]))
4009 && true_regnum (operands[0]) != true_regnum (operands[1])
4010 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4011 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4013 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4014 emit_move_insn (tmp, operands[1]);
4017 else if (!TARGET_SSE3)
4018 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4019 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4022 emit_insn (gen_sse2_loadlpd (operands[4],
4023 CONST0_RTX (V2DFmode), operands[1]));
4026 (define_expand "truncdfsf2_with_temp"
4027 [(parallel [(set (match_operand:SF 0 "" "")
4028 (float_truncate:SF (match_operand:DF 1 "" "")))
4029 (clobber (match_operand:SF 2 "" ""))])])
4031 (define_insn "*truncdfsf_fast_mixed"
4032 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4034 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4035 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4037 switch (which_alternative)
4040 return output_387_reg_move (insn, operands);
4042 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4047 [(set_attr "type" "fmov,ssecvt")
4048 (set_attr "prefix" "orig,maybe_vex")
4049 (set_attr "mode" "SF")])
4051 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4052 ;; because nothing we do here is unsafe.
4053 (define_insn "*truncdfsf_fast_sse"
4054 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4056 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4057 "TARGET_SSE2 && TARGET_SSE_MATH"
4058 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4059 [(set_attr "type" "ssecvt")
4060 (set_attr "prefix" "maybe_vex")
4061 (set_attr "mode" "SF")])
4063 (define_insn "*truncdfsf_fast_i387"
4064 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4066 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4067 "TARGET_80387 && flag_unsafe_math_optimizations"
4068 "* return output_387_reg_move (insn, operands);"
4069 [(set_attr "type" "fmov")
4070 (set_attr "mode" "SF")])
4072 (define_insn "*truncdfsf_mixed"
4073 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4075 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4076 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4077 "TARGET_MIX_SSE_I387"
4079 switch (which_alternative)
4082 return output_387_reg_move (insn, operands);
4084 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4090 [(set_attr "isa" "*,sse2,*,*,*")
4091 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4092 (set_attr "unit" "*,*,i387,i387,i387")
4093 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4094 (set_attr "mode" "SF")])
4096 (define_insn "*truncdfsf_i387"
4097 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4099 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4100 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4103 switch (which_alternative)
4106 return output_387_reg_move (insn, operands);
4112 [(set_attr "type" "fmov,multi,multi,multi")
4113 (set_attr "unit" "*,i387,i387,i387")
4114 (set_attr "mode" "SF")])
4116 (define_insn "*truncdfsf2_i387_1"
4117 [(set (match_operand:SF 0 "memory_operand" "=m")
4119 (match_operand:DF 1 "register_operand" "f")))]
4121 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4122 && !TARGET_MIX_SSE_I387"
4123 "* return output_387_reg_move (insn, operands);"
4124 [(set_attr "type" "fmov")
4125 (set_attr "mode" "SF")])
4128 [(set (match_operand:SF 0 "register_operand" "")
4130 (match_operand:DF 1 "fp_register_operand" "")))
4131 (clobber (match_operand 2 "" ""))]
4133 [(set (match_dup 2) (match_dup 1))
4134 (set (match_dup 0) (match_dup 2))]
4135 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4137 ;; Conversion from XFmode to {SF,DF}mode
4139 (define_expand "truncxf<mode>2"
4140 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4141 (float_truncate:MODEF
4142 (match_operand:XF 1 "register_operand" "")))
4143 (clobber (match_dup 2))])]
4146 if (flag_unsafe_math_optimizations)
4148 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4149 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4150 if (reg != operands[0])
4151 emit_move_insn (operands[0], reg);
4156 enum ix86_stack_slot slot = (virtuals_instantiated
4159 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4163 (define_insn "*truncxfsf2_mixed"
4164 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4166 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4167 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4170 gcc_assert (!which_alternative);
4171 return output_387_reg_move (insn, operands);
4173 [(set_attr "type" "fmov,multi,multi,multi")
4174 (set_attr "unit" "*,i387,i387,i387")
4175 (set_attr "mode" "SF")])
4177 (define_insn "*truncxfdf2_mixed"
4178 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4180 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4181 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4184 gcc_assert (!which_alternative);
4185 return output_387_reg_move (insn, operands);
4187 [(set_attr "isa" "*,*,sse2,*")
4188 (set_attr "type" "fmov,multi,multi,multi")
4189 (set_attr "unit" "*,i387,i387,i387")
4190 (set_attr "mode" "DF")])
4192 (define_insn "truncxf<mode>2_i387_noop"
4193 [(set (match_operand:MODEF 0 "register_operand" "=f")
4194 (float_truncate:MODEF
4195 (match_operand:XF 1 "register_operand" "f")))]
4196 "TARGET_80387 && flag_unsafe_math_optimizations"
4197 "* return output_387_reg_move (insn, operands);"
4198 [(set_attr "type" "fmov")
4199 (set_attr "mode" "<MODE>")])
4201 (define_insn "*truncxf<mode>2_i387"
4202 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4203 (float_truncate:MODEF
4204 (match_operand:XF 1 "register_operand" "f")))]
4206 "* return output_387_reg_move (insn, operands);"
4207 [(set_attr "type" "fmov")
4208 (set_attr "mode" "<MODE>")])
4211 [(set (match_operand:MODEF 0 "register_operand" "")
4212 (float_truncate:MODEF
4213 (match_operand:XF 1 "register_operand" "")))
4214 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4215 "TARGET_80387 && reload_completed"
4216 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4217 (set (match_dup 0) (match_dup 2))])
4220 [(set (match_operand:MODEF 0 "memory_operand" "")
4221 (float_truncate:MODEF
4222 (match_operand:XF 1 "register_operand" "")))
4223 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4225 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4227 ;; Signed conversion to DImode.
4229 (define_expand "fix_truncxfdi2"
4230 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4231 (fix:DI (match_operand:XF 1 "register_operand" "")))
4232 (clobber (reg:CC FLAGS_REG))])]
4237 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4242 (define_expand "fix_trunc<mode>di2"
4243 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4244 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4245 (clobber (reg:CC FLAGS_REG))])]
4246 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4249 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4251 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4254 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4256 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4257 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4258 if (out != operands[0])
4259 emit_move_insn (operands[0], out);
4264 ;; Signed conversion to SImode.
4266 (define_expand "fix_truncxfsi2"
4267 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4268 (fix:SI (match_operand:XF 1 "register_operand" "")))
4269 (clobber (reg:CC FLAGS_REG))])]
4274 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4279 (define_expand "fix_trunc<mode>si2"
4280 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4281 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4282 (clobber (reg:CC FLAGS_REG))])]
4283 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4286 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4288 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4291 if (SSE_FLOAT_MODE_P (<MODE>mode))
4293 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4294 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4295 if (out != operands[0])
4296 emit_move_insn (operands[0], out);
4301 ;; Signed conversion to HImode.
4303 (define_expand "fix_trunc<mode>hi2"
4304 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4305 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4306 (clobber (reg:CC FLAGS_REG))])]
4308 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4312 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4317 ;; Unsigned conversion to SImode.
4319 (define_expand "fixuns_trunc<mode>si2"
4321 [(set (match_operand:SI 0 "register_operand" "")
4323 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4325 (clobber (match_scratch:<ssevecmode> 3 ""))
4326 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4327 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4329 enum machine_mode mode = <MODE>mode;
4330 enum machine_mode vecmode = <ssevecmode>mode;
4331 REAL_VALUE_TYPE TWO31r;
4334 if (optimize_insn_for_size_p ())
4337 real_ldexp (&TWO31r, &dconst1, 31);
4338 two31 = const_double_from_real_value (TWO31r, mode);
4339 two31 = ix86_build_const_vector (vecmode, true, two31);
4340 operands[2] = force_reg (vecmode, two31);
4343 (define_insn_and_split "*fixuns_trunc<mode>_1"
4344 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4346 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4347 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4348 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4349 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4350 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4351 && optimize_function_for_speed_p (cfun)"
4353 "&& reload_completed"
4356 ix86_split_convert_uns_si_sse (operands);
4360 ;; Unsigned conversion to HImode.
4361 ;; Without these patterns, we'll try the unsigned SI conversion which
4362 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4364 (define_expand "fixuns_trunc<mode>hi2"
4366 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4367 (set (match_operand:HI 0 "nonimmediate_operand" "")
4368 (subreg:HI (match_dup 2) 0))]
4369 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4370 "operands[2] = gen_reg_rtx (SImode);")
4372 ;; When SSE is available, it is always faster to use it!
4373 (define_insn "fix_trunc<mode>di_sse"
4374 [(set (match_operand:DI 0 "register_operand" "=r,r")
4375 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4376 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4377 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4378 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4379 [(set_attr "type" "sseicvt")
4380 (set_attr "prefix" "maybe_vex")
4381 (set_attr "prefix_rex" "1")
4382 (set_attr "mode" "<MODE>")
4383 (set_attr "athlon_decode" "double,vector")
4384 (set_attr "amdfam10_decode" "double,double")
4385 (set_attr "bdver1_decode" "double,double")])
4387 (define_insn "fix_trunc<mode>si_sse"
4388 [(set (match_operand:SI 0 "register_operand" "=r,r")
4389 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4390 "SSE_FLOAT_MODE_P (<MODE>mode)
4391 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4392 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4393 [(set_attr "type" "sseicvt")
4394 (set_attr "prefix" "maybe_vex")
4395 (set_attr "mode" "<MODE>")
4396 (set_attr "athlon_decode" "double,vector")
4397 (set_attr "amdfam10_decode" "double,double")
4398 (set_attr "bdver1_decode" "double,double")])
4400 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4402 [(set (match_operand:MODEF 0 "register_operand" "")
4403 (match_operand:MODEF 1 "memory_operand" ""))
4404 (set (match_operand:SWI48x 2 "register_operand" "")
4405 (fix:SWI48x (match_dup 0)))]
4406 "TARGET_SHORTEN_X87_SSE
4407 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4408 && peep2_reg_dead_p (2, operands[0])"
4409 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4411 ;; Avoid vector decoded forms of the instruction.
4413 [(match_scratch:DF 2 "x")
4414 (set (match_operand:SWI48x 0 "register_operand" "")
4415 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4416 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4417 [(set (match_dup 2) (match_dup 1))
4418 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4421 [(match_scratch:SF 2 "x")
4422 (set (match_operand:SWI48x 0 "register_operand" "")
4423 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4424 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4425 [(set (match_dup 2) (match_dup 1))
4426 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4428 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4429 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4430 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4431 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4433 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4434 && (TARGET_64BIT || <MODE>mode != DImode))
4436 && can_create_pseudo_p ()"
4441 if (memory_operand (operands[0], VOIDmode))
4442 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4445 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4446 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4452 [(set_attr "type" "fisttp")
4453 (set_attr "mode" "<MODE>")])
4455 (define_insn "fix_trunc<mode>_i387_fisttp"
4456 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4457 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4458 (clobber (match_scratch:XF 2 "=&1f"))]
4459 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4461 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4462 && (TARGET_64BIT || <MODE>mode != DImode))
4463 && TARGET_SSE_MATH)"
4464 "* return output_fix_trunc (insn, operands, true);"
4465 [(set_attr "type" "fisttp")
4466 (set_attr "mode" "<MODE>")])
4468 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4469 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4470 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4471 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4472 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4473 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4475 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4476 && (TARGET_64BIT || <MODE>mode != DImode))
4477 && TARGET_SSE_MATH)"
4479 [(set_attr "type" "fisttp")
4480 (set_attr "mode" "<MODE>")])
4483 [(set (match_operand:SWI248x 0 "register_operand" "")
4484 (fix:SWI248x (match_operand 1 "register_operand" "")))
4485 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4486 (clobber (match_scratch 3 ""))]
4488 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4489 (clobber (match_dup 3))])
4490 (set (match_dup 0) (match_dup 2))])
4493 [(set (match_operand:SWI248x 0 "memory_operand" "")
4494 (fix:SWI248x (match_operand 1 "register_operand" "")))
4495 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4496 (clobber (match_scratch 3 ""))]
4498 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4499 (clobber (match_dup 3))])])
4501 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4502 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4503 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4504 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4505 ;; function in i386.c.
4506 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4507 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4508 (fix:SWI248x (match_operand 1 "register_operand" "")))
4509 (clobber (reg:CC FLAGS_REG))]
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 && can_create_pseudo_p ()"
4519 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4521 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4522 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4523 if (memory_operand (operands[0], VOIDmode))
4524 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4525 operands[2], operands[3]));
4528 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4529 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4530 operands[2], operands[3],
4535 [(set_attr "type" "fistp")
4536 (set_attr "i387_cw" "trunc")
4537 (set_attr "mode" "<MODE>")])
4539 (define_insn "fix_truncdi_i387"
4540 [(set (match_operand:DI 0 "memory_operand" "=m")
4541 (fix:DI (match_operand 1 "register_operand" "f")))
4542 (use (match_operand:HI 2 "memory_operand" "m"))
4543 (use (match_operand:HI 3 "memory_operand" "m"))
4544 (clobber (match_scratch:XF 4 "=&1f"))]
4545 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4547 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4548 "* return output_fix_trunc (insn, operands, false);"
4549 [(set_attr "type" "fistp")
4550 (set_attr "i387_cw" "trunc")
4551 (set_attr "mode" "DI")])
4553 (define_insn "fix_truncdi_i387_with_temp"
4554 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4555 (fix:DI (match_operand 1 "register_operand" "f,f")))
4556 (use (match_operand:HI 2 "memory_operand" "m,m"))
4557 (use (match_operand:HI 3 "memory_operand" "m,m"))
4558 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4559 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4560 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4562 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4564 [(set_attr "type" "fistp")
4565 (set_attr "i387_cw" "trunc")
4566 (set_attr "mode" "DI")])
4569 [(set (match_operand:DI 0 "register_operand" "")
4570 (fix:DI (match_operand 1 "register_operand" "")))
4571 (use (match_operand:HI 2 "memory_operand" ""))
4572 (use (match_operand:HI 3 "memory_operand" ""))
4573 (clobber (match_operand:DI 4 "memory_operand" ""))
4574 (clobber (match_scratch 5 ""))]
4576 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4579 (clobber (match_dup 5))])
4580 (set (match_dup 0) (match_dup 4))])
4583 [(set (match_operand:DI 0 "memory_operand" "")
4584 (fix:DI (match_operand 1 "register_operand" "")))
4585 (use (match_operand:HI 2 "memory_operand" ""))
4586 (use (match_operand:HI 3 "memory_operand" ""))
4587 (clobber (match_operand:DI 4 "memory_operand" ""))
4588 (clobber (match_scratch 5 ""))]
4590 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4593 (clobber (match_dup 5))])])
4595 (define_insn "fix_trunc<mode>_i387"
4596 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4597 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4598 (use (match_operand:HI 2 "memory_operand" "m"))
4599 (use (match_operand:HI 3 "memory_operand" "m"))]
4600 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4602 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4603 "* return output_fix_trunc (insn, operands, false);"
4604 [(set_attr "type" "fistp")
4605 (set_attr "i387_cw" "trunc")
4606 (set_attr "mode" "<MODE>")])
4608 (define_insn "fix_trunc<mode>_i387_with_temp"
4609 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4610 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4611 (use (match_operand:HI 2 "memory_operand" "m,m"))
4612 (use (match_operand:HI 3 "memory_operand" "m,m"))
4613 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4614 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4616 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4618 [(set_attr "type" "fistp")
4619 (set_attr "i387_cw" "trunc")
4620 (set_attr "mode" "<MODE>")])
4623 [(set (match_operand:SWI24 0 "register_operand" "")
4624 (fix:SWI24 (match_operand 1 "register_operand" "")))
4625 (use (match_operand:HI 2 "memory_operand" ""))
4626 (use (match_operand:HI 3 "memory_operand" ""))
4627 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4629 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4631 (use (match_dup 3))])
4632 (set (match_dup 0) (match_dup 4))])
4635 [(set (match_operand:SWI24 0 "memory_operand" "")
4636 (fix:SWI24 (match_operand 1 "register_operand" "")))
4637 (use (match_operand:HI 2 "memory_operand" ""))
4638 (use (match_operand:HI 3 "memory_operand" ""))
4639 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4641 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4643 (use (match_dup 3))])])
4645 (define_insn "x86_fnstcw_1"
4646 [(set (match_operand:HI 0 "memory_operand" "=m")
4647 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4650 [(set (attr "length")
4651 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4652 (set_attr "mode" "HI")
4653 (set_attr "unit" "i387")
4654 (set_attr "bdver1_decode" "vector")])
4656 (define_insn "x86_fldcw_1"
4657 [(set (reg:HI FPCR_REG)
4658 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4661 [(set (attr "length")
4662 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4663 (set_attr "mode" "HI")
4664 (set_attr "unit" "i387")
4665 (set_attr "athlon_decode" "vector")
4666 (set_attr "amdfam10_decode" "vector")
4667 (set_attr "bdver1_decode" "vector")])
4669 ;; Conversion between fixed point and floating point.
4671 ;; Even though we only accept memory inputs, the backend _really_
4672 ;; wants to be able to do this between registers.
4674 (define_expand "floathi<mode>2"
4675 [(set (match_operand:X87MODEF 0 "register_operand" "")
4676 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4678 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4679 || TARGET_MIX_SSE_I387)")
4681 ;; Pre-reload splitter to add memory clobber to the pattern.
4682 (define_insn_and_split "*floathi<mode>2_1"
4683 [(set (match_operand:X87MODEF 0 "register_operand" "")
4684 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4686 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4687 || TARGET_MIX_SSE_I387)
4688 && can_create_pseudo_p ()"
4691 [(parallel [(set (match_dup 0)
4692 (float:X87MODEF (match_dup 1)))
4693 (clobber (match_dup 2))])]
4694 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4696 (define_insn "*floathi<mode>2_i387_with_temp"
4697 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4698 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4699 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4701 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4702 || TARGET_MIX_SSE_I387)"
4704 [(set_attr "type" "fmov,multi")
4705 (set_attr "mode" "<MODE>")
4706 (set_attr "unit" "*,i387")
4707 (set_attr "fp_int_src" "true")])
4709 (define_insn "*floathi<mode>2_i387"
4710 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4711 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4713 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4714 || TARGET_MIX_SSE_I387)"
4716 [(set_attr "type" "fmov")
4717 (set_attr "mode" "<MODE>")
4718 (set_attr "fp_int_src" "true")])
4721 [(set (match_operand:X87MODEF 0 "register_operand" "")
4722 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4723 (clobber (match_operand:HI 2 "memory_operand" ""))]
4725 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4726 || TARGET_MIX_SSE_I387)
4727 && reload_completed"
4728 [(set (match_dup 2) (match_dup 1))
4729 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4732 [(set (match_operand:X87MODEF 0 "register_operand" "")
4733 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4734 (clobber (match_operand:HI 2 "memory_operand" ""))]
4736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4737 || TARGET_MIX_SSE_I387)
4738 && reload_completed"
4739 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4741 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4742 [(set (match_operand:X87MODEF 0 "register_operand" "")
4744 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4746 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4747 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4749 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4750 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4751 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4753 rtx reg = gen_reg_rtx (XFmode);
4754 rtx (*insn)(rtx, rtx);
4756 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4758 if (<X87MODEF:MODE>mode == SFmode)
4759 insn = gen_truncxfsf2;
4760 else if (<X87MODEF:MODE>mode == DFmode)
4761 insn = gen_truncxfdf2;
4765 emit_insn (insn (operands[0], reg));
4770 ;; Pre-reload splitter to add memory clobber to the pattern.
4771 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4772 [(set (match_operand:X87MODEF 0 "register_operand" "")
4773 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4775 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4776 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4777 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4778 || TARGET_MIX_SSE_I387))
4779 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4780 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4781 && ((<SWI48x:MODE>mode == SImode
4782 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4783 && optimize_function_for_speed_p (cfun)
4784 && flag_trapping_math)
4785 || !(TARGET_INTER_UNIT_CONVERSIONS
4786 || optimize_function_for_size_p (cfun)))))
4787 && can_create_pseudo_p ()"
4790 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4791 (clobber (match_dup 2))])]
4793 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4795 /* Avoid store forwarding (partial memory) stall penalty
4796 by passing DImode value through XMM registers. */
4797 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4798 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4799 && optimize_function_for_speed_p (cfun))
4801 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4808 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4809 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4811 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4812 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4813 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4814 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4816 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4817 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4818 (set_attr "unit" "*,i387,*,*,*")
4819 (set_attr "athlon_decode" "*,*,double,direct,double")
4820 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4821 (set_attr "bdver1_decode" "*,*,double,direct,double")
4822 (set_attr "fp_int_src" "true")])
4824 (define_insn "*floatsi<mode>2_vector_mixed"
4825 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4826 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4827 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4828 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4832 [(set_attr "type" "fmov,sseicvt")
4833 (set_attr "mode" "<MODE>,<ssevecmode>")
4834 (set_attr "unit" "i387,*")
4835 (set_attr "athlon_decode" "*,direct")
4836 (set_attr "amdfam10_decode" "*,double")
4837 (set_attr "bdver1_decode" "*,direct")
4838 (set_attr "fp_int_src" "true")])
4840 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4841 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4843 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4844 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4845 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4846 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4848 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4849 (set_attr "mode" "<MODEF:MODE>")
4850 (set_attr "unit" "*,i387,*,*")
4851 (set_attr "athlon_decode" "*,*,double,direct")
4852 (set_attr "amdfam10_decode" "*,*,vector,double")
4853 (set_attr "bdver1_decode" "*,*,double,direct")
4854 (set_attr "fp_int_src" "true")])
4857 [(set (match_operand:MODEF 0 "register_operand" "")
4858 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4859 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4860 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4861 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4862 && TARGET_INTER_UNIT_CONVERSIONS
4864 && (SSE_REG_P (operands[0])
4865 || (GET_CODE (operands[0]) == SUBREG
4866 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4867 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4870 [(set (match_operand:MODEF 0 "register_operand" "")
4871 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4872 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4873 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4874 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4875 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4877 && (SSE_REG_P (operands[0])
4878 || (GET_CODE (operands[0]) == SUBREG
4879 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4880 [(set (match_dup 2) (match_dup 1))
4881 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4883 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4884 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4886 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4887 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4888 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4889 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4892 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4893 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4894 [(set_attr "type" "fmov,sseicvt,sseicvt")
4895 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4896 (set_attr "mode" "<MODEF:MODE>")
4897 (set (attr "prefix_rex")
4899 (and (eq_attr "prefix" "maybe_vex")
4900 (match_test "<SWI48x:MODE>mode == DImode"))
4902 (const_string "*")))
4903 (set_attr "unit" "i387,*,*")
4904 (set_attr "athlon_decode" "*,double,direct")
4905 (set_attr "amdfam10_decode" "*,vector,double")
4906 (set_attr "bdver1_decode" "*,double,direct")
4907 (set_attr "fp_int_src" "true")])
4909 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4910 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4912 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4913 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4914 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4915 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4918 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4919 [(set_attr "type" "fmov,sseicvt")
4920 (set_attr "prefix" "orig,maybe_vex")
4921 (set_attr "mode" "<MODEF:MODE>")
4922 (set (attr "prefix_rex")
4924 (and (eq_attr "prefix" "maybe_vex")
4925 (match_test "<SWI48x:MODE>mode == DImode"))
4927 (const_string "*")))
4928 (set_attr "athlon_decode" "*,direct")
4929 (set_attr "amdfam10_decode" "*,double")
4930 (set_attr "bdver1_decode" "*,direct")
4931 (set_attr "fp_int_src" "true")])
4933 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4934 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4936 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4937 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4938 "TARGET_SSE2 && TARGET_SSE_MATH
4939 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4941 [(set_attr "type" "sseicvt")
4942 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4943 (set_attr "athlon_decode" "double,direct,double")
4944 (set_attr "amdfam10_decode" "vector,double,double")
4945 (set_attr "bdver1_decode" "double,direct,double")
4946 (set_attr "fp_int_src" "true")])
4948 (define_insn "*floatsi<mode>2_vector_sse"
4949 [(set (match_operand:MODEF 0 "register_operand" "=x")
4950 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4951 "TARGET_SSE2 && TARGET_SSE_MATH
4952 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4954 [(set_attr "type" "sseicvt")
4955 (set_attr "mode" "<MODE>")
4956 (set_attr "athlon_decode" "direct")
4957 (set_attr "amdfam10_decode" "double")
4958 (set_attr "bdver1_decode" "direct")
4959 (set_attr "fp_int_src" "true")])
4962 [(set (match_operand:MODEF 0 "register_operand" "")
4963 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4964 (clobber (match_operand:SI 2 "memory_operand" ""))]
4965 "TARGET_SSE2 && TARGET_SSE_MATH
4966 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4968 && (SSE_REG_P (operands[0])
4969 || (GET_CODE (operands[0]) == SUBREG
4970 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4973 rtx op1 = operands[1];
4975 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4977 if (GET_CODE (op1) == SUBREG)
4978 op1 = SUBREG_REG (op1);
4980 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4982 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4983 emit_insn (gen_sse2_loadld (operands[4],
4984 CONST0_RTX (V4SImode), operands[1]));
4986 /* We can ignore possible trapping value in the
4987 high part of SSE register for non-trapping math. */
4988 else if (SSE_REG_P (op1) && !flag_trapping_math)
4989 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4992 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4993 emit_move_insn (operands[2], operands[1]);
4994 emit_insn (gen_sse2_loadld (operands[4],
4995 CONST0_RTX (V4SImode), operands[2]));
4997 if (<ssevecmode>mode == V4SFmode)
4998 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5000 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5005 [(set (match_operand:MODEF 0 "register_operand" "")
5006 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5007 (clobber (match_operand:SI 2 "memory_operand" ""))]
5008 "TARGET_SSE2 && TARGET_SSE_MATH
5009 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5011 && (SSE_REG_P (operands[0])
5012 || (GET_CODE (operands[0]) == SUBREG
5013 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5016 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5018 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]));
5022 if (<ssevecmode>mode == V4SFmode)
5023 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5025 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5030 [(set (match_operand:MODEF 0 "register_operand" "")
5031 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5032 "TARGET_SSE2 && TARGET_SSE_MATH
5033 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5035 && (SSE_REG_P (operands[0])
5036 || (GET_CODE (operands[0]) == SUBREG
5037 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5040 rtx op1 = operands[1];
5042 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5044 if (GET_CODE (op1) == SUBREG)
5045 op1 = SUBREG_REG (op1);
5047 if (GENERAL_REG_P (op1))
5049 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5050 if (TARGET_INTER_UNIT_MOVES)
5051 emit_insn (gen_sse2_loadld (operands[4],
5052 CONST0_RTX (V4SImode), operands[1]));
5055 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5057 emit_insn (gen_sse2_loadld (operands[4],
5058 CONST0_RTX (V4SImode), operands[5]));
5059 ix86_free_from_memory (GET_MODE (operands[1]));
5062 /* We can ignore possible trapping value in the
5063 high part of SSE register for non-trapping math. */
5064 else if (SSE_REG_P (op1) && !flag_trapping_math)
5065 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5068 if (<ssevecmode>mode == V4SFmode)
5069 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5071 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5076 [(set (match_operand:MODEF 0 "register_operand" "")
5077 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5078 "TARGET_SSE2 && TARGET_SSE_MATH
5079 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5081 && (SSE_REG_P (operands[0])
5082 || (GET_CODE (operands[0]) == SUBREG
5083 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5086 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5088 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5090 emit_insn (gen_sse2_loadld (operands[4],
5091 CONST0_RTX (V4SImode), operands[1]));
5092 if (<ssevecmode>mode == V4SFmode)
5093 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5095 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5099 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5100 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5102 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5103 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5104 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5105 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5107 [(set_attr "type" "sseicvt")
5108 (set_attr "mode" "<MODEF:MODE>")
5109 (set_attr "athlon_decode" "double,direct")
5110 (set_attr "amdfam10_decode" "vector,double")
5111 (set_attr "bdver1_decode" "double,direct")
5112 (set_attr "fp_int_src" "true")])
5114 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5115 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5117 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5118 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5119 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5120 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5121 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5122 [(set_attr "type" "sseicvt")
5123 (set_attr "prefix" "maybe_vex")
5124 (set_attr "mode" "<MODEF:MODE>")
5125 (set (attr "prefix_rex")
5127 (and (eq_attr "prefix" "maybe_vex")
5128 (match_test "<SWI48x:MODE>mode == DImode"))
5130 (const_string "*")))
5131 (set_attr "athlon_decode" "double,direct")
5132 (set_attr "amdfam10_decode" "vector,double")
5133 (set_attr "bdver1_decode" "double,direct")
5134 (set_attr "fp_int_src" "true")])
5137 [(set (match_operand:MODEF 0 "register_operand" "")
5138 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5139 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5140 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5141 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5142 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5144 && (SSE_REG_P (operands[0])
5145 || (GET_CODE (operands[0]) == SUBREG
5146 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5147 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5149 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5150 [(set (match_operand:MODEF 0 "register_operand" "=x")
5152 (match_operand:SWI48x 1 "memory_operand" "m")))]
5153 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5154 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5155 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5156 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5157 [(set_attr "type" "sseicvt")
5158 (set_attr "prefix" "maybe_vex")
5159 (set_attr "mode" "<MODEF:MODE>")
5160 (set (attr "prefix_rex")
5162 (and (eq_attr "prefix" "maybe_vex")
5163 (match_test "<SWI48x:MODE>mode == DImode"))
5165 (const_string "*")))
5166 (set_attr "athlon_decode" "direct")
5167 (set_attr "amdfam10_decode" "double")
5168 (set_attr "bdver1_decode" "direct")
5169 (set_attr "fp_int_src" "true")])
5172 [(set (match_operand:MODEF 0 "register_operand" "")
5173 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5174 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5175 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5176 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5177 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5179 && (SSE_REG_P (operands[0])
5180 || (GET_CODE (operands[0]) == SUBREG
5181 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5182 [(set (match_dup 2) (match_dup 1))
5183 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5186 [(set (match_operand:MODEF 0 "register_operand" "")
5187 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5188 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5189 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5190 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5192 && (SSE_REG_P (operands[0])
5193 || (GET_CODE (operands[0]) == SUBREG
5194 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5195 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5197 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5198 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5200 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5201 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5203 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5207 [(set_attr "type" "fmov,multi")
5208 (set_attr "mode" "<X87MODEF:MODE>")
5209 (set_attr "unit" "*,i387")
5210 (set_attr "fp_int_src" "true")])
5212 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5213 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5215 (match_operand:SWI48x 1 "memory_operand" "m")))]
5217 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5219 [(set_attr "type" "fmov")
5220 (set_attr "mode" "<X87MODEF:MODE>")
5221 (set_attr "fp_int_src" "true")])
5224 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5225 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5226 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5228 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5229 && reload_completed"
5230 [(set (match_dup 2) (match_dup 1))
5231 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5234 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5235 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5236 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5238 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5239 && reload_completed"
5240 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5242 ;; Avoid store forwarding (partial memory) stall penalty
5243 ;; by passing DImode value through XMM registers. */
5245 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5246 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5248 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5249 (clobber (match_scratch:V4SI 3 "=X,x"))
5250 (clobber (match_scratch:V4SI 4 "=X,x"))
5251 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5252 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5253 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5254 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5256 [(set_attr "type" "multi")
5257 (set_attr "mode" "<X87MODEF:MODE>")
5258 (set_attr "unit" "i387")
5259 (set_attr "fp_int_src" "true")])
5262 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5263 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5264 (clobber (match_scratch:V4SI 3 ""))
5265 (clobber (match_scratch:V4SI 4 ""))
5266 (clobber (match_operand:DI 2 "memory_operand" ""))]
5267 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5268 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5269 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5270 && reload_completed"
5271 [(set (match_dup 2) (match_dup 3))
5272 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5274 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5275 Assemble the 64-bit DImode value in an xmm register. */
5276 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5277 gen_rtx_SUBREG (SImode, operands[1], 0)));
5278 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5279 gen_rtx_SUBREG (SImode, operands[1], 4)));
5280 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5283 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5287 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5288 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5289 (clobber (match_scratch:V4SI 3 ""))
5290 (clobber (match_scratch:V4SI 4 ""))
5291 (clobber (match_operand:DI 2 "memory_operand" ""))]
5292 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5293 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5294 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5295 && reload_completed"
5296 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5298 ;; Avoid store forwarding (partial memory) stall penalty by extending
5299 ;; SImode value to DImode through XMM register instead of pushing two
5300 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5301 ;; targets benefit from this optimization. Also note that fild
5302 ;; loads from memory only.
5304 (define_insn "*floatunssi<mode>2_1"
5305 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5306 (unsigned_float:X87MODEF
5307 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5308 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5309 (clobber (match_scratch:SI 3 "=X,x"))]
5311 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5314 [(set_attr "type" "multi")
5315 (set_attr "mode" "<MODE>")])
5318 [(set (match_operand:X87MODEF 0 "register_operand" "")
5319 (unsigned_float:X87MODEF
5320 (match_operand:SI 1 "register_operand" "")))
5321 (clobber (match_operand:DI 2 "memory_operand" ""))
5322 (clobber (match_scratch:SI 3 ""))]
5324 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5326 && reload_completed"
5327 [(set (match_dup 2) (match_dup 1))
5329 (float:X87MODEF (match_dup 2)))]
5330 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5333 [(set (match_operand:X87MODEF 0 "register_operand" "")
5334 (unsigned_float:X87MODEF
5335 (match_operand:SI 1 "memory_operand" "")))
5336 (clobber (match_operand:DI 2 "memory_operand" ""))
5337 (clobber (match_scratch:SI 3 ""))]
5339 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5341 && reload_completed"
5342 [(set (match_dup 2) (match_dup 3))
5344 (float:X87MODEF (match_dup 2)))]
5346 emit_move_insn (operands[3], operands[1]);
5347 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5350 (define_expand "floatunssi<mode>2"
5352 [(set (match_operand:X87MODEF 0 "register_operand" "")
5353 (unsigned_float:X87MODEF
5354 (match_operand:SI 1 "nonimmediate_operand" "")))
5355 (clobber (match_dup 2))
5356 (clobber (match_scratch:SI 3 ""))])]
5358 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5360 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5362 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5364 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5369 enum ix86_stack_slot slot = (virtuals_instantiated
5372 operands[2] = assign_386_stack_local (DImode, slot);
5376 (define_expand "floatunsdisf2"
5377 [(use (match_operand:SF 0 "register_operand" ""))
5378 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5379 "TARGET_64BIT && TARGET_SSE_MATH"
5380 "x86_emit_floatuns (operands); DONE;")
5382 (define_expand "floatunsdidf2"
5383 [(use (match_operand:DF 0 "register_operand" ""))
5384 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5385 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5386 && TARGET_SSE2 && TARGET_SSE_MATH"
5389 x86_emit_floatuns (operands);
5391 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5395 ;; Load effective address instructions
5397 (define_insn_and_split "*lea<mode>"
5398 [(set (match_operand:SWI48 0 "register_operand" "=r")
5399 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5402 rtx addr = operands[1];
5404 if (GET_CODE (addr) == SUBREG)
5406 gcc_assert (TARGET_64BIT);
5407 gcc_assert (<MODE>mode == SImode);
5408 gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
5409 return "lea{l}\t{%E1, %0|%0, %E1}";
5411 else if (GET_CODE (addr) == ZERO_EXTEND
5412 || GET_CODE (addr) == AND)
5414 gcc_assert (TARGET_64BIT);
5415 gcc_assert (<MODE>mode == DImode);
5416 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5419 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5421 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5424 ix86_split_lea_for_addr (operands, <MODE>mode);
5427 [(set_attr "type" "lea")
5428 (set_attr "mode" "<MODE>")])
5432 (define_expand "add<mode>3"
5433 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5434 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5435 (match_operand:SDWIM 2 "<general_operand>" "")))]
5437 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5439 (define_insn_and_split "*add<dwi>3_doubleword"
5440 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5442 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5443 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5444 (clobber (reg:CC FLAGS_REG))]
5445 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5448 [(parallel [(set (reg:CC FLAGS_REG)
5449 (unspec:CC [(match_dup 1) (match_dup 2)]
5452 (plus:DWIH (match_dup 1) (match_dup 2)))])
5453 (parallel [(set (match_dup 3)
5457 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5459 (clobber (reg:CC FLAGS_REG))])]
5460 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5462 (define_insn "*add<mode>3_cc"
5463 [(set (reg:CC FLAGS_REG)
5465 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5466 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5468 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5469 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5470 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5471 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5472 [(set_attr "type" "alu")
5473 (set_attr "mode" "<MODE>")])
5475 (define_insn "addqi3_cc"
5476 [(set (reg:CC FLAGS_REG)
5478 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5479 (match_operand:QI 2 "general_operand" "qn,qm")]
5481 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5482 (plus:QI (match_dup 1) (match_dup 2)))]
5483 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5484 "add{b}\t{%2, %0|%0, %2}"
5485 [(set_attr "type" "alu")
5486 (set_attr "mode" "QI")])
5488 (define_insn "*add<mode>_1"
5489 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5491 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5492 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5493 (clobber (reg:CC FLAGS_REG))]
5494 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5496 switch (get_attr_type (insn))
5502 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5503 if (operands[2] == const1_rtx)
5504 return "inc{<imodesuffix>}\t%0";
5507 gcc_assert (operands[2] == constm1_rtx);
5508 return "dec{<imodesuffix>}\t%0";
5512 /* For most processors, ADD is faster than LEA. This alternative
5513 was added to use ADD as much as possible. */
5514 if (which_alternative == 2)
5517 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5520 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5521 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5522 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5524 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5528 (cond [(eq_attr "alternative" "3")
5529 (const_string "lea")
5530 (match_operand:SWI48 2 "incdec_operand" "")
5531 (const_string "incdec")
5533 (const_string "alu")))
5534 (set (attr "length_immediate")
5536 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5538 (const_string "*")))
5539 (set_attr "mode" "<MODE>")])
5541 ;; It may seem that nonimmediate operand is proper one for operand 1.
5542 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5543 ;; we take care in ix86_binary_operator_ok to not allow two memory
5544 ;; operands so proper swapping will be done in reload. This allow
5545 ;; patterns constructed from addsi_1 to match.
5547 (define_insn "addsi_1_zext"
5548 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5550 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5551 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5552 (clobber (reg:CC FLAGS_REG))]
5553 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5555 switch (get_attr_type (insn))
5561 if (operands[2] == const1_rtx)
5562 return "inc{l}\t%k0";
5565 gcc_assert (operands[2] == constm1_rtx);
5566 return "dec{l}\t%k0";
5570 /* For most processors, ADD is faster than LEA. This alternative
5571 was added to use ADD as much as possible. */
5572 if (which_alternative == 1)
5575 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5578 if (x86_maybe_negate_const_int (&operands[2], SImode))
5579 return "sub{l}\t{%2, %k0|%k0, %2}";
5581 return "add{l}\t{%2, %k0|%k0, %2}";
5585 (cond [(eq_attr "alternative" "2")
5586 (const_string "lea")
5587 (match_operand:SI 2 "incdec_operand" "")
5588 (const_string "incdec")
5590 (const_string "alu")))
5591 (set (attr "length_immediate")
5593 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5595 (const_string "*")))
5596 (set_attr "mode" "SI")])
5598 (define_insn "*addhi_1"
5599 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5600 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5601 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5602 (clobber (reg:CC FLAGS_REG))]
5603 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5605 switch (get_attr_type (insn))
5611 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5612 if (operands[2] == const1_rtx)
5613 return "inc{w}\t%0";
5616 gcc_assert (operands[2] == constm1_rtx);
5617 return "dec{w}\t%0";
5621 /* For most processors, ADD is faster than LEA. This alternative
5622 was added to use ADD as much as possible. */
5623 if (which_alternative == 2)
5626 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5629 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5630 if (x86_maybe_negate_const_int (&operands[2], HImode))
5631 return "sub{w}\t{%2, %0|%0, %2}";
5633 return "add{w}\t{%2, %0|%0, %2}";
5637 (cond [(eq_attr "alternative" "3")
5638 (const_string "lea")
5639 (match_operand:HI 2 "incdec_operand" "")
5640 (const_string "incdec")
5642 (const_string "alu")))
5643 (set (attr "length_immediate")
5645 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5647 (const_string "*")))
5648 (set_attr "mode" "HI,HI,HI,SI")])
5650 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5651 (define_insn "*addqi_1"
5652 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5653 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5654 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5655 (clobber (reg:CC FLAGS_REG))]
5656 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5658 bool widen = (which_alternative == 3 || which_alternative == 4);
5660 switch (get_attr_type (insn))
5666 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5667 if (operands[2] == const1_rtx)
5668 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5671 gcc_assert (operands[2] == constm1_rtx);
5672 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5676 /* For most processors, ADD is faster than LEA. These alternatives
5677 were added to use ADD as much as possible. */
5678 if (which_alternative == 2 || which_alternative == 4)
5681 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5684 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5685 if (x86_maybe_negate_const_int (&operands[2], QImode))
5688 return "sub{l}\t{%2, %k0|%k0, %2}";
5690 return "sub{b}\t{%2, %0|%0, %2}";
5693 return "add{l}\t{%k2, %k0|%k0, %k2}";
5695 return "add{b}\t{%2, %0|%0, %2}";
5699 (cond [(eq_attr "alternative" "5")
5700 (const_string "lea")
5701 (match_operand:QI 2 "incdec_operand" "")
5702 (const_string "incdec")
5704 (const_string "alu")))
5705 (set (attr "length_immediate")
5707 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5709 (const_string "*")))
5710 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5712 (define_insn "*addqi_1_slp"
5713 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5714 (plus:QI (match_dup 0)
5715 (match_operand:QI 1 "general_operand" "qn,qm")))
5716 (clobber (reg:CC FLAGS_REG))]
5717 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5718 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5720 switch (get_attr_type (insn))
5723 if (operands[1] == const1_rtx)
5724 return "inc{b}\t%0";
5727 gcc_assert (operands[1] == constm1_rtx);
5728 return "dec{b}\t%0";
5732 if (x86_maybe_negate_const_int (&operands[1], QImode))
5733 return "sub{b}\t{%1, %0|%0, %1}";
5735 return "add{b}\t{%1, %0|%0, %1}";
5739 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5740 (const_string "incdec")
5741 (const_string "alu1")))
5742 (set (attr "memory")
5743 (if_then_else (match_operand 1 "memory_operand" "")
5744 (const_string "load")
5745 (const_string "none")))
5746 (set_attr "mode" "QI")])
5748 ;; Split non destructive adds if we cannot use lea.
5750 [(set (match_operand:SWI48 0 "register_operand" "")
5751 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5752 (match_operand:SWI48 2 "nonmemory_operand" "")))
5753 (clobber (reg:CC FLAGS_REG))]
5754 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5755 [(set (match_dup 0) (match_dup 1))
5756 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5757 (clobber (reg:CC FLAGS_REG))])])
5759 ;; Convert add to the lea pattern to avoid flags dependency.
5761 [(set (match_operand:SWI 0 "register_operand" "")
5762 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5763 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5764 (clobber (reg:CC FLAGS_REG))]
5765 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5768 enum machine_mode mode = <MODE>mode;
5771 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5774 operands[0] = gen_lowpart (mode, operands[0]);
5775 operands[1] = gen_lowpart (mode, operands[1]);
5776 operands[2] = gen_lowpart (mode, operands[2]);
5779 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5781 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5785 ;; Convert add to the lea pattern to avoid flags dependency.
5787 [(set (match_operand:DI 0 "register_operand" "")
5789 (plus:SI (match_operand:SI 1 "register_operand" "")
5790 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5791 (clobber (reg:CC FLAGS_REG))]
5792 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5794 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5796 (define_insn "*add<mode>_2"
5797 [(set (reg FLAGS_REG)
5800 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5801 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5803 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5804 (plus:SWI (match_dup 1) (match_dup 2)))]
5805 "ix86_match_ccmode (insn, CCGOCmode)
5806 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5808 switch (get_attr_type (insn))
5811 if (operands[2] == const1_rtx)
5812 return "inc{<imodesuffix>}\t%0";
5815 gcc_assert (operands[2] == constm1_rtx);
5816 return "dec{<imodesuffix>}\t%0";
5820 if (which_alternative == 2)
5823 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5826 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5827 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5828 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5830 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5834 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5835 (const_string "incdec")
5836 (const_string "alu")))
5837 (set (attr "length_immediate")
5839 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5841 (const_string "*")))
5842 (set_attr "mode" "<MODE>")])
5844 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5845 (define_insn "*addsi_2_zext"
5846 [(set (reg FLAGS_REG)
5848 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5849 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5851 (set (match_operand:DI 0 "register_operand" "=r,r")
5852 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5853 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5854 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5856 switch (get_attr_type (insn))
5859 if (operands[2] == const1_rtx)
5860 return "inc{l}\t%k0";
5863 gcc_assert (operands[2] == constm1_rtx);
5864 return "dec{l}\t%k0";
5868 if (which_alternative == 1)
5871 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5874 if (x86_maybe_negate_const_int (&operands[2], SImode))
5875 return "sub{l}\t{%2, %k0|%k0, %2}";
5877 return "add{l}\t{%2, %k0|%k0, %2}";
5881 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5882 (const_string "incdec")
5883 (const_string "alu")))
5884 (set (attr "length_immediate")
5886 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5888 (const_string "*")))
5889 (set_attr "mode" "SI")])
5891 (define_insn "*add<mode>_3"
5892 [(set (reg FLAGS_REG)
5894 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5895 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5896 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5897 "ix86_match_ccmode (insn, CCZmode)
5898 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5900 switch (get_attr_type (insn))
5903 if (operands[2] == const1_rtx)
5904 return "inc{<imodesuffix>}\t%0";
5907 gcc_assert (operands[2] == constm1_rtx);
5908 return "dec{<imodesuffix>}\t%0";
5912 if (which_alternative == 1)
5915 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5918 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5919 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5920 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5922 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5926 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5927 (const_string "incdec")
5928 (const_string "alu")))
5929 (set (attr "length_immediate")
5931 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5933 (const_string "*")))
5934 (set_attr "mode" "<MODE>")])
5936 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5937 (define_insn "*addsi_3_zext"
5938 [(set (reg FLAGS_REG)
5940 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5941 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5942 (set (match_operand:DI 0 "register_operand" "=r,r")
5943 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5944 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5945 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5947 switch (get_attr_type (insn))
5950 if (operands[2] == const1_rtx)
5951 return "inc{l}\t%k0";
5954 gcc_assert (operands[2] == constm1_rtx);
5955 return "dec{l}\t%k0";
5959 if (which_alternative == 1)
5962 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5965 if (x86_maybe_negate_const_int (&operands[2], SImode))
5966 return "sub{l}\t{%2, %k0|%k0, %2}";
5968 return "add{l}\t{%2, %k0|%k0, %2}";
5972 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5973 (const_string "incdec")
5974 (const_string "alu")))
5975 (set (attr "length_immediate")
5977 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5979 (const_string "*")))
5980 (set_attr "mode" "SI")])
5982 ; For comparisons against 1, -1 and 128, we may generate better code
5983 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5984 ; is matched then. We can't accept general immediate, because for
5985 ; case of overflows, the result is messed up.
5986 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5987 ; only for comparisons not depending on it.
5989 (define_insn "*adddi_4"
5990 [(set (reg FLAGS_REG)
5992 (match_operand:DI 1 "nonimmediate_operand" "0")
5993 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5994 (clobber (match_scratch:DI 0 "=rm"))]
5996 && ix86_match_ccmode (insn, CCGCmode)"
5998 switch (get_attr_type (insn))
6001 if (operands[2] == constm1_rtx)
6002 return "inc{q}\t%0";
6005 gcc_assert (operands[2] == const1_rtx);
6006 return "dec{q}\t%0";
6010 if (x86_maybe_negate_const_int (&operands[2], DImode))
6011 return "add{q}\t{%2, %0|%0, %2}";
6013 return "sub{q}\t{%2, %0|%0, %2}";
6017 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6018 (const_string "incdec")
6019 (const_string "alu")))
6020 (set (attr "length_immediate")
6022 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6024 (const_string "*")))
6025 (set_attr "mode" "DI")])
6027 ; For comparisons against 1, -1 and 128, we may generate better code
6028 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6029 ; is matched then. We can't accept general immediate, because for
6030 ; case of overflows, the result is messed up.
6031 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6032 ; only for comparisons not depending on it.
6034 (define_insn "*add<mode>_4"
6035 [(set (reg FLAGS_REG)
6037 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6038 (match_operand:SWI124 2 "const_int_operand" "n")))
6039 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6040 "ix86_match_ccmode (insn, CCGCmode)"
6042 switch (get_attr_type (insn))
6045 if (operands[2] == constm1_rtx)
6046 return "inc{<imodesuffix>}\t%0";
6049 gcc_assert (operands[2] == const1_rtx);
6050 return "dec{<imodesuffix>}\t%0";
6054 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6055 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6057 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6061 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6062 (const_string "incdec")
6063 (const_string "alu")))
6064 (set (attr "length_immediate")
6066 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6068 (const_string "*")))
6069 (set_attr "mode" "<MODE>")])
6071 (define_insn "*add<mode>_5"
6072 [(set (reg FLAGS_REG)
6075 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6076 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6078 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6079 "ix86_match_ccmode (insn, CCGOCmode)
6080 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6082 switch (get_attr_type (insn))
6085 if (operands[2] == const1_rtx)
6086 return "inc{<imodesuffix>}\t%0";
6089 gcc_assert (operands[2] == constm1_rtx);
6090 return "dec{<imodesuffix>}\t%0";
6094 if (which_alternative == 1)
6097 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6100 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6101 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6102 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6104 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6108 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6109 (const_string "incdec")
6110 (const_string "alu")))
6111 (set (attr "length_immediate")
6113 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6115 (const_string "*")))
6116 (set_attr "mode" "<MODE>")])
6118 (define_insn "*addqi_ext_1_rex64"
6119 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6124 (match_operand 1 "ext_register_operand" "0")
6127 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6128 (clobber (reg:CC FLAGS_REG))]
6131 switch (get_attr_type (insn))
6134 if (operands[2] == const1_rtx)
6135 return "inc{b}\t%h0";
6138 gcc_assert (operands[2] == constm1_rtx);
6139 return "dec{b}\t%h0";
6143 return "add{b}\t{%2, %h0|%h0, %2}";
6147 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6148 (const_string "incdec")
6149 (const_string "alu")))
6150 (set_attr "modrm" "1")
6151 (set_attr "mode" "QI")])
6153 (define_insn "addqi_ext_1"
6154 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6159 (match_operand 1 "ext_register_operand" "0")
6162 (match_operand:QI 2 "general_operand" "Qmn")))
6163 (clobber (reg:CC FLAGS_REG))]
6166 switch (get_attr_type (insn))
6169 if (operands[2] == const1_rtx)
6170 return "inc{b}\t%h0";
6173 gcc_assert (operands[2] == constm1_rtx);
6174 return "dec{b}\t%h0";
6178 return "add{b}\t{%2, %h0|%h0, %2}";
6182 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6183 (const_string "incdec")
6184 (const_string "alu")))
6185 (set_attr "modrm" "1")
6186 (set_attr "mode" "QI")])
6188 (define_insn "*addqi_ext_2"
6189 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6194 (match_operand 1 "ext_register_operand" "%0")
6198 (match_operand 2 "ext_register_operand" "Q")
6201 (clobber (reg:CC FLAGS_REG))]
6203 "add{b}\t{%h2, %h0|%h0, %h2}"
6204 [(set_attr "type" "alu")
6205 (set_attr "mode" "QI")])
6207 ;; The lea patterns for modes less than 32 bits need to be matched by
6208 ;; several insns converted to real lea by splitters.
6210 (define_insn_and_split "*lea_general_1"
6211 [(set (match_operand 0 "register_operand" "=r")
6212 (plus (plus (match_operand 1 "index_register_operand" "l")
6213 (match_operand 2 "register_operand" "r"))
6214 (match_operand 3 "immediate_operand" "i")))]
6215 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6216 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6217 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6218 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6219 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6220 || GET_MODE (operands[3]) == VOIDmode)"
6222 "&& reload_completed"
6225 enum machine_mode mode = SImode;
6228 operands[0] = gen_lowpart (mode, operands[0]);
6229 operands[1] = gen_lowpart (mode, operands[1]);
6230 operands[2] = gen_lowpart (mode, operands[2]);
6231 operands[3] = gen_lowpart (mode, operands[3]);
6233 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6236 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6239 [(set_attr "type" "lea")
6240 (set_attr "mode" "SI")])
6242 (define_insn_and_split "*lea_general_2"
6243 [(set (match_operand 0 "register_operand" "=r")
6244 (plus (mult (match_operand 1 "index_register_operand" "l")
6245 (match_operand 2 "const248_operand" "n"))
6246 (match_operand 3 "nonmemory_operand" "ri")))]
6247 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6248 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6249 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6250 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6251 || GET_MODE (operands[3]) == VOIDmode)"
6253 "&& reload_completed"
6256 enum machine_mode mode = SImode;
6259 operands[0] = gen_lowpart (mode, operands[0]);
6260 operands[1] = gen_lowpart (mode, operands[1]);
6261 operands[3] = gen_lowpart (mode, operands[3]);
6263 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6266 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6269 [(set_attr "type" "lea")
6270 (set_attr "mode" "SI")])
6272 (define_insn_and_split "*lea_general_3"
6273 [(set (match_operand 0 "register_operand" "=r")
6274 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6275 (match_operand 2 "const248_operand" "n"))
6276 (match_operand 3 "register_operand" "r"))
6277 (match_operand 4 "immediate_operand" "i")))]
6278 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6279 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6280 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6281 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6283 "&& reload_completed"
6286 enum machine_mode mode = SImode;
6289 operands[0] = gen_lowpart (mode, operands[0]);
6290 operands[1] = gen_lowpart (mode, operands[1]);
6291 operands[3] = gen_lowpart (mode, operands[3]);
6292 operands[4] = gen_lowpart (mode, operands[4]);
6294 pat = gen_rtx_PLUS (mode,
6296 gen_rtx_MULT (mode, operands[1],
6301 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6304 [(set_attr "type" "lea")
6305 (set_attr "mode" "SI")])
6307 (define_insn_and_split "*lea_general_4"
6308 [(set (match_operand 0 "register_operand" "=r")
6310 (match_operand 1 "index_register_operand" "l")
6311 (match_operand 2 "const_int_operand" "n"))
6312 (match_operand 3 "const_int_operand" "n")))]
6313 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6314 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6315 || GET_MODE (operands[0]) == SImode
6316 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6317 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6318 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6319 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6320 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6322 "&& reload_completed"
6325 enum machine_mode mode = GET_MODE (operands[0]);
6328 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6331 operands[0] = gen_lowpart (mode, operands[0]);
6332 operands[1] = gen_lowpart (mode, operands[1]);
6335 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6337 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6338 INTVAL (operands[3]));
6340 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6343 [(set_attr "type" "lea")
6345 (if_then_else (match_operand:DI 0 "" "")
6347 (const_string "SI")))])
6349 ;; Subtract instructions
6351 (define_expand "sub<mode>3"
6352 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6353 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6354 (match_operand:SDWIM 2 "<general_operand>" "")))]
6356 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6358 (define_insn_and_split "*sub<dwi>3_doubleword"
6359 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6361 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6362 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6363 (clobber (reg:CC FLAGS_REG))]
6364 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6367 [(parallel [(set (reg:CC FLAGS_REG)
6368 (compare:CC (match_dup 1) (match_dup 2)))
6370 (minus:DWIH (match_dup 1) (match_dup 2)))])
6371 (parallel [(set (match_dup 3)
6375 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6377 (clobber (reg:CC FLAGS_REG))])]
6378 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6380 (define_insn "*sub<mode>_1"
6381 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6383 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6384 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6385 (clobber (reg:CC FLAGS_REG))]
6386 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6387 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6388 [(set_attr "type" "alu")
6389 (set_attr "mode" "<MODE>")])
6391 (define_insn "*subsi_1_zext"
6392 [(set (match_operand:DI 0 "register_operand" "=r")
6394 (minus:SI (match_operand:SI 1 "register_operand" "0")
6395 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6396 (clobber (reg:CC FLAGS_REG))]
6397 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6398 "sub{l}\t{%2, %k0|%k0, %2}"
6399 [(set_attr "type" "alu")
6400 (set_attr "mode" "SI")])
6402 (define_insn "*subqi_1_slp"
6403 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6404 (minus:QI (match_dup 0)
6405 (match_operand:QI 1 "general_operand" "qn,qm")))
6406 (clobber (reg:CC FLAGS_REG))]
6407 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6408 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6409 "sub{b}\t{%1, %0|%0, %1}"
6410 [(set_attr "type" "alu1")
6411 (set_attr "mode" "QI")])
6413 (define_insn "*sub<mode>_2"
6414 [(set (reg FLAGS_REG)
6417 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6418 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6420 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6421 (minus:SWI (match_dup 1) (match_dup 2)))]
6422 "ix86_match_ccmode (insn, CCGOCmode)
6423 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6424 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6425 [(set_attr "type" "alu")
6426 (set_attr "mode" "<MODE>")])
6428 (define_insn "*subsi_2_zext"
6429 [(set (reg FLAGS_REG)
6431 (minus:SI (match_operand:SI 1 "register_operand" "0")
6432 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6434 (set (match_operand:DI 0 "register_operand" "=r")
6436 (minus:SI (match_dup 1)
6438 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6439 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6440 "sub{l}\t{%2, %k0|%k0, %2}"
6441 [(set_attr "type" "alu")
6442 (set_attr "mode" "SI")])
6444 (define_insn "*sub<mode>_3"
6445 [(set (reg FLAGS_REG)
6446 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6447 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6448 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6449 (minus:SWI (match_dup 1) (match_dup 2)))]
6450 "ix86_match_ccmode (insn, CCmode)
6451 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6452 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6453 [(set_attr "type" "alu")
6454 (set_attr "mode" "<MODE>")])
6456 (define_insn "*subsi_3_zext"
6457 [(set (reg FLAGS_REG)
6458 (compare (match_operand:SI 1 "register_operand" "0")
6459 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6460 (set (match_operand:DI 0 "register_operand" "=r")
6462 (minus:SI (match_dup 1)
6464 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6465 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6466 "sub{l}\t{%2, %1|%1, %2}"
6467 [(set_attr "type" "alu")
6468 (set_attr "mode" "SI")])
6470 ;; Add with carry and subtract with borrow
6472 (define_expand "<plusminus_insn><mode>3_carry"
6474 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6476 (match_operand:SWI 1 "nonimmediate_operand" "")
6477 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6478 [(match_operand 3 "flags_reg_operand" "")
6480 (match_operand:SWI 2 "<general_operand>" ""))))
6481 (clobber (reg:CC FLAGS_REG))])]
6482 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6484 (define_insn "*<plusminus_insn><mode>3_carry"
6485 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6487 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6489 (match_operator 3 "ix86_carry_flag_operator"
6490 [(reg FLAGS_REG) (const_int 0)])
6491 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6492 (clobber (reg:CC FLAGS_REG))]
6493 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6494 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6495 [(set_attr "type" "alu")
6496 (set_attr "use_carry" "1")
6497 (set_attr "pent_pair" "pu")
6498 (set_attr "mode" "<MODE>")])
6500 (define_insn "*addsi3_carry_zext"
6501 [(set (match_operand:DI 0 "register_operand" "=r")
6503 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6504 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6505 [(reg FLAGS_REG) (const_int 0)])
6506 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6507 (clobber (reg:CC FLAGS_REG))]
6508 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6509 "adc{l}\t{%2, %k0|%k0, %2}"
6510 [(set_attr "type" "alu")
6511 (set_attr "use_carry" "1")
6512 (set_attr "pent_pair" "pu")
6513 (set_attr "mode" "SI")])
6515 (define_insn "*subsi3_carry_zext"
6516 [(set (match_operand:DI 0 "register_operand" "=r")
6518 (minus:SI (match_operand:SI 1 "register_operand" "0")
6519 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6520 [(reg FLAGS_REG) (const_int 0)])
6521 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6522 (clobber (reg:CC FLAGS_REG))]
6523 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6524 "sbb{l}\t{%2, %k0|%k0, %2}"
6525 [(set_attr "type" "alu")
6526 (set_attr "pent_pair" "pu")
6527 (set_attr "mode" "SI")])
6529 ;; Overflow setting add and subtract instructions
6531 (define_insn "*add<mode>3_cconly_overflow"
6532 [(set (reg:CCC FLAGS_REG)
6535 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6536 (match_operand:SWI 2 "<general_operand>" "<g>"))
6538 (clobber (match_scratch:SWI 0 "=<r>"))]
6539 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6540 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6541 [(set_attr "type" "alu")
6542 (set_attr "mode" "<MODE>")])
6544 (define_insn "*sub<mode>3_cconly_overflow"
6545 [(set (reg:CCC FLAGS_REG)
6548 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6549 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6552 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6553 [(set_attr "type" "icmp")
6554 (set_attr "mode" "<MODE>")])
6556 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6557 [(set (reg:CCC FLAGS_REG)
6560 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6561 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6563 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6564 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6565 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6566 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6567 [(set_attr "type" "alu")
6568 (set_attr "mode" "<MODE>")])
6570 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6571 [(set (reg:CCC FLAGS_REG)
6574 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6575 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6577 (set (match_operand:DI 0 "register_operand" "=r")
6578 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6579 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6580 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6581 [(set_attr "type" "alu")
6582 (set_attr "mode" "SI")])
6584 ;; The patterns that match these are at the end of this file.
6586 (define_expand "<plusminus_insn>xf3"
6587 [(set (match_operand:XF 0 "register_operand" "")
6589 (match_operand:XF 1 "register_operand" "")
6590 (match_operand:XF 2 "register_operand" "")))]
6593 (define_expand "<plusminus_insn><mode>3"
6594 [(set (match_operand:MODEF 0 "register_operand" "")
6596 (match_operand:MODEF 1 "register_operand" "")
6597 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6598 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6599 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6601 ;; Multiply instructions
6603 (define_expand "mul<mode>3"
6604 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6606 (match_operand:SWIM248 1 "register_operand" "")
6607 (match_operand:SWIM248 2 "<general_operand>" "")))
6608 (clobber (reg:CC FLAGS_REG))])])
6610 (define_expand "mulqi3"
6611 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6613 (match_operand:QI 1 "register_operand" "")
6614 (match_operand:QI 2 "nonimmediate_operand" "")))
6615 (clobber (reg:CC FLAGS_REG))])]
6616 "TARGET_QIMODE_MATH")
6619 ;; IMUL reg32/64, reg32/64, imm8 Direct
6620 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6621 ;; IMUL reg32/64, reg32/64, imm32 Direct
6622 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6623 ;; IMUL reg32/64, reg32/64 Direct
6624 ;; IMUL reg32/64, mem32/64 Direct
6626 ;; On BDVER1, all above IMULs use DirectPath
6628 (define_insn "*mul<mode>3_1"
6629 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6631 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6632 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6633 (clobber (reg:CC FLAGS_REG))]
6634 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6636 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6637 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6638 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6639 [(set_attr "type" "imul")
6640 (set_attr "prefix_0f" "0,0,1")
6641 (set (attr "athlon_decode")
6642 (cond [(eq_attr "cpu" "athlon")
6643 (const_string "vector")
6644 (eq_attr "alternative" "1")
6645 (const_string "vector")
6646 (and (eq_attr "alternative" "2")
6647 (match_operand 1 "memory_operand" ""))
6648 (const_string "vector")]
6649 (const_string "direct")))
6650 (set (attr "amdfam10_decode")
6651 (cond [(and (eq_attr "alternative" "0,1")
6652 (match_operand 1 "memory_operand" ""))
6653 (const_string "vector")]
6654 (const_string "direct")))
6655 (set_attr "bdver1_decode" "direct")
6656 (set_attr "mode" "<MODE>")])
6658 (define_insn "*mulsi3_1_zext"
6659 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6661 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6662 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6663 (clobber (reg:CC FLAGS_REG))]
6665 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6667 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6668 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6669 imul{l}\t{%2, %k0|%k0, %2}"
6670 [(set_attr "type" "imul")
6671 (set_attr "prefix_0f" "0,0,1")
6672 (set (attr "athlon_decode")
6673 (cond [(eq_attr "cpu" "athlon")
6674 (const_string "vector")
6675 (eq_attr "alternative" "1")
6676 (const_string "vector")
6677 (and (eq_attr "alternative" "2")
6678 (match_operand 1 "memory_operand" ""))
6679 (const_string "vector")]
6680 (const_string "direct")))
6681 (set (attr "amdfam10_decode")
6682 (cond [(and (eq_attr "alternative" "0,1")
6683 (match_operand 1 "memory_operand" ""))
6684 (const_string "vector")]
6685 (const_string "direct")))
6686 (set_attr "bdver1_decode" "direct")
6687 (set_attr "mode" "SI")])
6690 ;; IMUL reg16, reg16, imm8 VectorPath
6691 ;; IMUL reg16, mem16, imm8 VectorPath
6692 ;; IMUL reg16, reg16, imm16 VectorPath
6693 ;; IMUL reg16, mem16, imm16 VectorPath
6694 ;; IMUL reg16, reg16 Direct
6695 ;; IMUL reg16, mem16 Direct
6697 ;; On BDVER1, all HI MULs use DoublePath
6699 (define_insn "*mulhi3_1"
6700 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6701 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6702 (match_operand:HI 2 "general_operand" "K,n,mr")))
6703 (clobber (reg:CC FLAGS_REG))]
6705 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6707 imul{w}\t{%2, %1, %0|%0, %1, %2}
6708 imul{w}\t{%2, %1, %0|%0, %1, %2}
6709 imul{w}\t{%2, %0|%0, %2}"
6710 [(set_attr "type" "imul")
6711 (set_attr "prefix_0f" "0,0,1")
6712 (set (attr "athlon_decode")
6713 (cond [(eq_attr "cpu" "athlon")
6714 (const_string "vector")
6715 (eq_attr "alternative" "1,2")
6716 (const_string "vector")]
6717 (const_string "direct")))
6718 (set (attr "amdfam10_decode")
6719 (cond [(eq_attr "alternative" "0,1")
6720 (const_string "vector")]
6721 (const_string "direct")))
6722 (set_attr "bdver1_decode" "double")
6723 (set_attr "mode" "HI")])
6725 ;;On AMDFAM10 and BDVER1
6729 (define_insn "*mulqi3_1"
6730 [(set (match_operand:QI 0 "register_operand" "=a")
6731 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6732 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6733 (clobber (reg:CC FLAGS_REG))]
6735 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6737 [(set_attr "type" "imul")
6738 (set_attr "length_immediate" "0")
6739 (set (attr "athlon_decode")
6740 (if_then_else (eq_attr "cpu" "athlon")
6741 (const_string "vector")
6742 (const_string "direct")))
6743 (set_attr "amdfam10_decode" "direct")
6744 (set_attr "bdver1_decode" "direct")
6745 (set_attr "mode" "QI")])
6747 (define_expand "<u>mul<mode><dwi>3"
6748 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6751 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6753 (match_operand:DWIH 2 "register_operand" ""))))
6754 (clobber (reg:CC FLAGS_REG))])])
6756 (define_expand "<u>mulqihi3"
6757 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6760 (match_operand:QI 1 "nonimmediate_operand" ""))
6762 (match_operand:QI 2 "register_operand" ""))))
6763 (clobber (reg:CC FLAGS_REG))])]
6764 "TARGET_QIMODE_MATH")
6766 (define_insn "*bmi2_umulditi3_1"
6767 [(set (match_operand:DI 0 "register_operand" "=r")
6769 (match_operand:DI 2 "nonimmediate_operand" "%d")
6770 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6771 (set (match_operand:DI 1 "register_operand" "=r")
6774 (mult:TI (zero_extend:TI (match_dup 2))
6775 (zero_extend:TI (match_dup 3)))
6777 "TARGET_64BIT && TARGET_BMI2
6778 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6779 "mulx\t{%3, %0, %1|%1, %0, %3}"
6780 [(set_attr "type" "imulx")
6781 (set_attr "prefix" "vex")
6782 (set_attr "mode" "DI")])
6784 (define_insn "*bmi2_umulsidi3_1"
6785 [(set (match_operand:SI 0 "register_operand" "=r")
6787 (match_operand:SI 2 "nonimmediate_operand" "%d")
6788 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6789 (set (match_operand:SI 1 "register_operand" "=r")
6792 (mult:DI (zero_extend:DI (match_dup 2))
6793 (zero_extend:DI (match_dup 3)))
6795 "!TARGET_64BIT && TARGET_BMI2
6796 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6797 "mulx\t{%3, %0, %1|%1, %0, %3}"
6798 [(set_attr "type" "imulx")
6799 (set_attr "prefix" "vex")
6800 (set_attr "mode" "SI")])
6802 (define_insn "*umul<mode><dwi>3_1"
6803 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6806 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6808 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6809 (clobber (reg:CC FLAGS_REG))]
6810 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6812 mul{<imodesuffix>}\t%2
6814 [(set_attr "isa" "*,bmi2")
6815 (set_attr "type" "imul,imulx")
6816 (set_attr "length_immediate" "0,*")
6817 (set (attr "athlon_decode")
6818 (cond [(eq_attr "alternative" "0")
6819 (if_then_else (eq_attr "cpu" "athlon")
6820 (const_string "vector")
6821 (const_string "double"))]
6822 (const_string "*")))
6823 (set_attr "amdfam10_decode" "double,*")
6824 (set_attr "bdver1_decode" "direct,*")
6825 (set_attr "prefix" "orig,vex")
6826 (set_attr "mode" "<MODE>")])
6828 ;; Convert mul to the mulx pattern to avoid flags dependency.
6830 [(set (match_operand:<DWI> 0 "register_operand" "")
6833 (match_operand:DWIH 1 "register_operand" ""))
6835 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6836 (clobber (reg:CC FLAGS_REG))]
6837 "TARGET_BMI2 && reload_completed
6838 && true_regnum (operands[1]) == DX_REG"
6839 [(parallel [(set (match_dup 3)
6840 (mult:DWIH (match_dup 1) (match_dup 2)))
6844 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6845 (zero_extend:<DWI> (match_dup 2)))
6848 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6850 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6853 (define_insn "*mul<mode><dwi>3_1"
6854 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6857 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6859 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6860 (clobber (reg:CC FLAGS_REG))]
6861 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6862 "imul{<imodesuffix>}\t%2"
6863 [(set_attr "type" "imul")
6864 (set_attr "length_immediate" "0")
6865 (set (attr "athlon_decode")
6866 (if_then_else (eq_attr "cpu" "athlon")
6867 (const_string "vector")
6868 (const_string "double")))
6869 (set_attr "amdfam10_decode" "double")
6870 (set_attr "bdver1_decode" "direct")
6871 (set_attr "mode" "<MODE>")])
6873 (define_insn "*<u>mulqihi3_1"
6874 [(set (match_operand:HI 0 "register_operand" "=a")
6877 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6879 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6880 (clobber (reg:CC FLAGS_REG))]
6882 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6883 "<sgnprefix>mul{b}\t%2"
6884 [(set_attr "type" "imul")
6885 (set_attr "length_immediate" "0")
6886 (set (attr "athlon_decode")
6887 (if_then_else (eq_attr "cpu" "athlon")
6888 (const_string "vector")
6889 (const_string "direct")))
6890 (set_attr "amdfam10_decode" "direct")
6891 (set_attr "bdver1_decode" "direct")
6892 (set_attr "mode" "QI")])
6894 (define_expand "<s>mul<mode>3_highpart"
6895 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6900 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6902 (match_operand:SWI48 2 "register_operand" "")))
6904 (clobber (match_scratch:SWI48 3 ""))
6905 (clobber (reg:CC FLAGS_REG))])]
6907 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6909 (define_insn "*<s>muldi3_highpart_1"
6910 [(set (match_operand:DI 0 "register_operand" "=d")
6915 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6917 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6919 (clobber (match_scratch:DI 3 "=1"))
6920 (clobber (reg:CC FLAGS_REG))]
6922 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6923 "<sgnprefix>mul{q}\t%2"
6924 [(set_attr "type" "imul")
6925 (set_attr "length_immediate" "0")
6926 (set (attr "athlon_decode")
6927 (if_then_else (eq_attr "cpu" "athlon")
6928 (const_string "vector")
6929 (const_string "double")))
6930 (set_attr "amdfam10_decode" "double")
6931 (set_attr "bdver1_decode" "direct")
6932 (set_attr "mode" "DI")])
6934 (define_insn "*<s>mulsi3_highpart_1"
6935 [(set (match_operand:SI 0 "register_operand" "=d")
6940 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6942 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6944 (clobber (match_scratch:SI 3 "=1"))
6945 (clobber (reg:CC FLAGS_REG))]
6946 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6947 "<sgnprefix>mul{l}\t%2"
6948 [(set_attr "type" "imul")
6949 (set_attr "length_immediate" "0")
6950 (set (attr "athlon_decode")
6951 (if_then_else (eq_attr "cpu" "athlon")
6952 (const_string "vector")
6953 (const_string "double")))
6954 (set_attr "amdfam10_decode" "double")
6955 (set_attr "bdver1_decode" "direct")
6956 (set_attr "mode" "SI")])
6958 (define_insn "*<s>mulsi3_highpart_zext"
6959 [(set (match_operand:DI 0 "register_operand" "=d")
6960 (zero_extend:DI (truncate:SI
6962 (mult:DI (any_extend:DI
6963 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6965 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6967 (clobber (match_scratch:SI 3 "=1"))
6968 (clobber (reg:CC FLAGS_REG))]
6970 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6971 "<sgnprefix>mul{l}\t%2"
6972 [(set_attr "type" "imul")
6973 (set_attr "length_immediate" "0")
6974 (set (attr "athlon_decode")
6975 (if_then_else (eq_attr "cpu" "athlon")
6976 (const_string "vector")
6977 (const_string "double")))
6978 (set_attr "amdfam10_decode" "double")
6979 (set_attr "bdver1_decode" "direct")
6980 (set_attr "mode" "SI")])
6982 ;; The patterns that match these are at the end of this file.
6984 (define_expand "mulxf3"
6985 [(set (match_operand:XF 0 "register_operand" "")
6986 (mult:XF (match_operand:XF 1 "register_operand" "")
6987 (match_operand:XF 2 "register_operand" "")))]
6990 (define_expand "mul<mode>3"
6991 [(set (match_operand:MODEF 0 "register_operand" "")
6992 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6993 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6994 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6995 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6997 ;; Divide instructions
6999 ;; The patterns that match these are at the end of this file.
7001 (define_expand "divxf3"
7002 [(set (match_operand:XF 0 "register_operand" "")
7003 (div:XF (match_operand:XF 1 "register_operand" "")
7004 (match_operand:XF 2 "register_operand" "")))]
7007 (define_expand "divdf3"
7008 [(set (match_operand:DF 0 "register_operand" "")
7009 (div:DF (match_operand:DF 1 "register_operand" "")
7010 (match_operand:DF 2 "nonimmediate_operand" "")))]
7011 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7012 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7014 (define_expand "divsf3"
7015 [(set (match_operand:SF 0 "register_operand" "")
7016 (div:SF (match_operand:SF 1 "register_operand" "")
7017 (match_operand:SF 2 "nonimmediate_operand" "")))]
7018 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7023 && optimize_insn_for_speed_p ()
7024 && flag_finite_math_only && !flag_trapping_math
7025 && flag_unsafe_math_optimizations)
7027 ix86_emit_swdivsf (operands[0], operands[1],
7028 operands[2], SFmode);
7033 ;; Divmod instructions.
7035 (define_expand "divmod<mode>4"
7036 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7038 (match_operand:SWIM248 1 "register_operand" "")
7039 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7040 (set (match_operand:SWIM248 3 "register_operand" "")
7041 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7042 (clobber (reg:CC FLAGS_REG))])])
7044 ;; Split with 8bit unsigned divide:
7045 ;; if (dividend an divisor are in [0-255])
7046 ;; use 8bit unsigned integer divide
7048 ;; use original integer divide
7050 [(set (match_operand:SWI48 0 "register_operand" "")
7051 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7052 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7053 (set (match_operand:SWI48 1 "register_operand" "")
7054 (mod:SWI48 (match_dup 2) (match_dup 3)))
7055 (clobber (reg:CC FLAGS_REG))]
7056 "TARGET_USE_8BIT_IDIV
7057 && TARGET_QIMODE_MATH
7058 && can_create_pseudo_p ()
7059 && !optimize_insn_for_size_p ()"
7061 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7063 (define_insn_and_split "divmod<mode>4_1"
7064 [(set (match_operand:SWI48 0 "register_operand" "=a")
7065 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7066 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7067 (set (match_operand:SWI48 1 "register_operand" "=&d")
7068 (mod:SWI48 (match_dup 2) (match_dup 3)))
7069 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7070 (clobber (reg:CC FLAGS_REG))]
7074 [(parallel [(set (match_dup 1)
7075 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7076 (clobber (reg:CC FLAGS_REG))])
7077 (parallel [(set (match_dup 0)
7078 (div:SWI48 (match_dup 2) (match_dup 3)))
7080 (mod:SWI48 (match_dup 2) (match_dup 3)))
7082 (clobber (reg:CC FLAGS_REG))])]
7084 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7086 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7087 operands[4] = operands[2];
7090 /* Avoid use of cltd in favor of a mov+shift. */
7091 emit_move_insn (operands[1], operands[2]);
7092 operands[4] = operands[1];
7095 [(set_attr "type" "multi")
7096 (set_attr "mode" "<MODE>")])
7098 (define_insn_and_split "*divmod<mode>4"
7099 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7100 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7101 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7102 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7103 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7104 (clobber (reg:CC FLAGS_REG))]
7108 [(parallel [(set (match_dup 1)
7109 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7110 (clobber (reg:CC FLAGS_REG))])
7111 (parallel [(set (match_dup 0)
7112 (div:SWIM248 (match_dup 2) (match_dup 3)))
7114 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7116 (clobber (reg:CC FLAGS_REG))])]
7118 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7120 if (<MODE>mode != HImode
7121 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7122 operands[4] = operands[2];
7125 /* Avoid use of cltd in favor of a mov+shift. */
7126 emit_move_insn (operands[1], operands[2]);
7127 operands[4] = operands[1];
7130 [(set_attr "type" "multi")
7131 (set_attr "mode" "<MODE>")])
7133 (define_insn "*divmod<mode>4_noext"
7134 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7135 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7136 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7137 (set (match_operand:SWIM248 1 "register_operand" "=d")
7138 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7139 (use (match_operand:SWIM248 4 "register_operand" "1"))
7140 (clobber (reg:CC FLAGS_REG))]
7142 "idiv{<imodesuffix>}\t%3"
7143 [(set_attr "type" "idiv")
7144 (set_attr "mode" "<MODE>")])
7146 (define_expand "divmodqi4"
7147 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7149 (match_operand:QI 1 "register_operand" "")
7150 (match_operand:QI 2 "nonimmediate_operand" "")))
7151 (set (match_operand:QI 3 "register_operand" "")
7152 (mod:QI (match_dup 1) (match_dup 2)))
7153 (clobber (reg:CC FLAGS_REG))])]
7154 "TARGET_QIMODE_MATH"
7159 tmp0 = gen_reg_rtx (HImode);
7160 tmp1 = gen_reg_rtx (HImode);
7162 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7164 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7165 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7167 /* Extract remainder from AH. */
7168 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7169 insn = emit_move_insn (operands[3], tmp1);
7171 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7172 set_unique_reg_note (insn, REG_EQUAL, mod);
7174 /* Extract quotient from AL. */
7175 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7177 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7178 set_unique_reg_note (insn, REG_EQUAL, div);
7183 ;; Divide AX by r/m8, with result stored in
7186 ;; Change div/mod to HImode and extend the second argument to HImode
7187 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7188 ;; combine may fail.
7189 (define_insn "divmodhiqi3"
7190 [(set (match_operand:HI 0 "register_operand" "=a")
7195 (mod:HI (match_operand:HI 1 "register_operand" "0")
7197 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7201 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7202 (clobber (reg:CC FLAGS_REG))]
7203 "TARGET_QIMODE_MATH"
7205 [(set_attr "type" "idiv")
7206 (set_attr "mode" "QI")])
7208 (define_expand "udivmod<mode>4"
7209 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7211 (match_operand:SWIM248 1 "register_operand" "")
7212 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7213 (set (match_operand:SWIM248 3 "register_operand" "")
7214 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7215 (clobber (reg:CC FLAGS_REG))])])
7217 ;; Split with 8bit unsigned divide:
7218 ;; if (dividend an divisor are in [0-255])
7219 ;; use 8bit unsigned integer divide
7221 ;; use original integer divide
7223 [(set (match_operand:SWI48 0 "register_operand" "")
7224 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7225 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7226 (set (match_operand:SWI48 1 "register_operand" "")
7227 (umod:SWI48 (match_dup 2) (match_dup 3)))
7228 (clobber (reg:CC FLAGS_REG))]
7229 "TARGET_USE_8BIT_IDIV
7230 && TARGET_QIMODE_MATH
7231 && can_create_pseudo_p ()
7232 && !optimize_insn_for_size_p ()"
7234 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7236 (define_insn_and_split "udivmod<mode>4_1"
7237 [(set (match_operand:SWI48 0 "register_operand" "=a")
7238 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7239 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7240 (set (match_operand:SWI48 1 "register_operand" "=&d")
7241 (umod:SWI48 (match_dup 2) (match_dup 3)))
7242 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7243 (clobber (reg:CC FLAGS_REG))]
7247 [(set (match_dup 1) (const_int 0))
7248 (parallel [(set (match_dup 0)
7249 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7251 (umod:SWI48 (match_dup 2) (match_dup 3)))
7253 (clobber (reg:CC FLAGS_REG))])]
7255 [(set_attr "type" "multi")
7256 (set_attr "mode" "<MODE>")])
7258 (define_insn_and_split "*udivmod<mode>4"
7259 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7260 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7261 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7262 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7263 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7264 (clobber (reg:CC FLAGS_REG))]
7268 [(set (match_dup 1) (const_int 0))
7269 (parallel [(set (match_dup 0)
7270 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7272 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7274 (clobber (reg:CC FLAGS_REG))])]
7276 [(set_attr "type" "multi")
7277 (set_attr "mode" "<MODE>")])
7279 (define_insn "*udivmod<mode>4_noext"
7280 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7281 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7282 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7283 (set (match_operand:SWIM248 1 "register_operand" "=d")
7284 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7285 (use (match_operand:SWIM248 4 "register_operand" "1"))
7286 (clobber (reg:CC FLAGS_REG))]
7288 "div{<imodesuffix>}\t%3"
7289 [(set_attr "type" "idiv")
7290 (set_attr "mode" "<MODE>")])
7292 (define_expand "udivmodqi4"
7293 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7295 (match_operand:QI 1 "register_operand" "")
7296 (match_operand:QI 2 "nonimmediate_operand" "")))
7297 (set (match_operand:QI 3 "register_operand" "")
7298 (umod:QI (match_dup 1) (match_dup 2)))
7299 (clobber (reg:CC FLAGS_REG))])]
7300 "TARGET_QIMODE_MATH"
7305 tmp0 = gen_reg_rtx (HImode);
7306 tmp1 = gen_reg_rtx (HImode);
7308 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7310 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7311 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7313 /* Extract remainder from AH. */
7314 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7315 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7316 insn = emit_move_insn (operands[3], tmp1);
7318 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7319 set_unique_reg_note (insn, REG_EQUAL, mod);
7321 /* Extract quotient from AL. */
7322 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7324 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7325 set_unique_reg_note (insn, REG_EQUAL, div);
7330 (define_insn "udivmodhiqi3"
7331 [(set (match_operand:HI 0 "register_operand" "=a")
7336 (mod:HI (match_operand:HI 1 "register_operand" "0")
7338 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7342 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7343 (clobber (reg:CC FLAGS_REG))]
7344 "TARGET_QIMODE_MATH"
7346 [(set_attr "type" "idiv")
7347 (set_attr "mode" "QI")])
7349 ;; We cannot use div/idiv for double division, because it causes
7350 ;; "division by zero" on the overflow and that's not what we expect
7351 ;; from truncate. Because true (non truncating) double division is
7352 ;; never generated, we can't create this insn anyway.
7355 ; [(set (match_operand:SI 0 "register_operand" "=a")
7357 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7359 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7360 ; (set (match_operand:SI 3 "register_operand" "=d")
7362 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7363 ; (clobber (reg:CC FLAGS_REG))]
7365 ; "div{l}\t{%2, %0|%0, %2}"
7366 ; [(set_attr "type" "idiv")])
7368 ;;- Logical AND instructions
7370 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7371 ;; Note that this excludes ah.
7373 (define_expand "testsi_ccno_1"
7374 [(set (reg:CCNO FLAGS_REG)
7376 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7377 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7380 (define_expand "testqi_ccz_1"
7381 [(set (reg:CCZ FLAGS_REG)
7382 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7383 (match_operand:QI 1 "nonmemory_operand" ""))
7386 (define_expand "testdi_ccno_1"
7387 [(set (reg:CCNO FLAGS_REG)
7389 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7390 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7392 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7394 (define_insn "*testdi_1"
7395 [(set (reg FLAGS_REG)
7398 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7399 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7401 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7402 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7404 test{l}\t{%k1, %k0|%k0, %k1}
7405 test{l}\t{%k1, %k0|%k0, %k1}
7406 test{q}\t{%1, %0|%0, %1}
7407 test{q}\t{%1, %0|%0, %1}
7408 test{q}\t{%1, %0|%0, %1}"
7409 [(set_attr "type" "test")
7410 (set_attr "modrm" "0,1,0,1,1")
7411 (set_attr "mode" "SI,SI,DI,DI,DI")])
7413 (define_insn "*testqi_1_maybe_si"
7414 [(set (reg FLAGS_REG)
7417 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7418 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7420 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7421 && ix86_match_ccmode (insn,
7422 CONST_INT_P (operands[1])
7423 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7425 if (which_alternative == 3)
7427 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7428 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7429 return "test{l}\t{%1, %k0|%k0, %1}";
7431 return "test{b}\t{%1, %0|%0, %1}";
7433 [(set_attr "type" "test")
7434 (set_attr "modrm" "0,1,1,1")
7435 (set_attr "mode" "QI,QI,QI,SI")
7436 (set_attr "pent_pair" "uv,np,uv,np")])
7438 (define_insn "*test<mode>_1"
7439 [(set (reg FLAGS_REG)
7442 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7443 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7445 "ix86_match_ccmode (insn, CCNOmode)
7446 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7447 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7448 [(set_attr "type" "test")
7449 (set_attr "modrm" "0,1,1")
7450 (set_attr "mode" "<MODE>")
7451 (set_attr "pent_pair" "uv,np,uv")])
7453 (define_expand "testqi_ext_ccno_0"
7454 [(set (reg:CCNO FLAGS_REG)
7458 (match_operand 0 "ext_register_operand" "")
7461 (match_operand 1 "const_int_operand" ""))
7464 (define_insn "*testqi_ext_0"
7465 [(set (reg FLAGS_REG)
7469 (match_operand 0 "ext_register_operand" "Q")
7472 (match_operand 1 "const_int_operand" "n"))
7474 "ix86_match_ccmode (insn, CCNOmode)"
7475 "test{b}\t{%1, %h0|%h0, %1}"
7476 [(set_attr "type" "test")
7477 (set_attr "mode" "QI")
7478 (set_attr "length_immediate" "1")
7479 (set_attr "modrm" "1")
7480 (set_attr "pent_pair" "np")])
7482 (define_insn "*testqi_ext_1_rex64"
7483 [(set (reg FLAGS_REG)
7487 (match_operand 0 "ext_register_operand" "Q")
7491 (match_operand:QI 1 "register_operand" "Q")))
7493 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7494 "test{b}\t{%1, %h0|%h0, %1}"
7495 [(set_attr "type" "test")
7496 (set_attr "mode" "QI")])
7498 (define_insn "*testqi_ext_1"
7499 [(set (reg FLAGS_REG)
7503 (match_operand 0 "ext_register_operand" "Q")
7507 (match_operand:QI 1 "general_operand" "Qm")))
7509 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7510 "test{b}\t{%1, %h0|%h0, %1}"
7511 [(set_attr "type" "test")
7512 (set_attr "mode" "QI")])
7514 (define_insn "*testqi_ext_2"
7515 [(set (reg FLAGS_REG)
7519 (match_operand 0 "ext_register_operand" "Q")
7523 (match_operand 1 "ext_register_operand" "Q")
7527 "ix86_match_ccmode (insn, CCNOmode)"
7528 "test{b}\t{%h1, %h0|%h0, %h1}"
7529 [(set_attr "type" "test")
7530 (set_attr "mode" "QI")])
7532 (define_insn "*testqi_ext_3_rex64"
7533 [(set (reg FLAGS_REG)
7534 (compare (zero_extract:DI
7535 (match_operand 0 "nonimmediate_operand" "rm")
7536 (match_operand:DI 1 "const_int_operand" "")
7537 (match_operand:DI 2 "const_int_operand" ""))
7540 && ix86_match_ccmode (insn, CCNOmode)
7541 && INTVAL (operands[1]) > 0
7542 && INTVAL (operands[2]) >= 0
7543 /* Ensure that resulting mask is zero or sign extended operand. */
7544 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7545 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7546 && INTVAL (operands[1]) > 32))
7547 && (GET_MODE (operands[0]) == SImode
7548 || GET_MODE (operands[0]) == DImode
7549 || GET_MODE (operands[0]) == HImode
7550 || GET_MODE (operands[0]) == QImode)"
7553 ;; Combine likes to form bit extractions for some tests. Humor it.
7554 (define_insn "*testqi_ext_3"
7555 [(set (reg FLAGS_REG)
7556 (compare (zero_extract:SI
7557 (match_operand 0 "nonimmediate_operand" "rm")
7558 (match_operand:SI 1 "const_int_operand" "")
7559 (match_operand:SI 2 "const_int_operand" ""))
7561 "ix86_match_ccmode (insn, CCNOmode)
7562 && INTVAL (operands[1]) > 0
7563 && INTVAL (operands[2]) >= 0
7564 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7565 && (GET_MODE (operands[0]) == SImode
7566 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7567 || GET_MODE (operands[0]) == HImode
7568 || GET_MODE (operands[0]) == QImode)"
7572 [(set (match_operand 0 "flags_reg_operand" "")
7573 (match_operator 1 "compare_operator"
7575 (match_operand 2 "nonimmediate_operand" "")
7576 (match_operand 3 "const_int_operand" "")
7577 (match_operand 4 "const_int_operand" ""))
7579 "ix86_match_ccmode (insn, CCNOmode)"
7580 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7582 rtx val = operands[2];
7583 HOST_WIDE_INT len = INTVAL (operands[3]);
7584 HOST_WIDE_INT pos = INTVAL (operands[4]);
7586 enum machine_mode mode, submode;
7588 mode = GET_MODE (val);
7591 /* ??? Combine likes to put non-volatile mem extractions in QImode
7592 no matter the size of the test. So find a mode that works. */
7593 if (! MEM_VOLATILE_P (val))
7595 mode = smallest_mode_for_size (pos + len, MODE_INT);
7596 val = adjust_address (val, mode, 0);
7599 else if (GET_CODE (val) == SUBREG
7600 && (submode = GET_MODE (SUBREG_REG (val)),
7601 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7602 && pos + len <= GET_MODE_BITSIZE (submode)
7603 && GET_MODE_CLASS (submode) == MODE_INT)
7605 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7607 val = SUBREG_REG (val);
7609 else if (mode == HImode && pos + len <= 8)
7611 /* Small HImode tests can be converted to QImode. */
7613 val = gen_lowpart (QImode, val);
7616 if (len == HOST_BITS_PER_WIDE_INT)
7619 mask = ((HOST_WIDE_INT)1 << len) - 1;
7622 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7625 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7626 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7627 ;; this is relatively important trick.
7628 ;; Do the conversion only post-reload to avoid limiting of the register class
7631 [(set (match_operand 0 "flags_reg_operand" "")
7632 (match_operator 1 "compare_operator"
7633 [(and (match_operand 2 "register_operand" "")
7634 (match_operand 3 "const_int_operand" ""))
7637 && QI_REG_P (operands[2])
7638 && GET_MODE (operands[2]) != QImode
7639 && ((ix86_match_ccmode (insn, CCZmode)
7640 && !(INTVAL (operands[3]) & ~(255 << 8)))
7641 || (ix86_match_ccmode (insn, CCNOmode)
7642 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7645 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7649 operands[2] = gen_lowpart (SImode, operands[2]);
7650 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7654 [(set (match_operand 0 "flags_reg_operand" "")
7655 (match_operator 1 "compare_operator"
7656 [(and (match_operand 2 "nonimmediate_operand" "")
7657 (match_operand 3 "const_int_operand" ""))
7660 && GET_MODE (operands[2]) != QImode
7661 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7662 && ((ix86_match_ccmode (insn, CCZmode)
7663 && !(INTVAL (operands[3]) & ~255))
7664 || (ix86_match_ccmode (insn, CCNOmode)
7665 && !(INTVAL (operands[3]) & ~127)))"
7667 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7670 operands[2] = gen_lowpart (QImode, operands[2]);
7671 operands[3] = gen_lowpart (QImode, operands[3]);
7674 ;; %%% This used to optimize known byte-wide and operations to memory,
7675 ;; and sometimes to QImode registers. If this is considered useful,
7676 ;; it should be done with splitters.
7678 (define_expand "and<mode>3"
7679 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7680 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7681 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7684 if (<MODE>mode == DImode
7685 && GET_CODE (operands[2]) == CONST_INT
7686 && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7687 && REG_P (operands[1]))
7688 emit_insn (gen_zero_extendsidi2 (operands[0],
7689 gen_lowpart (SImode, operands[1])));
7691 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7695 (define_insn "*anddi_1"
7696 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7698 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7699 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7700 (clobber (reg:CC FLAGS_REG))]
7701 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7703 switch (get_attr_type (insn))
7707 enum machine_mode mode;
7709 gcc_assert (CONST_INT_P (operands[2]));
7710 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7712 else if (INTVAL (operands[2]) == 0xffff)
7716 gcc_assert (INTVAL (operands[2]) == 0xff);
7720 operands[1] = gen_lowpart (mode, operands[1]);
7722 return "mov{l}\t{%1, %k0|%k0, %1}";
7723 else if (mode == HImode)
7724 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7726 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7730 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7731 if (get_attr_mode (insn) == MODE_SI)
7732 return "and{l}\t{%k2, %k0|%k0, %k2}";
7734 return "and{q}\t{%2, %0|%0, %2}";
7737 [(set_attr "type" "alu,alu,alu,imovx")
7738 (set_attr "length_immediate" "*,*,*,0")
7739 (set (attr "prefix_rex")
7741 (and (eq_attr "type" "imovx")
7742 (and (match_test "INTVAL (operands[2]) == 0xff")
7743 (match_operand 1 "ext_QIreg_operand" "")))
7745 (const_string "*")))
7746 (set_attr "mode" "SI,DI,DI,SI")])
7748 (define_insn "*andsi_1"
7749 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7750 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7751 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7752 (clobber (reg:CC FLAGS_REG))]
7753 "ix86_binary_operator_ok (AND, SImode, operands)"
7755 switch (get_attr_type (insn))
7759 enum machine_mode mode;
7761 gcc_assert (CONST_INT_P (operands[2]));
7762 if (INTVAL (operands[2]) == 0xffff)
7766 gcc_assert (INTVAL (operands[2]) == 0xff);
7770 operands[1] = gen_lowpart (mode, operands[1]);
7772 return "movz{wl|x}\t{%1, %0|%0, %1}";
7774 return "movz{bl|x}\t{%1, %0|%0, %1}";
7778 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7779 return "and{l}\t{%2, %0|%0, %2}";
7782 [(set_attr "type" "alu,alu,imovx")
7783 (set (attr "prefix_rex")
7785 (and (eq_attr "type" "imovx")
7786 (and (match_test "INTVAL (operands[2]) == 0xff")
7787 (match_operand 1 "ext_QIreg_operand" "")))
7789 (const_string "*")))
7790 (set_attr "length_immediate" "*,*,0")
7791 (set_attr "mode" "SI")])
7793 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7794 (define_insn "*andsi_1_zext"
7795 [(set (match_operand:DI 0 "register_operand" "=r")
7797 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7798 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7799 (clobber (reg:CC FLAGS_REG))]
7800 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7801 "and{l}\t{%2, %k0|%k0, %2}"
7802 [(set_attr "type" "alu")
7803 (set_attr "mode" "SI")])
7805 (define_insn "*andhi_1"
7806 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7807 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7808 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7809 (clobber (reg:CC FLAGS_REG))]
7810 "ix86_binary_operator_ok (AND, HImode, operands)"
7812 switch (get_attr_type (insn))
7815 gcc_assert (CONST_INT_P (operands[2]));
7816 gcc_assert (INTVAL (operands[2]) == 0xff);
7817 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7820 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7822 return "and{w}\t{%2, %0|%0, %2}";
7825 [(set_attr "type" "alu,alu,imovx")
7826 (set_attr "length_immediate" "*,*,0")
7827 (set (attr "prefix_rex")
7829 (and (eq_attr "type" "imovx")
7830 (match_operand 1 "ext_QIreg_operand" ""))
7832 (const_string "*")))
7833 (set_attr "mode" "HI,HI,SI")])
7835 ;; %%% Potential partial reg stall on alternative 2. What to do?
7836 (define_insn "*andqi_1"
7837 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7838 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7839 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7840 (clobber (reg:CC FLAGS_REG))]
7841 "ix86_binary_operator_ok (AND, QImode, operands)"
7843 and{b}\t{%2, %0|%0, %2}
7844 and{b}\t{%2, %0|%0, %2}
7845 and{l}\t{%k2, %k0|%k0, %k2}"
7846 [(set_attr "type" "alu")
7847 (set_attr "mode" "QI,QI,SI")])
7849 (define_insn "*andqi_1_slp"
7850 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7851 (and:QI (match_dup 0)
7852 (match_operand:QI 1 "general_operand" "qn,qmn")))
7853 (clobber (reg:CC FLAGS_REG))]
7854 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7855 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7856 "and{b}\t{%1, %0|%0, %1}"
7857 [(set_attr "type" "alu1")
7858 (set_attr "mode" "QI")])
7861 [(set (match_operand 0 "register_operand" "")
7863 (const_int -65536)))
7864 (clobber (reg:CC FLAGS_REG))]
7865 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7866 || optimize_function_for_size_p (cfun)"
7867 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7868 "operands[1] = gen_lowpart (HImode, operands[0]);")
7871 [(set (match_operand 0 "ext_register_operand" "")
7874 (clobber (reg:CC FLAGS_REG))]
7875 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7876 && reload_completed"
7877 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7878 "operands[1] = gen_lowpart (QImode, operands[0]);")
7881 [(set (match_operand 0 "ext_register_operand" "")
7883 (const_int -65281)))
7884 (clobber (reg:CC FLAGS_REG))]
7885 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7886 && reload_completed"
7887 [(parallel [(set (zero_extract:SI (match_dup 0)
7891 (zero_extract:SI (match_dup 0)
7894 (zero_extract:SI (match_dup 0)
7897 (clobber (reg:CC FLAGS_REG))])]
7898 "operands[0] = gen_lowpart (SImode, operands[0]);")
7900 (define_insn "*anddi_2"
7901 [(set (reg FLAGS_REG)
7904 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7905 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7907 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7908 (and:DI (match_dup 1) (match_dup 2)))]
7909 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7910 && ix86_binary_operator_ok (AND, DImode, operands)"
7912 and{l}\t{%k2, %k0|%k0, %k2}
7913 and{q}\t{%2, %0|%0, %2}
7914 and{q}\t{%2, %0|%0, %2}"
7915 [(set_attr "type" "alu")
7916 (set_attr "mode" "SI,DI,DI")])
7918 (define_insn "*andqi_2_maybe_si"
7919 [(set (reg FLAGS_REG)
7921 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7922 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7924 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7925 (and:QI (match_dup 1) (match_dup 2)))]
7926 "ix86_binary_operator_ok (AND, QImode, operands)
7927 && ix86_match_ccmode (insn,
7928 CONST_INT_P (operands[2])
7929 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7931 if (which_alternative == 2)
7933 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7934 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7935 return "and{l}\t{%2, %k0|%k0, %2}";
7937 return "and{b}\t{%2, %0|%0, %2}";
7939 [(set_attr "type" "alu")
7940 (set_attr "mode" "QI,QI,SI")])
7942 (define_insn "*and<mode>_2"
7943 [(set (reg FLAGS_REG)
7944 (compare (and:SWI124
7945 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7946 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7948 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7949 (and:SWI124 (match_dup 1) (match_dup 2)))]
7950 "ix86_match_ccmode (insn, CCNOmode)
7951 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7952 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7953 [(set_attr "type" "alu")
7954 (set_attr "mode" "<MODE>")])
7956 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7957 (define_insn "*andsi_2_zext"
7958 [(set (reg FLAGS_REG)
7960 (match_operand:SI 1 "nonimmediate_operand" "%0")
7961 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7963 (set (match_operand:DI 0 "register_operand" "=r")
7964 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7965 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7966 && ix86_binary_operator_ok (AND, SImode, operands)"
7967 "and{l}\t{%2, %k0|%k0, %2}"
7968 [(set_attr "type" "alu")
7969 (set_attr "mode" "SI")])
7971 (define_insn "*andqi_2_slp"
7972 [(set (reg FLAGS_REG)
7974 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7975 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7977 (set (strict_low_part (match_dup 0))
7978 (and:QI (match_dup 0) (match_dup 1)))]
7979 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7980 && ix86_match_ccmode (insn, CCNOmode)
7981 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7982 "and{b}\t{%1, %0|%0, %1}"
7983 [(set_attr "type" "alu1")
7984 (set_attr "mode" "QI")])
7986 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7987 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7988 ;; for a QImode operand, which of course failed.
7989 (define_insn "andqi_ext_0"
7990 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7995 (match_operand 1 "ext_register_operand" "0")
7998 (match_operand 2 "const_int_operand" "n")))
7999 (clobber (reg:CC FLAGS_REG))]
8001 "and{b}\t{%2, %h0|%h0, %2}"
8002 [(set_attr "type" "alu")
8003 (set_attr "length_immediate" "1")
8004 (set_attr "modrm" "1")
8005 (set_attr "mode" "QI")])
8007 ;; Generated by peephole translating test to and. This shows up
8008 ;; often in fp comparisons.
8009 (define_insn "*andqi_ext_0_cc"
8010 [(set (reg FLAGS_REG)
8014 (match_operand 1 "ext_register_operand" "0")
8017 (match_operand 2 "const_int_operand" "n"))
8019 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8028 "ix86_match_ccmode (insn, CCNOmode)"
8029 "and{b}\t{%2, %h0|%h0, %2}"
8030 [(set_attr "type" "alu")
8031 (set_attr "length_immediate" "1")
8032 (set_attr "modrm" "1")
8033 (set_attr "mode" "QI")])
8035 (define_insn "*andqi_ext_1_rex64"
8036 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8041 (match_operand 1 "ext_register_operand" "0")
8045 (match_operand 2 "ext_register_operand" "Q"))))
8046 (clobber (reg:CC FLAGS_REG))]
8048 "and{b}\t{%2, %h0|%h0, %2}"
8049 [(set_attr "type" "alu")
8050 (set_attr "length_immediate" "0")
8051 (set_attr "mode" "QI")])
8053 (define_insn "*andqi_ext_1"
8054 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8059 (match_operand 1 "ext_register_operand" "0")
8063 (match_operand:QI 2 "general_operand" "Qm"))))
8064 (clobber (reg:CC FLAGS_REG))]
8066 "and{b}\t{%2, %h0|%h0, %2}"
8067 [(set_attr "type" "alu")
8068 (set_attr "length_immediate" "0")
8069 (set_attr "mode" "QI")])
8071 (define_insn "*andqi_ext_2"
8072 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8077 (match_operand 1 "ext_register_operand" "%0")
8081 (match_operand 2 "ext_register_operand" "Q")
8084 (clobber (reg:CC FLAGS_REG))]
8086 "and{b}\t{%h2, %h0|%h0, %h2}"
8087 [(set_attr "type" "alu")
8088 (set_attr "length_immediate" "0")
8089 (set_attr "mode" "QI")])
8091 ;; Convert wide AND instructions with immediate operand to shorter QImode
8092 ;; equivalents when possible.
8093 ;; Don't do the splitting with memory operands, since it introduces risk
8094 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8095 ;; for size, but that can (should?) be handled by generic code instead.
8097 [(set (match_operand 0 "register_operand" "")
8098 (and (match_operand 1 "register_operand" "")
8099 (match_operand 2 "const_int_operand" "")))
8100 (clobber (reg:CC FLAGS_REG))]
8102 && QI_REG_P (operands[0])
8103 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8104 && !(~INTVAL (operands[2]) & ~(255 << 8))
8105 && GET_MODE (operands[0]) != QImode"
8106 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8107 (and:SI (zero_extract:SI (match_dup 1)
8108 (const_int 8) (const_int 8))
8110 (clobber (reg:CC FLAGS_REG))])]
8112 operands[0] = gen_lowpart (SImode, operands[0]);
8113 operands[1] = gen_lowpart (SImode, operands[1]);
8114 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8117 ;; Since AND can be encoded with sign extended immediate, this is only
8118 ;; profitable when 7th bit is not set.
8120 [(set (match_operand 0 "register_operand" "")
8121 (and (match_operand 1 "general_operand" "")
8122 (match_operand 2 "const_int_operand" "")))
8123 (clobber (reg:CC FLAGS_REG))]
8125 && ANY_QI_REG_P (operands[0])
8126 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8127 && !(~INTVAL (operands[2]) & ~255)
8128 && !(INTVAL (operands[2]) & 128)
8129 && GET_MODE (operands[0]) != QImode"
8130 [(parallel [(set (strict_low_part (match_dup 0))
8131 (and:QI (match_dup 1)
8133 (clobber (reg:CC FLAGS_REG))])]
8135 operands[0] = gen_lowpart (QImode, operands[0]);
8136 operands[1] = gen_lowpart (QImode, operands[1]);
8137 operands[2] = gen_lowpart (QImode, operands[2]);
8140 ;; Logical inclusive and exclusive OR instructions
8142 ;; %%% This used to optimize known byte-wide and operations to memory.
8143 ;; If this is considered useful, it should be done with splitters.
8145 (define_expand "<code><mode>3"
8146 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8147 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8148 (match_operand:SWIM 2 "<general_operand>" "")))]
8150 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8152 (define_insn "*<code><mode>_1"
8153 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8155 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8156 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8157 (clobber (reg:CC FLAGS_REG))]
8158 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8159 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8160 [(set_attr "type" "alu")
8161 (set_attr "mode" "<MODE>")])
8163 ;; %%% Potential partial reg stall on alternative 2. What to do?
8164 (define_insn "*<code>qi_1"
8165 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8166 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8167 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8168 (clobber (reg:CC FLAGS_REG))]
8169 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8171 <logic>{b}\t{%2, %0|%0, %2}
8172 <logic>{b}\t{%2, %0|%0, %2}
8173 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8174 [(set_attr "type" "alu")
8175 (set_attr "mode" "QI,QI,SI")])
8177 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8178 (define_insn "*<code>si_1_zext"
8179 [(set (match_operand:DI 0 "register_operand" "=r")
8181 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8182 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8183 (clobber (reg:CC FLAGS_REG))]
8184 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8185 "<logic>{l}\t{%2, %k0|%k0, %2}"
8186 [(set_attr "type" "alu")
8187 (set_attr "mode" "SI")])
8189 (define_insn "*<code>si_1_zext_imm"
8190 [(set (match_operand:DI 0 "register_operand" "=r")
8192 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8193 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8194 (clobber (reg:CC FLAGS_REG))]
8195 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8196 "<logic>{l}\t{%2, %k0|%k0, %2}"
8197 [(set_attr "type" "alu")
8198 (set_attr "mode" "SI")])
8200 (define_insn "*<code>qi_1_slp"
8201 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8202 (any_or:QI (match_dup 0)
8203 (match_operand:QI 1 "general_operand" "qmn,qn")))
8204 (clobber (reg:CC FLAGS_REG))]
8205 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8206 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8207 "<logic>{b}\t{%1, %0|%0, %1}"
8208 [(set_attr "type" "alu1")
8209 (set_attr "mode" "QI")])
8211 (define_insn "*<code><mode>_2"
8212 [(set (reg FLAGS_REG)
8213 (compare (any_or:SWI
8214 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8215 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8217 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8218 (any_or:SWI (match_dup 1) (match_dup 2)))]
8219 "ix86_match_ccmode (insn, CCNOmode)
8220 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8221 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8222 [(set_attr "type" "alu")
8223 (set_attr "mode" "<MODE>")])
8225 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8226 ;; ??? Special case for immediate operand is missing - it is tricky.
8227 (define_insn "*<code>si_2_zext"
8228 [(set (reg FLAGS_REG)
8229 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8230 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8232 (set (match_operand:DI 0 "register_operand" "=r")
8233 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8234 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8235 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8236 "<logic>{l}\t{%2, %k0|%k0, %2}"
8237 [(set_attr "type" "alu")
8238 (set_attr "mode" "SI")])
8240 (define_insn "*<code>si_2_zext_imm"
8241 [(set (reg FLAGS_REG)
8243 (match_operand:SI 1 "nonimmediate_operand" "%0")
8244 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8246 (set (match_operand:DI 0 "register_operand" "=r")
8247 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8248 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8249 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8250 "<logic>{l}\t{%2, %k0|%k0, %2}"
8251 [(set_attr "type" "alu")
8252 (set_attr "mode" "SI")])
8254 (define_insn "*<code>qi_2_slp"
8255 [(set (reg FLAGS_REG)
8256 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8257 (match_operand:QI 1 "general_operand" "qmn,qn"))
8259 (set (strict_low_part (match_dup 0))
8260 (any_or:QI (match_dup 0) (match_dup 1)))]
8261 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8262 && ix86_match_ccmode (insn, CCNOmode)
8263 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8264 "<logic>{b}\t{%1, %0|%0, %1}"
8265 [(set_attr "type" "alu1")
8266 (set_attr "mode" "QI")])
8268 (define_insn "*<code><mode>_3"
8269 [(set (reg FLAGS_REG)
8270 (compare (any_or:SWI
8271 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8272 (match_operand:SWI 2 "<general_operand>" "<g>"))
8274 (clobber (match_scratch:SWI 0 "=<r>"))]
8275 "ix86_match_ccmode (insn, CCNOmode)
8276 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8277 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8278 [(set_attr "type" "alu")
8279 (set_attr "mode" "<MODE>")])
8281 (define_insn "*<code>qi_ext_0"
8282 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8287 (match_operand 1 "ext_register_operand" "0")
8290 (match_operand 2 "const_int_operand" "n")))
8291 (clobber (reg:CC FLAGS_REG))]
8292 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8293 "<logic>{b}\t{%2, %h0|%h0, %2}"
8294 [(set_attr "type" "alu")
8295 (set_attr "length_immediate" "1")
8296 (set_attr "modrm" "1")
8297 (set_attr "mode" "QI")])
8299 (define_insn "*<code>qi_ext_1_rex64"
8300 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8305 (match_operand 1 "ext_register_operand" "0")
8309 (match_operand 2 "ext_register_operand" "Q"))))
8310 (clobber (reg:CC FLAGS_REG))]
8312 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8313 "<logic>{b}\t{%2, %h0|%h0, %2}"
8314 [(set_attr "type" "alu")
8315 (set_attr "length_immediate" "0")
8316 (set_attr "mode" "QI")])
8318 (define_insn "*<code>qi_ext_1"
8319 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8324 (match_operand 1 "ext_register_operand" "0")
8328 (match_operand:QI 2 "general_operand" "Qm"))))
8329 (clobber (reg:CC FLAGS_REG))]
8331 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8332 "<logic>{b}\t{%2, %h0|%h0, %2}"
8333 [(set_attr "type" "alu")
8334 (set_attr "length_immediate" "0")
8335 (set_attr "mode" "QI")])
8337 (define_insn "*<code>qi_ext_2"
8338 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8342 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8345 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8348 (clobber (reg:CC FLAGS_REG))]
8349 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8350 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8351 [(set_attr "type" "alu")
8352 (set_attr "length_immediate" "0")
8353 (set_attr "mode" "QI")])
8356 [(set (match_operand 0 "register_operand" "")
8357 (any_or (match_operand 1 "register_operand" "")
8358 (match_operand 2 "const_int_operand" "")))
8359 (clobber (reg:CC FLAGS_REG))]
8361 && QI_REG_P (operands[0])
8362 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8363 && !(INTVAL (operands[2]) & ~(255 << 8))
8364 && GET_MODE (operands[0]) != QImode"
8365 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8366 (any_or:SI (zero_extract:SI (match_dup 1)
8367 (const_int 8) (const_int 8))
8369 (clobber (reg:CC FLAGS_REG))])]
8371 operands[0] = gen_lowpart (SImode, operands[0]);
8372 operands[1] = gen_lowpart (SImode, operands[1]);
8373 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8376 ;; Since OR can be encoded with sign extended immediate, this is only
8377 ;; profitable when 7th bit is set.
8379 [(set (match_operand 0 "register_operand" "")
8380 (any_or (match_operand 1 "general_operand" "")
8381 (match_operand 2 "const_int_operand" "")))
8382 (clobber (reg:CC FLAGS_REG))]
8384 && ANY_QI_REG_P (operands[0])
8385 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8386 && !(INTVAL (operands[2]) & ~255)
8387 && (INTVAL (operands[2]) & 128)
8388 && GET_MODE (operands[0]) != QImode"
8389 [(parallel [(set (strict_low_part (match_dup 0))
8390 (any_or:QI (match_dup 1)
8392 (clobber (reg:CC FLAGS_REG))])]
8394 operands[0] = gen_lowpart (QImode, operands[0]);
8395 operands[1] = gen_lowpart (QImode, operands[1]);
8396 operands[2] = gen_lowpart (QImode, operands[2]);
8399 (define_expand "xorqi_cc_ext_1"
8401 (set (reg:CCNO FLAGS_REG)
8405 (match_operand 1 "ext_register_operand" "")
8408 (match_operand:QI 2 "general_operand" ""))
8410 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8420 (define_insn "*xorqi_cc_ext_1_rex64"
8421 [(set (reg FLAGS_REG)
8425 (match_operand 1 "ext_register_operand" "0")
8428 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8430 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8439 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8440 "xor{b}\t{%2, %h0|%h0, %2}"
8441 [(set_attr "type" "alu")
8442 (set_attr "modrm" "1")
8443 (set_attr "mode" "QI")])
8445 (define_insn "*xorqi_cc_ext_1"
8446 [(set (reg FLAGS_REG)
8450 (match_operand 1 "ext_register_operand" "0")
8453 (match_operand:QI 2 "general_operand" "qmn"))
8455 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8464 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8465 "xor{b}\t{%2, %h0|%h0, %2}"
8466 [(set_attr "type" "alu")
8467 (set_attr "modrm" "1")
8468 (set_attr "mode" "QI")])
8470 ;; Negation instructions
8472 (define_expand "neg<mode>2"
8473 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8474 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8476 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8478 (define_insn_and_split "*neg<dwi>2_doubleword"
8479 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8480 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8481 (clobber (reg:CC FLAGS_REG))]
8482 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8486 [(set (reg:CCZ FLAGS_REG)
8487 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8488 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8491 (plus:DWIH (match_dup 3)
8492 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8494 (clobber (reg:CC FLAGS_REG))])
8497 (neg:DWIH (match_dup 2)))
8498 (clobber (reg:CC FLAGS_REG))])]
8499 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8501 (define_insn "*neg<mode>2_1"
8502 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8503 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8504 (clobber (reg:CC FLAGS_REG))]
8505 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8506 "neg{<imodesuffix>}\t%0"
8507 [(set_attr "type" "negnot")
8508 (set_attr "mode" "<MODE>")])
8510 ;; Combine is quite creative about this pattern.
8511 (define_insn "*negsi2_1_zext"
8512 [(set (match_operand:DI 0 "register_operand" "=r")
8514 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8517 (clobber (reg:CC FLAGS_REG))]
8518 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8520 [(set_attr "type" "negnot")
8521 (set_attr "mode" "SI")])
8523 ;; The problem with neg is that it does not perform (compare x 0),
8524 ;; it really performs (compare 0 x), which leaves us with the zero
8525 ;; flag being the only useful item.
8527 (define_insn "*neg<mode>2_cmpz"
8528 [(set (reg:CCZ FLAGS_REG)
8530 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8532 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8533 (neg:SWI (match_dup 1)))]
8534 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8535 "neg{<imodesuffix>}\t%0"
8536 [(set_attr "type" "negnot")
8537 (set_attr "mode" "<MODE>")])
8539 (define_insn "*negsi2_cmpz_zext"
8540 [(set (reg:CCZ FLAGS_REG)
8544 (match_operand:DI 1 "register_operand" "0")
8548 (set (match_operand:DI 0 "register_operand" "=r")
8549 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8552 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8554 [(set_attr "type" "negnot")
8555 (set_attr "mode" "SI")])
8557 ;; Changing of sign for FP values is doable using integer unit too.
8559 (define_expand "<code><mode>2"
8560 [(set (match_operand:X87MODEF 0 "register_operand" "")
8561 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8562 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8563 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8565 (define_insn "*absneg<mode>2_mixed"
8566 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8567 (match_operator:MODEF 3 "absneg_operator"
8568 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8569 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8570 (clobber (reg:CC FLAGS_REG))]
8571 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8574 (define_insn "*absneg<mode>2_sse"
8575 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8576 (match_operator:MODEF 3 "absneg_operator"
8577 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8578 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8579 (clobber (reg:CC FLAGS_REG))]
8580 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8583 (define_insn "*absneg<mode>2_i387"
8584 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8585 (match_operator:X87MODEF 3 "absneg_operator"
8586 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8587 (use (match_operand 2 "" ""))
8588 (clobber (reg:CC FLAGS_REG))]
8589 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8592 (define_expand "<code>tf2"
8593 [(set (match_operand:TF 0 "register_operand" "")
8594 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8596 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8598 (define_insn "*absnegtf2_sse"
8599 [(set (match_operand:TF 0 "register_operand" "=x,x")
8600 (match_operator:TF 3 "absneg_operator"
8601 [(match_operand:TF 1 "register_operand" "0,x")]))
8602 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8603 (clobber (reg:CC FLAGS_REG))]
8607 ;; Splitters for fp abs and neg.
8610 [(set (match_operand 0 "fp_register_operand" "")
8611 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8612 (use (match_operand 2 "" ""))
8613 (clobber (reg:CC FLAGS_REG))]
8615 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8618 [(set (match_operand 0 "register_operand" "")
8619 (match_operator 3 "absneg_operator"
8620 [(match_operand 1 "register_operand" "")]))
8621 (use (match_operand 2 "nonimmediate_operand" ""))
8622 (clobber (reg:CC FLAGS_REG))]
8623 "reload_completed && SSE_REG_P (operands[0])"
8624 [(set (match_dup 0) (match_dup 3))]
8626 enum machine_mode mode = GET_MODE (operands[0]);
8627 enum machine_mode vmode = GET_MODE (operands[2]);
8630 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8631 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8632 if (operands_match_p (operands[0], operands[2]))
8635 operands[1] = operands[2];
8638 if (GET_CODE (operands[3]) == ABS)
8639 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8641 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8646 [(set (match_operand:SF 0 "register_operand" "")
8647 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8648 (use (match_operand:V4SF 2 "" ""))
8649 (clobber (reg:CC FLAGS_REG))]
8651 [(parallel [(set (match_dup 0) (match_dup 1))
8652 (clobber (reg:CC FLAGS_REG))])]
8655 operands[0] = gen_lowpart (SImode, operands[0]);
8656 if (GET_CODE (operands[1]) == ABS)
8658 tmp = gen_int_mode (0x7fffffff, SImode);
8659 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8663 tmp = gen_int_mode (0x80000000, SImode);
8664 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8670 [(set (match_operand:DF 0 "register_operand" "")
8671 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8672 (use (match_operand 2 "" ""))
8673 (clobber (reg:CC FLAGS_REG))]
8675 [(parallel [(set (match_dup 0) (match_dup 1))
8676 (clobber (reg:CC FLAGS_REG))])]
8681 tmp = gen_lowpart (DImode, operands[0]);
8682 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8685 if (GET_CODE (operands[1]) == ABS)
8688 tmp = gen_rtx_NOT (DImode, tmp);
8692 operands[0] = gen_highpart (SImode, operands[0]);
8693 if (GET_CODE (operands[1]) == ABS)
8695 tmp = gen_int_mode (0x7fffffff, SImode);
8696 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8700 tmp = gen_int_mode (0x80000000, SImode);
8701 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8708 [(set (match_operand:XF 0 "register_operand" "")
8709 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8710 (use (match_operand 2 "" ""))
8711 (clobber (reg:CC FLAGS_REG))]
8713 [(parallel [(set (match_dup 0) (match_dup 1))
8714 (clobber (reg:CC FLAGS_REG))])]
8717 operands[0] = gen_rtx_REG (SImode,
8718 true_regnum (operands[0])
8719 + (TARGET_64BIT ? 1 : 2));
8720 if (GET_CODE (operands[1]) == ABS)
8722 tmp = GEN_INT (0x7fff);
8723 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8727 tmp = GEN_INT (0x8000);
8728 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8733 ;; Conditionalize these after reload. If they match before reload, we
8734 ;; lose the clobber and ability to use integer instructions.
8736 (define_insn "*<code><mode>2_1"
8737 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8738 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8740 && (reload_completed
8741 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8742 "f<absneg_mnemonic>"
8743 [(set_attr "type" "fsgn")
8744 (set_attr "mode" "<MODE>")])
8746 (define_insn "*<code>extendsfdf2"
8747 [(set (match_operand:DF 0 "register_operand" "=f")
8748 (absneg:DF (float_extend:DF
8749 (match_operand:SF 1 "register_operand" "0"))))]
8750 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8751 "f<absneg_mnemonic>"
8752 [(set_attr "type" "fsgn")
8753 (set_attr "mode" "DF")])
8755 (define_insn "*<code>extendsfxf2"
8756 [(set (match_operand:XF 0 "register_operand" "=f")
8757 (absneg:XF (float_extend:XF
8758 (match_operand:SF 1 "register_operand" "0"))))]
8760 "f<absneg_mnemonic>"
8761 [(set_attr "type" "fsgn")
8762 (set_attr "mode" "XF")])
8764 (define_insn "*<code>extenddfxf2"
8765 [(set (match_operand:XF 0 "register_operand" "=f")
8766 (absneg:XF (float_extend:XF
8767 (match_operand:DF 1 "register_operand" "0"))))]
8769 "f<absneg_mnemonic>"
8770 [(set_attr "type" "fsgn")
8771 (set_attr "mode" "XF")])
8773 ;; Copysign instructions
8775 (define_mode_iterator CSGNMODE [SF DF TF])
8776 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8778 (define_expand "copysign<mode>3"
8779 [(match_operand:CSGNMODE 0 "register_operand" "")
8780 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8781 (match_operand:CSGNMODE 2 "register_operand" "")]
8782 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8783 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8784 "ix86_expand_copysign (operands); DONE;")
8786 (define_insn_and_split "copysign<mode>3_const"
8787 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8789 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8790 (match_operand:CSGNMODE 2 "register_operand" "0")
8791 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8793 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8794 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8796 "&& reload_completed"
8798 "ix86_split_copysign_const (operands); DONE;")
8800 (define_insn "copysign<mode>3_var"
8801 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8803 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8804 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8805 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8806 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8808 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8809 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8810 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8814 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8816 [(match_operand:CSGNMODE 2 "register_operand" "")
8817 (match_operand:CSGNMODE 3 "register_operand" "")
8818 (match_operand:<CSGNVMODE> 4 "" "")
8819 (match_operand:<CSGNVMODE> 5 "" "")]
8821 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8822 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8823 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8824 && reload_completed"
8826 "ix86_split_copysign_var (operands); DONE;")
8828 ;; One complement instructions
8830 (define_expand "one_cmpl<mode>2"
8831 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8832 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8834 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8836 (define_insn "*one_cmpl<mode>2_1"
8837 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8838 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8839 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8840 "not{<imodesuffix>}\t%0"
8841 [(set_attr "type" "negnot")
8842 (set_attr "mode" "<MODE>")])
8844 ;; %%% Potential partial reg stall on alternative 1. What to do?
8845 (define_insn "*one_cmplqi2_1"
8846 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8847 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8848 "ix86_unary_operator_ok (NOT, QImode, operands)"
8852 [(set_attr "type" "negnot")
8853 (set_attr "mode" "QI,SI")])
8855 ;; ??? Currently never generated - xor is used instead.
8856 (define_insn "*one_cmplsi2_1_zext"
8857 [(set (match_operand:DI 0 "register_operand" "=r")
8859 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8860 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8862 [(set_attr "type" "negnot")
8863 (set_attr "mode" "SI")])
8865 (define_insn "*one_cmpl<mode>2_2"
8866 [(set (reg FLAGS_REG)
8867 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8869 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8870 (not:SWI (match_dup 1)))]
8871 "ix86_match_ccmode (insn, CCNOmode)
8872 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8874 [(set_attr "type" "alu1")
8875 (set_attr "mode" "<MODE>")])
8878 [(set (match_operand 0 "flags_reg_operand" "")
8879 (match_operator 2 "compare_operator"
8880 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8882 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8883 (not:SWI (match_dup 3)))]
8884 "ix86_match_ccmode (insn, CCNOmode)"
8885 [(parallel [(set (match_dup 0)
8886 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8889 (xor:SWI (match_dup 3) (const_int -1)))])])
8891 ;; ??? Currently never generated - xor is used instead.
8892 (define_insn "*one_cmplsi2_2_zext"
8893 [(set (reg FLAGS_REG)
8894 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8896 (set (match_operand:DI 0 "register_operand" "=r")
8897 (zero_extend:DI (not:SI (match_dup 1))))]
8898 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8899 && ix86_unary_operator_ok (NOT, SImode, operands)"
8901 [(set_attr "type" "alu1")
8902 (set_attr "mode" "SI")])
8905 [(set (match_operand 0 "flags_reg_operand" "")
8906 (match_operator 2 "compare_operator"
8907 [(not:SI (match_operand:SI 3 "register_operand" ""))
8909 (set (match_operand:DI 1 "register_operand" "")
8910 (zero_extend:DI (not:SI (match_dup 3))))]
8911 "ix86_match_ccmode (insn, CCNOmode)"
8912 [(parallel [(set (match_dup 0)
8913 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8916 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8918 ;; Shift instructions
8920 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8921 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8922 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8923 ;; from the assembler input.
8925 ;; This instruction shifts the target reg/mem as usual, but instead of
8926 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8927 ;; is a left shift double, bits are taken from the high order bits of
8928 ;; reg, else if the insn is a shift right double, bits are taken from the
8929 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8930 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8932 ;; Since sh[lr]d does not change the `reg' operand, that is done
8933 ;; separately, making all shifts emit pairs of shift double and normal
8934 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8935 ;; support a 63 bit shift, each shift where the count is in a reg expands
8936 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8938 ;; If the shift count is a constant, we need never emit more than one
8939 ;; shift pair, instead using moves and sign extension for counts greater
8942 (define_expand "ashl<mode>3"
8943 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8944 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8945 (match_operand:QI 2 "nonmemory_operand" "")))]
8947 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8949 (define_insn "*ashl<mode>3_doubleword"
8950 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8951 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8952 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8953 (clobber (reg:CC FLAGS_REG))]
8956 [(set_attr "type" "multi")])
8959 [(set (match_operand:DWI 0 "register_operand" "")
8960 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8961 (match_operand:QI 2 "nonmemory_operand" "")))
8962 (clobber (reg:CC FLAGS_REG))]
8963 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8965 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8967 ;; By default we don't ask for a scratch register, because when DWImode
8968 ;; values are manipulated, registers are already at a premium. But if
8969 ;; we have one handy, we won't turn it away.
8972 [(match_scratch:DWIH 3 "r")
8973 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8975 (match_operand:<DWI> 1 "nonmemory_operand" "")
8976 (match_operand:QI 2 "nonmemory_operand" "")))
8977 (clobber (reg:CC FLAGS_REG))])
8981 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8983 (define_insn "x86_64_shld"
8984 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8985 (ior:DI (ashift:DI (match_dup 0)
8986 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8987 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8988 (minus:QI (const_int 64) (match_dup 2)))))
8989 (clobber (reg:CC FLAGS_REG))]
8991 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8992 [(set_attr "type" "ishift")
8993 (set_attr "prefix_0f" "1")
8994 (set_attr "mode" "DI")
8995 (set_attr "athlon_decode" "vector")
8996 (set_attr "amdfam10_decode" "vector")
8997 (set_attr "bdver1_decode" "vector")])
8999 (define_insn "x86_shld"
9000 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9001 (ior:SI (ashift:SI (match_dup 0)
9002 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9003 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9004 (minus:QI (const_int 32) (match_dup 2)))))
9005 (clobber (reg:CC FLAGS_REG))]
9007 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9008 [(set_attr "type" "ishift")
9009 (set_attr "prefix_0f" "1")
9010 (set_attr "mode" "SI")
9011 (set_attr "pent_pair" "np")
9012 (set_attr "athlon_decode" "vector")
9013 (set_attr "amdfam10_decode" "vector")
9014 (set_attr "bdver1_decode" "vector")])
9016 (define_expand "x86_shift<mode>_adj_1"
9017 [(set (reg:CCZ FLAGS_REG)
9018 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9021 (set (match_operand:SWI48 0 "register_operand" "")
9022 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9023 (match_operand:SWI48 1 "register_operand" "")
9026 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9027 (match_operand:SWI48 3 "register_operand" "")
9030 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9032 (define_expand "x86_shift<mode>_adj_2"
9033 [(use (match_operand:SWI48 0 "register_operand" ""))
9034 (use (match_operand:SWI48 1 "register_operand" ""))
9035 (use (match_operand:QI 2 "register_operand" ""))]
9038 rtx label = gen_label_rtx ();
9041 emit_insn (gen_testqi_ccz_1 (operands[2],
9042 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9044 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9045 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9046 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9047 gen_rtx_LABEL_REF (VOIDmode, label),
9049 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9050 JUMP_LABEL (tmp) = label;
9052 emit_move_insn (operands[0], operands[1]);
9053 ix86_expand_clear (operands[1]);
9056 LABEL_NUSES (label) = 1;
9061 ;; Avoid useless masking of count operand.
9062 (define_insn_and_split "*ashl<mode>3_mask"
9063 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9065 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9068 (match_operand:SI 2 "nonimmediate_operand" "c")
9069 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9070 (clobber (reg:CC FLAGS_REG))]
9071 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9072 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9073 == GET_MODE_BITSIZE (<MODE>mode)-1"
9076 [(parallel [(set (match_dup 0)
9077 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9078 (clobber (reg:CC FLAGS_REG))])]
9080 if (can_create_pseudo_p ())
9081 operands [2] = force_reg (SImode, operands[2]);
9083 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9085 [(set_attr "type" "ishift")
9086 (set_attr "mode" "<MODE>")])
9088 (define_insn "*bmi2_ashl<mode>3_1"
9089 [(set (match_operand:SWI48 0 "register_operand" "=r")
9090 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9091 (match_operand:SWI48 2 "register_operand" "r")))]
9093 "shlx\t{%2, %1, %0|%0, %1, %2}"
9094 [(set_attr "type" "ishiftx")
9095 (set_attr "mode" "<MODE>")])
9097 (define_insn "*ashl<mode>3_1"
9098 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9099 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9100 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9101 (clobber (reg:CC FLAGS_REG))]
9102 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9104 switch (get_attr_type (insn))
9111 gcc_assert (operands[2] == const1_rtx);
9112 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9113 return "add{<imodesuffix>}\t%0, %0";
9116 if (operands[2] == const1_rtx
9117 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9118 return "sal{<imodesuffix>}\t%0";
9120 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9123 [(set_attr "isa" "*,*,bmi2")
9125 (cond [(eq_attr "alternative" "1")
9126 (const_string "lea")
9127 (eq_attr "alternative" "2")
9128 (const_string "ishiftx")
9129 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9130 (match_operand 0 "register_operand" ""))
9131 (match_operand 2 "const1_operand" ""))
9132 (const_string "alu")
9134 (const_string "ishift")))
9135 (set (attr "length_immediate")
9137 (ior (eq_attr "type" "alu")
9138 (and (eq_attr "type" "ishift")
9139 (and (match_operand 2 "const1_operand" "")
9140 (ior (match_test "TARGET_SHIFT1")
9141 (match_test "optimize_function_for_size_p (cfun)")))))
9143 (const_string "*")))
9144 (set_attr "mode" "<MODE>")])
9146 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9148 [(set (match_operand:SWI48 0 "register_operand" "")
9149 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9150 (match_operand:QI 2 "register_operand" "")))
9151 (clobber (reg:CC FLAGS_REG))]
9152 "TARGET_BMI2 && reload_completed"
9154 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9155 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9157 (define_insn "*bmi2_ashlsi3_1_zext"
9158 [(set (match_operand:DI 0 "register_operand" "=r")
9160 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9161 (match_operand:SI 2 "register_operand" "r"))))]
9162 "TARGET_64BIT && TARGET_BMI2"
9163 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9164 [(set_attr "type" "ishiftx")
9165 (set_attr "mode" "SI")])
9167 (define_insn "*ashlsi3_1_zext"
9168 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9170 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9171 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9172 (clobber (reg:CC FLAGS_REG))]
9173 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9175 switch (get_attr_type (insn))
9182 gcc_assert (operands[2] == const1_rtx);
9183 return "add{l}\t%k0, %k0";
9186 if (operands[2] == const1_rtx
9187 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9188 return "sal{l}\t%k0";
9190 return "sal{l}\t{%2, %k0|%k0, %2}";
9193 [(set_attr "isa" "*,*,bmi2")
9195 (cond [(eq_attr "alternative" "1")
9196 (const_string "lea")
9197 (eq_attr "alternative" "2")
9198 (const_string "ishiftx")
9199 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9200 (match_operand 2 "const1_operand" ""))
9201 (const_string "alu")
9203 (const_string "ishift")))
9204 (set (attr "length_immediate")
9206 (ior (eq_attr "type" "alu")
9207 (and (eq_attr "type" "ishift")
9208 (and (match_operand 2 "const1_operand" "")
9209 (ior (match_test "TARGET_SHIFT1")
9210 (match_test "optimize_function_for_size_p (cfun)")))))
9212 (const_string "*")))
9213 (set_attr "mode" "SI")])
9215 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9217 [(set (match_operand:DI 0 "register_operand" "")
9219 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9220 (match_operand:QI 2 "register_operand" ""))))
9221 (clobber (reg:CC FLAGS_REG))]
9222 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9224 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9225 "operands[2] = gen_lowpart (SImode, operands[2]);")
9227 (define_insn "*ashlhi3_1"
9228 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9229 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9230 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9231 (clobber (reg:CC FLAGS_REG))]
9232 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9234 switch (get_attr_type (insn))
9240 gcc_assert (operands[2] == const1_rtx);
9241 return "add{w}\t%0, %0";
9244 if (operands[2] == const1_rtx
9245 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9246 return "sal{w}\t%0";
9248 return "sal{w}\t{%2, %0|%0, %2}";
9252 (cond [(eq_attr "alternative" "1")
9253 (const_string "lea")
9254 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9255 (match_operand 0 "register_operand" ""))
9256 (match_operand 2 "const1_operand" ""))
9257 (const_string "alu")
9259 (const_string "ishift")))
9260 (set (attr "length_immediate")
9262 (ior (eq_attr "type" "alu")
9263 (and (eq_attr "type" "ishift")
9264 (and (match_operand 2 "const1_operand" "")
9265 (ior (match_test "TARGET_SHIFT1")
9266 (match_test "optimize_function_for_size_p (cfun)")))))
9268 (const_string "*")))
9269 (set_attr "mode" "HI,SI")])
9271 ;; %%% Potential partial reg stall on alternative 1. What to do?
9272 (define_insn "*ashlqi3_1"
9273 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9274 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9275 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9276 (clobber (reg:CC FLAGS_REG))]
9277 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9279 switch (get_attr_type (insn))
9285 gcc_assert (operands[2] == const1_rtx);
9286 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9287 return "add{l}\t%k0, %k0";
9289 return "add{b}\t%0, %0";
9292 if (operands[2] == const1_rtx
9293 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9295 if (get_attr_mode (insn) == MODE_SI)
9296 return "sal{l}\t%k0";
9298 return "sal{b}\t%0";
9302 if (get_attr_mode (insn) == MODE_SI)
9303 return "sal{l}\t{%2, %k0|%k0, %2}";
9305 return "sal{b}\t{%2, %0|%0, %2}";
9310 (cond [(eq_attr "alternative" "2")
9311 (const_string "lea")
9312 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9313 (match_operand 0 "register_operand" ""))
9314 (match_operand 2 "const1_operand" ""))
9315 (const_string "alu")
9317 (const_string "ishift")))
9318 (set (attr "length_immediate")
9320 (ior (eq_attr "type" "alu")
9321 (and (eq_attr "type" "ishift")
9322 (and (match_operand 2 "const1_operand" "")
9323 (ior (match_test "TARGET_SHIFT1")
9324 (match_test "optimize_function_for_size_p (cfun)")))))
9326 (const_string "*")))
9327 (set_attr "mode" "QI,SI,SI")])
9329 (define_insn "*ashlqi3_1_slp"
9330 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9331 (ashift:QI (match_dup 0)
9332 (match_operand:QI 1 "nonmemory_operand" "cI")))
9333 (clobber (reg:CC FLAGS_REG))]
9334 "(optimize_function_for_size_p (cfun)
9335 || !TARGET_PARTIAL_FLAG_REG_STALL
9336 || (operands[1] == const1_rtx
9338 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9340 switch (get_attr_type (insn))
9343 gcc_assert (operands[1] == const1_rtx);
9344 return "add{b}\t%0, %0";
9347 if (operands[1] == const1_rtx
9348 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9349 return "sal{b}\t%0";
9351 return "sal{b}\t{%1, %0|%0, %1}";
9355 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9356 (match_operand 0 "register_operand" ""))
9357 (match_operand 1 "const1_operand" ""))
9358 (const_string "alu")
9360 (const_string "ishift1")))
9361 (set (attr "length_immediate")
9363 (ior (eq_attr "type" "alu")
9364 (and (eq_attr "type" "ishift1")
9365 (and (match_operand 1 "const1_operand" "")
9366 (ior (match_test "TARGET_SHIFT1")
9367 (match_test "optimize_function_for_size_p (cfun)")))))
9369 (const_string "*")))
9370 (set_attr "mode" "QI")])
9372 ;; Convert ashift to the lea pattern to avoid flags dependency.
9374 [(set (match_operand 0 "register_operand" "")
9375 (ashift (match_operand 1 "index_register_operand" "")
9376 (match_operand:QI 2 "const_int_operand" "")))
9377 (clobber (reg:CC FLAGS_REG))]
9378 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9380 && true_regnum (operands[0]) != true_regnum (operands[1])"
9383 enum machine_mode mode = GET_MODE (operands[0]);
9386 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9389 operands[0] = gen_lowpart (mode, operands[0]);
9390 operands[1] = gen_lowpart (mode, operands[1]);
9393 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9395 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9397 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9401 ;; Convert ashift to the lea pattern to avoid flags dependency.
9403 [(set (match_operand:DI 0 "register_operand" "")
9405 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9406 (match_operand:QI 2 "const_int_operand" ""))))
9407 (clobber (reg:CC FLAGS_REG))]
9408 "TARGET_64BIT && reload_completed
9409 && true_regnum (operands[0]) != true_regnum (operands[1])"
9411 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9413 operands[1] = gen_lowpart (DImode, operands[1]);
9414 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9417 ;; This pattern can't accept a variable shift count, since shifts by
9418 ;; zero don't affect the flags. We assume that shifts by constant
9419 ;; zero are optimized away.
9420 (define_insn "*ashl<mode>3_cmp"
9421 [(set (reg FLAGS_REG)
9423 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9424 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9426 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9427 (ashift:SWI (match_dup 1) (match_dup 2)))]
9428 "(optimize_function_for_size_p (cfun)
9429 || !TARGET_PARTIAL_FLAG_REG_STALL
9430 || (operands[2] == const1_rtx
9432 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9433 && ix86_match_ccmode (insn, CCGOCmode)
9434 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9436 switch (get_attr_type (insn))
9439 gcc_assert (operands[2] == const1_rtx);
9440 return "add{<imodesuffix>}\t%0, %0";
9443 if (operands[2] == const1_rtx
9444 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9445 return "sal{<imodesuffix>}\t%0";
9447 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9451 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9452 (match_operand 0 "register_operand" ""))
9453 (match_operand 2 "const1_operand" ""))
9454 (const_string "alu")
9456 (const_string "ishift")))
9457 (set (attr "length_immediate")
9459 (ior (eq_attr "type" "alu")
9460 (and (eq_attr "type" "ishift")
9461 (and (match_operand 2 "const1_operand" "")
9462 (ior (match_test "TARGET_SHIFT1")
9463 (match_test "optimize_function_for_size_p (cfun)")))))
9465 (const_string "*")))
9466 (set_attr "mode" "<MODE>")])
9468 (define_insn "*ashlsi3_cmp_zext"
9469 [(set (reg FLAGS_REG)
9471 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9472 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9474 (set (match_operand:DI 0 "register_operand" "=r")
9475 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9477 && (optimize_function_for_size_p (cfun)
9478 || !TARGET_PARTIAL_FLAG_REG_STALL
9479 || (operands[2] == const1_rtx
9481 || TARGET_DOUBLE_WITH_ADD)))
9482 && ix86_match_ccmode (insn, CCGOCmode)
9483 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9485 switch (get_attr_type (insn))
9488 gcc_assert (operands[2] == const1_rtx);
9489 return "add{l}\t%k0, %k0";
9492 if (operands[2] == const1_rtx
9493 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9494 return "sal{l}\t%k0";
9496 return "sal{l}\t{%2, %k0|%k0, %2}";
9500 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9501 (match_operand 2 "const1_operand" ""))
9502 (const_string "alu")
9504 (const_string "ishift")))
9505 (set (attr "length_immediate")
9507 (ior (eq_attr "type" "alu")
9508 (and (eq_attr "type" "ishift")
9509 (and (match_operand 2 "const1_operand" "")
9510 (ior (match_test "TARGET_SHIFT1")
9511 (match_test "optimize_function_for_size_p (cfun)")))))
9513 (const_string "*")))
9514 (set_attr "mode" "SI")])
9516 (define_insn "*ashl<mode>3_cconly"
9517 [(set (reg FLAGS_REG)
9519 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9520 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9522 (clobber (match_scratch:SWI 0 "=<r>"))]
9523 "(optimize_function_for_size_p (cfun)
9524 || !TARGET_PARTIAL_FLAG_REG_STALL
9525 || (operands[2] == const1_rtx
9527 || TARGET_DOUBLE_WITH_ADD)))
9528 && ix86_match_ccmode (insn, CCGOCmode)"
9530 switch (get_attr_type (insn))
9533 gcc_assert (operands[2] == const1_rtx);
9534 return "add{<imodesuffix>}\t%0, %0";
9537 if (operands[2] == const1_rtx
9538 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9539 return "sal{<imodesuffix>}\t%0";
9541 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9545 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9546 (match_operand 0 "register_operand" ""))
9547 (match_operand 2 "const1_operand" ""))
9548 (const_string "alu")
9550 (const_string "ishift")))
9551 (set (attr "length_immediate")
9553 (ior (eq_attr "type" "alu")
9554 (and (eq_attr "type" "ishift")
9555 (and (match_operand 2 "const1_operand" "")
9556 (ior (match_test "TARGET_SHIFT1")
9557 (match_test "optimize_function_for_size_p (cfun)")))))
9559 (const_string "*")))
9560 (set_attr "mode" "<MODE>")])
9562 ;; See comment above `ashl<mode>3' about how this works.
9564 (define_expand "<shift_insn><mode>3"
9565 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9566 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9567 (match_operand:QI 2 "nonmemory_operand" "")))]
9569 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9571 ;; Avoid useless masking of count operand.
9572 (define_insn_and_split "*<shift_insn><mode>3_mask"
9573 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9575 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9578 (match_operand:SI 2 "nonimmediate_operand" "c")
9579 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9580 (clobber (reg:CC FLAGS_REG))]
9581 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9582 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9583 == GET_MODE_BITSIZE (<MODE>mode)-1"
9586 [(parallel [(set (match_dup 0)
9587 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9588 (clobber (reg:CC FLAGS_REG))])]
9590 if (can_create_pseudo_p ())
9591 operands [2] = force_reg (SImode, operands[2]);
9593 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9595 [(set_attr "type" "ishift")
9596 (set_attr "mode" "<MODE>")])
9598 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9599 [(set (match_operand:DWI 0 "register_operand" "=r")
9600 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9601 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9602 (clobber (reg:CC FLAGS_REG))]
9605 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9607 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9608 [(set_attr "type" "multi")])
9610 ;; By default we don't ask for a scratch register, because when DWImode
9611 ;; values are manipulated, registers are already at a premium. But if
9612 ;; we have one handy, we won't turn it away.
9615 [(match_scratch:DWIH 3 "r")
9616 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9618 (match_operand:<DWI> 1 "register_operand" "")
9619 (match_operand:QI 2 "nonmemory_operand" "")))
9620 (clobber (reg:CC FLAGS_REG))])
9624 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9626 (define_insn "x86_64_shrd"
9627 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9628 (ior:DI (ashiftrt:DI (match_dup 0)
9629 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9630 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9631 (minus:QI (const_int 64) (match_dup 2)))))
9632 (clobber (reg:CC FLAGS_REG))]
9634 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9635 [(set_attr "type" "ishift")
9636 (set_attr "prefix_0f" "1")
9637 (set_attr "mode" "DI")
9638 (set_attr "athlon_decode" "vector")
9639 (set_attr "amdfam10_decode" "vector")
9640 (set_attr "bdver1_decode" "vector")])
9642 (define_insn "x86_shrd"
9643 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9644 (ior:SI (ashiftrt:SI (match_dup 0)
9645 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9646 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9647 (minus:QI (const_int 32) (match_dup 2)))))
9648 (clobber (reg:CC FLAGS_REG))]
9650 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9651 [(set_attr "type" "ishift")
9652 (set_attr "prefix_0f" "1")
9653 (set_attr "mode" "SI")
9654 (set_attr "pent_pair" "np")
9655 (set_attr "athlon_decode" "vector")
9656 (set_attr "amdfam10_decode" "vector")
9657 (set_attr "bdver1_decode" "vector")])
9659 (define_insn "ashrdi3_cvt"
9660 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9661 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9662 (match_operand:QI 2 "const_int_operand" "")))
9663 (clobber (reg:CC FLAGS_REG))]
9664 "TARGET_64BIT && INTVAL (operands[2]) == 63
9665 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9666 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9669 sar{q}\t{%2, %0|%0, %2}"
9670 [(set_attr "type" "imovx,ishift")
9671 (set_attr "prefix_0f" "0,*")
9672 (set_attr "length_immediate" "0,*")
9673 (set_attr "modrm" "0,1")
9674 (set_attr "mode" "DI")])
9676 (define_insn "ashrsi3_cvt"
9677 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9678 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9679 (match_operand:QI 2 "const_int_operand" "")))
9680 (clobber (reg:CC FLAGS_REG))]
9681 "INTVAL (operands[2]) == 31
9682 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9683 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9686 sar{l}\t{%2, %0|%0, %2}"
9687 [(set_attr "type" "imovx,ishift")
9688 (set_attr "prefix_0f" "0,*")
9689 (set_attr "length_immediate" "0,*")
9690 (set_attr "modrm" "0,1")
9691 (set_attr "mode" "SI")])
9693 (define_insn "*ashrsi3_cvt_zext"
9694 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9696 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9697 (match_operand:QI 2 "const_int_operand" ""))))
9698 (clobber (reg:CC FLAGS_REG))]
9699 "TARGET_64BIT && INTVAL (operands[2]) == 31
9700 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9701 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9704 sar{l}\t{%2, %k0|%k0, %2}"
9705 [(set_attr "type" "imovx,ishift")
9706 (set_attr "prefix_0f" "0,*")
9707 (set_attr "length_immediate" "0,*")
9708 (set_attr "modrm" "0,1")
9709 (set_attr "mode" "SI")])
9711 (define_expand "x86_shift<mode>_adj_3"
9712 [(use (match_operand:SWI48 0 "register_operand" ""))
9713 (use (match_operand:SWI48 1 "register_operand" ""))
9714 (use (match_operand:QI 2 "register_operand" ""))]
9717 rtx label = gen_label_rtx ();
9720 emit_insn (gen_testqi_ccz_1 (operands[2],
9721 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9723 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9724 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9725 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9726 gen_rtx_LABEL_REF (VOIDmode, label),
9728 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9729 JUMP_LABEL (tmp) = label;
9731 emit_move_insn (operands[0], operands[1]);
9732 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9733 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9735 LABEL_NUSES (label) = 1;
9740 (define_insn "*bmi2_<shift_insn><mode>3_1"
9741 [(set (match_operand:SWI48 0 "register_operand" "=r")
9742 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9743 (match_operand:SWI48 2 "register_operand" "r")))]
9745 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9746 [(set_attr "type" "ishiftx")
9747 (set_attr "mode" "<MODE>")])
9749 (define_insn "*<shift_insn><mode>3_1"
9750 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9752 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9753 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9754 (clobber (reg:CC FLAGS_REG))]
9755 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9757 switch (get_attr_type (insn))
9763 if (operands[2] == const1_rtx
9764 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9765 return "<shift>{<imodesuffix>}\t%0";
9767 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9770 [(set_attr "isa" "*,bmi2")
9771 (set_attr "type" "ishift,ishiftx")
9772 (set (attr "length_immediate")
9774 (and (match_operand 2 "const1_operand" "")
9775 (ior (match_test "TARGET_SHIFT1")
9776 (match_test "optimize_function_for_size_p (cfun)")))
9778 (const_string "*")))
9779 (set_attr "mode" "<MODE>")])
9781 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9783 [(set (match_operand:SWI48 0 "register_operand" "")
9784 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9785 (match_operand:QI 2 "register_operand" "")))
9786 (clobber (reg:CC FLAGS_REG))]
9787 "TARGET_BMI2 && reload_completed"
9789 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9790 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9792 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9793 [(set (match_operand:DI 0 "register_operand" "=r")
9795 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9796 (match_operand:SI 2 "register_operand" "r"))))]
9797 "TARGET_64BIT && TARGET_BMI2"
9798 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9799 [(set_attr "type" "ishiftx")
9800 (set_attr "mode" "SI")])
9802 (define_insn "*<shift_insn>si3_1_zext"
9803 [(set (match_operand:DI 0 "register_operand" "=r,r")
9805 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9806 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9807 (clobber (reg:CC FLAGS_REG))]
9808 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9810 switch (get_attr_type (insn))
9816 if (operands[2] == const1_rtx
9817 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9818 return "<shift>{l}\t%k0";
9820 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9823 [(set_attr "isa" "*,bmi2")
9824 (set_attr "type" "ishift,ishiftx")
9825 (set (attr "length_immediate")
9827 (and (match_operand 2 "const1_operand" "")
9828 (ior (match_test "TARGET_SHIFT1")
9829 (match_test "optimize_function_for_size_p (cfun)")))
9831 (const_string "*")))
9832 (set_attr "mode" "SI")])
9834 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9836 [(set (match_operand:DI 0 "register_operand" "")
9838 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9839 (match_operand:QI 2 "register_operand" ""))))
9840 (clobber (reg:CC FLAGS_REG))]
9841 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9843 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9844 "operands[2] = gen_lowpart (SImode, operands[2]);")
9846 (define_insn "*<shift_insn><mode>3_1"
9847 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9849 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9850 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9851 (clobber (reg:CC FLAGS_REG))]
9852 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9854 if (operands[2] == const1_rtx
9855 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9856 return "<shift>{<imodesuffix>}\t%0";
9858 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9860 [(set_attr "type" "ishift")
9861 (set (attr "length_immediate")
9863 (and (match_operand 2 "const1_operand" "")
9864 (ior (match_test "TARGET_SHIFT1")
9865 (match_test "optimize_function_for_size_p (cfun)")))
9867 (const_string "*")))
9868 (set_attr "mode" "<MODE>")])
9870 (define_insn "*<shift_insn>qi3_1_slp"
9871 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9872 (any_shiftrt:QI (match_dup 0)
9873 (match_operand:QI 1 "nonmemory_operand" "cI")))
9874 (clobber (reg:CC FLAGS_REG))]
9875 "(optimize_function_for_size_p (cfun)
9876 || !TARGET_PARTIAL_REG_STALL
9877 || (operands[1] == const1_rtx
9880 if (operands[1] == const1_rtx
9881 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9882 return "<shift>{b}\t%0";
9884 return "<shift>{b}\t{%1, %0|%0, %1}";
9886 [(set_attr "type" "ishift1")
9887 (set (attr "length_immediate")
9889 (and (match_operand 1 "const1_operand" "")
9890 (ior (match_test "TARGET_SHIFT1")
9891 (match_test "optimize_function_for_size_p (cfun)")))
9893 (const_string "*")))
9894 (set_attr "mode" "QI")])
9896 ;; This pattern can't accept a variable shift count, since shifts by
9897 ;; zero don't affect the flags. We assume that shifts by constant
9898 ;; zero are optimized away.
9899 (define_insn "*<shift_insn><mode>3_cmp"
9900 [(set (reg FLAGS_REG)
9903 (match_operand:SWI 1 "nonimmediate_operand" "0")
9904 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9906 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9907 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9908 "(optimize_function_for_size_p (cfun)
9909 || !TARGET_PARTIAL_FLAG_REG_STALL
9910 || (operands[2] == const1_rtx
9912 && ix86_match_ccmode (insn, CCGOCmode)
9913 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9915 if (operands[2] == const1_rtx
9916 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9917 return "<shift>{<imodesuffix>}\t%0";
9919 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9921 [(set_attr "type" "ishift")
9922 (set (attr "length_immediate")
9924 (and (match_operand 2 "const1_operand" "")
9925 (ior (match_test "TARGET_SHIFT1")
9926 (match_test "optimize_function_for_size_p (cfun)")))
9928 (const_string "*")))
9929 (set_attr "mode" "<MODE>")])
9931 (define_insn "*<shift_insn>si3_cmp_zext"
9932 [(set (reg FLAGS_REG)
9934 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9935 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9937 (set (match_operand:DI 0 "register_operand" "=r")
9938 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9940 && (optimize_function_for_size_p (cfun)
9941 || !TARGET_PARTIAL_FLAG_REG_STALL
9942 || (operands[2] == const1_rtx
9944 && ix86_match_ccmode (insn, CCGOCmode)
9945 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9947 if (operands[2] == const1_rtx
9948 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9949 return "<shift>{l}\t%k0";
9951 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9953 [(set_attr "type" "ishift")
9954 (set (attr "length_immediate")
9956 (and (match_operand 2 "const1_operand" "")
9957 (ior (match_test "TARGET_SHIFT1")
9958 (match_test "optimize_function_for_size_p (cfun)")))
9960 (const_string "*")))
9961 (set_attr "mode" "SI")])
9963 (define_insn "*<shift_insn><mode>3_cconly"
9964 [(set (reg FLAGS_REG)
9967 (match_operand:SWI 1 "register_operand" "0")
9968 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9970 (clobber (match_scratch:SWI 0 "=<r>"))]
9971 "(optimize_function_for_size_p (cfun)
9972 || !TARGET_PARTIAL_FLAG_REG_STALL
9973 || (operands[2] == const1_rtx
9975 && ix86_match_ccmode (insn, CCGOCmode)"
9977 if (operands[2] == const1_rtx
9978 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9979 return "<shift>{<imodesuffix>}\t%0";
9981 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9983 [(set_attr "type" "ishift")
9984 (set (attr "length_immediate")
9986 (and (match_operand 2 "const1_operand" "")
9987 (ior (match_test "TARGET_SHIFT1")
9988 (match_test "optimize_function_for_size_p (cfun)")))
9990 (const_string "*")))
9991 (set_attr "mode" "<MODE>")])
9993 ;; Rotate instructions
9995 (define_expand "<rotate_insn>ti3"
9996 [(set (match_operand:TI 0 "register_operand" "")
9997 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9998 (match_operand:QI 2 "nonmemory_operand" "")))]
10001 if (const_1_to_63_operand (operands[2], VOIDmode))
10002 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10003 (operands[0], operands[1], operands[2]));
10010 (define_expand "<rotate_insn>di3"
10011 [(set (match_operand:DI 0 "shiftdi_operand" "")
10012 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10013 (match_operand:QI 2 "nonmemory_operand" "")))]
10017 ix86_expand_binary_operator (<CODE>, DImode, operands);
10018 else if (const_1_to_31_operand (operands[2], VOIDmode))
10019 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10020 (operands[0], operands[1], operands[2]));
10027 (define_expand "<rotate_insn><mode>3"
10028 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10029 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10030 (match_operand:QI 2 "nonmemory_operand" "")))]
10032 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10034 ;; Avoid useless masking of count operand.
10035 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10036 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10038 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10041 (match_operand:SI 2 "nonimmediate_operand" "c")
10042 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10043 (clobber (reg:CC FLAGS_REG))]
10044 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10045 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10046 == GET_MODE_BITSIZE (<MODE>mode)-1"
10049 [(parallel [(set (match_dup 0)
10050 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10051 (clobber (reg:CC FLAGS_REG))])]
10053 if (can_create_pseudo_p ())
10054 operands [2] = force_reg (SImode, operands[2]);
10056 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10058 [(set_attr "type" "rotate")
10059 (set_attr "mode" "<MODE>")])
10061 ;; Implement rotation using two double-precision
10062 ;; shift instructions and a scratch register.
10064 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10065 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10066 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10067 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10068 (clobber (reg:CC FLAGS_REG))
10069 (clobber (match_scratch:DWIH 3 "=&r"))]
10073 [(set (match_dup 3) (match_dup 4))
10075 [(set (match_dup 4)
10076 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10077 (lshiftrt:DWIH (match_dup 5)
10078 (minus:QI (match_dup 6) (match_dup 2)))))
10079 (clobber (reg:CC FLAGS_REG))])
10081 [(set (match_dup 5)
10082 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10083 (lshiftrt:DWIH (match_dup 3)
10084 (minus:QI (match_dup 6) (match_dup 2)))))
10085 (clobber (reg:CC FLAGS_REG))])]
10087 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10089 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10092 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10093 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10094 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10095 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10096 (clobber (reg:CC FLAGS_REG))
10097 (clobber (match_scratch:DWIH 3 "=&r"))]
10101 [(set (match_dup 3) (match_dup 4))
10103 [(set (match_dup 4)
10104 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10105 (ashift:DWIH (match_dup 5)
10106 (minus:QI (match_dup 6) (match_dup 2)))))
10107 (clobber (reg:CC FLAGS_REG))])
10109 [(set (match_dup 5)
10110 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10111 (ashift:DWIH (match_dup 3)
10112 (minus:QI (match_dup 6) (match_dup 2)))))
10113 (clobber (reg:CC FLAGS_REG))])]
10115 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10117 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10120 (define_insn "*bmi2_rorx<mode>3_1"
10121 [(set (match_operand:SWI48 0 "register_operand" "=r")
10122 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10123 (match_operand:QI 2 "immediate_operand" "<S>")))]
10125 "rorx\t{%2, %1, %0|%0, %1, %2}"
10126 [(set_attr "type" "rotatex")
10127 (set_attr "mode" "<MODE>")])
10129 (define_insn "*<rotate_insn><mode>3_1"
10130 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10132 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10133 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10134 (clobber (reg:CC FLAGS_REG))]
10135 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10137 switch (get_attr_type (insn))
10143 if (operands[2] == const1_rtx
10144 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10145 return "<rotate>{<imodesuffix>}\t%0";
10147 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10150 [(set_attr "isa" "*,bmi2")
10151 (set_attr "type" "rotate,rotatex")
10152 (set (attr "length_immediate")
10154 (and (eq_attr "type" "rotate")
10155 (and (match_operand 2 "const1_operand" "")
10156 (ior (match_test "TARGET_SHIFT1")
10157 (match_test "optimize_function_for_size_p (cfun)"))))
10159 (const_string "*")))
10160 (set_attr "mode" "<MODE>")])
10162 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10164 [(set (match_operand:SWI48 0 "register_operand" "")
10165 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10166 (match_operand:QI 2 "immediate_operand" "")))
10167 (clobber (reg:CC FLAGS_REG))]
10168 "TARGET_BMI2 && reload_completed"
10169 [(set (match_dup 0)
10170 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10173 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10177 [(set (match_operand:SWI48 0 "register_operand" "")
10178 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10179 (match_operand:QI 2 "immediate_operand" "")))
10180 (clobber (reg:CC FLAGS_REG))]
10181 "TARGET_BMI2 && reload_completed"
10182 [(set (match_dup 0)
10183 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10185 (define_insn "*bmi2_rorxsi3_1_zext"
10186 [(set (match_operand:DI 0 "register_operand" "=r")
10188 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10189 (match_operand:QI 2 "immediate_operand" "I"))))]
10190 "TARGET_64BIT && TARGET_BMI2"
10191 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10192 [(set_attr "type" "rotatex")
10193 (set_attr "mode" "SI")])
10195 (define_insn "*<rotate_insn>si3_1_zext"
10196 [(set (match_operand:DI 0 "register_operand" "=r,r")
10198 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10199 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10200 (clobber (reg:CC FLAGS_REG))]
10201 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10203 switch (get_attr_type (insn))
10209 if (operands[2] == const1_rtx
10210 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10211 return "<rotate>{l}\t%k0";
10213 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10216 [(set_attr "isa" "*,bmi2")
10217 (set_attr "type" "rotate,rotatex")
10218 (set (attr "length_immediate")
10220 (and (eq_attr "type" "rotate")
10221 (and (match_operand 2 "const1_operand" "")
10222 (ior (match_test "TARGET_SHIFT1")
10223 (match_test "optimize_function_for_size_p (cfun)"))))
10225 (const_string "*")))
10226 (set_attr "mode" "SI")])
10228 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10230 [(set (match_operand:DI 0 "register_operand" "")
10232 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10233 (match_operand:QI 2 "immediate_operand" ""))))
10234 (clobber (reg:CC FLAGS_REG))]
10235 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10236 [(set (match_dup 0)
10237 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10240 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10244 [(set (match_operand:DI 0 "register_operand" "")
10246 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10247 (match_operand:QI 2 "immediate_operand" ""))))
10248 (clobber (reg:CC FLAGS_REG))]
10249 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10250 [(set (match_dup 0)
10251 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10253 (define_insn "*<rotate_insn><mode>3_1"
10254 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10255 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10256 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10257 (clobber (reg:CC FLAGS_REG))]
10258 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10260 if (operands[2] == const1_rtx
10261 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10262 return "<rotate>{<imodesuffix>}\t%0";
10264 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10266 [(set_attr "type" "rotate")
10267 (set (attr "length_immediate")
10269 (and (match_operand 2 "const1_operand" "")
10270 (ior (match_test "TARGET_SHIFT1")
10271 (match_test "optimize_function_for_size_p (cfun)")))
10273 (const_string "*")))
10274 (set_attr "mode" "<MODE>")])
10276 (define_insn "*<rotate_insn>qi3_1_slp"
10277 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10278 (any_rotate:QI (match_dup 0)
10279 (match_operand:QI 1 "nonmemory_operand" "cI")))
10280 (clobber (reg:CC FLAGS_REG))]
10281 "(optimize_function_for_size_p (cfun)
10282 || !TARGET_PARTIAL_REG_STALL
10283 || (operands[1] == const1_rtx
10284 && TARGET_SHIFT1))"
10286 if (operands[1] == const1_rtx
10287 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10288 return "<rotate>{b}\t%0";
10290 return "<rotate>{b}\t{%1, %0|%0, %1}";
10292 [(set_attr "type" "rotate1")
10293 (set (attr "length_immediate")
10295 (and (match_operand 1 "const1_operand" "")
10296 (ior (match_test "TARGET_SHIFT1")
10297 (match_test "optimize_function_for_size_p (cfun)")))
10299 (const_string "*")))
10300 (set_attr "mode" "QI")])
10303 [(set (match_operand:HI 0 "register_operand" "")
10304 (any_rotate:HI (match_dup 0) (const_int 8)))
10305 (clobber (reg:CC FLAGS_REG))]
10307 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10308 [(parallel [(set (strict_low_part (match_dup 0))
10309 (bswap:HI (match_dup 0)))
10310 (clobber (reg:CC FLAGS_REG))])])
10312 ;; Bit set / bit test instructions
10314 (define_expand "extv"
10315 [(set (match_operand:SI 0 "register_operand" "")
10316 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10317 (match_operand:SI 2 "const8_operand" "")
10318 (match_operand:SI 3 "const8_operand" "")))]
10321 /* Handle extractions from %ah et al. */
10322 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10325 /* From mips.md: extract_bit_field doesn't verify that our source
10326 matches the predicate, so check it again here. */
10327 if (! ext_register_operand (operands[1], VOIDmode))
10331 (define_expand "extzv"
10332 [(set (match_operand:SI 0 "register_operand" "")
10333 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10334 (match_operand:SI 2 "const8_operand" "")
10335 (match_operand:SI 3 "const8_operand" "")))]
10338 /* Handle extractions from %ah et al. */
10339 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10342 /* From mips.md: extract_bit_field doesn't verify that our source
10343 matches the predicate, so check it again here. */
10344 if (! ext_register_operand (operands[1], VOIDmode))
10348 (define_expand "insv"
10349 [(set (zero_extract (match_operand 0 "register_operand" "")
10350 (match_operand 1 "const_int_operand" "")
10351 (match_operand 2 "const_int_operand" ""))
10352 (match_operand 3 "register_operand" ""))]
10355 rtx (*gen_mov_insv_1) (rtx, rtx);
10357 if (ix86_expand_pinsr (operands))
10360 /* Handle insertions to %ah et al. */
10361 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10364 /* From mips.md: insert_bit_field doesn't verify that our source
10365 matches the predicate, so check it again here. */
10366 if (! ext_register_operand (operands[0], VOIDmode))
10369 gen_mov_insv_1 = (TARGET_64BIT
10370 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10372 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10376 ;; %%% bts, btr, btc, bt.
10377 ;; In general these instructions are *slow* when applied to memory,
10378 ;; since they enforce atomic operation. When applied to registers,
10379 ;; it depends on the cpu implementation. They're never faster than
10380 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10381 ;; no point. But in 64-bit, we can't hold the relevant immediates
10382 ;; within the instruction itself, so operating on bits in the high
10383 ;; 32-bits of a register becomes easier.
10385 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10386 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10387 ;; negdf respectively, so they can never be disabled entirely.
10389 (define_insn "*btsq"
10390 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10392 (match_operand:DI 1 "const_0_to_63_operand" ""))
10394 (clobber (reg:CC FLAGS_REG))]
10395 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10396 "bts{q}\t{%1, %0|%0, %1}"
10397 [(set_attr "type" "alu1")
10398 (set_attr "prefix_0f" "1")
10399 (set_attr "mode" "DI")])
10401 (define_insn "*btrq"
10402 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10404 (match_operand:DI 1 "const_0_to_63_operand" ""))
10406 (clobber (reg:CC FLAGS_REG))]
10407 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10408 "btr{q}\t{%1, %0|%0, %1}"
10409 [(set_attr "type" "alu1")
10410 (set_attr "prefix_0f" "1")
10411 (set_attr "mode" "DI")])
10413 (define_insn "*btcq"
10414 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10416 (match_operand:DI 1 "const_0_to_63_operand" ""))
10417 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10418 (clobber (reg:CC FLAGS_REG))]
10419 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10420 "btc{q}\t{%1, %0|%0, %1}"
10421 [(set_attr "type" "alu1")
10422 (set_attr "prefix_0f" "1")
10423 (set_attr "mode" "DI")])
10425 ;; Allow Nocona to avoid these instructions if a register is available.
10428 [(match_scratch:DI 2 "r")
10429 (parallel [(set (zero_extract:DI
10430 (match_operand:DI 0 "register_operand" "")
10432 (match_operand:DI 1 "const_0_to_63_operand" ""))
10434 (clobber (reg:CC FLAGS_REG))])]
10435 "TARGET_64BIT && !TARGET_USE_BT"
10438 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10441 if (HOST_BITS_PER_WIDE_INT >= 64)
10442 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10443 else if (i < HOST_BITS_PER_WIDE_INT)
10444 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10446 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10448 op1 = immed_double_const (lo, hi, DImode);
10451 emit_move_insn (operands[2], op1);
10455 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10460 [(match_scratch:DI 2 "r")
10461 (parallel [(set (zero_extract:DI
10462 (match_operand:DI 0 "register_operand" "")
10464 (match_operand:DI 1 "const_0_to_63_operand" ""))
10466 (clobber (reg:CC FLAGS_REG))])]
10467 "TARGET_64BIT && !TARGET_USE_BT"
10470 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10473 if (HOST_BITS_PER_WIDE_INT >= 64)
10474 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10475 else if (i < HOST_BITS_PER_WIDE_INT)
10476 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10478 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10480 op1 = immed_double_const (~lo, ~hi, DImode);
10483 emit_move_insn (operands[2], op1);
10487 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10492 [(match_scratch:DI 2 "r")
10493 (parallel [(set (zero_extract:DI
10494 (match_operand:DI 0 "register_operand" "")
10496 (match_operand:DI 1 "const_0_to_63_operand" ""))
10497 (not:DI (zero_extract:DI
10498 (match_dup 0) (const_int 1) (match_dup 1))))
10499 (clobber (reg:CC FLAGS_REG))])]
10500 "TARGET_64BIT && !TARGET_USE_BT"
10503 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10506 if (HOST_BITS_PER_WIDE_INT >= 64)
10507 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10508 else if (i < HOST_BITS_PER_WIDE_INT)
10509 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10511 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10513 op1 = immed_double_const (lo, hi, DImode);
10516 emit_move_insn (operands[2], op1);
10520 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10524 (define_insn "*bt<mode>"
10525 [(set (reg:CCC FLAGS_REG)
10527 (zero_extract:SWI48
10528 (match_operand:SWI48 0 "register_operand" "r")
10530 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10532 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10533 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10534 [(set_attr "type" "alu1")
10535 (set_attr "prefix_0f" "1")
10536 (set_attr "mode" "<MODE>")])
10538 ;; Store-flag instructions.
10540 ;; For all sCOND expanders, also expand the compare or test insn that
10541 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10543 (define_insn_and_split "*setcc_di_1"
10544 [(set (match_operand:DI 0 "register_operand" "=q")
10545 (match_operator:DI 1 "ix86_comparison_operator"
10546 [(reg FLAGS_REG) (const_int 0)]))]
10547 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10549 "&& reload_completed"
10550 [(set (match_dup 2) (match_dup 1))
10551 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10553 PUT_MODE (operands[1], QImode);
10554 operands[2] = gen_lowpart (QImode, operands[0]);
10557 (define_insn_and_split "*setcc_si_1_and"
10558 [(set (match_operand:SI 0 "register_operand" "=q")
10559 (match_operator:SI 1 "ix86_comparison_operator"
10560 [(reg FLAGS_REG) (const_int 0)]))
10561 (clobber (reg:CC FLAGS_REG))]
10562 "!TARGET_PARTIAL_REG_STALL
10563 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10565 "&& reload_completed"
10566 [(set (match_dup 2) (match_dup 1))
10567 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10568 (clobber (reg:CC FLAGS_REG))])]
10570 PUT_MODE (operands[1], QImode);
10571 operands[2] = gen_lowpart (QImode, operands[0]);
10574 (define_insn_and_split "*setcc_si_1_movzbl"
10575 [(set (match_operand:SI 0 "register_operand" "=q")
10576 (match_operator:SI 1 "ix86_comparison_operator"
10577 [(reg FLAGS_REG) (const_int 0)]))]
10578 "!TARGET_PARTIAL_REG_STALL
10579 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10581 "&& reload_completed"
10582 [(set (match_dup 2) (match_dup 1))
10583 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10585 PUT_MODE (operands[1], QImode);
10586 operands[2] = gen_lowpart (QImode, operands[0]);
10589 (define_insn "*setcc_qi"
10590 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10591 (match_operator:QI 1 "ix86_comparison_operator"
10592 [(reg FLAGS_REG) (const_int 0)]))]
10595 [(set_attr "type" "setcc")
10596 (set_attr "mode" "QI")])
10598 (define_insn "*setcc_qi_slp"
10599 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10600 (match_operator:QI 1 "ix86_comparison_operator"
10601 [(reg FLAGS_REG) (const_int 0)]))]
10604 [(set_attr "type" "setcc")
10605 (set_attr "mode" "QI")])
10607 ;; In general it is not safe to assume too much about CCmode registers,
10608 ;; so simplify-rtx stops when it sees a second one. Under certain
10609 ;; conditions this is safe on x86, so help combine not create
10616 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10617 (ne:QI (match_operator 1 "ix86_comparison_operator"
10618 [(reg FLAGS_REG) (const_int 0)])
10621 [(set (match_dup 0) (match_dup 1))]
10622 "PUT_MODE (operands[1], QImode);")
10625 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10626 (ne:QI (match_operator 1 "ix86_comparison_operator"
10627 [(reg FLAGS_REG) (const_int 0)])
10630 [(set (match_dup 0) (match_dup 1))]
10631 "PUT_MODE (operands[1], QImode);")
10634 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10635 (eq:QI (match_operator 1 "ix86_comparison_operator"
10636 [(reg FLAGS_REG) (const_int 0)])
10639 [(set (match_dup 0) (match_dup 1))]
10641 rtx new_op1 = copy_rtx (operands[1]);
10642 operands[1] = new_op1;
10643 PUT_MODE (new_op1, QImode);
10644 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10645 GET_MODE (XEXP (new_op1, 0))));
10647 /* Make sure that (a) the CCmode we have for the flags is strong
10648 enough for the reversed compare or (b) we have a valid FP compare. */
10649 if (! ix86_comparison_operator (new_op1, VOIDmode))
10654 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10655 (eq:QI (match_operator 1 "ix86_comparison_operator"
10656 [(reg FLAGS_REG) (const_int 0)])
10659 [(set (match_dup 0) (match_dup 1))]
10661 rtx new_op1 = copy_rtx (operands[1]);
10662 operands[1] = new_op1;
10663 PUT_MODE (new_op1, QImode);
10664 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10665 GET_MODE (XEXP (new_op1, 0))));
10667 /* Make sure that (a) the CCmode we have for the flags is strong
10668 enough for the reversed compare or (b) we have a valid FP compare. */
10669 if (! ix86_comparison_operator (new_op1, VOIDmode))
10673 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10674 ;; subsequent logical operations are used to imitate conditional moves.
10675 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10678 (define_insn "setcc_<mode>_sse"
10679 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10680 (match_operator:MODEF 3 "sse_comparison_operator"
10681 [(match_operand:MODEF 1 "register_operand" "0,x")
10682 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10683 "SSE_FLOAT_MODE_P (<MODE>mode)"
10685 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10686 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10687 [(set_attr "isa" "noavx,avx")
10688 (set_attr "type" "ssecmp")
10689 (set_attr "length_immediate" "1")
10690 (set_attr "prefix" "orig,vex")
10691 (set_attr "mode" "<MODE>")])
10693 ;; Basic conditional jump instructions.
10694 ;; We ignore the overflow flag for signed branch instructions.
10696 (define_insn "*jcc_1"
10698 (if_then_else (match_operator 1 "ix86_comparison_operator"
10699 [(reg FLAGS_REG) (const_int 0)])
10700 (label_ref (match_operand 0 "" ""))
10704 [(set_attr "type" "ibr")
10705 (set_attr "modrm" "0")
10706 (set (attr "length")
10707 (if_then_else (and (ge (minus (match_dup 0) (pc))
10709 (lt (minus (match_dup 0) (pc))
10714 (define_insn "*jcc_2"
10716 (if_then_else (match_operator 1 "ix86_comparison_operator"
10717 [(reg FLAGS_REG) (const_int 0)])
10719 (label_ref (match_operand 0 "" ""))))]
10722 [(set_attr "type" "ibr")
10723 (set_attr "modrm" "0")
10724 (set (attr "length")
10725 (if_then_else (and (ge (minus (match_dup 0) (pc))
10727 (lt (minus (match_dup 0) (pc))
10732 ;; In general it is not safe to assume too much about CCmode registers,
10733 ;; so simplify-rtx stops when it sees a second one. Under certain
10734 ;; conditions this is safe on x86, so help combine not create
10742 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10743 [(reg FLAGS_REG) (const_int 0)])
10745 (label_ref (match_operand 1 "" ""))
10749 (if_then_else (match_dup 0)
10750 (label_ref (match_dup 1))
10752 "PUT_MODE (operands[0], VOIDmode);")
10756 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10757 [(reg FLAGS_REG) (const_int 0)])
10759 (label_ref (match_operand 1 "" ""))
10763 (if_then_else (match_dup 0)
10764 (label_ref (match_dup 1))
10767 rtx new_op0 = copy_rtx (operands[0]);
10768 operands[0] = new_op0;
10769 PUT_MODE (new_op0, VOIDmode);
10770 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10771 GET_MODE (XEXP (new_op0, 0))));
10773 /* Make sure that (a) the CCmode we have for the flags is strong
10774 enough for the reversed compare or (b) we have a valid FP compare. */
10775 if (! ix86_comparison_operator (new_op0, VOIDmode))
10779 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10780 ;; pass generates from shift insn with QImode operand. Actually, the mode
10781 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10782 ;; appropriate modulo of the bit offset value.
10784 (define_insn_and_split "*jcc_bt<mode>"
10786 (if_then_else (match_operator 0 "bt_comparison_operator"
10787 [(zero_extract:SWI48
10788 (match_operand:SWI48 1 "register_operand" "r")
10791 (match_operand:QI 2 "register_operand" "r")))
10793 (label_ref (match_operand 3 "" ""))
10795 (clobber (reg:CC FLAGS_REG))]
10796 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10799 [(set (reg:CCC FLAGS_REG)
10801 (zero_extract:SWI48
10807 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10808 (label_ref (match_dup 3))
10811 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10813 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10816 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10817 ;; also for DImode, this is what combine produces.
10818 (define_insn_and_split "*jcc_bt<mode>_mask"
10820 (if_then_else (match_operator 0 "bt_comparison_operator"
10821 [(zero_extract:SWI48
10822 (match_operand:SWI48 1 "register_operand" "r")
10825 (match_operand:SI 2 "register_operand" "r")
10826 (match_operand:SI 3 "const_int_operand" "n")))])
10827 (label_ref (match_operand 4 "" ""))
10829 (clobber (reg:CC FLAGS_REG))]
10830 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10831 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10832 == GET_MODE_BITSIZE (<MODE>mode)-1"
10835 [(set (reg:CCC FLAGS_REG)
10837 (zero_extract:SWI48
10843 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10844 (label_ref (match_dup 4))
10847 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10849 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10852 (define_insn_and_split "*jcc_btsi_1"
10854 (if_then_else (match_operator 0 "bt_comparison_operator"
10857 (match_operand:SI 1 "register_operand" "r")
10858 (match_operand:QI 2 "register_operand" "r"))
10861 (label_ref (match_operand 3 "" ""))
10863 (clobber (reg:CC FLAGS_REG))]
10864 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10867 [(set (reg:CCC FLAGS_REG)
10875 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10876 (label_ref (match_dup 3))
10879 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10881 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10884 ;; avoid useless masking of bit offset operand
10885 (define_insn_and_split "*jcc_btsi_mask_1"
10888 (match_operator 0 "bt_comparison_operator"
10891 (match_operand:SI 1 "register_operand" "r")
10894 (match_operand:SI 2 "register_operand" "r")
10895 (match_operand:SI 3 "const_int_operand" "n")) 0))
10898 (label_ref (match_operand 4 "" ""))
10900 (clobber (reg:CC FLAGS_REG))]
10901 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10902 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10905 [(set (reg:CCC FLAGS_REG)
10913 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10914 (label_ref (match_dup 4))
10916 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10918 ;; Define combination compare-and-branch fp compare instructions to help
10921 (define_insn "*fp_jcc_1_387"
10923 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10924 [(match_operand 1 "register_operand" "f")
10925 (match_operand 2 "nonimmediate_operand" "fm")])
10926 (label_ref (match_operand 3 "" ""))
10928 (clobber (reg:CCFP FPSR_REG))
10929 (clobber (reg:CCFP FLAGS_REG))
10930 (clobber (match_scratch:HI 4 "=a"))]
10932 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10933 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10934 && SELECT_CC_MODE (GET_CODE (operands[0]),
10935 operands[1], operands[2]) == CCFPmode
10939 (define_insn "*fp_jcc_1r_387"
10941 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10942 [(match_operand 1 "register_operand" "f")
10943 (match_operand 2 "nonimmediate_operand" "fm")])
10945 (label_ref (match_operand 3 "" ""))))
10946 (clobber (reg:CCFP FPSR_REG))
10947 (clobber (reg:CCFP FLAGS_REG))
10948 (clobber (match_scratch:HI 4 "=a"))]
10950 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10951 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10952 && SELECT_CC_MODE (GET_CODE (operands[0]),
10953 operands[1], operands[2]) == CCFPmode
10957 (define_insn "*fp_jcc_2_387"
10959 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10960 [(match_operand 1 "register_operand" "f")
10961 (match_operand 2 "register_operand" "f")])
10962 (label_ref (match_operand 3 "" ""))
10964 (clobber (reg:CCFP FPSR_REG))
10965 (clobber (reg:CCFP FLAGS_REG))
10966 (clobber (match_scratch:HI 4 "=a"))]
10967 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10968 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10972 (define_insn "*fp_jcc_2r_387"
10974 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10975 [(match_operand 1 "register_operand" "f")
10976 (match_operand 2 "register_operand" "f")])
10978 (label_ref (match_operand 3 "" ""))))
10979 (clobber (reg:CCFP FPSR_REG))
10980 (clobber (reg:CCFP FLAGS_REG))
10981 (clobber (match_scratch:HI 4 "=a"))]
10982 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10983 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10987 (define_insn "*fp_jcc_3_387"
10989 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10990 [(match_operand 1 "register_operand" "f")
10991 (match_operand 2 "const0_operand" "")])
10992 (label_ref (match_operand 3 "" ""))
10994 (clobber (reg:CCFP FPSR_REG))
10995 (clobber (reg:CCFP FLAGS_REG))
10996 (clobber (match_scratch:HI 4 "=a"))]
10997 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10998 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10999 && SELECT_CC_MODE (GET_CODE (operands[0]),
11000 operands[1], operands[2]) == CCFPmode
11006 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11007 [(match_operand 1 "register_operand" "")
11008 (match_operand 2 "nonimmediate_operand" "")])
11009 (match_operand 3 "" "")
11010 (match_operand 4 "" "")))
11011 (clobber (reg:CCFP FPSR_REG))
11012 (clobber (reg:CCFP FLAGS_REG))]
11016 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11017 operands[3], operands[4], NULL_RTX, NULL_RTX);
11023 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11024 [(match_operand 1 "register_operand" "")
11025 (match_operand 2 "general_operand" "")])
11026 (match_operand 3 "" "")
11027 (match_operand 4 "" "")))
11028 (clobber (reg:CCFP FPSR_REG))
11029 (clobber (reg:CCFP FLAGS_REG))
11030 (clobber (match_scratch:HI 5 "=a"))]
11034 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11035 operands[3], operands[4], operands[5], NULL_RTX);
11039 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11040 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11041 ;; with a precedence over other operators and is always put in the first
11042 ;; place. Swap condition and operands to match ficom instruction.
11044 (define_insn "*fp_jcc_4_<mode>_387"
11047 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11048 [(match_operator 1 "float_operator"
11049 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11050 (match_operand 3 "register_operand" "f,f")])
11051 (label_ref (match_operand 4 "" ""))
11053 (clobber (reg:CCFP FPSR_REG))
11054 (clobber (reg:CCFP FLAGS_REG))
11055 (clobber (match_scratch:HI 5 "=a,a"))]
11056 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11057 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11058 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11059 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11066 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11067 [(match_operator 1 "float_operator"
11068 [(match_operand:SWI24 2 "memory_operand" "")])
11069 (match_operand 3 "register_operand" "")])
11070 (match_operand 4 "" "")
11071 (match_operand 5 "" "")))
11072 (clobber (reg:CCFP FPSR_REG))
11073 (clobber (reg:CCFP FLAGS_REG))
11074 (clobber (match_scratch:HI 6 "=a"))]
11078 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11080 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11081 operands[3], operands[7],
11082 operands[4], operands[5], operands[6], NULL_RTX);
11086 ;; %%% Kill this when reload knows how to do it.
11090 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11091 [(match_operator 1 "float_operator"
11092 [(match_operand:SWI24 2 "register_operand" "")])
11093 (match_operand 3 "register_operand" "")])
11094 (match_operand 4 "" "")
11095 (match_operand 5 "" "")))
11096 (clobber (reg:CCFP FPSR_REG))
11097 (clobber (reg:CCFP FLAGS_REG))
11098 (clobber (match_scratch:HI 6 "=a"))]
11102 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11103 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11105 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11106 operands[3], operands[7],
11107 operands[4], operands[5], operands[6], operands[2]);
11111 ;; Unconditional and other jump instructions
11113 (define_insn "jump"
11115 (label_ref (match_operand 0 "" "")))]
11118 [(set_attr "type" "ibr")
11119 (set (attr "length")
11120 (if_then_else (and (ge (minus (match_dup 0) (pc))
11122 (lt (minus (match_dup 0) (pc))
11126 (set_attr "modrm" "0")])
11128 (define_expand "indirect_jump"
11129 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11131 (define_insn "*indirect_jump"
11132 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11135 [(set_attr "type" "ibr")
11136 (set_attr "length_immediate" "0")])
11138 (define_expand "tablejump"
11139 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11140 (use (label_ref (match_operand 1 "" "")))])]
11143 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11144 relative. Convert the relative address to an absolute address. */
11148 enum rtx_code code;
11150 /* We can't use @GOTOFF for text labels on VxWorks;
11151 see gotoff_operand. */
11152 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11156 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11158 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11162 op1 = pic_offset_table_rtx;
11167 op0 = pic_offset_table_rtx;
11171 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11174 else if (TARGET_X32)
11175 operands[0] = convert_memory_address (Pmode, operands[0]);
11178 (define_insn "*tablejump_1"
11179 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11180 (use (label_ref (match_operand 1 "" "")))]
11183 [(set_attr "type" "ibr")
11184 (set_attr "length_immediate" "0")])
11186 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11189 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11190 (set (match_operand:QI 1 "register_operand" "")
11191 (match_operator:QI 2 "ix86_comparison_operator"
11192 [(reg FLAGS_REG) (const_int 0)]))
11193 (set (match_operand 3 "q_regs_operand" "")
11194 (zero_extend (match_dup 1)))]
11195 "(peep2_reg_dead_p (3, operands[1])
11196 || operands_match_p (operands[1], operands[3]))
11197 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11198 [(set (match_dup 4) (match_dup 0))
11199 (set (strict_low_part (match_dup 5))
11202 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11203 operands[5] = gen_lowpart (QImode, operands[3]);
11204 ix86_expand_clear (operands[3]);
11207 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11210 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11211 (set (match_operand:QI 1 "register_operand" "")
11212 (match_operator:QI 2 "ix86_comparison_operator"
11213 [(reg FLAGS_REG) (const_int 0)]))
11214 (parallel [(set (match_operand 3 "q_regs_operand" "")
11215 (zero_extend (match_dup 1)))
11216 (clobber (reg:CC FLAGS_REG))])]
11217 "(peep2_reg_dead_p (3, operands[1])
11218 || operands_match_p (operands[1], operands[3]))
11219 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11220 [(set (match_dup 4) (match_dup 0))
11221 (set (strict_low_part (match_dup 5))
11224 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11225 operands[5] = gen_lowpart (QImode, operands[3]);
11226 ix86_expand_clear (operands[3]);
11229 ;; Call instructions.
11231 ;; The predicates normally associated with named expanders are not properly
11232 ;; checked for calls. This is a bug in the generic code, but it isn't that
11233 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11235 ;; P6 processors will jump to the address after the decrement when %esp
11236 ;; is used as a call operand, so they will execute return address as a code.
11237 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11239 ;; Register constraint for call instruction.
11240 (define_mode_attr c [(SI "l") (DI "r")])
11242 ;; Call subroutine returning no value.
11244 (define_expand "call"
11245 [(call (match_operand:QI 0 "" "")
11246 (match_operand 1 "" ""))
11247 (use (match_operand 2 "" ""))]
11250 ix86_expand_call (NULL, operands[0], operands[1],
11251 operands[2], NULL, false);
11255 (define_expand "sibcall"
11256 [(call (match_operand:QI 0 "" "")
11257 (match_operand 1 "" ""))
11258 (use (match_operand 2 "" ""))]
11261 ix86_expand_call (NULL, operands[0], operands[1],
11262 operands[2], NULL, true);
11266 (define_insn_and_split "*call_vzeroupper"
11267 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11268 (match_operand 1 "" ""))
11269 (unspec [(match_operand 2 "const_int_operand" "")]
11270 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11271 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11273 "&& reload_completed"
11275 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11276 [(set_attr "type" "call")])
11278 (define_insn "*call"
11279 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11280 (match_operand 1 "" ""))]
11281 "!SIBLING_CALL_P (insn)"
11282 "* return ix86_output_call_insn (insn, operands[0]);"
11283 [(set_attr "type" "call")])
11285 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11286 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11287 (match_operand 1 "" ""))
11288 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11289 (clobber (reg:TI XMM6_REG))
11290 (clobber (reg:TI XMM7_REG))
11291 (clobber (reg:TI XMM8_REG))
11292 (clobber (reg:TI XMM9_REG))
11293 (clobber (reg:TI XMM10_REG))
11294 (clobber (reg:TI XMM11_REG))
11295 (clobber (reg:TI XMM12_REG))
11296 (clobber (reg:TI XMM13_REG))
11297 (clobber (reg:TI XMM14_REG))
11298 (clobber (reg:TI XMM15_REG))
11299 (clobber (reg:DI SI_REG))
11300 (clobber (reg:DI DI_REG))
11301 (unspec [(match_operand 2 "const_int_operand" "")]
11302 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11303 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11305 "&& reload_completed"
11307 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11308 [(set_attr "type" "call")])
11310 (define_insn "*call_rex64_ms_sysv"
11311 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11312 (match_operand 1 "" ""))
11313 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11314 (clobber (reg:TI XMM6_REG))
11315 (clobber (reg:TI XMM7_REG))
11316 (clobber (reg:TI XMM8_REG))
11317 (clobber (reg:TI XMM9_REG))
11318 (clobber (reg:TI XMM10_REG))
11319 (clobber (reg:TI XMM11_REG))
11320 (clobber (reg:TI XMM12_REG))
11321 (clobber (reg:TI XMM13_REG))
11322 (clobber (reg:TI XMM14_REG))
11323 (clobber (reg:TI XMM15_REG))
11324 (clobber (reg:DI SI_REG))
11325 (clobber (reg:DI DI_REG))]
11326 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11327 "* return ix86_output_call_insn (insn, operands[0]);"
11328 [(set_attr "type" "call")])
11330 (define_insn_and_split "*sibcall_vzeroupper"
11331 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11332 (match_operand 1 "" ""))
11333 (unspec [(match_operand 2 "const_int_operand" "")]
11334 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11335 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11337 "&& reload_completed"
11339 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11340 [(set_attr "type" "call")])
11342 (define_insn "*sibcall"
11343 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11344 (match_operand 1 "" ""))]
11345 "SIBLING_CALL_P (insn)"
11346 "* return ix86_output_call_insn (insn, operands[0]);"
11347 [(set_attr "type" "call")])
11349 (define_expand "call_pop"
11350 [(parallel [(call (match_operand:QI 0 "" "")
11351 (match_operand:SI 1 "" ""))
11352 (set (reg:SI SP_REG)
11353 (plus:SI (reg:SI SP_REG)
11354 (match_operand:SI 3 "" "")))])]
11357 ix86_expand_call (NULL, operands[0], operands[1],
11358 operands[2], operands[3], false);
11362 (define_insn_and_split "*call_pop_vzeroupper"
11363 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11364 (match_operand:SI 1 "" ""))
11365 (set (reg:SI SP_REG)
11366 (plus:SI (reg:SI SP_REG)
11367 (match_operand:SI 2 "immediate_operand" "i")))
11368 (unspec [(match_operand 3 "const_int_operand" "")]
11369 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11370 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11372 "&& reload_completed"
11374 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11375 [(set_attr "type" "call")])
11377 (define_insn "*call_pop"
11378 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11379 (match_operand 1 "" ""))
11380 (set (reg:SI SP_REG)
11381 (plus:SI (reg:SI SP_REG)
11382 (match_operand:SI 2 "immediate_operand" "i")))]
11383 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11384 "* return ix86_output_call_insn (insn, operands[0]);"
11385 [(set_attr "type" "call")])
11387 (define_insn_and_split "*sibcall_pop_vzeroupper"
11388 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11389 (match_operand 1 "" ""))
11390 (set (reg:SI SP_REG)
11391 (plus:SI (reg:SI SP_REG)
11392 (match_operand:SI 2 "immediate_operand" "i")))
11393 (unspec [(match_operand 3 "const_int_operand" "")]
11394 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11395 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11397 "&& reload_completed"
11399 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11400 [(set_attr "type" "call")])
11402 (define_insn "*sibcall_pop"
11403 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11404 (match_operand 1 "" ""))
11405 (set (reg:SI SP_REG)
11406 (plus:SI (reg:SI SP_REG)
11407 (match_operand:SI 2 "immediate_operand" "i")))]
11408 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11409 "* return ix86_output_call_insn (insn, operands[0]);"
11410 [(set_attr "type" "call")])
11412 ;; Call subroutine, returning value in operand 0
11414 (define_expand "call_value"
11415 [(set (match_operand 0 "" "")
11416 (call (match_operand:QI 1 "" "")
11417 (match_operand 2 "" "")))
11418 (use (match_operand 3 "" ""))]
11421 ix86_expand_call (operands[0], operands[1], operands[2],
11422 operands[3], NULL, false);
11426 (define_expand "sibcall_value"
11427 [(set (match_operand 0 "" "")
11428 (call (match_operand:QI 1 "" "")
11429 (match_operand 2 "" "")))
11430 (use (match_operand 3 "" ""))]
11433 ix86_expand_call (operands[0], operands[1], operands[2],
11434 operands[3], NULL, true);
11438 (define_insn_and_split "*call_value_vzeroupper"
11439 [(set (match_operand 0 "" "")
11440 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11441 (match_operand 2 "" "")))
11442 (unspec [(match_operand 3 "const_int_operand" "")]
11443 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11444 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11446 "&& reload_completed"
11448 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11449 [(set_attr "type" "callv")])
11451 (define_insn "*call_value"
11452 [(set (match_operand 0 "" "")
11453 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11454 (match_operand 2 "" "")))]
11455 "!SIBLING_CALL_P (insn)"
11456 "* return ix86_output_call_insn (insn, operands[1]);"
11457 [(set_attr "type" "callv")])
11459 (define_insn_and_split "*sibcall_value_vzeroupper"
11460 [(set (match_operand 0 "" "")
11461 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11462 (match_operand 2 "" "")))
11463 (unspec [(match_operand 3 "const_int_operand" "")]
11464 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11465 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11467 "&& reload_completed"
11469 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11470 [(set_attr "type" "callv")])
11472 (define_insn "*sibcall_value"
11473 [(set (match_operand 0 "" "")
11474 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11475 (match_operand 2 "" "")))]
11476 "SIBLING_CALL_P (insn)"
11477 "* return ix86_output_call_insn (insn, operands[1]);"
11478 [(set_attr "type" "callv")])
11480 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11481 [(set (match_operand 0 "" "")
11482 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11483 (match_operand 2 "" "")))
11484 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11485 (clobber (reg:TI XMM6_REG))
11486 (clobber (reg:TI XMM7_REG))
11487 (clobber (reg:TI XMM8_REG))
11488 (clobber (reg:TI XMM9_REG))
11489 (clobber (reg:TI XMM10_REG))
11490 (clobber (reg:TI XMM11_REG))
11491 (clobber (reg:TI XMM12_REG))
11492 (clobber (reg:TI XMM13_REG))
11493 (clobber (reg:TI XMM14_REG))
11494 (clobber (reg:TI XMM15_REG))
11495 (clobber (reg:DI SI_REG))
11496 (clobber (reg:DI DI_REG))
11497 (unspec [(match_operand 3 "const_int_operand" "")]
11498 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11499 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11501 "&& reload_completed"
11503 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11504 [(set_attr "type" "callv")])
11506 (define_insn "*call_value_rex64_ms_sysv"
11507 [(set (match_operand 0 "" "")
11508 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11509 (match_operand 2 "" "")))
11510 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11511 (clobber (reg:TI XMM6_REG))
11512 (clobber (reg:TI XMM7_REG))
11513 (clobber (reg:TI XMM8_REG))
11514 (clobber (reg:TI XMM9_REG))
11515 (clobber (reg:TI XMM10_REG))
11516 (clobber (reg:TI XMM11_REG))
11517 (clobber (reg:TI XMM12_REG))
11518 (clobber (reg:TI XMM13_REG))
11519 (clobber (reg:TI XMM14_REG))
11520 (clobber (reg:TI XMM15_REG))
11521 (clobber (reg:DI SI_REG))
11522 (clobber (reg:DI DI_REG))]
11523 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11524 "* return ix86_output_call_insn (insn, operands[1]);"
11525 [(set_attr "type" "callv")])
11527 (define_expand "call_value_pop"
11528 [(parallel [(set (match_operand 0 "" "")
11529 (call (match_operand:QI 1 "" "")
11530 (match_operand:SI 2 "" "")))
11531 (set (reg:SI SP_REG)
11532 (plus:SI (reg:SI SP_REG)
11533 (match_operand:SI 4 "" "")))])]
11536 ix86_expand_call (operands[0], operands[1], operands[2],
11537 operands[3], operands[4], false);
11541 (define_insn_and_split "*call_value_pop_vzeroupper"
11542 [(set (match_operand 0 "" "")
11543 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11544 (match_operand 2 "" "")))
11545 (set (reg:SI SP_REG)
11546 (plus:SI (reg:SI SP_REG)
11547 (match_operand:SI 3 "immediate_operand" "i")))
11548 (unspec [(match_operand 4 "const_int_operand" "")]
11549 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11550 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11552 "&& reload_completed"
11554 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11555 [(set_attr "type" "callv")])
11557 (define_insn "*call_value_pop"
11558 [(set (match_operand 0 "" "")
11559 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11560 (match_operand 2 "" "")))
11561 (set (reg:SI SP_REG)
11562 (plus:SI (reg:SI SP_REG)
11563 (match_operand:SI 3 "immediate_operand" "i")))]
11564 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11565 "* return ix86_output_call_insn (insn, operands[1]);"
11566 [(set_attr "type" "callv")])
11568 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11569 [(set (match_operand 0 "" "")
11570 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
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 "*sibcall_value_pop"
11585 [(set (match_operand 0 "" "")
11586 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
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 ;; Call subroutine returning any type.
11597 (define_expand "untyped_call"
11598 [(parallel [(call (match_operand 0 "" "")
11600 (match_operand 1 "" "")
11601 (match_operand 2 "" "")])]
11606 /* In order to give reg-stack an easier job in validating two
11607 coprocessor registers as containing a possible return value,
11608 simply pretend the untyped call returns a complex long double
11611 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11612 and should have the default ABI. */
11614 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11615 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11616 operands[0], const0_rtx,
11617 GEN_INT ((TARGET_64BIT
11618 ? (ix86_abi == SYSV_ABI
11619 ? X86_64_SSE_REGPARM_MAX
11620 : X86_64_MS_SSE_REGPARM_MAX)
11621 : X86_32_SSE_REGPARM_MAX)
11625 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11627 rtx set = XVECEXP (operands[2], 0, i);
11628 emit_move_insn (SET_DEST (set), SET_SRC (set));
11631 /* The optimizer does not know that the call sets the function value
11632 registers we stored in the result block. We avoid problems by
11633 claiming that all hard registers are used and clobbered at this
11635 emit_insn (gen_blockage ());
11640 ;; Prologue and epilogue instructions
11642 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11643 ;; all of memory. This blocks insns from being moved across this point.
11645 (define_insn "blockage"
11646 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11649 [(set_attr "length" "0")])
11651 ;; Do not schedule instructions accessing memory across this point.
11653 (define_expand "memory_blockage"
11654 [(set (match_dup 0)
11655 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11658 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11659 MEM_VOLATILE_P (operands[0]) = 1;
11662 (define_insn "*memory_blockage"
11663 [(set (match_operand:BLK 0 "" "")
11664 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11667 [(set_attr "length" "0")])
11669 ;; As USE insns aren't meaningful after reload, this is used instead
11670 ;; to prevent deleting instructions setting registers for PIC code
11671 (define_insn "prologue_use"
11672 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11675 [(set_attr "length" "0")])
11677 ;; Insn emitted into the body of a function to return from a function.
11678 ;; This is only done if the function's epilogue is known to be simple.
11679 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11681 (define_expand "return"
11683 "ix86_can_use_return_insn_p ()"
11685 ix86_maybe_emit_epilogue_vzeroupper ();
11686 if (crtl->args.pops_args)
11688 rtx popc = GEN_INT (crtl->args.pops_args);
11689 emit_jump_insn (gen_simple_return_pop_internal (popc));
11694 ;; We need to disable this for TARGET_SEH, as otherwise
11695 ;; shrink-wrapped prologue gets enabled too. This might exceed
11696 ;; the maximum size of prologue in unwind information.
11698 (define_expand "simple_return"
11702 ix86_maybe_emit_epilogue_vzeroupper ();
11703 if (crtl->args.pops_args)
11705 rtx popc = GEN_INT (crtl->args.pops_args);
11706 emit_jump_insn (gen_simple_return_pop_internal (popc));
11711 (define_insn "simple_return_internal"
11715 [(set_attr "length" "1")
11716 (set_attr "atom_unit" "jeu")
11717 (set_attr "length_immediate" "0")
11718 (set_attr "modrm" "0")])
11720 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11721 ;; instruction Athlon and K8 have.
11723 (define_insn "simple_return_internal_long"
11725 (unspec [(const_int 0)] UNSPEC_REP)]
11728 [(set_attr "length" "2")
11729 (set_attr "atom_unit" "jeu")
11730 (set_attr "length_immediate" "0")
11731 (set_attr "prefix_rep" "1")
11732 (set_attr "modrm" "0")])
11734 (define_insn "simple_return_pop_internal"
11736 (use (match_operand:SI 0 "const_int_operand" ""))]
11739 [(set_attr "length" "3")
11740 (set_attr "atom_unit" "jeu")
11741 (set_attr "length_immediate" "2")
11742 (set_attr "modrm" "0")])
11744 (define_insn "simple_return_indirect_internal"
11746 (use (match_operand:SI 0 "register_operand" "r"))]
11749 [(set_attr "type" "ibr")
11750 (set_attr "length_immediate" "0")])
11756 [(set_attr "length" "1")
11757 (set_attr "length_immediate" "0")
11758 (set_attr "modrm" "0")])
11760 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11761 (define_insn "nops"
11762 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11766 int num = INTVAL (operands[0]);
11768 gcc_assert (num >= 1 && num <= 8);
11771 fputs ("\tnop\n", asm_out_file);
11775 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11776 (set_attr "length_immediate" "0")
11777 (set_attr "modrm" "0")])
11779 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11780 ;; branch prediction penalty for the third jump in a 16-byte
11784 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11787 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11788 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11790 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11791 The align insn is used to avoid 3 jump instructions in the row to improve
11792 branch prediction and the benefits hardly outweigh the cost of extra 8
11793 nops on the average inserted by full alignment pseudo operation. */
11797 [(set_attr "length" "16")])
11799 (define_expand "prologue"
11802 "ix86_expand_prologue (); DONE;")
11804 (define_insn "set_got"
11805 [(set (match_operand:SI 0 "register_operand" "=r")
11806 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11807 (clobber (reg:CC FLAGS_REG))]
11809 "* return output_set_got (operands[0], NULL_RTX);"
11810 [(set_attr "type" "multi")
11811 (set_attr "length" "12")])
11813 (define_insn "set_got_labelled"
11814 [(set (match_operand:SI 0 "register_operand" "=r")
11815 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11817 (clobber (reg:CC FLAGS_REG))]
11819 "* return output_set_got (operands[0], operands[1]);"
11820 [(set_attr "type" "multi")
11821 (set_attr "length" "12")])
11823 (define_insn "set_got_rex64"
11824 [(set (match_operand:DI 0 "register_operand" "=r")
11825 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11827 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11828 [(set_attr "type" "lea")
11829 (set_attr "length_address" "4")
11830 (set_attr "mode" "DI")])
11832 (define_insn "set_rip_rex64"
11833 [(set (match_operand:DI 0 "register_operand" "=r")
11834 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11836 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11837 [(set_attr "type" "lea")
11838 (set_attr "length_address" "4")
11839 (set_attr "mode" "DI")])
11841 (define_insn "set_got_offset_rex64"
11842 [(set (match_operand:DI 0 "register_operand" "=r")
11844 [(label_ref (match_operand 1 "" ""))]
11845 UNSPEC_SET_GOT_OFFSET))]
11847 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11848 [(set_attr "type" "imov")
11849 (set_attr "length_immediate" "0")
11850 (set_attr "length_address" "8")
11851 (set_attr "mode" "DI")])
11853 (define_expand "epilogue"
11856 "ix86_expand_epilogue (1); DONE;")
11858 (define_expand "sibcall_epilogue"
11861 "ix86_expand_epilogue (0); DONE;")
11863 (define_expand "eh_return"
11864 [(use (match_operand 0 "register_operand" ""))]
11867 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11869 /* Tricky bit: we write the address of the handler to which we will
11870 be returning into someone else's stack frame, one word below the
11871 stack address we wish to restore. */
11872 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11873 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11874 tmp = gen_rtx_MEM (Pmode, tmp);
11875 emit_move_insn (tmp, ra);
11877 emit_jump_insn (gen_eh_return_internal ());
11882 (define_insn_and_split "eh_return_internal"
11886 "epilogue_completed"
11888 "ix86_expand_epilogue (2); DONE;")
11890 (define_insn "leave"
11891 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11892 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11893 (clobber (mem:BLK (scratch)))]
11896 [(set_attr "type" "leave")])
11898 (define_insn "leave_rex64"
11899 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11900 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11901 (clobber (mem:BLK (scratch)))]
11904 [(set_attr "type" "leave")])
11906 ;; Handle -fsplit-stack.
11908 (define_expand "split_stack_prologue"
11912 ix86_expand_split_stack_prologue ();
11916 ;; In order to support the call/return predictor, we use a return
11917 ;; instruction which the middle-end doesn't see.
11918 (define_insn "split_stack_return"
11919 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11920 UNSPECV_SPLIT_STACK_RETURN)]
11923 if (operands[0] == const0_rtx)
11928 [(set_attr "atom_unit" "jeu")
11929 (set_attr "modrm" "0")
11930 (set (attr "length")
11931 (if_then_else (match_operand:SI 0 "const0_operand" "")
11934 (set (attr "length_immediate")
11935 (if_then_else (match_operand:SI 0 "const0_operand" "")
11939 ;; If there are operand 0 bytes available on the stack, jump to
11942 (define_expand "split_stack_space_check"
11943 [(set (pc) (if_then_else
11944 (ltu (minus (reg SP_REG)
11945 (match_operand 0 "register_operand" ""))
11946 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11947 (label_ref (match_operand 1 "" ""))
11951 rtx reg, size, limit;
11953 reg = gen_reg_rtx (Pmode);
11954 size = force_reg (Pmode, operands[0]);
11955 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11956 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11957 UNSPEC_STACK_CHECK);
11958 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11959 ix86_expand_branch (GEU, reg, limit, operands[1]);
11964 ;; Bit manipulation instructions.
11966 (define_expand "ffs<mode>2"
11967 [(set (match_dup 2) (const_int -1))
11968 (parallel [(set (reg:CCZ FLAGS_REG)
11970 (match_operand:SWI48 1 "nonimmediate_operand" "")
11972 (set (match_operand:SWI48 0 "register_operand" "")
11973 (ctz:SWI48 (match_dup 1)))])
11974 (set (match_dup 0) (if_then_else:SWI48
11975 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11978 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11979 (clobber (reg:CC FLAGS_REG))])]
11982 if (<MODE>mode == SImode && !TARGET_CMOVE)
11984 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11987 operands[2] = gen_reg_rtx (<MODE>mode);
11990 (define_insn_and_split "ffssi2_no_cmove"
11991 [(set (match_operand:SI 0 "register_operand" "=r")
11992 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11993 (clobber (match_scratch:SI 2 "=&q"))
11994 (clobber (reg:CC FLAGS_REG))]
11997 "&& reload_completed"
11998 [(parallel [(set (reg:CCZ FLAGS_REG)
11999 (compare:CCZ (match_dup 1) (const_int 0)))
12000 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12001 (set (strict_low_part (match_dup 3))
12002 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12003 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12004 (clobber (reg:CC FLAGS_REG))])
12005 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12006 (clobber (reg:CC FLAGS_REG))])
12007 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12008 (clobber (reg:CC FLAGS_REG))])]
12010 operands[3] = gen_lowpart (QImode, operands[2]);
12011 ix86_expand_clear (operands[2]);
12014 (define_insn "*ffs<mode>_1"
12015 [(set (reg:CCZ FLAGS_REG)
12016 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12018 (set (match_operand:SWI48 0 "register_operand" "=r")
12019 (ctz:SWI48 (match_dup 1)))]
12021 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12022 [(set_attr "type" "alu1")
12023 (set_attr "prefix_0f" "1")
12024 (set_attr "mode" "<MODE>")])
12026 (define_insn "ctz<mode>2"
12027 [(set (match_operand:SWI248 0 "register_operand" "=r")
12028 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12029 (clobber (reg:CC FLAGS_REG))]
12033 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12035 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12037 [(set_attr "type" "alu1")
12038 (set_attr "prefix_0f" "1")
12039 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12040 (set_attr "mode" "<MODE>")])
12042 (define_expand "clz<mode>2"
12044 [(set (match_operand:SWI248 0 "register_operand" "")
12047 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12048 (clobber (reg:CC FLAGS_REG))])
12050 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12051 (clobber (reg:CC FLAGS_REG))])]
12056 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12059 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12062 (define_insn "clz<mode>2_lzcnt"
12063 [(set (match_operand:SWI248 0 "register_operand" "=r")
12064 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12065 (clobber (reg:CC FLAGS_REG))]
12067 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12068 [(set_attr "prefix_rep" "1")
12069 (set_attr "type" "bitmanip")
12070 (set_attr "mode" "<MODE>")])
12072 ;; BMI instructions.
12073 (define_insn "*bmi_andn_<mode>"
12074 [(set (match_operand:SWI48 0 "register_operand" "=r")
12077 (match_operand:SWI48 1 "register_operand" "r"))
12078 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12079 (clobber (reg:CC FLAGS_REG))]
12081 "andn\t{%2, %1, %0|%0, %1, %2}"
12082 [(set_attr "type" "bitmanip")
12083 (set_attr "mode" "<MODE>")])
12085 (define_insn "bmi_bextr_<mode>"
12086 [(set (match_operand:SWI48 0 "register_operand" "=r")
12087 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12088 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12090 (clobber (reg:CC FLAGS_REG))]
12092 "bextr\t{%2, %1, %0|%0, %1, %2}"
12093 [(set_attr "type" "bitmanip")
12094 (set_attr "mode" "<MODE>")])
12096 (define_insn "*bmi_blsi_<mode>"
12097 [(set (match_operand:SWI48 0 "register_operand" "=r")
12100 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12102 (clobber (reg:CC FLAGS_REG))]
12104 "blsi\t{%1, %0|%0, %1}"
12105 [(set_attr "type" "bitmanip")
12106 (set_attr "mode" "<MODE>")])
12108 (define_insn "*bmi_blsmsk_<mode>"
12109 [(set (match_operand:SWI48 0 "register_operand" "=r")
12112 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12115 (clobber (reg:CC FLAGS_REG))]
12117 "blsmsk\t{%1, %0|%0, %1}"
12118 [(set_attr "type" "bitmanip")
12119 (set_attr "mode" "<MODE>")])
12121 (define_insn "*bmi_blsr_<mode>"
12122 [(set (match_operand:SWI48 0 "register_operand" "=r")
12125 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12128 (clobber (reg:CC FLAGS_REG))]
12130 "blsr\t{%1, %0|%0, %1}"
12131 [(set_attr "type" "bitmanip")
12132 (set_attr "mode" "<MODE>")])
12134 ;; BMI2 instructions.
12135 (define_insn "bmi2_bzhi_<mode>3"
12136 [(set (match_operand:SWI48 0 "register_operand" "=r")
12137 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12138 (lshiftrt:SWI48 (const_int -1)
12139 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12140 (clobber (reg:CC FLAGS_REG))]
12142 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12143 [(set_attr "type" "bitmanip")
12144 (set_attr "prefix" "vex")
12145 (set_attr "mode" "<MODE>")])
12147 (define_insn "bmi2_pdep_<mode>3"
12148 [(set (match_operand:SWI48 0 "register_operand" "=r")
12149 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12150 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12153 "pdep\t{%2, %1, %0|%0, %1, %2}"
12154 [(set_attr "type" "bitmanip")
12155 (set_attr "prefix" "vex")
12156 (set_attr "mode" "<MODE>")])
12158 (define_insn "bmi2_pext_<mode>3"
12159 [(set (match_operand:SWI48 0 "register_operand" "=r")
12160 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12161 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12164 "pext\t{%2, %1, %0|%0, %1, %2}"
12165 [(set_attr "type" "bitmanip")
12166 (set_attr "prefix" "vex")
12167 (set_attr "mode" "<MODE>")])
12169 ;; TBM instructions.
12170 (define_insn "tbm_bextri_<mode>"
12171 [(set (match_operand:SWI48 0 "register_operand" "=r")
12172 (zero_extract:SWI48
12173 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12174 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12175 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12176 (clobber (reg:CC FLAGS_REG))]
12179 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12180 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12182 [(set_attr "type" "bitmanip")
12183 (set_attr "mode" "<MODE>")])
12185 (define_insn "*tbm_blcfill_<mode>"
12186 [(set (match_operand:SWI48 0 "register_operand" "=r")
12189 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12192 (clobber (reg:CC FLAGS_REG))]
12194 "blcfill\t{%1, %0|%0, %1}"
12195 [(set_attr "type" "bitmanip")
12196 (set_attr "mode" "<MODE>")])
12198 (define_insn "*tbm_blci_<mode>"
12199 [(set (match_operand:SWI48 0 "register_operand" "=r")
12203 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12206 (clobber (reg:CC FLAGS_REG))]
12208 "blci\t{%1, %0|%0, %1}"
12209 [(set_attr "type" "bitmanip")
12210 (set_attr "mode" "<MODE>")])
12212 (define_insn "*tbm_blcic_<mode>"
12213 [(set (match_operand:SWI48 0 "register_operand" "=r")
12216 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12220 (clobber (reg:CC FLAGS_REG))]
12222 "blcic\t{%1, %0|%0, %1}"
12223 [(set_attr "type" "bitmanip")
12224 (set_attr "mode" "<MODE>")])
12226 (define_insn "*tbm_blcmsk_<mode>"
12227 [(set (match_operand:SWI48 0 "register_operand" "=r")
12230 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12233 (clobber (reg:CC FLAGS_REG))]
12235 "blcmsk\t{%1, %0|%0, %1}"
12236 [(set_attr "type" "bitmanip")
12237 (set_attr "mode" "<MODE>")])
12239 (define_insn "*tbm_blcs_<mode>"
12240 [(set (match_operand:SWI48 0 "register_operand" "=r")
12243 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12246 (clobber (reg:CC FLAGS_REG))]
12248 "blcs\t{%1, %0|%0, %1}"
12249 [(set_attr "type" "bitmanip")
12250 (set_attr "mode" "<MODE>")])
12252 (define_insn "*tbm_blsfill_<mode>"
12253 [(set (match_operand:SWI48 0 "register_operand" "=r")
12256 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12259 (clobber (reg:CC FLAGS_REG))]
12261 "blsfill\t{%1, %0|%0, %1}"
12262 [(set_attr "type" "bitmanip")
12263 (set_attr "mode" "<MODE>")])
12265 (define_insn "*tbm_blsic_<mode>"
12266 [(set (match_operand:SWI48 0 "register_operand" "=r")
12269 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12273 (clobber (reg:CC FLAGS_REG))]
12275 "blsic\t{%1, %0|%0, %1}"
12276 [(set_attr "type" "bitmanip")
12277 (set_attr "mode" "<MODE>")])
12279 (define_insn "*tbm_t1mskc_<mode>"
12280 [(set (match_operand:SWI48 0 "register_operand" "=r")
12283 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12287 (clobber (reg:CC FLAGS_REG))]
12289 "t1mskc\t{%1, %0|%0, %1}"
12290 [(set_attr "type" "bitmanip")
12291 (set_attr "mode" "<MODE>")])
12293 (define_insn "*tbm_tzmsk_<mode>"
12294 [(set (match_operand:SWI48 0 "register_operand" "=r")
12297 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12301 (clobber (reg:CC FLAGS_REG))]
12303 "tzmsk\t{%1, %0|%0, %1}"
12304 [(set_attr "type" "bitmanip")
12305 (set_attr "mode" "<MODE>")])
12307 (define_insn "bsr_rex64"
12308 [(set (match_operand:DI 0 "register_operand" "=r")
12309 (minus:DI (const_int 63)
12310 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12311 (clobber (reg:CC FLAGS_REG))]
12313 "bsr{q}\t{%1, %0|%0, %1}"
12314 [(set_attr "type" "alu1")
12315 (set_attr "prefix_0f" "1")
12316 (set_attr "mode" "DI")])
12319 [(set (match_operand:SI 0 "register_operand" "=r")
12320 (minus:SI (const_int 31)
12321 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12322 (clobber (reg:CC FLAGS_REG))]
12324 "bsr{l}\t{%1, %0|%0, %1}"
12325 [(set_attr "type" "alu1")
12326 (set_attr "prefix_0f" "1")
12327 (set_attr "mode" "SI")])
12329 (define_insn "*bsrhi"
12330 [(set (match_operand:HI 0 "register_operand" "=r")
12331 (minus:HI (const_int 15)
12332 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12333 (clobber (reg:CC FLAGS_REG))]
12335 "bsr{w}\t{%1, %0|%0, %1}"
12336 [(set_attr "type" "alu1")
12337 (set_attr "prefix_0f" "1")
12338 (set_attr "mode" "HI")])
12340 (define_insn "popcount<mode>2"
12341 [(set (match_operand:SWI248 0 "register_operand" "=r")
12343 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12344 (clobber (reg:CC FLAGS_REG))]
12348 return "popcnt\t{%1, %0|%0, %1}";
12350 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12353 [(set_attr "prefix_rep" "1")
12354 (set_attr "type" "bitmanip")
12355 (set_attr "mode" "<MODE>")])
12357 (define_insn "*popcount<mode>2_cmp"
12358 [(set (reg FLAGS_REG)
12361 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12363 (set (match_operand:SWI248 0 "register_operand" "=r")
12364 (popcount:SWI248 (match_dup 1)))]
12365 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12368 return "popcnt\t{%1, %0|%0, %1}";
12370 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12373 [(set_attr "prefix_rep" "1")
12374 (set_attr "type" "bitmanip")
12375 (set_attr "mode" "<MODE>")])
12377 (define_insn "*popcountsi2_cmp_zext"
12378 [(set (reg FLAGS_REG)
12380 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12382 (set (match_operand:DI 0 "register_operand" "=r")
12383 (zero_extend:DI(popcount:SI (match_dup 1))))]
12384 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12387 return "popcnt\t{%1, %0|%0, %1}";
12389 return "popcnt{l}\t{%1, %0|%0, %1}";
12392 [(set_attr "prefix_rep" "1")
12393 (set_attr "type" "bitmanip")
12394 (set_attr "mode" "SI")])
12396 (define_expand "bswap<mode>2"
12397 [(set (match_operand:SWI48 0 "register_operand" "")
12398 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12401 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12403 rtx x = operands[0];
12405 emit_move_insn (x, operands[1]);
12406 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12407 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12408 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12413 (define_insn "*bswap<mode>2_movbe"
12414 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12415 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12417 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12420 movbe\t{%1, %0|%0, %1}
12421 movbe\t{%1, %0|%0, %1}"
12422 [(set_attr "type" "bitmanip,imov,imov")
12423 (set_attr "modrm" "0,1,1")
12424 (set_attr "prefix_0f" "*,1,1")
12425 (set_attr "prefix_extra" "*,1,1")
12426 (set_attr "mode" "<MODE>")])
12428 (define_insn "*bswap<mode>2_1"
12429 [(set (match_operand:SWI48 0 "register_operand" "=r")
12430 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12433 [(set_attr "type" "bitmanip")
12434 (set_attr "modrm" "0")
12435 (set_attr "mode" "<MODE>")])
12437 (define_insn "*bswaphi_lowpart_1"
12438 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12439 (bswap:HI (match_dup 0)))
12440 (clobber (reg:CC FLAGS_REG))]
12441 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12443 xchg{b}\t{%h0, %b0|%b0, %h0}
12444 rol{w}\t{$8, %0|%0, 8}"
12445 [(set_attr "length" "2,4")
12446 (set_attr "mode" "QI,HI")])
12448 (define_insn "bswaphi_lowpart"
12449 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12450 (bswap:HI (match_dup 0)))
12451 (clobber (reg:CC FLAGS_REG))]
12453 "rol{w}\t{$8, %0|%0, 8}"
12454 [(set_attr "length" "4")
12455 (set_attr "mode" "HI")])
12457 (define_expand "paritydi2"
12458 [(set (match_operand:DI 0 "register_operand" "")
12459 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12462 rtx scratch = gen_reg_rtx (QImode);
12465 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12466 NULL_RTX, operands[1]));
12468 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12469 gen_rtx_REG (CCmode, FLAGS_REG),
12471 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12474 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12477 rtx tmp = gen_reg_rtx (SImode);
12479 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12480 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12485 (define_expand "paritysi2"
12486 [(set (match_operand:SI 0 "register_operand" "")
12487 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12490 rtx scratch = gen_reg_rtx (QImode);
12493 emit_insn (gen_paritysi2_cmp (NULL_RTX, 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));
12500 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12504 (define_insn_and_split "paritydi2_cmp"
12505 [(set (reg:CC FLAGS_REG)
12506 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12508 (clobber (match_scratch:DI 0 "=r"))
12509 (clobber (match_scratch:SI 1 "=&r"))
12510 (clobber (match_scratch:HI 2 "=Q"))]
12513 "&& reload_completed"
12515 [(set (match_dup 1)
12516 (xor:SI (match_dup 1) (match_dup 4)))
12517 (clobber (reg:CC FLAGS_REG))])
12519 [(set (reg:CC FLAGS_REG)
12520 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12521 (clobber (match_dup 1))
12522 (clobber (match_dup 2))])]
12524 operands[4] = gen_lowpart (SImode, operands[3]);
12528 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12529 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12532 operands[1] = gen_highpart (SImode, operands[3]);
12535 (define_insn_and_split "paritysi2_cmp"
12536 [(set (reg:CC FLAGS_REG)
12537 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12539 (clobber (match_scratch:SI 0 "=r"))
12540 (clobber (match_scratch:HI 1 "=&Q"))]
12543 "&& reload_completed"
12545 [(set (match_dup 1)
12546 (xor:HI (match_dup 1) (match_dup 3)))
12547 (clobber (reg:CC FLAGS_REG))])
12549 [(set (reg:CC FLAGS_REG)
12550 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12551 (clobber (match_dup 1))])]
12553 operands[3] = gen_lowpart (HImode, operands[2]);
12555 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12556 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12559 (define_insn "*parityhi2_cmp"
12560 [(set (reg:CC FLAGS_REG)
12561 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12563 (clobber (match_scratch:HI 0 "=Q"))]
12565 "xor{b}\t{%h0, %b0|%b0, %h0}"
12566 [(set_attr "length" "2")
12567 (set_attr "mode" "HI")])
12570 ;; Thread-local storage patterns for ELF.
12572 ;; Note that these code sequences must appear exactly as shown
12573 ;; in order to allow linker relaxation.
12575 (define_insn "*tls_global_dynamic_32_gnu"
12576 [(set (match_operand:SI 0 "register_operand" "=a")
12578 [(match_operand:SI 1 "register_operand" "b")
12579 (match_operand:SI 2 "tls_symbolic_operand" "")
12580 (match_operand:SI 3 "constant_call_address_operand" "z")]
12582 (clobber (match_scratch:SI 4 "=d"))
12583 (clobber (match_scratch:SI 5 "=c"))
12584 (clobber (reg:CC FLAGS_REG))]
12585 "!TARGET_64BIT && TARGET_GNU_TLS"
12588 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12589 if (TARGET_SUN_TLS)
12590 #ifdef HAVE_AS_IX86_TLSGDPLT
12591 return "call\t%a2@tlsgdplt";
12593 return "call\t%p3@plt";
12595 return "call\t%P3";
12597 [(set_attr "type" "multi")
12598 (set_attr "length" "12")])
12600 (define_expand "tls_global_dynamic_32"
12602 [(set (match_operand:SI 0 "register_operand" "")
12603 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12604 (match_operand:SI 1 "tls_symbolic_operand" "")
12605 (match_operand:SI 3 "constant_call_address_operand" "")]
12607 (clobber (match_scratch:SI 4 ""))
12608 (clobber (match_scratch:SI 5 ""))
12609 (clobber (reg:CC FLAGS_REG))])])
12611 (define_insn "*tls_global_dynamic_64"
12612 [(set (match_operand:DI 0 "register_operand" "=a")
12614 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12615 (match_operand:DI 3 "" "")))
12616 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12621 fputs (ASM_BYTE "0x66\n", asm_out_file);
12623 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12624 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12625 fputs ("\trex64\n", asm_out_file);
12626 if (TARGET_SUN_TLS)
12627 return "call\t%p2@plt";
12628 return "call\t%P2";
12630 [(set_attr "type" "multi")
12631 (set (attr "length")
12632 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12634 (define_expand "tls_global_dynamic_64"
12636 [(set (match_operand:DI 0 "register_operand" "")
12638 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12640 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12643 (define_insn "*tls_local_dynamic_base_32_gnu"
12644 [(set (match_operand:SI 0 "register_operand" "=a")
12646 [(match_operand:SI 1 "register_operand" "b")
12647 (match_operand:SI 2 "constant_call_address_operand" "z")]
12648 UNSPEC_TLS_LD_BASE))
12649 (clobber (match_scratch:SI 3 "=d"))
12650 (clobber (match_scratch:SI 4 "=c"))
12651 (clobber (reg:CC FLAGS_REG))]
12652 "!TARGET_64BIT && TARGET_GNU_TLS"
12655 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12656 if (TARGET_SUN_TLS)
12657 #ifdef HAVE_AS_IX86_TLSLDMPLT
12658 return "call\t%&@tlsldmplt";
12660 return "call\t%p2@plt";
12662 return "call\t%P2";
12664 [(set_attr "type" "multi")
12665 (set_attr "length" "11")])
12667 (define_expand "tls_local_dynamic_base_32"
12669 [(set (match_operand:SI 0 "register_operand" "")
12671 [(match_operand:SI 1 "register_operand" "")
12672 (match_operand:SI 2 "constant_call_address_operand" "")]
12673 UNSPEC_TLS_LD_BASE))
12674 (clobber (match_scratch:SI 3 ""))
12675 (clobber (match_scratch:SI 4 ""))
12676 (clobber (reg:CC FLAGS_REG))])])
12678 (define_insn "*tls_local_dynamic_base_64"
12679 [(set (match_operand:DI 0 "register_operand" "=a")
12681 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12682 (match_operand:DI 2 "" "")))
12683 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12687 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12688 if (TARGET_SUN_TLS)
12689 return "call\t%p1@plt";
12690 return "call\t%P1";
12692 [(set_attr "type" "multi")
12693 (set_attr "length" "12")])
12695 (define_expand "tls_local_dynamic_base_64"
12697 [(set (match_operand:DI 0 "register_operand" "")
12699 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12701 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12703 ;; Local dynamic of a single variable is a lose. Show combine how
12704 ;; to convert that back to global dynamic.
12706 (define_insn_and_split "*tls_local_dynamic_32_once"
12707 [(set (match_operand:SI 0 "register_operand" "=a")
12709 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12710 (match_operand:SI 2 "constant_call_address_operand" "z")]
12711 UNSPEC_TLS_LD_BASE)
12712 (const:SI (unspec:SI
12713 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12715 (clobber (match_scratch:SI 4 "=d"))
12716 (clobber (match_scratch:SI 5 "=c"))
12717 (clobber (reg:CC FLAGS_REG))]
12722 [(set (match_dup 0)
12723 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12725 (clobber (match_dup 4))
12726 (clobber (match_dup 5))
12727 (clobber (reg:CC FLAGS_REG))])])
12729 ;; Segment register for the thread base ptr load
12730 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12732 ;; Load and add the thread base pointer from %<tp_seg>:0.
12733 (define_insn "*load_tp_x32"
12734 [(set (match_operand:SI 0 "register_operand" "=r")
12735 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12737 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12738 [(set_attr "type" "imov")
12739 (set_attr "modrm" "0")
12740 (set_attr "length" "7")
12741 (set_attr "memory" "load")
12742 (set_attr "imm_disp" "false")])
12744 (define_insn "*load_tp_x32_zext"
12745 [(set (match_operand:DI 0 "register_operand" "=r")
12746 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12748 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12749 [(set_attr "type" "imov")
12750 (set_attr "modrm" "0")
12751 (set_attr "length" "7")
12752 (set_attr "memory" "load")
12753 (set_attr "imm_disp" "false")])
12755 (define_insn "*load_tp_<mode>"
12756 [(set (match_operand:P 0 "register_operand" "=r")
12757 (unspec:P [(const_int 0)] UNSPEC_TP))]
12759 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12760 [(set_attr "type" "imov")
12761 (set_attr "modrm" "0")
12762 (set_attr "length" "7")
12763 (set_attr "memory" "load")
12764 (set_attr "imm_disp" "false")])
12766 (define_insn "*add_tp_x32"
12767 [(set (match_operand:SI 0 "register_operand" "=r")
12768 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12769 (match_operand:SI 1 "register_operand" "0")))
12770 (clobber (reg:CC FLAGS_REG))]
12772 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12773 [(set_attr "type" "alu")
12774 (set_attr "modrm" "0")
12775 (set_attr "length" "7")
12776 (set_attr "memory" "load")
12777 (set_attr "imm_disp" "false")])
12779 (define_insn "*add_tp_x32_zext"
12780 [(set (match_operand:DI 0 "register_operand" "=r")
12782 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12783 (match_operand:SI 1 "register_operand" "0"))))
12784 (clobber (reg:CC FLAGS_REG))]
12786 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12787 [(set_attr "type" "alu")
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_<mode>"
12794 [(set (match_operand:P 0 "register_operand" "=r")
12795 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12796 (match_operand:P 1 "register_operand" "0")))
12797 (clobber (reg:CC FLAGS_REG))]
12799 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>: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 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12807 ;; %rax as destination of the initial executable code sequence.
12808 (define_insn "tls_initial_exec_64_sun"
12809 [(set (match_operand:DI 0 "register_operand" "=a")
12811 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12812 UNSPEC_TLS_IE_SUN))
12813 (clobber (reg:CC FLAGS_REG))]
12814 "TARGET_64BIT && TARGET_SUN_TLS"
12817 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12818 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12820 [(set_attr "type" "multi")])
12822 ;; GNU2 TLS patterns can be split.
12824 (define_expand "tls_dynamic_gnu2_32"
12825 [(set (match_dup 3)
12826 (plus:SI (match_operand:SI 2 "register_operand" "")
12828 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12831 [(set (match_operand:SI 0 "register_operand" "")
12832 (unspec:SI [(match_dup 1) (match_dup 3)
12833 (match_dup 2) (reg:SI SP_REG)]
12835 (clobber (reg:CC FLAGS_REG))])]
12836 "!TARGET_64BIT && TARGET_GNU2_TLS"
12838 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12839 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12842 (define_insn "*tls_dynamic_gnu2_lea_32"
12843 [(set (match_operand:SI 0 "register_operand" "=r")
12844 (plus:SI (match_operand:SI 1 "register_operand" "b")
12846 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12847 UNSPEC_TLSDESC))))]
12848 "!TARGET_64BIT && TARGET_GNU2_TLS"
12849 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12850 [(set_attr "type" "lea")
12851 (set_attr "mode" "SI")
12852 (set_attr "length" "6")
12853 (set_attr "length_address" "4")])
12855 (define_insn "*tls_dynamic_gnu2_call_32"
12856 [(set (match_operand:SI 0 "register_operand" "=a")
12857 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12858 (match_operand:SI 2 "register_operand" "0")
12859 ;; we have to make sure %ebx still points to the GOT
12860 (match_operand:SI 3 "register_operand" "b")
12863 (clobber (reg:CC FLAGS_REG))]
12864 "!TARGET_64BIT && TARGET_GNU2_TLS"
12865 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12866 [(set_attr "type" "call")
12867 (set_attr "length" "2")
12868 (set_attr "length_address" "0")])
12870 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12871 [(set (match_operand:SI 0 "register_operand" "=&a")
12873 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12874 (match_operand:SI 4 "" "")
12875 (match_operand:SI 2 "register_operand" "b")
12878 (const:SI (unspec:SI
12879 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12881 (clobber (reg:CC FLAGS_REG))]
12882 "!TARGET_64BIT && TARGET_GNU2_TLS"
12885 [(set (match_dup 0) (match_dup 5))]
12887 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12888 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12891 (define_expand "tls_dynamic_gnu2_64"
12892 [(set (match_dup 2)
12893 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12896 [(set (match_operand:DI 0 "register_operand" "")
12897 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12899 (clobber (reg:CC FLAGS_REG))])]
12900 "TARGET_64BIT && TARGET_GNU2_TLS"
12902 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12903 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12906 (define_insn "*tls_dynamic_gnu2_lea_64"
12907 [(set (match_operand:DI 0 "register_operand" "=r")
12908 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12910 "TARGET_64BIT && TARGET_GNU2_TLS"
12911 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12912 [(set_attr "type" "lea")
12913 (set_attr "mode" "DI")
12914 (set_attr "length" "7")
12915 (set_attr "length_address" "4")])
12917 (define_insn "*tls_dynamic_gnu2_call_64"
12918 [(set (match_operand:DI 0 "register_operand" "=a")
12919 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12920 (match_operand:DI 2 "register_operand" "0")
12923 (clobber (reg:CC FLAGS_REG))]
12924 "TARGET_64BIT && TARGET_GNU2_TLS"
12925 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12926 [(set_attr "type" "call")
12927 (set_attr "length" "2")
12928 (set_attr "length_address" "0")])
12930 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12931 [(set (match_operand:DI 0 "register_operand" "=&a")
12933 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12934 (match_operand:DI 3 "" "")
12937 (const:DI (unspec:DI
12938 [(match_operand 1 "tls_symbolic_operand" "")]
12940 (clobber (reg:CC FLAGS_REG))]
12941 "TARGET_64BIT && TARGET_GNU2_TLS"
12944 [(set (match_dup 0) (match_dup 4))]
12946 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12947 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12950 ;; These patterns match the binary 387 instructions for addM3, subM3,
12951 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12952 ;; SFmode. The first is the normal insn, the second the same insn but
12953 ;; with one operand a conversion, and the third the same insn but with
12954 ;; the other operand a conversion. The conversion may be SFmode or
12955 ;; SImode if the target mode DFmode, but only SImode if the target mode
12958 ;; Gcc is slightly more smart about handling normal two address instructions
12959 ;; so use special patterns for add and mull.
12961 (define_insn "*fop_<mode>_comm_mixed"
12962 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12963 (match_operator:MODEF 3 "binary_fp_operator"
12964 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12965 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12966 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12967 && COMMUTATIVE_ARITH_P (operands[3])
12968 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12969 "* return output_387_binary_op (insn, operands);"
12970 [(set (attr "type")
12971 (if_then_else (eq_attr "alternative" "1,2")
12972 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12973 (const_string "ssemul")
12974 (const_string "sseadd"))
12975 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12976 (const_string "fmul")
12977 (const_string "fop"))))
12978 (set_attr "isa" "*,noavx,avx")
12979 (set_attr "prefix" "orig,orig,vex")
12980 (set_attr "mode" "<MODE>")])
12982 (define_insn "*fop_<mode>_comm_sse"
12983 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12984 (match_operator:MODEF 3 "binary_fp_operator"
12985 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12986 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12987 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12988 && COMMUTATIVE_ARITH_P (operands[3])
12989 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12990 "* return output_387_binary_op (insn, operands);"
12991 [(set (attr "type")
12992 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12993 (const_string "ssemul")
12994 (const_string "sseadd")))
12995 (set_attr "isa" "noavx,avx")
12996 (set_attr "prefix" "orig,vex")
12997 (set_attr "mode" "<MODE>")])
12999 (define_insn "*fop_<mode>_comm_i387"
13000 [(set (match_operand:MODEF 0 "register_operand" "=f")
13001 (match_operator:MODEF 3 "binary_fp_operator"
13002 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13003 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13004 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13005 && COMMUTATIVE_ARITH_P (operands[3])
13006 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13007 "* return output_387_binary_op (insn, operands);"
13008 [(set (attr "type")
13009 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13010 (const_string "fmul")
13011 (const_string "fop")))
13012 (set_attr "mode" "<MODE>")])
13014 (define_insn "*fop_<mode>_1_mixed"
13015 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13016 (match_operator:MODEF 3 "binary_fp_operator"
13017 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13018 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13019 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13020 && !COMMUTATIVE_ARITH_P (operands[3])
13021 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13022 "* return output_387_binary_op (insn, operands);"
13023 [(set (attr "type")
13024 (cond [(and (eq_attr "alternative" "2,3")
13025 (match_operand:MODEF 3 "mult_operator" ""))
13026 (const_string "ssemul")
13027 (and (eq_attr "alternative" "2,3")
13028 (match_operand:MODEF 3 "div_operator" ""))
13029 (const_string "ssediv")
13030 (eq_attr "alternative" "2,3")
13031 (const_string "sseadd")
13032 (match_operand:MODEF 3 "mult_operator" "")
13033 (const_string "fmul")
13034 (match_operand:MODEF 3 "div_operator" "")
13035 (const_string "fdiv")
13037 (const_string "fop")))
13038 (set_attr "isa" "*,*,noavx,avx")
13039 (set_attr "prefix" "orig,orig,orig,vex")
13040 (set_attr "mode" "<MODE>")])
13042 (define_insn "*rcpsf2_sse"
13043 [(set (match_operand:SF 0 "register_operand" "=x")
13044 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13047 "%vrcpss\t{%1, %d0|%d0, %1}"
13048 [(set_attr "type" "sse")
13049 (set_attr "atom_sse_attr" "rcp")
13050 (set_attr "prefix" "maybe_vex")
13051 (set_attr "mode" "SF")])
13053 (define_insn "*fop_<mode>_1_sse"
13054 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13055 (match_operator:MODEF 3 "binary_fp_operator"
13056 [(match_operand:MODEF 1 "register_operand" "0,x")
13057 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13058 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13059 && !COMMUTATIVE_ARITH_P (operands[3])"
13060 "* return output_387_binary_op (insn, operands);"
13061 [(set (attr "type")
13062 (cond [(match_operand:MODEF 3 "mult_operator" "")
13063 (const_string "ssemul")
13064 (match_operand:MODEF 3 "div_operator" "")
13065 (const_string "ssediv")
13067 (const_string "sseadd")))
13068 (set_attr "isa" "noavx,avx")
13069 (set_attr "prefix" "orig,vex")
13070 (set_attr "mode" "<MODE>")])
13072 ;; This pattern is not fully shadowed by the pattern above.
13073 (define_insn "*fop_<mode>_1_i387"
13074 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13075 (match_operator:MODEF 3 "binary_fp_operator"
13076 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13077 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13078 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13079 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13080 && !COMMUTATIVE_ARITH_P (operands[3])
13081 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13082 "* return output_387_binary_op (insn, operands);"
13083 [(set (attr "type")
13084 (cond [(match_operand:MODEF 3 "mult_operator" "")
13085 (const_string "fmul")
13086 (match_operand:MODEF 3 "div_operator" "")
13087 (const_string "fdiv")
13089 (const_string "fop")))
13090 (set_attr "mode" "<MODE>")])
13092 ;; ??? Add SSE splitters for these!
13093 (define_insn "*fop_<MODEF:mode>_2_i387"
13094 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13095 (match_operator:MODEF 3 "binary_fp_operator"
13097 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13098 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13099 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13100 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13101 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13102 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13103 [(set (attr "type")
13104 (cond [(match_operand:MODEF 3 "mult_operator" "")
13105 (const_string "fmul")
13106 (match_operand:MODEF 3 "div_operator" "")
13107 (const_string "fdiv")
13109 (const_string "fop")))
13110 (set_attr "fp_int_src" "true")
13111 (set_attr "mode" "<SWI24:MODE>")])
13113 (define_insn "*fop_<MODEF:mode>_3_i387"
13114 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13115 (match_operator:MODEF 3 "binary_fp_operator"
13116 [(match_operand:MODEF 1 "register_operand" "0,0")
13118 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13119 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13120 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13121 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13122 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13123 [(set (attr "type")
13124 (cond [(match_operand:MODEF 3 "mult_operator" "")
13125 (const_string "fmul")
13126 (match_operand:MODEF 3 "div_operator" "")
13127 (const_string "fdiv")
13129 (const_string "fop")))
13130 (set_attr "fp_int_src" "true")
13131 (set_attr "mode" "<MODE>")])
13133 (define_insn "*fop_df_4_i387"
13134 [(set (match_operand:DF 0 "register_operand" "=f,f")
13135 (match_operator:DF 3 "binary_fp_operator"
13137 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13138 (match_operand:DF 2 "register_operand" "0,f")]))]
13139 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13140 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13141 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13142 "* return output_387_binary_op (insn, operands);"
13143 [(set (attr "type")
13144 (cond [(match_operand:DF 3 "mult_operator" "")
13145 (const_string "fmul")
13146 (match_operand:DF 3 "div_operator" "")
13147 (const_string "fdiv")
13149 (const_string "fop")))
13150 (set_attr "mode" "SF")])
13152 (define_insn "*fop_df_5_i387"
13153 [(set (match_operand:DF 0 "register_operand" "=f,f")
13154 (match_operator:DF 3 "binary_fp_operator"
13155 [(match_operand:DF 1 "register_operand" "0,f")
13157 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13158 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13159 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13160 "* return output_387_binary_op (insn, operands);"
13161 [(set (attr "type")
13162 (cond [(match_operand:DF 3 "mult_operator" "")
13163 (const_string "fmul")
13164 (match_operand:DF 3 "div_operator" "")
13165 (const_string "fdiv")
13167 (const_string "fop")))
13168 (set_attr "mode" "SF")])
13170 (define_insn "*fop_df_6_i387"
13171 [(set (match_operand:DF 0 "register_operand" "=f,f")
13172 (match_operator:DF 3 "binary_fp_operator"
13174 (match_operand:SF 1 "register_operand" "0,f"))
13176 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13177 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13178 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13179 "* return output_387_binary_op (insn, operands);"
13180 [(set (attr "type")
13181 (cond [(match_operand:DF 3 "mult_operator" "")
13182 (const_string "fmul")
13183 (match_operand:DF 3 "div_operator" "")
13184 (const_string "fdiv")
13186 (const_string "fop")))
13187 (set_attr "mode" "SF")])
13189 (define_insn "*fop_xf_comm_i387"
13190 [(set (match_operand:XF 0 "register_operand" "=f")
13191 (match_operator:XF 3 "binary_fp_operator"
13192 [(match_operand:XF 1 "register_operand" "%0")
13193 (match_operand:XF 2 "register_operand" "f")]))]
13195 && COMMUTATIVE_ARITH_P (operands[3])"
13196 "* return output_387_binary_op (insn, operands);"
13197 [(set (attr "type")
13198 (if_then_else (match_operand:XF 3 "mult_operator" "")
13199 (const_string "fmul")
13200 (const_string "fop")))
13201 (set_attr "mode" "XF")])
13203 (define_insn "*fop_xf_1_i387"
13204 [(set (match_operand:XF 0 "register_operand" "=f,f")
13205 (match_operator:XF 3 "binary_fp_operator"
13206 [(match_operand:XF 1 "register_operand" "0,f")
13207 (match_operand:XF 2 "register_operand" "f,0")]))]
13209 && !COMMUTATIVE_ARITH_P (operands[3])"
13210 "* return output_387_binary_op (insn, operands);"
13211 [(set (attr "type")
13212 (cond [(match_operand:XF 3 "mult_operator" "")
13213 (const_string "fmul")
13214 (match_operand:XF 3 "div_operator" "")
13215 (const_string "fdiv")
13217 (const_string "fop")))
13218 (set_attr "mode" "XF")])
13220 (define_insn "*fop_xf_2_i387"
13221 [(set (match_operand:XF 0 "register_operand" "=f,f")
13222 (match_operator:XF 3 "binary_fp_operator"
13224 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13225 (match_operand:XF 2 "register_operand" "0,0")]))]
13226 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13227 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13228 [(set (attr "type")
13229 (cond [(match_operand:XF 3 "mult_operator" "")
13230 (const_string "fmul")
13231 (match_operand:XF 3 "div_operator" "")
13232 (const_string "fdiv")
13234 (const_string "fop")))
13235 (set_attr "fp_int_src" "true")
13236 (set_attr "mode" "<MODE>")])
13238 (define_insn "*fop_xf_3_i387"
13239 [(set (match_operand:XF 0 "register_operand" "=f,f")
13240 (match_operator:XF 3 "binary_fp_operator"
13241 [(match_operand:XF 1 "register_operand" "0,0")
13243 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13244 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13245 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13246 [(set (attr "type")
13247 (cond [(match_operand:XF 3 "mult_operator" "")
13248 (const_string "fmul")
13249 (match_operand:XF 3 "div_operator" "")
13250 (const_string "fdiv")
13252 (const_string "fop")))
13253 (set_attr "fp_int_src" "true")
13254 (set_attr "mode" "<MODE>")])
13256 (define_insn "*fop_xf_4_i387"
13257 [(set (match_operand:XF 0 "register_operand" "=f,f")
13258 (match_operator:XF 3 "binary_fp_operator"
13260 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13261 (match_operand:XF 2 "register_operand" "0,f")]))]
13263 "* return output_387_binary_op (insn, operands);"
13264 [(set (attr "type")
13265 (cond [(match_operand:XF 3 "mult_operator" "")
13266 (const_string "fmul")
13267 (match_operand:XF 3 "div_operator" "")
13268 (const_string "fdiv")
13270 (const_string "fop")))
13271 (set_attr "mode" "<MODE>")])
13273 (define_insn "*fop_xf_5_i387"
13274 [(set (match_operand:XF 0 "register_operand" "=f,f")
13275 (match_operator:XF 3 "binary_fp_operator"
13276 [(match_operand:XF 1 "register_operand" "0,f")
13278 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13280 "* return output_387_binary_op (insn, operands);"
13281 [(set (attr "type")
13282 (cond [(match_operand:XF 3 "mult_operator" "")
13283 (const_string "fmul")
13284 (match_operand:XF 3 "div_operator" "")
13285 (const_string "fdiv")
13287 (const_string "fop")))
13288 (set_attr "mode" "<MODE>")])
13290 (define_insn "*fop_xf_6_i387"
13291 [(set (match_operand:XF 0 "register_operand" "=f,f")
13292 (match_operator:XF 3 "binary_fp_operator"
13294 (match_operand:MODEF 1 "register_operand" "0,f"))
13296 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13298 "* return output_387_binary_op (insn, operands);"
13299 [(set (attr "type")
13300 (cond [(match_operand:XF 3 "mult_operator" "")
13301 (const_string "fmul")
13302 (match_operand:XF 3 "div_operator" "")
13303 (const_string "fdiv")
13305 (const_string "fop")))
13306 (set_attr "mode" "<MODE>")])
13309 [(set (match_operand 0 "register_operand" "")
13310 (match_operator 3 "binary_fp_operator"
13311 [(float (match_operand:SWI24 1 "register_operand" ""))
13312 (match_operand 2 "register_operand" "")]))]
13314 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13315 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13318 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13319 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13320 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13321 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13322 GET_MODE (operands[3]),
13325 ix86_free_from_memory (GET_MODE (operands[1]));
13330 [(set (match_operand 0 "register_operand" "")
13331 (match_operator 3 "binary_fp_operator"
13332 [(match_operand 1 "register_operand" "")
13333 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13335 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13336 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13339 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13340 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13341 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13342 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13343 GET_MODE (operands[3]),
13346 ix86_free_from_memory (GET_MODE (operands[2]));
13350 ;; FPU special functions.
13352 ;; This pattern implements a no-op XFmode truncation for
13353 ;; all fancy i386 XFmode math functions.
13355 (define_insn "truncxf<mode>2_i387_noop_unspec"
13356 [(set (match_operand:MODEF 0 "register_operand" "=f")
13357 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13358 UNSPEC_TRUNC_NOOP))]
13359 "TARGET_USE_FANCY_MATH_387"
13360 "* return output_387_reg_move (insn, operands);"
13361 [(set_attr "type" "fmov")
13362 (set_attr "mode" "<MODE>")])
13364 (define_insn "sqrtxf2"
13365 [(set (match_operand:XF 0 "register_operand" "=f")
13366 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13367 "TARGET_USE_FANCY_MATH_387"
13369 [(set_attr "type" "fpspc")
13370 (set_attr "mode" "XF")
13371 (set_attr "athlon_decode" "direct")
13372 (set_attr "amdfam10_decode" "direct")
13373 (set_attr "bdver1_decode" "direct")])
13375 (define_insn "sqrt_extend<mode>xf2_i387"
13376 [(set (match_operand:XF 0 "register_operand" "=f")
13379 (match_operand:MODEF 1 "register_operand" "0"))))]
13380 "TARGET_USE_FANCY_MATH_387"
13382 [(set_attr "type" "fpspc")
13383 (set_attr "mode" "XF")
13384 (set_attr "athlon_decode" "direct")
13385 (set_attr "amdfam10_decode" "direct")
13386 (set_attr "bdver1_decode" "direct")])
13388 (define_insn "*rsqrtsf2_sse"
13389 [(set (match_operand:SF 0 "register_operand" "=x")
13390 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13393 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13394 [(set_attr "type" "sse")
13395 (set_attr "atom_sse_attr" "rcp")
13396 (set_attr "prefix" "maybe_vex")
13397 (set_attr "mode" "SF")])
13399 (define_expand "rsqrtsf2"
13400 [(set (match_operand:SF 0 "register_operand" "")
13401 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13405 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13409 (define_insn "*sqrt<mode>2_sse"
13410 [(set (match_operand:MODEF 0 "register_operand" "=x")
13412 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13413 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13414 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13415 [(set_attr "type" "sse")
13416 (set_attr "atom_sse_attr" "sqrt")
13417 (set_attr "prefix" "maybe_vex")
13418 (set_attr "mode" "<MODE>")
13419 (set_attr "athlon_decode" "*")
13420 (set_attr "amdfam10_decode" "*")
13421 (set_attr "bdver1_decode" "*")])
13423 (define_expand "sqrt<mode>2"
13424 [(set (match_operand:MODEF 0 "register_operand" "")
13426 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13427 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13428 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13430 if (<MODE>mode == SFmode
13432 && TARGET_RECIP_SQRT
13433 && !optimize_function_for_size_p (cfun)
13434 && flag_finite_math_only && !flag_trapping_math
13435 && flag_unsafe_math_optimizations)
13437 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13441 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13443 rtx op0 = gen_reg_rtx (XFmode);
13444 rtx op1 = force_reg (<MODE>mode, operands[1]);
13446 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13447 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13452 (define_insn "fpremxf4_i387"
13453 [(set (match_operand:XF 0 "register_operand" "=f")
13454 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13455 (match_operand:XF 3 "register_operand" "1")]
13457 (set (match_operand:XF 1 "register_operand" "=u")
13458 (unspec:XF [(match_dup 2) (match_dup 3)]
13460 (set (reg:CCFP FPSR_REG)
13461 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13463 "TARGET_USE_FANCY_MATH_387"
13465 [(set_attr "type" "fpspc")
13466 (set_attr "mode" "XF")])
13468 (define_expand "fmodxf3"
13469 [(use (match_operand:XF 0 "register_operand" ""))
13470 (use (match_operand:XF 1 "general_operand" ""))
13471 (use (match_operand:XF 2 "general_operand" ""))]
13472 "TARGET_USE_FANCY_MATH_387"
13474 rtx label = gen_label_rtx ();
13476 rtx op1 = gen_reg_rtx (XFmode);
13477 rtx op2 = gen_reg_rtx (XFmode);
13479 emit_move_insn (op2, operands[2]);
13480 emit_move_insn (op1, operands[1]);
13482 emit_label (label);
13483 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13484 ix86_emit_fp_unordered_jump (label);
13485 LABEL_NUSES (label) = 1;
13487 emit_move_insn (operands[0], op1);
13491 (define_expand "fmod<mode>3"
13492 [(use (match_operand:MODEF 0 "register_operand" ""))
13493 (use (match_operand:MODEF 1 "general_operand" ""))
13494 (use (match_operand:MODEF 2 "general_operand" ""))]
13495 "TARGET_USE_FANCY_MATH_387"
13497 rtx (*gen_truncxf) (rtx, rtx);
13499 rtx label = gen_label_rtx ();
13501 rtx op1 = gen_reg_rtx (XFmode);
13502 rtx op2 = gen_reg_rtx (XFmode);
13504 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13505 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13507 emit_label (label);
13508 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13509 ix86_emit_fp_unordered_jump (label);
13510 LABEL_NUSES (label) = 1;
13512 /* Truncate the result properly for strict SSE math. */
13513 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13514 && !TARGET_MIX_SSE_I387)
13515 gen_truncxf = gen_truncxf<mode>2;
13517 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13519 emit_insn (gen_truncxf (operands[0], op1));
13523 (define_insn "fprem1xf4_i387"
13524 [(set (match_operand:XF 0 "register_operand" "=f")
13525 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13526 (match_operand:XF 3 "register_operand" "1")]
13528 (set (match_operand:XF 1 "register_operand" "=u")
13529 (unspec:XF [(match_dup 2) (match_dup 3)]
13531 (set (reg:CCFP FPSR_REG)
13532 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13534 "TARGET_USE_FANCY_MATH_387"
13536 [(set_attr "type" "fpspc")
13537 (set_attr "mode" "XF")])
13539 (define_expand "remainderxf3"
13540 [(use (match_operand:XF 0 "register_operand" ""))
13541 (use (match_operand:XF 1 "general_operand" ""))
13542 (use (match_operand:XF 2 "general_operand" ""))]
13543 "TARGET_USE_FANCY_MATH_387"
13545 rtx label = gen_label_rtx ();
13547 rtx op1 = gen_reg_rtx (XFmode);
13548 rtx op2 = gen_reg_rtx (XFmode);
13550 emit_move_insn (op2, operands[2]);
13551 emit_move_insn (op1, operands[1]);
13553 emit_label (label);
13554 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13555 ix86_emit_fp_unordered_jump (label);
13556 LABEL_NUSES (label) = 1;
13558 emit_move_insn (operands[0], op1);
13562 (define_expand "remainder<mode>3"
13563 [(use (match_operand:MODEF 0 "register_operand" ""))
13564 (use (match_operand:MODEF 1 "general_operand" ""))
13565 (use (match_operand:MODEF 2 "general_operand" ""))]
13566 "TARGET_USE_FANCY_MATH_387"
13568 rtx (*gen_truncxf) (rtx, rtx);
13570 rtx label = gen_label_rtx ();
13572 rtx op1 = gen_reg_rtx (XFmode);
13573 rtx op2 = gen_reg_rtx (XFmode);
13575 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13576 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13578 emit_label (label);
13580 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13581 ix86_emit_fp_unordered_jump (label);
13582 LABEL_NUSES (label) = 1;
13584 /* Truncate the result properly for strict SSE math. */
13585 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13586 && !TARGET_MIX_SSE_I387)
13587 gen_truncxf = gen_truncxf<mode>2;
13589 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13591 emit_insn (gen_truncxf (operands[0], op1));
13595 (define_insn "*sinxf2_i387"
13596 [(set (match_operand:XF 0 "register_operand" "=f")
13597 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13598 "TARGET_USE_FANCY_MATH_387
13599 && flag_unsafe_math_optimizations"
13601 [(set_attr "type" "fpspc")
13602 (set_attr "mode" "XF")])
13604 (define_insn "*sin_extend<mode>xf2_i387"
13605 [(set (match_operand:XF 0 "register_operand" "=f")
13606 (unspec:XF [(float_extend:XF
13607 (match_operand:MODEF 1 "register_operand" "0"))]
13609 "TARGET_USE_FANCY_MATH_387
13610 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13611 || TARGET_MIX_SSE_I387)
13612 && flag_unsafe_math_optimizations"
13614 [(set_attr "type" "fpspc")
13615 (set_attr "mode" "XF")])
13617 (define_insn "*cosxf2_i387"
13618 [(set (match_operand:XF 0 "register_operand" "=f")
13619 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13620 "TARGET_USE_FANCY_MATH_387
13621 && flag_unsafe_math_optimizations"
13623 [(set_attr "type" "fpspc")
13624 (set_attr "mode" "XF")])
13626 (define_insn "*cos_extend<mode>xf2_i387"
13627 [(set (match_operand:XF 0 "register_operand" "=f")
13628 (unspec:XF [(float_extend:XF
13629 (match_operand:MODEF 1 "register_operand" "0"))]
13631 "TARGET_USE_FANCY_MATH_387
13632 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13633 || TARGET_MIX_SSE_I387)
13634 && flag_unsafe_math_optimizations"
13636 [(set_attr "type" "fpspc")
13637 (set_attr "mode" "XF")])
13639 ;; When sincos pattern is defined, sin and cos builtin functions will be
13640 ;; expanded to sincos pattern with one of its outputs left unused.
13641 ;; CSE pass will figure out if two sincos patterns can be combined,
13642 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13643 ;; depending on the unused output.
13645 (define_insn "sincosxf3"
13646 [(set (match_operand:XF 0 "register_operand" "=f")
13647 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13648 UNSPEC_SINCOS_COS))
13649 (set (match_operand:XF 1 "register_operand" "=u")
13650 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13651 "TARGET_USE_FANCY_MATH_387
13652 && flag_unsafe_math_optimizations"
13654 [(set_attr "type" "fpspc")
13655 (set_attr "mode" "XF")])
13658 [(set (match_operand:XF 0 "register_operand" "")
13659 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13660 UNSPEC_SINCOS_COS))
13661 (set (match_operand:XF 1 "register_operand" "")
13662 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13663 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13664 && can_create_pseudo_p ()"
13665 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13668 [(set (match_operand:XF 0 "register_operand" "")
13669 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13670 UNSPEC_SINCOS_COS))
13671 (set (match_operand:XF 1 "register_operand" "")
13672 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13673 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13674 && can_create_pseudo_p ()"
13675 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13677 (define_insn "sincos_extend<mode>xf3_i387"
13678 [(set (match_operand:XF 0 "register_operand" "=f")
13679 (unspec:XF [(float_extend:XF
13680 (match_operand:MODEF 2 "register_operand" "0"))]
13681 UNSPEC_SINCOS_COS))
13682 (set (match_operand:XF 1 "register_operand" "=u")
13683 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13684 "TARGET_USE_FANCY_MATH_387
13685 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13686 || TARGET_MIX_SSE_I387)
13687 && flag_unsafe_math_optimizations"
13689 [(set_attr "type" "fpspc")
13690 (set_attr "mode" "XF")])
13693 [(set (match_operand:XF 0 "register_operand" "")
13694 (unspec:XF [(float_extend:XF
13695 (match_operand:MODEF 2 "register_operand" ""))]
13696 UNSPEC_SINCOS_COS))
13697 (set (match_operand:XF 1 "register_operand" "")
13698 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13699 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13700 && can_create_pseudo_p ()"
13701 [(set (match_dup 1)
13702 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13705 [(set (match_operand:XF 0 "register_operand" "")
13706 (unspec:XF [(float_extend:XF
13707 (match_operand:MODEF 2 "register_operand" ""))]
13708 UNSPEC_SINCOS_COS))
13709 (set (match_operand:XF 1 "register_operand" "")
13710 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13711 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13712 && can_create_pseudo_p ()"
13713 [(set (match_dup 0)
13714 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13716 (define_expand "sincos<mode>3"
13717 [(use (match_operand:MODEF 0 "register_operand" ""))
13718 (use (match_operand:MODEF 1 "register_operand" ""))
13719 (use (match_operand:MODEF 2 "register_operand" ""))]
13720 "TARGET_USE_FANCY_MATH_387
13721 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13722 || TARGET_MIX_SSE_I387)
13723 && flag_unsafe_math_optimizations"
13725 rtx op0 = gen_reg_rtx (XFmode);
13726 rtx op1 = gen_reg_rtx (XFmode);
13728 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13729 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13730 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13734 (define_insn "fptanxf4_i387"
13735 [(set (match_operand:XF 0 "register_operand" "=f")
13736 (match_operand:XF 3 "const_double_operand" "F"))
13737 (set (match_operand:XF 1 "register_operand" "=u")
13738 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13740 "TARGET_USE_FANCY_MATH_387
13741 && flag_unsafe_math_optimizations
13742 && standard_80387_constant_p (operands[3]) == 2"
13744 [(set_attr "type" "fpspc")
13745 (set_attr "mode" "XF")])
13747 (define_insn "fptan_extend<mode>xf4_i387"
13748 [(set (match_operand:MODEF 0 "register_operand" "=f")
13749 (match_operand:MODEF 3 "const_double_operand" "F"))
13750 (set (match_operand:XF 1 "register_operand" "=u")
13751 (unspec:XF [(float_extend:XF
13752 (match_operand:MODEF 2 "register_operand" "0"))]
13754 "TARGET_USE_FANCY_MATH_387
13755 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13756 || TARGET_MIX_SSE_I387)
13757 && flag_unsafe_math_optimizations
13758 && standard_80387_constant_p (operands[3]) == 2"
13760 [(set_attr "type" "fpspc")
13761 (set_attr "mode" "XF")])
13763 (define_expand "tanxf2"
13764 [(use (match_operand:XF 0 "register_operand" ""))
13765 (use (match_operand:XF 1 "register_operand" ""))]
13766 "TARGET_USE_FANCY_MATH_387
13767 && flag_unsafe_math_optimizations"
13769 rtx one = gen_reg_rtx (XFmode);
13770 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13772 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13776 (define_expand "tan<mode>2"
13777 [(use (match_operand:MODEF 0 "register_operand" ""))
13778 (use (match_operand:MODEF 1 "register_operand" ""))]
13779 "TARGET_USE_FANCY_MATH_387
13780 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13781 || TARGET_MIX_SSE_I387)
13782 && flag_unsafe_math_optimizations"
13784 rtx op0 = gen_reg_rtx (XFmode);
13786 rtx one = gen_reg_rtx (<MODE>mode);
13787 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13789 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13790 operands[1], op2));
13791 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13795 (define_insn "*fpatanxf3_i387"
13796 [(set (match_operand:XF 0 "register_operand" "=f")
13797 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13798 (match_operand:XF 2 "register_operand" "u")]
13800 (clobber (match_scratch:XF 3 "=2"))]
13801 "TARGET_USE_FANCY_MATH_387
13802 && flag_unsafe_math_optimizations"
13804 [(set_attr "type" "fpspc")
13805 (set_attr "mode" "XF")])
13807 (define_insn "fpatan_extend<mode>xf3_i387"
13808 [(set (match_operand:XF 0 "register_operand" "=f")
13809 (unspec:XF [(float_extend:XF
13810 (match_operand:MODEF 1 "register_operand" "0"))
13812 (match_operand:MODEF 2 "register_operand" "u"))]
13814 (clobber (match_scratch:XF 3 "=2"))]
13815 "TARGET_USE_FANCY_MATH_387
13816 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13817 || TARGET_MIX_SSE_I387)
13818 && flag_unsafe_math_optimizations"
13820 [(set_attr "type" "fpspc")
13821 (set_attr "mode" "XF")])
13823 (define_expand "atan2xf3"
13824 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13825 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13826 (match_operand:XF 1 "register_operand" "")]
13828 (clobber (match_scratch:XF 3 ""))])]
13829 "TARGET_USE_FANCY_MATH_387
13830 && flag_unsafe_math_optimizations")
13832 (define_expand "atan2<mode>3"
13833 [(use (match_operand:MODEF 0 "register_operand" ""))
13834 (use (match_operand:MODEF 1 "register_operand" ""))
13835 (use (match_operand:MODEF 2 "register_operand" ""))]
13836 "TARGET_USE_FANCY_MATH_387
13837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13838 || TARGET_MIX_SSE_I387)
13839 && flag_unsafe_math_optimizations"
13841 rtx op0 = gen_reg_rtx (XFmode);
13843 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13844 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13848 (define_expand "atanxf2"
13849 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13850 (unspec:XF [(match_dup 2)
13851 (match_operand:XF 1 "register_operand" "")]
13853 (clobber (match_scratch:XF 3 ""))])]
13854 "TARGET_USE_FANCY_MATH_387
13855 && flag_unsafe_math_optimizations"
13857 operands[2] = gen_reg_rtx (XFmode);
13858 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13861 (define_expand "atan<mode>2"
13862 [(use (match_operand:MODEF 0 "register_operand" ""))
13863 (use (match_operand:MODEF 1 "register_operand" ""))]
13864 "TARGET_USE_FANCY_MATH_387
13865 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13866 || TARGET_MIX_SSE_I387)
13867 && flag_unsafe_math_optimizations"
13869 rtx op0 = gen_reg_rtx (XFmode);
13871 rtx op2 = gen_reg_rtx (<MODE>mode);
13872 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13874 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13875 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13879 (define_expand "asinxf2"
13880 [(set (match_dup 2)
13881 (mult:XF (match_operand:XF 1 "register_operand" "")
13883 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13884 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13885 (parallel [(set (match_operand:XF 0 "register_operand" "")
13886 (unspec:XF [(match_dup 5) (match_dup 1)]
13888 (clobber (match_scratch:XF 6 ""))])]
13889 "TARGET_USE_FANCY_MATH_387
13890 && flag_unsafe_math_optimizations"
13894 if (optimize_insn_for_size_p ())
13897 for (i = 2; i < 6; i++)
13898 operands[i] = gen_reg_rtx (XFmode);
13900 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13903 (define_expand "asin<mode>2"
13904 [(use (match_operand:MODEF 0 "register_operand" ""))
13905 (use (match_operand:MODEF 1 "general_operand" ""))]
13906 "TARGET_USE_FANCY_MATH_387
13907 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13908 || TARGET_MIX_SSE_I387)
13909 && flag_unsafe_math_optimizations"
13911 rtx op0 = gen_reg_rtx (XFmode);
13912 rtx op1 = gen_reg_rtx (XFmode);
13914 if (optimize_insn_for_size_p ())
13917 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13918 emit_insn (gen_asinxf2 (op0, op1));
13919 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13923 (define_expand "acosxf2"
13924 [(set (match_dup 2)
13925 (mult:XF (match_operand:XF 1 "register_operand" "")
13927 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13928 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13929 (parallel [(set (match_operand:XF 0 "register_operand" "")
13930 (unspec:XF [(match_dup 1) (match_dup 5)]
13932 (clobber (match_scratch:XF 6 ""))])]
13933 "TARGET_USE_FANCY_MATH_387
13934 && flag_unsafe_math_optimizations"
13938 if (optimize_insn_for_size_p ())
13941 for (i = 2; i < 6; i++)
13942 operands[i] = gen_reg_rtx (XFmode);
13944 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13947 (define_expand "acos<mode>2"
13948 [(use (match_operand:MODEF 0 "register_operand" ""))
13949 (use (match_operand:MODEF 1 "general_operand" ""))]
13950 "TARGET_USE_FANCY_MATH_387
13951 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13952 || TARGET_MIX_SSE_I387)
13953 && flag_unsafe_math_optimizations"
13955 rtx op0 = gen_reg_rtx (XFmode);
13956 rtx op1 = gen_reg_rtx (XFmode);
13958 if (optimize_insn_for_size_p ())
13961 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13962 emit_insn (gen_acosxf2 (op0, op1));
13963 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13967 (define_insn "fyl2xxf3_i387"
13968 [(set (match_operand:XF 0 "register_operand" "=f")
13969 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13970 (match_operand:XF 2 "register_operand" "u")]
13972 (clobber (match_scratch:XF 3 "=2"))]
13973 "TARGET_USE_FANCY_MATH_387
13974 && flag_unsafe_math_optimizations"
13976 [(set_attr "type" "fpspc")
13977 (set_attr "mode" "XF")])
13979 (define_insn "fyl2x_extend<mode>xf3_i387"
13980 [(set (match_operand:XF 0 "register_operand" "=f")
13981 (unspec:XF [(float_extend:XF
13982 (match_operand:MODEF 1 "register_operand" "0"))
13983 (match_operand:XF 2 "register_operand" "u")]
13985 (clobber (match_scratch:XF 3 "=2"))]
13986 "TARGET_USE_FANCY_MATH_387
13987 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13988 || TARGET_MIX_SSE_I387)
13989 && flag_unsafe_math_optimizations"
13991 [(set_attr "type" "fpspc")
13992 (set_attr "mode" "XF")])
13994 (define_expand "logxf2"
13995 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13996 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13997 (match_dup 2)] UNSPEC_FYL2X))
13998 (clobber (match_scratch:XF 3 ""))])]
13999 "TARGET_USE_FANCY_MATH_387
14000 && flag_unsafe_math_optimizations"
14002 operands[2] = gen_reg_rtx (XFmode);
14003 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14006 (define_expand "log<mode>2"
14007 [(use (match_operand:MODEF 0 "register_operand" ""))
14008 (use (match_operand:MODEF 1 "register_operand" ""))]
14009 "TARGET_USE_FANCY_MATH_387
14010 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14011 || TARGET_MIX_SSE_I387)
14012 && flag_unsafe_math_optimizations"
14014 rtx op0 = gen_reg_rtx (XFmode);
14016 rtx op2 = gen_reg_rtx (XFmode);
14017 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14019 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14020 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14024 (define_expand "log10xf2"
14025 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14026 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14027 (match_dup 2)] UNSPEC_FYL2X))
14028 (clobber (match_scratch:XF 3 ""))])]
14029 "TARGET_USE_FANCY_MATH_387
14030 && flag_unsafe_math_optimizations"
14032 operands[2] = gen_reg_rtx (XFmode);
14033 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14036 (define_expand "log10<mode>2"
14037 [(use (match_operand:MODEF 0 "register_operand" ""))
14038 (use (match_operand:MODEF 1 "register_operand" ""))]
14039 "TARGET_USE_FANCY_MATH_387
14040 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14041 || TARGET_MIX_SSE_I387)
14042 && flag_unsafe_math_optimizations"
14044 rtx op0 = gen_reg_rtx (XFmode);
14046 rtx op2 = gen_reg_rtx (XFmode);
14047 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14049 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14050 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14054 (define_expand "log2xf2"
14055 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14056 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14057 (match_dup 2)] UNSPEC_FYL2X))
14058 (clobber (match_scratch:XF 3 ""))])]
14059 "TARGET_USE_FANCY_MATH_387
14060 && flag_unsafe_math_optimizations"
14062 operands[2] = gen_reg_rtx (XFmode);
14063 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14066 (define_expand "log2<mode>2"
14067 [(use (match_operand:MODEF 0 "register_operand" ""))
14068 (use (match_operand:MODEF 1 "register_operand" ""))]
14069 "TARGET_USE_FANCY_MATH_387
14070 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14071 || TARGET_MIX_SSE_I387)
14072 && flag_unsafe_math_optimizations"
14074 rtx op0 = gen_reg_rtx (XFmode);
14076 rtx op2 = gen_reg_rtx (XFmode);
14077 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14079 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14080 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14084 (define_insn "fyl2xp1xf3_i387"
14085 [(set (match_operand:XF 0 "register_operand" "=f")
14086 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14087 (match_operand:XF 2 "register_operand" "u")]
14089 (clobber (match_scratch:XF 3 "=2"))]
14090 "TARGET_USE_FANCY_MATH_387
14091 && flag_unsafe_math_optimizations"
14093 [(set_attr "type" "fpspc")
14094 (set_attr "mode" "XF")])
14096 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14097 [(set (match_operand:XF 0 "register_operand" "=f")
14098 (unspec:XF [(float_extend:XF
14099 (match_operand:MODEF 1 "register_operand" "0"))
14100 (match_operand:XF 2 "register_operand" "u")]
14102 (clobber (match_scratch:XF 3 "=2"))]
14103 "TARGET_USE_FANCY_MATH_387
14104 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14105 || TARGET_MIX_SSE_I387)
14106 && flag_unsafe_math_optimizations"
14108 [(set_attr "type" "fpspc")
14109 (set_attr "mode" "XF")])
14111 (define_expand "log1pxf2"
14112 [(use (match_operand:XF 0 "register_operand" ""))
14113 (use (match_operand:XF 1 "register_operand" ""))]
14114 "TARGET_USE_FANCY_MATH_387
14115 && flag_unsafe_math_optimizations"
14117 if (optimize_insn_for_size_p ())
14120 ix86_emit_i387_log1p (operands[0], operands[1]);
14124 (define_expand "log1p<mode>2"
14125 [(use (match_operand:MODEF 0 "register_operand" ""))
14126 (use (match_operand:MODEF 1 "register_operand" ""))]
14127 "TARGET_USE_FANCY_MATH_387
14128 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14129 || TARGET_MIX_SSE_I387)
14130 && flag_unsafe_math_optimizations"
14134 if (optimize_insn_for_size_p ())
14137 op0 = gen_reg_rtx (XFmode);
14139 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14141 ix86_emit_i387_log1p (op0, operands[1]);
14142 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14146 (define_insn "fxtractxf3_i387"
14147 [(set (match_operand:XF 0 "register_operand" "=f")
14148 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14149 UNSPEC_XTRACT_FRACT))
14150 (set (match_operand:XF 1 "register_operand" "=u")
14151 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14152 "TARGET_USE_FANCY_MATH_387
14153 && flag_unsafe_math_optimizations"
14155 [(set_attr "type" "fpspc")
14156 (set_attr "mode" "XF")])
14158 (define_insn "fxtract_extend<mode>xf3_i387"
14159 [(set (match_operand:XF 0 "register_operand" "=f")
14160 (unspec:XF [(float_extend:XF
14161 (match_operand:MODEF 2 "register_operand" "0"))]
14162 UNSPEC_XTRACT_FRACT))
14163 (set (match_operand:XF 1 "register_operand" "=u")
14164 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14165 "TARGET_USE_FANCY_MATH_387
14166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14167 || TARGET_MIX_SSE_I387)
14168 && flag_unsafe_math_optimizations"
14170 [(set_attr "type" "fpspc")
14171 (set_attr "mode" "XF")])
14173 (define_expand "logbxf2"
14174 [(parallel [(set (match_dup 2)
14175 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14176 UNSPEC_XTRACT_FRACT))
14177 (set (match_operand:XF 0 "register_operand" "")
14178 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14179 "TARGET_USE_FANCY_MATH_387
14180 && flag_unsafe_math_optimizations"
14181 "operands[2] = gen_reg_rtx (XFmode);")
14183 (define_expand "logb<mode>2"
14184 [(use (match_operand:MODEF 0 "register_operand" ""))
14185 (use (match_operand:MODEF 1 "register_operand" ""))]
14186 "TARGET_USE_FANCY_MATH_387
14187 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14188 || TARGET_MIX_SSE_I387)
14189 && flag_unsafe_math_optimizations"
14191 rtx op0 = gen_reg_rtx (XFmode);
14192 rtx op1 = gen_reg_rtx (XFmode);
14194 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14195 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14199 (define_expand "ilogbxf2"
14200 [(use (match_operand:SI 0 "register_operand" ""))
14201 (use (match_operand:XF 1 "register_operand" ""))]
14202 "TARGET_USE_FANCY_MATH_387
14203 && flag_unsafe_math_optimizations"
14207 if (optimize_insn_for_size_p ())
14210 op0 = gen_reg_rtx (XFmode);
14211 op1 = gen_reg_rtx (XFmode);
14213 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14214 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14218 (define_expand "ilogb<mode>2"
14219 [(use (match_operand:SI 0 "register_operand" ""))
14220 (use (match_operand:MODEF 1 "register_operand" ""))]
14221 "TARGET_USE_FANCY_MATH_387
14222 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14223 || TARGET_MIX_SSE_I387)
14224 && flag_unsafe_math_optimizations"
14228 if (optimize_insn_for_size_p ())
14231 op0 = gen_reg_rtx (XFmode);
14232 op1 = gen_reg_rtx (XFmode);
14234 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14235 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14239 (define_insn "*f2xm1xf2_i387"
14240 [(set (match_operand:XF 0 "register_operand" "=f")
14241 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14243 "TARGET_USE_FANCY_MATH_387
14244 && flag_unsafe_math_optimizations"
14246 [(set_attr "type" "fpspc")
14247 (set_attr "mode" "XF")])
14249 (define_insn "*fscalexf4_i387"
14250 [(set (match_operand:XF 0 "register_operand" "=f")
14251 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14252 (match_operand:XF 3 "register_operand" "1")]
14253 UNSPEC_FSCALE_FRACT))
14254 (set (match_operand:XF 1 "register_operand" "=u")
14255 (unspec:XF [(match_dup 2) (match_dup 3)]
14256 UNSPEC_FSCALE_EXP))]
14257 "TARGET_USE_FANCY_MATH_387
14258 && flag_unsafe_math_optimizations"
14260 [(set_attr "type" "fpspc")
14261 (set_attr "mode" "XF")])
14263 (define_expand "expNcorexf3"
14264 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14265 (match_operand:XF 2 "register_operand" "")))
14266 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14267 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14268 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14269 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14270 (parallel [(set (match_operand:XF 0 "register_operand" "")
14271 (unspec:XF [(match_dup 8) (match_dup 4)]
14272 UNSPEC_FSCALE_FRACT))
14274 (unspec:XF [(match_dup 8) (match_dup 4)]
14275 UNSPEC_FSCALE_EXP))])]
14276 "TARGET_USE_FANCY_MATH_387
14277 && flag_unsafe_math_optimizations"
14281 if (optimize_insn_for_size_p ())
14284 for (i = 3; i < 10; i++)
14285 operands[i] = gen_reg_rtx (XFmode);
14287 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14290 (define_expand "expxf2"
14291 [(use (match_operand:XF 0 "register_operand" ""))
14292 (use (match_operand:XF 1 "register_operand" ""))]
14293 "TARGET_USE_FANCY_MATH_387
14294 && flag_unsafe_math_optimizations"
14298 if (optimize_insn_for_size_p ())
14301 op2 = gen_reg_rtx (XFmode);
14302 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14304 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14308 (define_expand "exp<mode>2"
14309 [(use (match_operand:MODEF 0 "register_operand" ""))
14310 (use (match_operand:MODEF 1 "general_operand" ""))]
14311 "TARGET_USE_FANCY_MATH_387
14312 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14313 || TARGET_MIX_SSE_I387)
14314 && flag_unsafe_math_optimizations"
14318 if (optimize_insn_for_size_p ())
14321 op0 = gen_reg_rtx (XFmode);
14322 op1 = gen_reg_rtx (XFmode);
14324 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14325 emit_insn (gen_expxf2 (op0, op1));
14326 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14330 (define_expand "exp10xf2"
14331 [(use (match_operand:XF 0 "register_operand" ""))
14332 (use (match_operand:XF 1 "register_operand" ""))]
14333 "TARGET_USE_FANCY_MATH_387
14334 && flag_unsafe_math_optimizations"
14338 if (optimize_insn_for_size_p ())
14341 op2 = gen_reg_rtx (XFmode);
14342 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14344 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14348 (define_expand "exp10<mode>2"
14349 [(use (match_operand:MODEF 0 "register_operand" ""))
14350 (use (match_operand:MODEF 1 "general_operand" ""))]
14351 "TARGET_USE_FANCY_MATH_387
14352 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14353 || TARGET_MIX_SSE_I387)
14354 && flag_unsafe_math_optimizations"
14358 if (optimize_insn_for_size_p ())
14361 op0 = gen_reg_rtx (XFmode);
14362 op1 = gen_reg_rtx (XFmode);
14364 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14365 emit_insn (gen_exp10xf2 (op0, op1));
14366 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14370 (define_expand "exp2xf2"
14371 [(use (match_operand:XF 0 "register_operand" ""))
14372 (use (match_operand:XF 1 "register_operand" ""))]
14373 "TARGET_USE_FANCY_MATH_387
14374 && flag_unsafe_math_optimizations"
14378 if (optimize_insn_for_size_p ())
14381 op2 = gen_reg_rtx (XFmode);
14382 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14384 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14388 (define_expand "exp2<mode>2"
14389 [(use (match_operand:MODEF 0 "register_operand" ""))
14390 (use (match_operand:MODEF 1 "general_operand" ""))]
14391 "TARGET_USE_FANCY_MATH_387
14392 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14393 || TARGET_MIX_SSE_I387)
14394 && flag_unsafe_math_optimizations"
14398 if (optimize_insn_for_size_p ())
14401 op0 = gen_reg_rtx (XFmode);
14402 op1 = gen_reg_rtx (XFmode);
14404 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14405 emit_insn (gen_exp2xf2 (op0, op1));
14406 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14410 (define_expand "expm1xf2"
14411 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14413 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14414 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14415 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14416 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14417 (parallel [(set (match_dup 7)
14418 (unspec:XF [(match_dup 6) (match_dup 4)]
14419 UNSPEC_FSCALE_FRACT))
14421 (unspec:XF [(match_dup 6) (match_dup 4)]
14422 UNSPEC_FSCALE_EXP))])
14423 (parallel [(set (match_dup 10)
14424 (unspec:XF [(match_dup 9) (match_dup 8)]
14425 UNSPEC_FSCALE_FRACT))
14426 (set (match_dup 11)
14427 (unspec:XF [(match_dup 9) (match_dup 8)]
14428 UNSPEC_FSCALE_EXP))])
14429 (set (match_dup 12) (minus:XF (match_dup 10)
14430 (float_extend:XF (match_dup 13))))
14431 (set (match_operand:XF 0 "register_operand" "")
14432 (plus:XF (match_dup 12) (match_dup 7)))]
14433 "TARGET_USE_FANCY_MATH_387
14434 && flag_unsafe_math_optimizations"
14438 if (optimize_insn_for_size_p ())
14441 for (i = 2; i < 13; i++)
14442 operands[i] = gen_reg_rtx (XFmode);
14445 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14447 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14450 (define_expand "expm1<mode>2"
14451 [(use (match_operand:MODEF 0 "register_operand" ""))
14452 (use (match_operand:MODEF 1 "general_operand" ""))]
14453 "TARGET_USE_FANCY_MATH_387
14454 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14455 || TARGET_MIX_SSE_I387)
14456 && flag_unsafe_math_optimizations"
14460 if (optimize_insn_for_size_p ())
14463 op0 = gen_reg_rtx (XFmode);
14464 op1 = gen_reg_rtx (XFmode);
14466 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14467 emit_insn (gen_expm1xf2 (op0, op1));
14468 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14472 (define_expand "ldexpxf3"
14473 [(set (match_dup 3)
14474 (float:XF (match_operand:SI 2 "register_operand" "")))
14475 (parallel [(set (match_operand:XF 0 " register_operand" "")
14476 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14478 UNSPEC_FSCALE_FRACT))
14480 (unspec:XF [(match_dup 1) (match_dup 3)]
14481 UNSPEC_FSCALE_EXP))])]
14482 "TARGET_USE_FANCY_MATH_387
14483 && flag_unsafe_math_optimizations"
14485 if (optimize_insn_for_size_p ())
14488 operands[3] = gen_reg_rtx (XFmode);
14489 operands[4] = gen_reg_rtx (XFmode);
14492 (define_expand "ldexp<mode>3"
14493 [(use (match_operand:MODEF 0 "register_operand" ""))
14494 (use (match_operand:MODEF 1 "general_operand" ""))
14495 (use (match_operand:SI 2 "register_operand" ""))]
14496 "TARGET_USE_FANCY_MATH_387
14497 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14498 || TARGET_MIX_SSE_I387)
14499 && flag_unsafe_math_optimizations"
14503 if (optimize_insn_for_size_p ())
14506 op0 = gen_reg_rtx (XFmode);
14507 op1 = gen_reg_rtx (XFmode);
14509 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14510 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14511 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14515 (define_expand "scalbxf3"
14516 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14517 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14518 (match_operand:XF 2 "register_operand" "")]
14519 UNSPEC_FSCALE_FRACT))
14521 (unspec:XF [(match_dup 1) (match_dup 2)]
14522 UNSPEC_FSCALE_EXP))])]
14523 "TARGET_USE_FANCY_MATH_387
14524 && flag_unsafe_math_optimizations"
14526 if (optimize_insn_for_size_p ())
14529 operands[3] = gen_reg_rtx (XFmode);
14532 (define_expand "scalb<mode>3"
14533 [(use (match_operand:MODEF 0 "register_operand" ""))
14534 (use (match_operand:MODEF 1 "general_operand" ""))
14535 (use (match_operand:MODEF 2 "general_operand" ""))]
14536 "TARGET_USE_FANCY_MATH_387
14537 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14538 || TARGET_MIX_SSE_I387)
14539 && flag_unsafe_math_optimizations"
14543 if (optimize_insn_for_size_p ())
14546 op0 = gen_reg_rtx (XFmode);
14547 op1 = gen_reg_rtx (XFmode);
14548 op2 = gen_reg_rtx (XFmode);
14550 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14551 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14552 emit_insn (gen_scalbxf3 (op0, op1, op2));
14553 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14557 (define_expand "significandxf2"
14558 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14559 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14560 UNSPEC_XTRACT_FRACT))
14562 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14563 "TARGET_USE_FANCY_MATH_387
14564 && flag_unsafe_math_optimizations"
14565 "operands[2] = gen_reg_rtx (XFmode);")
14567 (define_expand "significand<mode>2"
14568 [(use (match_operand:MODEF 0 "register_operand" ""))
14569 (use (match_operand:MODEF 1 "register_operand" ""))]
14570 "TARGET_USE_FANCY_MATH_387
14571 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14572 || TARGET_MIX_SSE_I387)
14573 && flag_unsafe_math_optimizations"
14575 rtx op0 = gen_reg_rtx (XFmode);
14576 rtx op1 = gen_reg_rtx (XFmode);
14578 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14579 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14584 (define_insn "sse4_1_round<mode>2"
14585 [(set (match_operand:MODEF 0 "register_operand" "=x")
14586 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14587 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14590 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14591 [(set_attr "type" "ssecvt")
14592 (set_attr "prefix_extra" "1")
14593 (set_attr "prefix" "maybe_vex")
14594 (set_attr "mode" "<MODE>")])
14596 (define_insn "rintxf2"
14597 [(set (match_operand:XF 0 "register_operand" "=f")
14598 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14600 "TARGET_USE_FANCY_MATH_387
14601 && flag_unsafe_math_optimizations"
14603 [(set_attr "type" "fpspc")
14604 (set_attr "mode" "XF")])
14606 (define_expand "rint<mode>2"
14607 [(use (match_operand:MODEF 0 "register_operand" ""))
14608 (use (match_operand:MODEF 1 "register_operand" ""))]
14609 "(TARGET_USE_FANCY_MATH_387
14610 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14611 || TARGET_MIX_SSE_I387)
14612 && flag_unsafe_math_optimizations)
14613 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14614 && !flag_trapping_math)"
14616 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14617 && !flag_trapping_math)
14620 emit_insn (gen_sse4_1_round<mode>2
14621 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14622 else if (optimize_insn_for_size_p ())
14625 ix86_expand_rint (operands[0], operands[1]);
14629 rtx op0 = gen_reg_rtx (XFmode);
14630 rtx op1 = gen_reg_rtx (XFmode);
14632 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14633 emit_insn (gen_rintxf2 (op0, op1));
14635 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14640 (define_expand "round<mode>2"
14641 [(match_operand:X87MODEF 0 "register_operand" "")
14642 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14643 "(TARGET_USE_FANCY_MATH_387
14644 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14645 || TARGET_MIX_SSE_I387)
14646 && flag_unsafe_math_optimizations)
14647 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14648 && !flag_trapping_math && !flag_rounding_math)"
14650 if (optimize_insn_for_size_p ())
14653 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14654 && !flag_trapping_math && !flag_rounding_math)
14658 operands[1] = force_reg (<MODE>mode, operands[1]);
14659 ix86_expand_round_sse4 (operands[0], operands[1]);
14661 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14662 ix86_expand_round (operands[0], operands[1]);
14664 ix86_expand_rounddf_32 (operands[0], operands[1]);
14668 operands[1] = force_reg (<MODE>mode, operands[1]);
14669 ix86_emit_i387_round (operands[0], operands[1]);
14674 (define_insn_and_split "*fistdi2_1"
14675 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14676 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14678 "TARGET_USE_FANCY_MATH_387
14679 && can_create_pseudo_p ()"
14684 if (memory_operand (operands[0], VOIDmode))
14685 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14688 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14689 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14694 [(set_attr "type" "fpspc")
14695 (set_attr "mode" "DI")])
14697 (define_insn "fistdi2"
14698 [(set (match_operand:DI 0 "memory_operand" "=m")
14699 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14701 (clobber (match_scratch:XF 2 "=&1f"))]
14702 "TARGET_USE_FANCY_MATH_387"
14703 "* return output_fix_trunc (insn, operands, false);"
14704 [(set_attr "type" "fpspc")
14705 (set_attr "mode" "DI")])
14707 (define_insn "fistdi2_with_temp"
14708 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14709 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14711 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14712 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14713 "TARGET_USE_FANCY_MATH_387"
14715 [(set_attr "type" "fpspc")
14716 (set_attr "mode" "DI")])
14719 [(set (match_operand:DI 0 "register_operand" "")
14720 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14722 (clobber (match_operand:DI 2 "memory_operand" ""))
14723 (clobber (match_scratch 3 ""))]
14725 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14726 (clobber (match_dup 3))])
14727 (set (match_dup 0) (match_dup 2))])
14730 [(set (match_operand:DI 0 "memory_operand" "")
14731 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14733 (clobber (match_operand:DI 2 "memory_operand" ""))
14734 (clobber (match_scratch 3 ""))]
14736 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14737 (clobber (match_dup 3))])])
14739 (define_insn_and_split "*fist<mode>2_1"
14740 [(set (match_operand:SWI24 0 "register_operand" "")
14741 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14743 "TARGET_USE_FANCY_MATH_387
14744 && can_create_pseudo_p ()"
14749 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14750 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14754 [(set_attr "type" "fpspc")
14755 (set_attr "mode" "<MODE>")])
14757 (define_insn "fist<mode>2"
14758 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14759 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14761 "TARGET_USE_FANCY_MATH_387"
14762 "* return output_fix_trunc (insn, operands, false);"
14763 [(set_attr "type" "fpspc")
14764 (set_attr "mode" "<MODE>")])
14766 (define_insn "fist<mode>2_with_temp"
14767 [(set (match_operand:SWI24 0 "register_operand" "=r")
14768 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14770 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14771 "TARGET_USE_FANCY_MATH_387"
14773 [(set_attr "type" "fpspc")
14774 (set_attr "mode" "<MODE>")])
14777 [(set (match_operand:SWI24 0 "register_operand" "")
14778 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14780 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14782 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14783 (set (match_dup 0) (match_dup 2))])
14786 [(set (match_operand:SWI24 0 "memory_operand" "")
14787 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14789 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14791 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14793 (define_expand "lrintxf<mode>2"
14794 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14795 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14797 "TARGET_USE_FANCY_MATH_387")
14799 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14800 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14801 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14802 UNSPEC_FIX_NOTRUNC))]
14803 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14804 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14806 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14807 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14808 (match_operand:X87MODEF 1 "register_operand" "")]
14809 "(TARGET_USE_FANCY_MATH_387
14810 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14811 || TARGET_MIX_SSE_I387)
14812 && flag_unsafe_math_optimizations)
14813 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14814 && <SWI248x:MODE>mode != HImode
14815 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14816 && !flag_trapping_math && !flag_rounding_math)"
14818 if (optimize_insn_for_size_p ())
14821 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14822 && <SWI248x:MODE>mode != HImode
14823 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14824 && !flag_trapping_math && !flag_rounding_math)
14825 ix86_expand_lround (operands[0], operands[1]);
14827 ix86_emit_i387_round (operands[0], operands[1]);
14831 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14832 (define_insn_and_split "frndintxf2_floor"
14833 [(set (match_operand:XF 0 "register_operand" "")
14834 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14835 UNSPEC_FRNDINT_FLOOR))
14836 (clobber (reg:CC FLAGS_REG))]
14837 "TARGET_USE_FANCY_MATH_387
14838 && flag_unsafe_math_optimizations
14839 && can_create_pseudo_p ()"
14844 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14846 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14847 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14849 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14850 operands[2], operands[3]));
14853 [(set_attr "type" "frndint")
14854 (set_attr "i387_cw" "floor")
14855 (set_attr "mode" "XF")])
14857 (define_insn "frndintxf2_floor_i387"
14858 [(set (match_operand:XF 0 "register_operand" "=f")
14859 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14860 UNSPEC_FRNDINT_FLOOR))
14861 (use (match_operand:HI 2 "memory_operand" "m"))
14862 (use (match_operand:HI 3 "memory_operand" "m"))]
14863 "TARGET_USE_FANCY_MATH_387
14864 && flag_unsafe_math_optimizations"
14865 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14866 [(set_attr "type" "frndint")
14867 (set_attr "i387_cw" "floor")
14868 (set_attr "mode" "XF")])
14870 (define_expand "floorxf2"
14871 [(use (match_operand:XF 0 "register_operand" ""))
14872 (use (match_operand:XF 1 "register_operand" ""))]
14873 "TARGET_USE_FANCY_MATH_387
14874 && flag_unsafe_math_optimizations"
14876 if (optimize_insn_for_size_p ())
14878 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14882 (define_expand "floor<mode>2"
14883 [(use (match_operand:MODEF 0 "register_operand" ""))
14884 (use (match_operand:MODEF 1 "register_operand" ""))]
14885 "(TARGET_USE_FANCY_MATH_387
14886 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14887 || TARGET_MIX_SSE_I387)
14888 && flag_unsafe_math_optimizations)
14889 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14890 && !flag_trapping_math)"
14892 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14893 && !flag_trapping_math)
14896 emit_insn (gen_sse4_1_round<mode>2
14897 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14898 else if (optimize_insn_for_size_p ())
14900 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14901 ix86_expand_floorceil (operands[0], operands[1], true);
14903 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14909 if (optimize_insn_for_size_p ())
14912 op0 = gen_reg_rtx (XFmode);
14913 op1 = gen_reg_rtx (XFmode);
14914 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14915 emit_insn (gen_frndintxf2_floor (op0, op1));
14917 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14922 (define_insn_and_split "*fist<mode>2_floor_1"
14923 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14924 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14925 UNSPEC_FIST_FLOOR))
14926 (clobber (reg:CC FLAGS_REG))]
14927 "TARGET_USE_FANCY_MATH_387
14928 && flag_unsafe_math_optimizations
14929 && can_create_pseudo_p ()"
14934 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14936 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14937 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14938 if (memory_operand (operands[0], VOIDmode))
14939 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14940 operands[2], operands[3]));
14943 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14944 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14945 operands[2], operands[3],
14950 [(set_attr "type" "fistp")
14951 (set_attr "i387_cw" "floor")
14952 (set_attr "mode" "<MODE>")])
14954 (define_insn "fistdi2_floor"
14955 [(set (match_operand:DI 0 "memory_operand" "=m")
14956 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14957 UNSPEC_FIST_FLOOR))
14958 (use (match_operand:HI 2 "memory_operand" "m"))
14959 (use (match_operand:HI 3 "memory_operand" "m"))
14960 (clobber (match_scratch:XF 4 "=&1f"))]
14961 "TARGET_USE_FANCY_MATH_387
14962 && flag_unsafe_math_optimizations"
14963 "* return output_fix_trunc (insn, operands, false);"
14964 [(set_attr "type" "fistp")
14965 (set_attr "i387_cw" "floor")
14966 (set_attr "mode" "DI")])
14968 (define_insn "fistdi2_floor_with_temp"
14969 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14970 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14971 UNSPEC_FIST_FLOOR))
14972 (use (match_operand:HI 2 "memory_operand" "m,m"))
14973 (use (match_operand:HI 3 "memory_operand" "m,m"))
14974 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14975 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14976 "TARGET_USE_FANCY_MATH_387
14977 && flag_unsafe_math_optimizations"
14979 [(set_attr "type" "fistp")
14980 (set_attr "i387_cw" "floor")
14981 (set_attr "mode" "DI")])
14984 [(set (match_operand:DI 0 "register_operand" "")
14985 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14986 UNSPEC_FIST_FLOOR))
14987 (use (match_operand:HI 2 "memory_operand" ""))
14988 (use (match_operand:HI 3 "memory_operand" ""))
14989 (clobber (match_operand:DI 4 "memory_operand" ""))
14990 (clobber (match_scratch 5 ""))]
14992 [(parallel [(set (match_dup 4)
14993 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14994 (use (match_dup 2))
14995 (use (match_dup 3))
14996 (clobber (match_dup 5))])
14997 (set (match_dup 0) (match_dup 4))])
15000 [(set (match_operand:DI 0 "memory_operand" "")
15001 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15002 UNSPEC_FIST_FLOOR))
15003 (use (match_operand:HI 2 "memory_operand" ""))
15004 (use (match_operand:HI 3 "memory_operand" ""))
15005 (clobber (match_operand:DI 4 "memory_operand" ""))
15006 (clobber (match_scratch 5 ""))]
15008 [(parallel [(set (match_dup 0)
15009 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15010 (use (match_dup 2))
15011 (use (match_dup 3))
15012 (clobber (match_dup 5))])])
15014 (define_insn "fist<mode>2_floor"
15015 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15016 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15017 UNSPEC_FIST_FLOOR))
15018 (use (match_operand:HI 2 "memory_operand" "m"))
15019 (use (match_operand:HI 3 "memory_operand" "m"))]
15020 "TARGET_USE_FANCY_MATH_387
15021 && flag_unsafe_math_optimizations"
15022 "* return output_fix_trunc (insn, operands, false);"
15023 [(set_attr "type" "fistp")
15024 (set_attr "i387_cw" "floor")
15025 (set_attr "mode" "<MODE>")])
15027 (define_insn "fist<mode>2_floor_with_temp"
15028 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15029 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15030 UNSPEC_FIST_FLOOR))
15031 (use (match_operand:HI 2 "memory_operand" "m,m"))
15032 (use (match_operand:HI 3 "memory_operand" "m,m"))
15033 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15034 "TARGET_USE_FANCY_MATH_387
15035 && flag_unsafe_math_optimizations"
15037 [(set_attr "type" "fistp")
15038 (set_attr "i387_cw" "floor")
15039 (set_attr "mode" "<MODE>")])
15042 [(set (match_operand:SWI24 0 "register_operand" "")
15043 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15044 UNSPEC_FIST_FLOOR))
15045 (use (match_operand:HI 2 "memory_operand" ""))
15046 (use (match_operand:HI 3 "memory_operand" ""))
15047 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15049 [(parallel [(set (match_dup 4)
15050 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15051 (use (match_dup 2))
15052 (use (match_dup 3))])
15053 (set (match_dup 0) (match_dup 4))])
15056 [(set (match_operand:SWI24 0 "memory_operand" "")
15057 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15058 UNSPEC_FIST_FLOOR))
15059 (use (match_operand:HI 2 "memory_operand" ""))
15060 (use (match_operand:HI 3 "memory_operand" ""))
15061 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15063 [(parallel [(set (match_dup 0)
15064 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15065 (use (match_dup 2))
15066 (use (match_dup 3))])])
15068 (define_expand "lfloorxf<mode>2"
15069 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15070 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15071 UNSPEC_FIST_FLOOR))
15072 (clobber (reg:CC FLAGS_REG))])]
15073 "TARGET_USE_FANCY_MATH_387
15074 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15075 && flag_unsafe_math_optimizations")
15077 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15078 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15079 (match_operand:MODEF 1 "register_operand" "")]
15080 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15081 && !flag_trapping_math"
15083 if (TARGET_64BIT && optimize_insn_for_size_p ())
15085 ix86_expand_lfloorceil (operands[0], operands[1], true);
15089 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15090 (define_insn_and_split "frndintxf2_ceil"
15091 [(set (match_operand:XF 0 "register_operand" "")
15092 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15093 UNSPEC_FRNDINT_CEIL))
15094 (clobber (reg:CC FLAGS_REG))]
15095 "TARGET_USE_FANCY_MATH_387
15096 && flag_unsafe_math_optimizations
15097 && can_create_pseudo_p ()"
15102 ix86_optimize_mode_switching[I387_CEIL] = 1;
15104 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15105 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15107 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15108 operands[2], operands[3]));
15111 [(set_attr "type" "frndint")
15112 (set_attr "i387_cw" "ceil")
15113 (set_attr "mode" "XF")])
15115 (define_insn "frndintxf2_ceil_i387"
15116 [(set (match_operand:XF 0 "register_operand" "=f")
15117 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15118 UNSPEC_FRNDINT_CEIL))
15119 (use (match_operand:HI 2 "memory_operand" "m"))
15120 (use (match_operand:HI 3 "memory_operand" "m"))]
15121 "TARGET_USE_FANCY_MATH_387
15122 && flag_unsafe_math_optimizations"
15123 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15124 [(set_attr "type" "frndint")
15125 (set_attr "i387_cw" "ceil")
15126 (set_attr "mode" "XF")])
15128 (define_expand "ceilxf2"
15129 [(use (match_operand:XF 0 "register_operand" ""))
15130 (use (match_operand:XF 1 "register_operand" ""))]
15131 "TARGET_USE_FANCY_MATH_387
15132 && flag_unsafe_math_optimizations"
15134 if (optimize_insn_for_size_p ())
15136 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15140 (define_expand "ceil<mode>2"
15141 [(use (match_operand:MODEF 0 "register_operand" ""))
15142 (use (match_operand:MODEF 1 "register_operand" ""))]
15143 "(TARGET_USE_FANCY_MATH_387
15144 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15145 || TARGET_MIX_SSE_I387)
15146 && flag_unsafe_math_optimizations)
15147 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15148 && !flag_trapping_math)"
15150 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15151 && !flag_trapping_math)
15154 emit_insn (gen_sse4_1_round<mode>2
15155 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15156 else if (optimize_insn_for_size_p ())
15158 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15159 ix86_expand_floorceil (operands[0], operands[1], false);
15161 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15167 if (optimize_insn_for_size_p ())
15170 op0 = gen_reg_rtx (XFmode);
15171 op1 = gen_reg_rtx (XFmode);
15172 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15173 emit_insn (gen_frndintxf2_ceil (op0, op1));
15175 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15180 (define_insn_and_split "*fist<mode>2_ceil_1"
15181 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15182 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15184 (clobber (reg:CC FLAGS_REG))]
15185 "TARGET_USE_FANCY_MATH_387
15186 && flag_unsafe_math_optimizations
15187 && can_create_pseudo_p ()"
15192 ix86_optimize_mode_switching[I387_CEIL] = 1;
15194 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15195 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15196 if (memory_operand (operands[0], VOIDmode))
15197 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15198 operands[2], operands[3]));
15201 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15202 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15203 operands[2], operands[3],
15208 [(set_attr "type" "fistp")
15209 (set_attr "i387_cw" "ceil")
15210 (set_attr "mode" "<MODE>")])
15212 (define_insn "fistdi2_ceil"
15213 [(set (match_operand:DI 0 "memory_operand" "=m")
15214 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15216 (use (match_operand:HI 2 "memory_operand" "m"))
15217 (use (match_operand:HI 3 "memory_operand" "m"))
15218 (clobber (match_scratch:XF 4 "=&1f"))]
15219 "TARGET_USE_FANCY_MATH_387
15220 && flag_unsafe_math_optimizations"
15221 "* return output_fix_trunc (insn, operands, false);"
15222 [(set_attr "type" "fistp")
15223 (set_attr "i387_cw" "ceil")
15224 (set_attr "mode" "DI")])
15226 (define_insn "fistdi2_ceil_with_temp"
15227 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15228 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15230 (use (match_operand:HI 2 "memory_operand" "m,m"))
15231 (use (match_operand:HI 3 "memory_operand" "m,m"))
15232 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15233 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15234 "TARGET_USE_FANCY_MATH_387
15235 && flag_unsafe_math_optimizations"
15237 [(set_attr "type" "fistp")
15238 (set_attr "i387_cw" "ceil")
15239 (set_attr "mode" "DI")])
15242 [(set (match_operand:DI 0 "register_operand" "")
15243 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15245 (use (match_operand:HI 2 "memory_operand" ""))
15246 (use (match_operand:HI 3 "memory_operand" ""))
15247 (clobber (match_operand:DI 4 "memory_operand" ""))
15248 (clobber (match_scratch 5 ""))]
15250 [(parallel [(set (match_dup 4)
15251 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15252 (use (match_dup 2))
15253 (use (match_dup 3))
15254 (clobber (match_dup 5))])
15255 (set (match_dup 0) (match_dup 4))])
15258 [(set (match_operand:DI 0 "memory_operand" "")
15259 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15261 (use (match_operand:HI 2 "memory_operand" ""))
15262 (use (match_operand:HI 3 "memory_operand" ""))
15263 (clobber (match_operand:DI 4 "memory_operand" ""))
15264 (clobber (match_scratch 5 ""))]
15266 [(parallel [(set (match_dup 0)
15267 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15268 (use (match_dup 2))
15269 (use (match_dup 3))
15270 (clobber (match_dup 5))])])
15272 (define_insn "fist<mode>2_ceil"
15273 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15274 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15276 (use (match_operand:HI 2 "memory_operand" "m"))
15277 (use (match_operand:HI 3 "memory_operand" "m"))]
15278 "TARGET_USE_FANCY_MATH_387
15279 && flag_unsafe_math_optimizations"
15280 "* return output_fix_trunc (insn, operands, false);"
15281 [(set_attr "type" "fistp")
15282 (set_attr "i387_cw" "ceil")
15283 (set_attr "mode" "<MODE>")])
15285 (define_insn "fist<mode>2_ceil_with_temp"
15286 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15287 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15289 (use (match_operand:HI 2 "memory_operand" "m,m"))
15290 (use (match_operand:HI 3 "memory_operand" "m,m"))
15291 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15292 "TARGET_USE_FANCY_MATH_387
15293 && flag_unsafe_math_optimizations"
15295 [(set_attr "type" "fistp")
15296 (set_attr "i387_cw" "ceil")
15297 (set_attr "mode" "<MODE>")])
15300 [(set (match_operand:SWI24 0 "register_operand" "")
15301 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15303 (use (match_operand:HI 2 "memory_operand" ""))
15304 (use (match_operand:HI 3 "memory_operand" ""))
15305 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15307 [(parallel [(set (match_dup 4)
15308 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15309 (use (match_dup 2))
15310 (use (match_dup 3))])
15311 (set (match_dup 0) (match_dup 4))])
15314 [(set (match_operand:SWI24 0 "memory_operand" "")
15315 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15317 (use (match_operand:HI 2 "memory_operand" ""))
15318 (use (match_operand:HI 3 "memory_operand" ""))
15319 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15321 [(parallel [(set (match_dup 0)
15322 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15323 (use (match_dup 2))
15324 (use (match_dup 3))])])
15326 (define_expand "lceilxf<mode>2"
15327 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15328 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15330 (clobber (reg:CC FLAGS_REG))])]
15331 "TARGET_USE_FANCY_MATH_387
15332 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15333 && flag_unsafe_math_optimizations")
15335 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15336 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15337 (match_operand:MODEF 1 "register_operand" "")]
15338 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15339 && !flag_trapping_math"
15341 ix86_expand_lfloorceil (operands[0], operands[1], false);
15345 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15346 (define_insn_and_split "frndintxf2_trunc"
15347 [(set (match_operand:XF 0 "register_operand" "")
15348 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15349 UNSPEC_FRNDINT_TRUNC))
15350 (clobber (reg:CC FLAGS_REG))]
15351 "TARGET_USE_FANCY_MATH_387
15352 && flag_unsafe_math_optimizations
15353 && can_create_pseudo_p ()"
15358 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15360 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15361 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15363 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15364 operands[2], operands[3]));
15367 [(set_attr "type" "frndint")
15368 (set_attr "i387_cw" "trunc")
15369 (set_attr "mode" "XF")])
15371 (define_insn "frndintxf2_trunc_i387"
15372 [(set (match_operand:XF 0 "register_operand" "=f")
15373 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15374 UNSPEC_FRNDINT_TRUNC))
15375 (use (match_operand:HI 2 "memory_operand" "m"))
15376 (use (match_operand:HI 3 "memory_operand" "m"))]
15377 "TARGET_USE_FANCY_MATH_387
15378 && flag_unsafe_math_optimizations"
15379 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15380 [(set_attr "type" "frndint")
15381 (set_attr "i387_cw" "trunc")
15382 (set_attr "mode" "XF")])
15384 (define_expand "btruncxf2"
15385 [(use (match_operand:XF 0 "register_operand" ""))
15386 (use (match_operand:XF 1 "register_operand" ""))]
15387 "TARGET_USE_FANCY_MATH_387
15388 && flag_unsafe_math_optimizations"
15390 if (optimize_insn_for_size_p ())
15392 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15396 (define_expand "btrunc<mode>2"
15397 [(use (match_operand:MODEF 0 "register_operand" ""))
15398 (use (match_operand:MODEF 1 "register_operand" ""))]
15399 "(TARGET_USE_FANCY_MATH_387
15400 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15401 || TARGET_MIX_SSE_I387)
15402 && flag_unsafe_math_optimizations)
15403 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15404 && !flag_trapping_math)"
15406 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15407 && !flag_trapping_math)
15410 emit_insn (gen_sse4_1_round<mode>2
15411 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15412 else if (optimize_insn_for_size_p ())
15414 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15415 ix86_expand_trunc (operands[0], operands[1]);
15417 ix86_expand_truncdf_32 (operands[0], operands[1]);
15423 if (optimize_insn_for_size_p ())
15426 op0 = gen_reg_rtx (XFmode);
15427 op1 = gen_reg_rtx (XFmode);
15428 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15429 emit_insn (gen_frndintxf2_trunc (op0, op1));
15431 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15436 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15437 (define_insn_and_split "frndintxf2_mask_pm"
15438 [(set (match_operand:XF 0 "register_operand" "")
15439 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15440 UNSPEC_FRNDINT_MASK_PM))
15441 (clobber (reg:CC FLAGS_REG))]
15442 "TARGET_USE_FANCY_MATH_387
15443 && flag_unsafe_math_optimizations
15444 && can_create_pseudo_p ()"
15449 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15451 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15452 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15454 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15455 operands[2], operands[3]));
15458 [(set_attr "type" "frndint")
15459 (set_attr "i387_cw" "mask_pm")
15460 (set_attr "mode" "XF")])
15462 (define_insn "frndintxf2_mask_pm_i387"
15463 [(set (match_operand:XF 0 "register_operand" "=f")
15464 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15465 UNSPEC_FRNDINT_MASK_PM))
15466 (use (match_operand:HI 2 "memory_operand" "m"))
15467 (use (match_operand:HI 3 "memory_operand" "m"))]
15468 "TARGET_USE_FANCY_MATH_387
15469 && flag_unsafe_math_optimizations"
15470 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15471 [(set_attr "type" "frndint")
15472 (set_attr "i387_cw" "mask_pm")
15473 (set_attr "mode" "XF")])
15475 (define_expand "nearbyintxf2"
15476 [(use (match_operand:XF 0 "register_operand" ""))
15477 (use (match_operand:XF 1 "register_operand" ""))]
15478 "TARGET_USE_FANCY_MATH_387
15479 && flag_unsafe_math_optimizations"
15481 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15485 (define_expand "nearbyint<mode>2"
15486 [(use (match_operand:MODEF 0 "register_operand" ""))
15487 (use (match_operand:MODEF 1 "register_operand" ""))]
15488 "TARGET_USE_FANCY_MATH_387
15489 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15490 || TARGET_MIX_SSE_I387)
15491 && flag_unsafe_math_optimizations"
15493 rtx op0 = gen_reg_rtx (XFmode);
15494 rtx op1 = gen_reg_rtx (XFmode);
15496 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15497 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15499 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15503 (define_insn "fxam<mode>2_i387"
15504 [(set (match_operand:HI 0 "register_operand" "=a")
15506 [(match_operand:X87MODEF 1 "register_operand" "f")]
15508 "TARGET_USE_FANCY_MATH_387"
15509 "fxam\n\tfnstsw\t%0"
15510 [(set_attr "type" "multi")
15511 (set_attr "length" "4")
15512 (set_attr "unit" "i387")
15513 (set_attr "mode" "<MODE>")])
15515 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15516 [(set (match_operand:HI 0 "register_operand" "")
15518 [(match_operand:MODEF 1 "memory_operand" "")]
15520 "TARGET_USE_FANCY_MATH_387
15521 && can_create_pseudo_p ()"
15524 [(set (match_dup 2)(match_dup 1))
15526 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15528 operands[2] = gen_reg_rtx (<MODE>mode);
15530 MEM_VOLATILE_P (operands[1]) = 1;
15532 [(set_attr "type" "multi")
15533 (set_attr "unit" "i387")
15534 (set_attr "mode" "<MODE>")])
15536 (define_expand "isinfxf2"
15537 [(use (match_operand:SI 0 "register_operand" ""))
15538 (use (match_operand:XF 1 "register_operand" ""))]
15539 "TARGET_USE_FANCY_MATH_387
15540 && TARGET_C99_FUNCTIONS"
15542 rtx mask = GEN_INT (0x45);
15543 rtx val = GEN_INT (0x05);
15547 rtx scratch = gen_reg_rtx (HImode);
15548 rtx res = gen_reg_rtx (QImode);
15550 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15552 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15553 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15554 cond = gen_rtx_fmt_ee (EQ, QImode,
15555 gen_rtx_REG (CCmode, FLAGS_REG),
15557 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15558 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15562 (define_expand "isinf<mode>2"
15563 [(use (match_operand:SI 0 "register_operand" ""))
15564 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15565 "TARGET_USE_FANCY_MATH_387
15566 && TARGET_C99_FUNCTIONS
15567 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
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 /* Remove excess precision by forcing value through memory. */
15578 if (memory_operand (operands[1], VOIDmode))
15579 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15582 enum ix86_stack_slot slot = (virtuals_instantiated
15585 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15587 emit_move_insn (temp, operands[1]);
15588 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15591 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15592 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15593 cond = gen_rtx_fmt_ee (EQ, QImode,
15594 gen_rtx_REG (CCmode, FLAGS_REG),
15596 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15597 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15601 (define_expand "signbitxf2"
15602 [(use (match_operand:SI 0 "register_operand" ""))
15603 (use (match_operand:XF 1 "register_operand" ""))]
15604 "TARGET_USE_FANCY_MATH_387"
15606 rtx scratch = gen_reg_rtx (HImode);
15608 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15609 emit_insn (gen_andsi3 (operands[0],
15610 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15614 (define_insn "movmsk_df"
15615 [(set (match_operand:SI 0 "register_operand" "=r")
15617 [(match_operand:DF 1 "register_operand" "x")]
15619 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15620 "%vmovmskpd\t{%1, %0|%0, %1}"
15621 [(set_attr "type" "ssemov")
15622 (set_attr "prefix" "maybe_vex")
15623 (set_attr "mode" "DF")])
15625 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15626 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15627 (define_expand "signbitdf2"
15628 [(use (match_operand:SI 0 "register_operand" ""))
15629 (use (match_operand:DF 1 "register_operand" ""))]
15630 "TARGET_USE_FANCY_MATH_387
15631 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15633 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15635 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15636 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15640 rtx scratch = gen_reg_rtx (HImode);
15642 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15643 emit_insn (gen_andsi3 (operands[0],
15644 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15649 (define_expand "signbitsf2"
15650 [(use (match_operand:SI 0 "register_operand" ""))
15651 (use (match_operand:SF 1 "register_operand" ""))]
15652 "TARGET_USE_FANCY_MATH_387
15653 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15655 rtx scratch = gen_reg_rtx (HImode);
15657 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15658 emit_insn (gen_andsi3 (operands[0],
15659 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15663 ;; Block operation instructions
15666 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15669 [(set_attr "length" "1")
15670 (set_attr "length_immediate" "0")
15671 (set_attr "modrm" "0")])
15673 (define_expand "movmem<mode>"
15674 [(use (match_operand:BLK 0 "memory_operand" ""))
15675 (use (match_operand:BLK 1 "memory_operand" ""))
15676 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15677 (use (match_operand:SWI48 3 "const_int_operand" ""))
15678 (use (match_operand:SI 4 "const_int_operand" ""))
15679 (use (match_operand:SI 5 "const_int_operand" ""))]
15682 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15683 operands[4], operands[5]))
15689 ;; Most CPUs don't like single string operations
15690 ;; Handle this case here to simplify previous expander.
15692 (define_expand "strmov"
15693 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15694 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15695 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15696 (clobber (reg:CC FLAGS_REG))])
15697 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15698 (clobber (reg:CC FLAGS_REG))])]
15701 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15703 /* If .md ever supports :P for Pmode, these can be directly
15704 in the pattern above. */
15705 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15706 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15708 /* Can't use this if the user has appropriated esi or edi. */
15709 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15710 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15712 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15713 operands[2], operands[3],
15714 operands[5], operands[6]));
15718 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15721 (define_expand "strmov_singleop"
15722 [(parallel [(set (match_operand 1 "memory_operand" "")
15723 (match_operand 3 "memory_operand" ""))
15724 (set (match_operand 0 "register_operand" "")
15725 (match_operand 4 "" ""))
15726 (set (match_operand 2 "register_operand" "")
15727 (match_operand 5 "" ""))])]
15729 "ix86_current_function_needs_cld = 1;")
15731 (define_insn "*strmovdi_rex_1"
15732 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15733 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15734 (set (match_operand:DI 0 "register_operand" "=D")
15735 (plus:DI (match_dup 2)
15737 (set (match_operand:DI 1 "register_operand" "=S")
15738 (plus:DI (match_dup 3)
15741 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15743 [(set_attr "type" "str")
15744 (set_attr "memory" "both")
15745 (set_attr "mode" "DI")])
15747 (define_insn "*strmovsi_1"
15748 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15749 (mem:SI (match_operand:P 3 "register_operand" "1")))
15750 (set (match_operand:P 0 "register_operand" "=D")
15751 (plus:P (match_dup 2)
15753 (set (match_operand:P 1 "register_operand" "=S")
15754 (plus:P (match_dup 3)
15756 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15758 [(set_attr "type" "str")
15759 (set_attr "memory" "both")
15760 (set_attr "mode" "SI")])
15762 (define_insn "*strmovhi_1"
15763 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15764 (mem:HI (match_operand:P 3 "register_operand" "1")))
15765 (set (match_operand:P 0 "register_operand" "=D")
15766 (plus:P (match_dup 2)
15768 (set (match_operand:P 1 "register_operand" "=S")
15769 (plus:P (match_dup 3)
15771 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15773 [(set_attr "type" "str")
15774 (set_attr "memory" "both")
15775 (set_attr "mode" "HI")])
15777 (define_insn "*strmovqi_1"
15778 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15779 (mem:QI (match_operand:P 3 "register_operand" "1")))
15780 (set (match_operand:P 0 "register_operand" "=D")
15781 (plus:P (match_dup 2)
15783 (set (match_operand:P 1 "register_operand" "=S")
15784 (plus:P (match_dup 3)
15786 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15788 [(set_attr "type" "str")
15789 (set_attr "memory" "both")
15790 (set (attr "prefix_rex")
15792 (match_test "<P:MODE>mode == DImode")
15794 (const_string "*")))
15795 (set_attr "mode" "QI")])
15797 (define_expand "rep_mov"
15798 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15799 (set (match_operand 0 "register_operand" "")
15800 (match_operand 5 "" ""))
15801 (set (match_operand 2 "register_operand" "")
15802 (match_operand 6 "" ""))
15803 (set (match_operand 1 "memory_operand" "")
15804 (match_operand 3 "memory_operand" ""))
15805 (use (match_dup 4))])]
15807 "ix86_current_function_needs_cld = 1;")
15809 (define_insn "*rep_movdi_rex64"
15810 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15811 (set (match_operand:DI 0 "register_operand" "=D")
15812 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15814 (match_operand:DI 3 "register_operand" "0")))
15815 (set (match_operand:DI 1 "register_operand" "=S")
15816 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15817 (match_operand:DI 4 "register_operand" "1")))
15818 (set (mem:BLK (match_dup 3))
15819 (mem:BLK (match_dup 4)))
15820 (use (match_dup 5))]
15822 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15824 [(set_attr "type" "str")
15825 (set_attr "prefix_rep" "1")
15826 (set_attr "memory" "both")
15827 (set_attr "mode" "DI")])
15829 (define_insn "*rep_movsi"
15830 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15831 (set (match_operand:P 0 "register_operand" "=D")
15832 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15834 (match_operand:P 3 "register_operand" "0")))
15835 (set (match_operand:P 1 "register_operand" "=S")
15836 (plus:P (ashift:P (match_dup 5) (const_int 2))
15837 (match_operand:P 4 "register_operand" "1")))
15838 (set (mem:BLK (match_dup 3))
15839 (mem:BLK (match_dup 4)))
15840 (use (match_dup 5))]
15841 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15842 "rep{%;} movs{l|d}"
15843 [(set_attr "type" "str")
15844 (set_attr "prefix_rep" "1")
15845 (set_attr "memory" "both")
15846 (set_attr "mode" "SI")])
15848 (define_insn "*rep_movqi"
15849 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15850 (set (match_operand:P 0 "register_operand" "=D")
15851 (plus:P (match_operand:P 3 "register_operand" "0")
15852 (match_operand:P 5 "register_operand" "2")))
15853 (set (match_operand:P 1 "register_operand" "=S")
15854 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15855 (set (mem:BLK (match_dup 3))
15856 (mem:BLK (match_dup 4)))
15857 (use (match_dup 5))]
15858 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15860 [(set_attr "type" "str")
15861 (set_attr "prefix_rep" "1")
15862 (set_attr "memory" "both")
15863 (set_attr "mode" "QI")])
15865 (define_expand "setmem<mode>"
15866 [(use (match_operand:BLK 0 "memory_operand" ""))
15867 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15868 (use (match_operand:QI 2 "nonmemory_operand" ""))
15869 (use (match_operand 3 "const_int_operand" ""))
15870 (use (match_operand:SI 4 "const_int_operand" ""))
15871 (use (match_operand:SI 5 "const_int_operand" ""))]
15874 if (ix86_expand_setmem (operands[0], operands[1],
15875 operands[2], operands[3],
15876 operands[4], operands[5]))
15882 ;; Most CPUs don't like single string operations
15883 ;; Handle this case here to simplify previous expander.
15885 (define_expand "strset"
15886 [(set (match_operand 1 "memory_operand" "")
15887 (match_operand 2 "register_operand" ""))
15888 (parallel [(set (match_operand 0 "register_operand" "")
15890 (clobber (reg:CC FLAGS_REG))])]
15893 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15894 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15896 /* If .md ever supports :P for Pmode, this can be directly
15897 in the pattern above. */
15898 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15899 GEN_INT (GET_MODE_SIZE (GET_MODE
15901 /* Can't use this if the user has appropriated eax or edi. */
15902 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15903 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15905 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15911 (define_expand "strset_singleop"
15912 [(parallel [(set (match_operand 1 "memory_operand" "")
15913 (match_operand 2 "register_operand" ""))
15914 (set (match_operand 0 "register_operand" "")
15915 (match_operand 3 "" ""))])]
15917 "ix86_current_function_needs_cld = 1;")
15919 (define_insn "*strsetdi_rex_1"
15920 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15921 (match_operand:DI 2 "register_operand" "a"))
15922 (set (match_operand:DI 0 "register_operand" "=D")
15923 (plus:DI (match_dup 1)
15926 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15928 [(set_attr "type" "str")
15929 (set_attr "memory" "store")
15930 (set_attr "mode" "DI")])
15932 (define_insn "*strsetsi_1"
15933 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15934 (match_operand:SI 2 "register_operand" "a"))
15935 (set (match_operand:P 0 "register_operand" "=D")
15936 (plus:P (match_dup 1)
15938 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15940 [(set_attr "type" "str")
15941 (set_attr "memory" "store")
15942 (set_attr "mode" "SI")])
15944 (define_insn "*strsethi_1"
15945 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15946 (match_operand:HI 2 "register_operand" "a"))
15947 (set (match_operand:P 0 "register_operand" "=D")
15948 (plus:P (match_dup 1)
15950 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15952 [(set_attr "type" "str")
15953 (set_attr "memory" "store")
15954 (set_attr "mode" "HI")])
15956 (define_insn "*strsetqi_1"
15957 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15958 (match_operand:QI 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 "prefix_rex")
15968 (match_test "<P:MODE>mode == DImode")
15970 (const_string "*")))
15971 (set_attr "mode" "QI")])
15973 (define_expand "rep_stos"
15974 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15975 (set (match_operand 0 "register_operand" "")
15976 (match_operand 4 "" ""))
15977 (set (match_operand 2 "memory_operand" "") (const_int 0))
15978 (use (match_operand 3 "register_operand" ""))
15979 (use (match_dup 1))])]
15981 "ix86_current_function_needs_cld = 1;")
15983 (define_insn "*rep_stosdi_rex64"
15984 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15985 (set (match_operand:DI 0 "register_operand" "=D")
15986 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15988 (match_operand:DI 3 "register_operand" "0")))
15989 (set (mem:BLK (match_dup 3))
15991 (use (match_operand:DI 2 "register_operand" "a"))
15992 (use (match_dup 4))]
15994 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15996 [(set_attr "type" "str")
15997 (set_attr "prefix_rep" "1")
15998 (set_attr "memory" "store")
15999 (set_attr "mode" "DI")])
16001 (define_insn "*rep_stossi"
16002 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16003 (set (match_operand:P 0 "register_operand" "=D")
16004 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16006 (match_operand:P 3 "register_operand" "0")))
16007 (set (mem:BLK (match_dup 3))
16009 (use (match_operand:SI 2 "register_operand" "a"))
16010 (use (match_dup 4))]
16011 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16012 "rep{%;} stos{l|d}"
16013 [(set_attr "type" "str")
16014 (set_attr "prefix_rep" "1")
16015 (set_attr "memory" "store")
16016 (set_attr "mode" "SI")])
16018 (define_insn "*rep_stosqi"
16019 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16020 (set (match_operand:P 0 "register_operand" "=D")
16021 (plus:P (match_operand:P 3 "register_operand" "0")
16022 (match_operand:P 4 "register_operand" "1")))
16023 (set (mem:BLK (match_dup 3))
16025 (use (match_operand:QI 2 "register_operand" "a"))
16026 (use (match_dup 4))]
16027 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16029 [(set_attr "type" "str")
16030 (set_attr "prefix_rep" "1")
16031 (set_attr "memory" "store")
16032 (set (attr "prefix_rex")
16034 (match_test "<P:MODE>mode == DImode")
16036 (const_string "*")))
16037 (set_attr "mode" "QI")])
16039 (define_expand "cmpstrnsi"
16040 [(set (match_operand:SI 0 "register_operand" "")
16041 (compare:SI (match_operand:BLK 1 "general_operand" "")
16042 (match_operand:BLK 2 "general_operand" "")))
16043 (use (match_operand 3 "general_operand" ""))
16044 (use (match_operand 4 "immediate_operand" ""))]
16047 rtx addr1, addr2, out, outlow, count, countreg, align;
16049 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16052 /* Can't use this if the user has appropriated ecx, esi or edi. */
16053 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16058 out = gen_reg_rtx (SImode);
16060 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16061 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16062 if (addr1 != XEXP (operands[1], 0))
16063 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16064 if (addr2 != XEXP (operands[2], 0))
16065 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16067 count = operands[3];
16068 countreg = ix86_zero_extend_to_Pmode (count);
16070 /* %%% Iff we are testing strict equality, we can use known alignment
16071 to good advantage. This may be possible with combine, particularly
16072 once cc0 is dead. */
16073 align = operands[4];
16075 if (CONST_INT_P (count))
16077 if (INTVAL (count) == 0)
16079 emit_move_insn (operands[0], const0_rtx);
16082 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16083 operands[1], operands[2]));
16087 rtx (*gen_cmp) (rtx, rtx);
16089 gen_cmp = (TARGET_64BIT
16090 ? gen_cmpdi_1 : gen_cmpsi_1);
16092 emit_insn (gen_cmp (countreg, countreg));
16093 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16094 operands[1], operands[2]));
16097 outlow = gen_lowpart (QImode, out);
16098 emit_insn (gen_cmpintqi (outlow));
16099 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16101 if (operands[0] != out)
16102 emit_move_insn (operands[0], out);
16107 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16109 (define_expand "cmpintqi"
16110 [(set (match_dup 1)
16111 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16113 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16114 (parallel [(set (match_operand:QI 0 "register_operand" "")
16115 (minus:QI (match_dup 1)
16117 (clobber (reg:CC FLAGS_REG))])]
16120 operands[1] = gen_reg_rtx (QImode);
16121 operands[2] = gen_reg_rtx (QImode);
16124 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16125 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16127 (define_expand "cmpstrnqi_nz_1"
16128 [(parallel [(set (reg:CC FLAGS_REG)
16129 (compare:CC (match_operand 4 "memory_operand" "")
16130 (match_operand 5 "memory_operand" "")))
16131 (use (match_operand 2 "register_operand" ""))
16132 (use (match_operand:SI 3 "immediate_operand" ""))
16133 (clobber (match_operand 0 "register_operand" ""))
16134 (clobber (match_operand 1 "register_operand" ""))
16135 (clobber (match_dup 2))])]
16137 "ix86_current_function_needs_cld = 1;")
16139 (define_insn "*cmpstrnqi_nz_1"
16140 [(set (reg:CC FLAGS_REG)
16141 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16142 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16143 (use (match_operand:P 6 "register_operand" "2"))
16144 (use (match_operand:SI 3 "immediate_operand" "i"))
16145 (clobber (match_operand:P 0 "register_operand" "=S"))
16146 (clobber (match_operand:P 1 "register_operand" "=D"))
16147 (clobber (match_operand:P 2 "register_operand" "=c"))]
16148 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16150 [(set_attr "type" "str")
16151 (set_attr "mode" "QI")
16152 (set (attr "prefix_rex")
16154 (match_test "<P:MODE>mode == DImode")
16156 (const_string "*")))
16157 (set_attr "prefix_rep" "1")])
16159 ;; The same, but the count is not known to not be zero.
16161 (define_expand "cmpstrnqi_1"
16162 [(parallel [(set (reg:CC FLAGS_REG)
16163 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16165 (compare:CC (match_operand 4 "memory_operand" "")
16166 (match_operand 5 "memory_operand" ""))
16168 (use (match_operand:SI 3 "immediate_operand" ""))
16169 (use (reg:CC FLAGS_REG))
16170 (clobber (match_operand 0 "register_operand" ""))
16171 (clobber (match_operand 1 "register_operand" ""))
16172 (clobber (match_dup 2))])]
16174 "ix86_current_function_needs_cld = 1;")
16176 (define_insn "*cmpstrnqi_1"
16177 [(set (reg:CC FLAGS_REG)
16178 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16180 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16181 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16183 (use (match_operand:SI 3 "immediate_operand" "i"))
16184 (use (reg:CC FLAGS_REG))
16185 (clobber (match_operand:P 0 "register_operand" "=S"))
16186 (clobber (match_operand:P 1 "register_operand" "=D"))
16187 (clobber (match_operand:P 2 "register_operand" "=c"))]
16188 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16190 [(set_attr "type" "str")
16191 (set_attr "mode" "QI")
16192 (set (attr "prefix_rex")
16194 (match_test "<P:MODE>mode == DImode")
16196 (const_string "*")))
16197 (set_attr "prefix_rep" "1")])
16199 (define_expand "strlen<mode>"
16200 [(set (match_operand:P 0 "register_operand" "")
16201 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16202 (match_operand:QI 2 "immediate_operand" "")
16203 (match_operand 3 "immediate_operand" "")]
16207 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16213 (define_expand "strlenqi_1"
16214 [(parallel [(set (match_operand 0 "register_operand" "")
16215 (match_operand 2 "" ""))
16216 (clobber (match_operand 1 "register_operand" ""))
16217 (clobber (reg:CC FLAGS_REG))])]
16219 "ix86_current_function_needs_cld = 1;")
16221 (define_insn "*strlenqi_1"
16222 [(set (match_operand:P 0 "register_operand" "=&c")
16223 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16224 (match_operand:QI 2 "register_operand" "a")
16225 (match_operand:P 3 "immediate_operand" "i")
16226 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16227 (clobber (match_operand:P 1 "register_operand" "=D"))
16228 (clobber (reg:CC FLAGS_REG))]
16229 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16231 [(set_attr "type" "str")
16232 (set_attr "mode" "QI")
16233 (set (attr "prefix_rex")
16235 (match_test "<P:MODE>mode == DImode")
16237 (const_string "*")))
16238 (set_attr "prefix_rep" "1")])
16240 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16241 ;; handled in combine, but it is not currently up to the task.
16242 ;; When used for their truth value, the cmpstrn* expanders generate
16251 ;; The intermediate three instructions are unnecessary.
16253 ;; This one handles cmpstrn*_nz_1...
16256 (set (reg:CC FLAGS_REG)
16257 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16258 (mem:BLK (match_operand 5 "register_operand" ""))))
16259 (use (match_operand 6 "register_operand" ""))
16260 (use (match_operand:SI 3 "immediate_operand" ""))
16261 (clobber (match_operand 0 "register_operand" ""))
16262 (clobber (match_operand 1 "register_operand" ""))
16263 (clobber (match_operand 2 "register_operand" ""))])
16264 (set (match_operand:QI 7 "register_operand" "")
16265 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16266 (set (match_operand:QI 8 "register_operand" "")
16267 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16268 (set (reg FLAGS_REG)
16269 (compare (match_dup 7) (match_dup 8)))
16271 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16273 (set (reg:CC FLAGS_REG)
16274 (compare:CC (mem:BLK (match_dup 4))
16275 (mem:BLK (match_dup 5))))
16276 (use (match_dup 6))
16277 (use (match_dup 3))
16278 (clobber (match_dup 0))
16279 (clobber (match_dup 1))
16280 (clobber (match_dup 2))])])
16282 ;; ...and this one handles cmpstrn*_1.
16285 (set (reg:CC FLAGS_REG)
16286 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16288 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16289 (mem:BLK (match_operand 5 "register_operand" "")))
16291 (use (match_operand:SI 3 "immediate_operand" ""))
16292 (use (reg:CC FLAGS_REG))
16293 (clobber (match_operand 0 "register_operand" ""))
16294 (clobber (match_operand 1 "register_operand" ""))
16295 (clobber (match_operand 2 "register_operand" ""))])
16296 (set (match_operand:QI 7 "register_operand" "")
16297 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16298 (set (match_operand:QI 8 "register_operand" "")
16299 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16300 (set (reg FLAGS_REG)
16301 (compare (match_dup 7) (match_dup 8)))
16303 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16305 (set (reg:CC FLAGS_REG)
16306 (if_then_else:CC (ne (match_dup 6)
16308 (compare:CC (mem:BLK (match_dup 4))
16309 (mem:BLK (match_dup 5)))
16311 (use (match_dup 3))
16312 (use (reg:CC FLAGS_REG))
16313 (clobber (match_dup 0))
16314 (clobber (match_dup 1))
16315 (clobber (match_dup 2))])])
16317 ;; Conditional move instructions.
16319 (define_expand "mov<mode>cc"
16320 [(set (match_operand:SWIM 0 "register_operand" "")
16321 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16322 (match_operand:SWIM 2 "<general_operand>" "")
16323 (match_operand:SWIM 3 "<general_operand>" "")))]
16325 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16327 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16328 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16329 ;; So just document what we're doing explicitly.
16331 (define_expand "x86_mov<mode>cc_0_m1"
16333 [(set (match_operand:SWI48 0 "register_operand" "")
16334 (if_then_else:SWI48
16335 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16336 [(match_operand 1 "flags_reg_operand" "")
16340 (clobber (reg:CC FLAGS_REG))])])
16342 (define_insn "*x86_mov<mode>cc_0_m1"
16343 [(set (match_operand:SWI48 0 "register_operand" "=r")
16344 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16345 [(reg FLAGS_REG) (const_int 0)])
16348 (clobber (reg:CC FLAGS_REG))]
16350 "sbb{<imodesuffix>}\t%0, %0"
16351 ; Since we don't have the proper number of operands for an alu insn,
16352 ; fill in all the blanks.
16353 [(set_attr "type" "alu")
16354 (set_attr "use_carry" "1")
16355 (set_attr "pent_pair" "pu")
16356 (set_attr "memory" "none")
16357 (set_attr "imm_disp" "false")
16358 (set_attr "mode" "<MODE>")
16359 (set_attr "length_immediate" "0")])
16361 (define_insn "*x86_mov<mode>cc_0_m1_se"
16362 [(set (match_operand:SWI48 0 "register_operand" "=r")
16363 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16364 [(reg FLAGS_REG) (const_int 0)])
16367 (clobber (reg:CC FLAGS_REG))]
16369 "sbb{<imodesuffix>}\t%0, %0"
16370 [(set_attr "type" "alu")
16371 (set_attr "use_carry" "1")
16372 (set_attr "pent_pair" "pu")
16373 (set_attr "memory" "none")
16374 (set_attr "imm_disp" "false")
16375 (set_attr "mode" "<MODE>")
16376 (set_attr "length_immediate" "0")])
16378 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16379 [(set (match_operand:SWI48 0 "register_operand" "=r")
16380 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16381 [(reg FLAGS_REG) (const_int 0)])))
16382 (clobber (reg:CC FLAGS_REG))]
16384 "sbb{<imodesuffix>}\t%0, %0"
16385 [(set_attr "type" "alu")
16386 (set_attr "use_carry" "1")
16387 (set_attr "pent_pair" "pu")
16388 (set_attr "memory" "none")
16389 (set_attr "imm_disp" "false")
16390 (set_attr "mode" "<MODE>")
16391 (set_attr "length_immediate" "0")])
16393 (define_insn "*mov<mode>cc_noc"
16394 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16395 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16396 [(reg FLAGS_REG) (const_int 0)])
16397 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16398 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16399 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16401 cmov%O2%C1\t{%2, %0|%0, %2}
16402 cmov%O2%c1\t{%3, %0|%0, %3}"
16403 [(set_attr "type" "icmov")
16404 (set_attr "mode" "<MODE>")])
16406 (define_insn "*movqicc_noc"
16407 [(set (match_operand:QI 0 "register_operand" "=r,r")
16408 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16409 [(reg FLAGS_REG) (const_int 0)])
16410 (match_operand:QI 2 "register_operand" "r,0")
16411 (match_operand:QI 3 "register_operand" "0,r")))]
16412 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16414 [(set_attr "type" "icmov")
16415 (set_attr "mode" "QI")])
16418 [(set (match_operand 0 "register_operand")
16419 (if_then_else (match_operator 1 "ix86_comparison_operator"
16420 [(reg FLAGS_REG) (const_int 0)])
16421 (match_operand 2 "register_operand")
16422 (match_operand 3 "register_operand")))]
16423 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16424 && (GET_MODE (operands[0]) == QImode
16425 || GET_MODE (operands[0]) == HImode)
16426 && reload_completed"
16427 [(set (match_dup 0)
16428 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16430 operands[0] = gen_lowpart (SImode, operands[0]);
16431 operands[2] = gen_lowpart (SImode, operands[2]);
16432 operands[3] = gen_lowpart (SImode, operands[3]);
16435 (define_expand "mov<mode>cc"
16436 [(set (match_operand:X87MODEF 0 "register_operand" "")
16437 (if_then_else:X87MODEF
16438 (match_operand 1 "ix86_fp_comparison_operator" "")
16439 (match_operand:X87MODEF 2 "register_operand" "")
16440 (match_operand:X87MODEF 3 "register_operand" "")))]
16441 "(TARGET_80387 && TARGET_CMOVE)
16442 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16443 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16445 (define_insn "*movxfcc_1"
16446 [(set (match_operand:XF 0 "register_operand" "=f,f")
16447 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16448 [(reg FLAGS_REG) (const_int 0)])
16449 (match_operand:XF 2 "register_operand" "f,0")
16450 (match_operand:XF 3 "register_operand" "0,f")))]
16451 "TARGET_80387 && TARGET_CMOVE"
16453 fcmov%F1\t{%2, %0|%0, %2}
16454 fcmov%f1\t{%3, %0|%0, %3}"
16455 [(set_attr "type" "fcmov")
16456 (set_attr "mode" "XF")])
16458 (define_insn "*movdfcc_1_rex64"
16459 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16460 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16461 [(reg FLAGS_REG) (const_int 0)])
16462 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16463 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16464 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16465 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16467 fcmov%F1\t{%2, %0|%0, %2}
16468 fcmov%f1\t{%3, %0|%0, %3}
16469 cmov%O2%C1\t{%2, %0|%0, %2}
16470 cmov%O2%c1\t{%3, %0|%0, %3}"
16471 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16472 (set_attr "mode" "DF,DF,DI,DI")])
16474 (define_insn "*movdfcc_1"
16475 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16476 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16477 [(reg FLAGS_REG) (const_int 0)])
16478 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16479 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16480 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16481 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16483 fcmov%F1\t{%2, %0|%0, %2}
16484 fcmov%f1\t{%3, %0|%0, %3}
16487 [(set_attr "type" "fcmov,fcmov,multi,multi")
16488 (set_attr "mode" "DF,DF,DI,DI")])
16491 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16492 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16493 [(reg FLAGS_REG) (const_int 0)])
16494 (match_operand:DF 2 "nonimmediate_operand")
16495 (match_operand:DF 3 "nonimmediate_operand")))]
16496 "!TARGET_64BIT && reload_completed"
16497 [(set (match_dup 2)
16498 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16500 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16502 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16503 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16506 (define_insn "*movsfcc_1_387"
16507 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16508 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16509 [(reg FLAGS_REG) (const_int 0)])
16510 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16511 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16512 "TARGET_80387 && TARGET_CMOVE
16513 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16515 fcmov%F1\t{%2, %0|%0, %2}
16516 fcmov%f1\t{%3, %0|%0, %3}
16517 cmov%O2%C1\t{%2, %0|%0, %2}
16518 cmov%O2%c1\t{%3, %0|%0, %3}"
16519 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16520 (set_attr "mode" "SF,SF,SI,SI")])
16522 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16523 ;; the scalar versions to have only XMM registers as operands.
16525 ;; XOP conditional move
16526 (define_insn "*xop_pcmov_<mode>"
16527 [(set (match_operand:MODEF 0 "register_operand" "=x")
16528 (if_then_else:MODEF
16529 (match_operand:MODEF 1 "register_operand" "x")
16530 (match_operand:MODEF 2 "register_operand" "x")
16531 (match_operand:MODEF 3 "register_operand" "x")))]
16533 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16534 [(set_attr "type" "sse4arg")])
16536 ;; These versions of the min/max patterns are intentionally ignorant of
16537 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16538 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16539 ;; are undefined in this condition, we're certain this is correct.
16541 (define_insn "<code><mode>3"
16542 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16544 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16545 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16546 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16548 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16549 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16550 [(set_attr "isa" "noavx,avx")
16551 (set_attr "prefix" "orig,vex")
16552 (set_attr "type" "sseadd")
16553 (set_attr "mode" "<MODE>")])
16555 ;; These versions of the min/max patterns implement exactly the operations
16556 ;; min = (op1 < op2 ? op1 : op2)
16557 ;; max = (!(op1 < op2) ? op1 : op2)
16558 ;; Their operands are not commutative, and thus they may be used in the
16559 ;; presence of -0.0 and NaN.
16561 (define_insn "*ieee_smin<mode>3"
16562 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16564 [(match_operand:MODEF 1 "register_operand" "0,x")
16565 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16567 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16569 min<ssemodesuffix>\t{%2, %0|%0, %2}
16570 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16571 [(set_attr "isa" "noavx,avx")
16572 (set_attr "prefix" "orig,vex")
16573 (set_attr "type" "sseadd")
16574 (set_attr "mode" "<MODE>")])
16576 (define_insn "*ieee_smax<mode>3"
16577 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16579 [(match_operand:MODEF 1 "register_operand" "0,x")
16580 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16582 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16584 max<ssemodesuffix>\t{%2, %0|%0, %2}
16585 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16586 [(set_attr "isa" "noavx,avx")
16587 (set_attr "prefix" "orig,vex")
16588 (set_attr "type" "sseadd")
16589 (set_attr "mode" "<MODE>")])
16591 ;; Make two stack loads independent:
16593 ;; fld %st(0) -> fld bb
16594 ;; fmul bb fmul %st(1), %st
16596 ;; Actually we only match the last two instructions for simplicity.
16598 [(set (match_operand 0 "fp_register_operand" "")
16599 (match_operand 1 "fp_register_operand" ""))
16601 (match_operator 2 "binary_fp_operator"
16603 (match_operand 3 "memory_operand" "")]))]
16604 "REGNO (operands[0]) != REGNO (operands[1])"
16605 [(set (match_dup 0) (match_dup 3))
16606 (set (match_dup 0) (match_dup 4))]
16608 ;; The % modifier is not operational anymore in peephole2's, so we have to
16609 ;; swap the operands manually in the case of addition and multiplication.
16613 if (COMMUTATIVE_ARITH_P (operands[2]))
16614 op0 = operands[0], op1 = operands[1];
16616 op0 = operands[1], op1 = operands[0];
16618 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16619 GET_MODE (operands[2]),
16623 ;; Conditional addition patterns
16624 (define_expand "add<mode>cc"
16625 [(match_operand:SWI 0 "register_operand" "")
16626 (match_operand 1 "ordered_comparison_operator" "")
16627 (match_operand:SWI 2 "register_operand" "")
16628 (match_operand:SWI 3 "const_int_operand" "")]
16630 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16632 ;; Misc patterns (?)
16634 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16635 ;; Otherwise there will be nothing to keep
16637 ;; [(set (reg ebp) (reg esp))]
16638 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16639 ;; (clobber (eflags)]
16640 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16642 ;; in proper program order.
16644 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16645 [(set (match_operand:P 0 "register_operand" "=r,r")
16646 (plus:P (match_operand:P 1 "register_operand" "0,r")
16647 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16648 (clobber (reg:CC FLAGS_REG))
16649 (clobber (mem:BLK (scratch)))]
16652 switch (get_attr_type (insn))
16655 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16658 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16659 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16660 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16662 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16665 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16666 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16669 [(set (attr "type")
16670 (cond [(and (eq_attr "alternative" "0")
16671 (not (match_test "TARGET_OPT_AGU")))
16672 (const_string "alu")
16673 (match_operand:<MODE> 2 "const0_operand" "")
16674 (const_string "imov")
16676 (const_string "lea")))
16677 (set (attr "length_immediate")
16678 (cond [(eq_attr "type" "imov")
16680 (and (eq_attr "type" "alu")
16681 (match_operand 2 "const128_operand" ""))
16684 (const_string "*")))
16685 (set_attr "mode" "<MODE>")])
16687 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16688 [(set (match_operand:P 0 "register_operand" "=r")
16689 (minus:P (match_operand:P 1 "register_operand" "0")
16690 (match_operand:P 2 "register_operand" "r")))
16691 (clobber (reg:CC FLAGS_REG))
16692 (clobber (mem:BLK (scratch)))]
16694 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16695 [(set_attr "type" "alu")
16696 (set_attr "mode" "<MODE>")])
16698 (define_insn "allocate_stack_worker_probe_<mode>"
16699 [(set (match_operand:P 0 "register_operand" "=a")
16700 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16701 UNSPECV_STACK_PROBE))
16702 (clobber (reg:CC FLAGS_REG))]
16703 "ix86_target_stack_probe ()"
16704 "call\t___chkstk_ms"
16705 [(set_attr "type" "multi")
16706 (set_attr "length" "5")])
16708 (define_expand "allocate_stack"
16709 [(match_operand 0 "register_operand" "")
16710 (match_operand 1 "general_operand" "")]
16711 "ix86_target_stack_probe ()"
16715 #ifndef CHECK_STACK_LIMIT
16716 #define CHECK_STACK_LIMIT 0
16719 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16720 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16722 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16723 stack_pointer_rtx, 0, OPTAB_DIRECT);
16724 if (x != stack_pointer_rtx)
16725 emit_move_insn (stack_pointer_rtx, x);
16729 x = copy_to_mode_reg (Pmode, operands[1]);
16731 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16733 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16734 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16735 stack_pointer_rtx, 0, OPTAB_DIRECT);
16736 if (x != stack_pointer_rtx)
16737 emit_move_insn (stack_pointer_rtx, x);
16740 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16744 ;; Use IOR for stack probes, this is shorter.
16745 (define_expand "probe_stack"
16746 [(match_operand 0 "memory_operand" "")]
16749 rtx (*gen_ior3) (rtx, rtx, rtx);
16751 gen_ior3 = (GET_MODE (operands[0]) == DImode
16752 ? gen_iordi3 : gen_iorsi3);
16754 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16758 (define_insn "adjust_stack_and_probe<mode>"
16759 [(set (match_operand:P 0 "register_operand" "=r")
16760 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16761 UNSPECV_PROBE_STACK_RANGE))
16762 (set (reg:P SP_REG)
16763 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16764 (clobber (reg:CC FLAGS_REG))
16765 (clobber (mem:BLK (scratch)))]
16767 "* return output_adjust_stack_and_probe (operands[0]);"
16768 [(set_attr "type" "multi")])
16770 (define_insn "probe_stack_range<mode>"
16771 [(set (match_operand:P 0 "register_operand" "=r")
16772 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16773 (match_operand:P 2 "const_int_operand" "n")]
16774 UNSPECV_PROBE_STACK_RANGE))
16775 (clobber (reg:CC FLAGS_REG))]
16777 "* return output_probe_stack_range (operands[0], operands[2]);"
16778 [(set_attr "type" "multi")])
16780 (define_expand "builtin_setjmp_receiver"
16781 [(label_ref (match_operand 0 "" ""))]
16782 "!TARGET_64BIT && flag_pic"
16788 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16789 rtx label_rtx = gen_label_rtx ();
16790 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16791 xops[0] = xops[1] = picreg;
16792 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16793 ix86_expand_binary_operator (MINUS, SImode, xops);
16797 emit_insn (gen_set_got (pic_offset_table_rtx));
16801 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16804 [(set (match_operand 0 "register_operand" "")
16805 (match_operator 3 "promotable_binary_operator"
16806 [(match_operand 1 "register_operand" "")
16807 (match_operand 2 "aligned_operand" "")]))
16808 (clobber (reg:CC FLAGS_REG))]
16809 "! TARGET_PARTIAL_REG_STALL && reload_completed
16810 && ((GET_MODE (operands[0]) == HImode
16811 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16812 /* ??? next two lines just !satisfies_constraint_K (...) */
16813 || !CONST_INT_P (operands[2])
16814 || satisfies_constraint_K (operands[2])))
16815 || (GET_MODE (operands[0]) == QImode
16816 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16817 [(parallel [(set (match_dup 0)
16818 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16819 (clobber (reg:CC FLAGS_REG))])]
16821 operands[0] = gen_lowpart (SImode, operands[0]);
16822 operands[1] = gen_lowpart (SImode, operands[1]);
16823 if (GET_CODE (operands[3]) != ASHIFT)
16824 operands[2] = gen_lowpart (SImode, operands[2]);
16825 PUT_MODE (operands[3], SImode);
16828 ; Promote the QImode tests, as i386 has encoding of the AND
16829 ; instruction with 32-bit sign-extended immediate and thus the
16830 ; instruction size is unchanged, except in the %eax case for
16831 ; which it is increased by one byte, hence the ! optimize_size.
16833 [(set (match_operand 0 "flags_reg_operand" "")
16834 (match_operator 2 "compare_operator"
16835 [(and (match_operand 3 "aligned_operand" "")
16836 (match_operand 4 "const_int_operand" ""))
16838 (set (match_operand 1 "register_operand" "")
16839 (and (match_dup 3) (match_dup 4)))]
16840 "! TARGET_PARTIAL_REG_STALL && reload_completed
16841 && optimize_insn_for_speed_p ()
16842 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16843 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16844 /* Ensure that the operand will remain sign-extended immediate. */
16845 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16846 [(parallel [(set (match_dup 0)
16847 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16850 (and:SI (match_dup 3) (match_dup 4)))])]
16853 = gen_int_mode (INTVAL (operands[4])
16854 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16855 operands[1] = gen_lowpart (SImode, operands[1]);
16856 operands[3] = gen_lowpart (SImode, operands[3]);
16859 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16860 ; the TEST instruction with 32-bit sign-extended immediate and thus
16861 ; the instruction size would at least double, which is not what we
16862 ; want even with ! optimize_size.
16864 [(set (match_operand 0 "flags_reg_operand" "")
16865 (match_operator 1 "compare_operator"
16866 [(and (match_operand:HI 2 "aligned_operand" "")
16867 (match_operand:HI 3 "const_int_operand" ""))
16869 "! TARGET_PARTIAL_REG_STALL && reload_completed
16870 && ! TARGET_FAST_PREFIX
16871 && optimize_insn_for_speed_p ()
16872 /* Ensure that the operand will remain sign-extended immediate. */
16873 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16874 [(set (match_dup 0)
16875 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16879 = gen_int_mode (INTVAL (operands[3])
16880 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16881 operands[2] = gen_lowpart (SImode, operands[2]);
16885 [(set (match_operand 0 "register_operand" "")
16886 (neg (match_operand 1 "register_operand" "")))
16887 (clobber (reg:CC FLAGS_REG))]
16888 "! TARGET_PARTIAL_REG_STALL && reload_completed
16889 && (GET_MODE (operands[0]) == HImode
16890 || (GET_MODE (operands[0]) == QImode
16891 && (TARGET_PROMOTE_QImode
16892 || optimize_insn_for_size_p ())))"
16893 [(parallel [(set (match_dup 0)
16894 (neg:SI (match_dup 1)))
16895 (clobber (reg:CC FLAGS_REG))])]
16897 operands[0] = gen_lowpart (SImode, operands[0]);
16898 operands[1] = gen_lowpart (SImode, operands[1]);
16902 [(set (match_operand 0 "register_operand" "")
16903 (not (match_operand 1 "register_operand" "")))]
16904 "! TARGET_PARTIAL_REG_STALL && reload_completed
16905 && (GET_MODE (operands[0]) == HImode
16906 || (GET_MODE (operands[0]) == QImode
16907 && (TARGET_PROMOTE_QImode
16908 || optimize_insn_for_size_p ())))"
16909 [(set (match_dup 0)
16910 (not:SI (match_dup 1)))]
16912 operands[0] = gen_lowpart (SImode, operands[0]);
16913 operands[1] = gen_lowpart (SImode, operands[1]);
16916 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16917 ;; transform a complex memory operation into two memory to register operations.
16919 ;; Don't push memory operands
16921 [(set (match_operand:SWI 0 "push_operand" "")
16922 (match_operand:SWI 1 "memory_operand" ""))
16923 (match_scratch:SWI 2 "<r>")]
16924 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16925 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16926 [(set (match_dup 2) (match_dup 1))
16927 (set (match_dup 0) (match_dup 2))])
16929 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16932 [(set (match_operand:SF 0 "push_operand" "")
16933 (match_operand:SF 1 "memory_operand" ""))
16934 (match_scratch:SF 2 "r")]
16935 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16936 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16937 [(set (match_dup 2) (match_dup 1))
16938 (set (match_dup 0) (match_dup 2))])
16940 ;; Don't move an immediate directly to memory when the instruction
16943 [(match_scratch:SWI124 1 "<r>")
16944 (set (match_operand:SWI124 0 "memory_operand" "")
16946 "optimize_insn_for_speed_p ()
16947 && !TARGET_USE_MOV0
16948 && TARGET_SPLIT_LONG_MOVES
16949 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16950 && peep2_regno_dead_p (0, FLAGS_REG)"
16951 [(parallel [(set (match_dup 2) (const_int 0))
16952 (clobber (reg:CC FLAGS_REG))])
16953 (set (match_dup 0) (match_dup 1))]
16954 "operands[2] = gen_lowpart (SImode, operands[1]);")
16957 [(match_scratch:SWI124 2 "<r>")
16958 (set (match_operand:SWI124 0 "memory_operand" "")
16959 (match_operand:SWI124 1 "immediate_operand" ""))]
16960 "optimize_insn_for_speed_p ()
16961 && TARGET_SPLIT_LONG_MOVES
16962 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16963 [(set (match_dup 2) (match_dup 1))
16964 (set (match_dup 0) (match_dup 2))])
16966 ;; Don't compare memory with zero, load and use a test instead.
16968 [(set (match_operand 0 "flags_reg_operand" "")
16969 (match_operator 1 "compare_operator"
16970 [(match_operand:SI 2 "memory_operand" "")
16972 (match_scratch:SI 3 "r")]
16973 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16974 [(set (match_dup 3) (match_dup 2))
16975 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16977 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16978 ;; Don't split NOTs with a displacement operand, because resulting XOR
16979 ;; will not be pairable anyway.
16981 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16982 ;; represented using a modRM byte. The XOR replacement is long decoded,
16983 ;; so this split helps here as well.
16985 ;; Note: Can't do this as a regular split because we can't get proper
16986 ;; lifetime information then.
16989 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16990 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16991 "optimize_insn_for_speed_p ()
16992 && ((TARGET_NOT_UNPAIRABLE
16993 && (!MEM_P (operands[0])
16994 || !memory_displacement_operand (operands[0], <MODE>mode)))
16995 || (TARGET_NOT_VECTORMODE
16996 && long_memory_operand (operands[0], <MODE>mode)))
16997 && peep2_regno_dead_p (0, FLAGS_REG)"
16998 [(parallel [(set (match_dup 0)
16999 (xor:SWI124 (match_dup 1) (const_int -1)))
17000 (clobber (reg:CC FLAGS_REG))])])
17002 ;; Non pairable "test imm, reg" instructions can be translated to
17003 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17004 ;; byte opcode instead of two, have a short form for byte operands),
17005 ;; so do it for other CPUs as well. Given that the value was dead,
17006 ;; this should not create any new dependencies. Pass on the sub-word
17007 ;; versions if we're concerned about partial register stalls.
17010 [(set (match_operand 0 "flags_reg_operand" "")
17011 (match_operator 1 "compare_operator"
17012 [(and:SI (match_operand:SI 2 "register_operand" "")
17013 (match_operand:SI 3 "immediate_operand" ""))
17015 "ix86_match_ccmode (insn, CCNOmode)
17016 && (true_regnum (operands[2]) != AX_REG
17017 || satisfies_constraint_K (operands[3]))
17018 && peep2_reg_dead_p (1, operands[2])"
17020 [(set (match_dup 0)
17021 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17024 (and:SI (match_dup 2) (match_dup 3)))])])
17026 ;; We don't need to handle HImode case, because it will be promoted to SImode
17027 ;; on ! TARGET_PARTIAL_REG_STALL
17030 [(set (match_operand 0 "flags_reg_operand" "")
17031 (match_operator 1 "compare_operator"
17032 [(and:QI (match_operand:QI 2 "register_operand" "")
17033 (match_operand:QI 3 "immediate_operand" ""))
17035 "! TARGET_PARTIAL_REG_STALL
17036 && ix86_match_ccmode (insn, CCNOmode)
17037 && true_regnum (operands[2]) != AX_REG
17038 && peep2_reg_dead_p (1, operands[2])"
17040 [(set (match_dup 0)
17041 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17044 (and:QI (match_dup 2) (match_dup 3)))])])
17047 [(set (match_operand 0 "flags_reg_operand" "")
17048 (match_operator 1 "compare_operator"
17051 (match_operand 2 "ext_register_operand" "")
17054 (match_operand 3 "const_int_operand" ""))
17056 "! TARGET_PARTIAL_REG_STALL
17057 && ix86_match_ccmode (insn, CCNOmode)
17058 && true_regnum (operands[2]) != AX_REG
17059 && peep2_reg_dead_p (1, operands[2])"
17060 [(parallel [(set (match_dup 0)
17069 (set (zero_extract:SI (match_dup 2)
17077 (match_dup 3)))])])
17079 ;; Don't do logical operations with memory inputs.
17081 [(match_scratch:SI 2 "r")
17082 (parallel [(set (match_operand:SI 0 "register_operand" "")
17083 (match_operator:SI 3 "arith_or_logical_operator"
17085 (match_operand:SI 1 "memory_operand" "")]))
17086 (clobber (reg:CC FLAGS_REG))])]
17087 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17088 [(set (match_dup 2) (match_dup 1))
17089 (parallel [(set (match_dup 0)
17090 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17091 (clobber (reg:CC FLAGS_REG))])])
17094 [(match_scratch:SI 2 "r")
17095 (parallel [(set (match_operand:SI 0 "register_operand" "")
17096 (match_operator:SI 3 "arith_or_logical_operator"
17097 [(match_operand:SI 1 "memory_operand" "")
17099 (clobber (reg:CC FLAGS_REG))])]
17100 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17101 [(set (match_dup 2) (match_dup 1))
17102 (parallel [(set (match_dup 0)
17103 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17104 (clobber (reg:CC FLAGS_REG))])])
17106 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17107 ;; refers to the destination of the load!
17110 [(set (match_operand:SI 0 "register_operand" "")
17111 (match_operand:SI 1 "register_operand" ""))
17112 (parallel [(set (match_dup 0)
17113 (match_operator:SI 3 "commutative_operator"
17115 (match_operand:SI 2 "memory_operand" "")]))
17116 (clobber (reg:CC FLAGS_REG))])]
17117 "REGNO (operands[0]) != REGNO (operands[1])
17118 && GENERAL_REGNO_P (REGNO (operands[0]))
17119 && GENERAL_REGNO_P (REGNO (operands[1]))"
17120 [(set (match_dup 0) (match_dup 4))
17121 (parallel [(set (match_dup 0)
17122 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17123 (clobber (reg:CC FLAGS_REG))])]
17124 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17127 [(set (match_operand 0 "register_operand" "")
17128 (match_operand 1 "register_operand" ""))
17130 (match_operator 3 "commutative_operator"
17132 (match_operand 2 "memory_operand" "")]))]
17133 "REGNO (operands[0]) != REGNO (operands[1])
17134 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17135 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17136 [(set (match_dup 0) (match_dup 2))
17138 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17140 ; Don't do logical operations with memory outputs
17142 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17143 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17144 ; the same decoder scheduling characteristics as the original.
17147 [(match_scratch:SI 2 "r")
17148 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17149 (match_operator:SI 3 "arith_or_logical_operator"
17151 (match_operand:SI 1 "nonmemory_operand" "")]))
17152 (clobber (reg:CC FLAGS_REG))])]
17153 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17154 /* Do not split stack checking probes. */
17155 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17156 [(set (match_dup 2) (match_dup 0))
17157 (parallel [(set (match_dup 2)
17158 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17159 (clobber (reg:CC FLAGS_REG))])
17160 (set (match_dup 0) (match_dup 2))])
17163 [(match_scratch:SI 2 "r")
17164 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17165 (match_operator:SI 3 "arith_or_logical_operator"
17166 [(match_operand:SI 1 "nonmemory_operand" "")
17168 (clobber (reg:CC FLAGS_REG))])]
17169 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17170 /* Do not split stack checking probes. */
17171 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17172 [(set (match_dup 2) (match_dup 0))
17173 (parallel [(set (match_dup 2)
17174 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17175 (clobber (reg:CC FLAGS_REG))])
17176 (set (match_dup 0) (match_dup 2))])
17178 ;; Attempt to use arith or logical operations with memory outputs with
17179 ;; setting of flags.
17181 [(set (match_operand:SWI 0 "register_operand" "")
17182 (match_operand:SWI 1 "memory_operand" ""))
17183 (parallel [(set (match_dup 0)
17184 (match_operator:SWI 3 "plusminuslogic_operator"
17186 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17187 (clobber (reg:CC FLAGS_REG))])
17188 (set (match_dup 1) (match_dup 0))
17189 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17190 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17191 && peep2_reg_dead_p (4, operands[0])
17192 && !reg_overlap_mentioned_p (operands[0], operands[1])
17193 && (<MODE>mode != QImode
17194 || immediate_operand (operands[2], QImode)
17195 || q_regs_operand (operands[2], QImode))
17196 && ix86_match_ccmode (peep2_next_insn (3),
17197 (GET_CODE (operands[3]) == PLUS
17198 || GET_CODE (operands[3]) == MINUS)
17199 ? CCGOCmode : CCNOmode)"
17200 [(parallel [(set (match_dup 4) (match_dup 5))
17201 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17202 (match_dup 2)]))])]
17204 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17205 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17206 copy_rtx (operands[1]),
17207 copy_rtx (operands[2]));
17208 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17209 operands[5], const0_rtx);
17213 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17214 (match_operator:SWI 2 "plusminuslogic_operator"
17216 (match_operand:SWI 1 "memory_operand" "")]))
17217 (clobber (reg:CC FLAGS_REG))])
17218 (set (match_dup 1) (match_dup 0))
17219 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17220 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17221 && GET_CODE (operands[2]) != MINUS
17222 && peep2_reg_dead_p (3, operands[0])
17223 && !reg_overlap_mentioned_p (operands[0], operands[1])
17224 && ix86_match_ccmode (peep2_next_insn (2),
17225 GET_CODE (operands[2]) == PLUS
17226 ? CCGOCmode : CCNOmode)"
17227 [(parallel [(set (match_dup 3) (match_dup 4))
17228 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17229 (match_dup 0)]))])]
17231 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17232 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17233 copy_rtx (operands[1]),
17234 copy_rtx (operands[0]));
17235 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17236 operands[4], const0_rtx);
17240 [(set (match_operand:SWI12 0 "register_operand" "")
17241 (match_operand:SWI12 1 "memory_operand" ""))
17242 (parallel [(set (match_operand:SI 4 "register_operand" "")
17243 (match_operator:SI 3 "plusminuslogic_operator"
17245 (match_operand:SI 2 "nonmemory_operand" "")]))
17246 (clobber (reg:CC FLAGS_REG))])
17247 (set (match_dup 1) (match_dup 0))
17248 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17249 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17250 && REG_P (operands[0]) && REG_P (operands[4])
17251 && REGNO (operands[0]) == REGNO (operands[4])
17252 && peep2_reg_dead_p (4, operands[0])
17253 && (<MODE>mode != QImode
17254 || immediate_operand (operands[2], SImode)
17255 || q_regs_operand (operands[2], SImode))
17256 && !reg_overlap_mentioned_p (operands[0], operands[1])
17257 && ix86_match_ccmode (peep2_next_insn (3),
17258 (GET_CODE (operands[3]) == PLUS
17259 || GET_CODE (operands[3]) == MINUS)
17260 ? CCGOCmode : CCNOmode)"
17261 [(parallel [(set (match_dup 4) (match_dup 5))
17262 (set (match_dup 1) (match_dup 6))])]
17264 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17265 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17266 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17267 copy_rtx (operands[1]), operands[2]);
17268 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17269 operands[5], const0_rtx);
17270 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17271 copy_rtx (operands[1]),
17272 copy_rtx (operands[2]));
17275 ;; Attempt to always use XOR for zeroing registers.
17277 [(set (match_operand 0 "register_operand" "")
17278 (match_operand 1 "const0_operand" ""))]
17279 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17280 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17281 && GENERAL_REG_P (operands[0])
17282 && peep2_regno_dead_p (0, FLAGS_REG)"
17283 [(parallel [(set (match_dup 0) (const_int 0))
17284 (clobber (reg:CC FLAGS_REG))])]
17285 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17288 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17290 "(GET_MODE (operands[0]) == QImode
17291 || GET_MODE (operands[0]) == HImode)
17292 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17293 && peep2_regno_dead_p (0, FLAGS_REG)"
17294 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17295 (clobber (reg:CC FLAGS_REG))])])
17297 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17299 [(set (match_operand:SWI248 0 "register_operand" "")
17301 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17302 && peep2_regno_dead_p (0, FLAGS_REG)"
17303 [(parallel [(set (match_dup 0) (const_int -1))
17304 (clobber (reg:CC FLAGS_REG))])]
17306 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17307 operands[0] = gen_lowpart (SImode, operands[0]);
17310 ;; Attempt to convert simple lea to add/shift.
17311 ;; These can be created by move expanders.
17314 [(set (match_operand:SWI48 0 "register_operand" "")
17315 (plus:SWI48 (match_dup 0)
17316 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17317 "peep2_regno_dead_p (0, FLAGS_REG)"
17318 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17319 (clobber (reg:CC FLAGS_REG))])])
17322 [(set (match_operand:SI 0 "register_operand" "")
17323 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17324 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17326 && peep2_regno_dead_p (0, FLAGS_REG)
17327 && REGNO (operands[0]) == REGNO (operands[1])"
17328 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17329 (clobber (reg:CC FLAGS_REG))])]
17330 "operands[2] = gen_lowpart (SImode, operands[2]);")
17333 [(set (match_operand:SWI48 0 "register_operand" "")
17334 (mult:SWI48 (match_dup 0)
17335 (match_operand:SWI48 1 "const_int_operand" "")))]
17336 "exact_log2 (INTVAL (operands[1])) >= 0
17337 && peep2_regno_dead_p (0, FLAGS_REG)"
17338 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17339 (clobber (reg:CC FLAGS_REG))])]
17340 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17343 [(set (match_operand:SI 0 "register_operand" "")
17344 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17345 (match_operand:DI 2 "const_int_operand" "")) 0))]
17347 && exact_log2 (INTVAL (operands[2])) >= 0
17348 && REGNO (operands[0]) == REGNO (operands[1])
17349 && peep2_regno_dead_p (0, FLAGS_REG)"
17350 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17351 (clobber (reg:CC FLAGS_REG))])]
17352 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17354 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17355 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17356 ;; On many CPUs it is also faster, since special hardware to avoid esp
17357 ;; dependencies is present.
17359 ;; While some of these conversions may be done using splitters, we use
17360 ;; peepholes in order to allow combine_stack_adjustments pass to see
17361 ;; nonobfuscated RTL.
17363 ;; Convert prologue esp subtractions to push.
17364 ;; We need register to push. In order to keep verify_flow_info happy we have
17366 ;; - use scratch and clobber it in order to avoid dependencies
17367 ;; - use already live register
17368 ;; We can't use the second way right now, since there is no reliable way how to
17369 ;; verify that given register is live. First choice will also most likely in
17370 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17371 ;; call clobbered registers are dead. We may want to use base pointer as an
17372 ;; alternative when no register is available later.
17375 [(match_scratch:P 1 "r")
17376 (parallel [(set (reg:P SP_REG)
17377 (plus:P (reg:P SP_REG)
17378 (match_operand:P 0 "const_int_operand" "")))
17379 (clobber (reg:CC FLAGS_REG))
17380 (clobber (mem:BLK (scratch)))])]
17381 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17382 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17383 [(clobber (match_dup 1))
17384 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17385 (clobber (mem:BLK (scratch)))])])
17388 [(match_scratch:P 1 "r")
17389 (parallel [(set (reg:P SP_REG)
17390 (plus:P (reg:P SP_REG)
17391 (match_operand:P 0 "const_int_operand" "")))
17392 (clobber (reg:CC FLAGS_REG))
17393 (clobber (mem:BLK (scratch)))])]
17394 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17395 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17396 [(clobber (match_dup 1))
17397 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17398 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17399 (clobber (mem:BLK (scratch)))])])
17401 ;; Convert esp subtractions to push.
17403 [(match_scratch:P 1 "r")
17404 (parallel [(set (reg:P SP_REG)
17405 (plus:P (reg:P SP_REG)
17406 (match_operand:P 0 "const_int_operand" "")))
17407 (clobber (reg:CC FLAGS_REG))])]
17408 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17409 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17410 [(clobber (match_dup 1))
17411 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17414 [(match_scratch:P 1 "r")
17415 (parallel [(set (reg:P SP_REG)
17416 (plus:P (reg:P SP_REG)
17417 (match_operand:P 0 "const_int_operand" "")))
17418 (clobber (reg:CC FLAGS_REG))])]
17419 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17420 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17421 [(clobber (match_dup 1))
17422 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17423 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17425 ;; Convert epilogue deallocator to pop.
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 (clobber (mem:BLK (scratch)))])]
17433 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17434 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17435 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17436 (clobber (mem:BLK (scratch)))])])
17438 ;; Two pops case is tricky, since pop causes dependency
17439 ;; on destination register. We use two registers if available.
17441 [(match_scratch:P 1 "r")
17442 (match_scratch:P 2 "r")
17443 (parallel [(set (reg:P SP_REG)
17444 (plus:P (reg:P SP_REG)
17445 (match_operand:P 0 "const_int_operand" "")))
17446 (clobber (reg:CC FLAGS_REG))
17447 (clobber (mem:BLK (scratch)))])]
17448 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17449 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17450 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17451 (clobber (mem:BLK (scratch)))])
17452 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17455 [(match_scratch:P 1 "r")
17456 (parallel [(set (reg:P SP_REG)
17457 (plus:P (reg:P SP_REG)
17458 (match_operand:P 0 "const_int_operand" "")))
17459 (clobber (reg:CC FLAGS_REG))
17460 (clobber (mem:BLK (scratch)))])]
17461 "optimize_insn_for_size_p ()
17462 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17463 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17464 (clobber (mem:BLK (scratch)))])
17465 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17467 ;; Convert esp additions to pop.
17469 [(match_scratch:P 1 "r")
17470 (parallel [(set (reg:P SP_REG)
17471 (plus:P (reg:P SP_REG)
17472 (match_operand:P 0 "const_int_operand" "")))
17473 (clobber (reg:CC FLAGS_REG))])]
17474 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17475 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17477 ;; Two pops case is tricky, since pop causes dependency
17478 ;; on destination register. We use two registers if available.
17480 [(match_scratch:P 1 "r")
17481 (match_scratch:P 2 "r")
17482 (parallel [(set (reg:P SP_REG)
17483 (plus:P (reg:P SP_REG)
17484 (match_operand:P 0 "const_int_operand" "")))
17485 (clobber (reg:CC FLAGS_REG))])]
17486 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17487 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17488 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17491 [(match_scratch:P 1 "r")
17492 (parallel [(set (reg:P SP_REG)
17493 (plus:P (reg:P SP_REG)
17494 (match_operand:P 0 "const_int_operand" "")))
17495 (clobber (reg:CC FLAGS_REG))])]
17496 "optimize_insn_for_size_p ()
17497 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17498 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17499 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17501 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17502 ;; required and register dies. Similarly for 128 to -128.
17504 [(set (match_operand 0 "flags_reg_operand" "")
17505 (match_operator 1 "compare_operator"
17506 [(match_operand 2 "register_operand" "")
17507 (match_operand 3 "const_int_operand" "")]))]
17508 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17509 && incdec_operand (operands[3], GET_MODE (operands[3])))
17510 || (!TARGET_FUSE_CMP_AND_BRANCH
17511 && INTVAL (operands[3]) == 128))
17512 && ix86_match_ccmode (insn, CCGCmode)
17513 && peep2_reg_dead_p (1, operands[2])"
17514 [(parallel [(set (match_dup 0)
17515 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17516 (clobber (match_dup 2))])])
17518 ;; Convert imul by three, five and nine into lea
17521 [(set (match_operand:SWI48 0 "register_operand" "")
17522 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17523 (match_operand:SWI48 2 "const359_operand" "")))
17524 (clobber (reg:CC FLAGS_REG))])]
17525 "!TARGET_PARTIAL_REG_STALL
17526 || <MODE>mode == SImode
17527 || optimize_function_for_size_p (cfun)"
17528 [(set (match_dup 0)
17529 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17531 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17535 [(set (match_operand:SWI48 0 "register_operand" "")
17536 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17537 (match_operand:SWI48 2 "const359_operand" "")))
17538 (clobber (reg:CC FLAGS_REG))])]
17539 "optimize_insn_for_speed_p ()
17540 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17541 [(set (match_dup 0) (match_dup 1))
17543 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17545 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17547 ;; imul $32bit_imm, mem, reg is vector decoded, while
17548 ;; imul $32bit_imm, reg, reg is direct decoded.
17550 [(match_scratch:SWI48 3 "r")
17551 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17552 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17553 (match_operand:SWI48 2 "immediate_operand" "")))
17554 (clobber (reg:CC FLAGS_REG))])]
17555 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17556 && !satisfies_constraint_K (operands[2])"
17557 [(set (match_dup 3) (match_dup 1))
17558 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17559 (clobber (reg:CC FLAGS_REG))])])
17562 [(match_scratch:SI 3 "r")
17563 (parallel [(set (match_operand:DI 0 "register_operand" "")
17565 (mult:SI (match_operand:SI 1 "memory_operand" "")
17566 (match_operand:SI 2 "immediate_operand" ""))))
17567 (clobber (reg:CC FLAGS_REG))])]
17569 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17570 && !satisfies_constraint_K (operands[2])"
17571 [(set (match_dup 3) (match_dup 1))
17572 (parallel [(set (match_dup 0)
17573 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17574 (clobber (reg:CC FLAGS_REG))])])
17576 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17577 ;; Convert it into imul reg, reg
17578 ;; It would be better to force assembler to encode instruction using long
17579 ;; immediate, but there is apparently no way to do so.
17581 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17583 (match_operand:SWI248 1 "nonimmediate_operand" "")
17584 (match_operand:SWI248 2 "const_int_operand" "")))
17585 (clobber (reg:CC FLAGS_REG))])
17586 (match_scratch:SWI248 3 "r")]
17587 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17588 && satisfies_constraint_K (operands[2])"
17589 [(set (match_dup 3) (match_dup 2))
17590 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17591 (clobber (reg:CC FLAGS_REG))])]
17593 if (!rtx_equal_p (operands[0], operands[1]))
17594 emit_move_insn (operands[0], operands[1]);
17597 ;; After splitting up read-modify operations, array accesses with memory
17598 ;; operands might end up in form:
17600 ;; movl 4(%esp), %edx
17602 ;; instead of pre-splitting:
17604 ;; addl 4(%esp), %eax
17606 ;; movl 4(%esp), %edx
17607 ;; leal (%edx,%eax,4), %eax
17610 [(match_scratch:P 5 "r")
17611 (parallel [(set (match_operand 0 "register_operand" "")
17612 (ashift (match_operand 1 "register_operand" "")
17613 (match_operand 2 "const_int_operand" "")))
17614 (clobber (reg:CC FLAGS_REG))])
17615 (parallel [(set (match_operand 3 "register_operand" "")
17616 (plus (match_dup 0)
17617 (match_operand 4 "x86_64_general_operand" "")))
17618 (clobber (reg:CC FLAGS_REG))])]
17619 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17620 /* Validate MODE for lea. */
17621 && ((!TARGET_PARTIAL_REG_STALL
17622 && (GET_MODE (operands[0]) == QImode
17623 || GET_MODE (operands[0]) == HImode))
17624 || GET_MODE (operands[0]) == SImode
17625 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17626 && (rtx_equal_p (operands[0], operands[3])
17627 || peep2_reg_dead_p (2, operands[0]))
17628 /* We reorder load and the shift. */
17629 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17630 [(set (match_dup 5) (match_dup 4))
17631 (set (match_dup 0) (match_dup 1))]
17633 enum machine_mode op1mode = GET_MODE (operands[1]);
17634 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17635 int scale = 1 << INTVAL (operands[2]);
17636 rtx index = gen_lowpart (Pmode, operands[1]);
17637 rtx base = gen_lowpart (Pmode, operands[5]);
17638 rtx dest = gen_lowpart (mode, operands[3]);
17640 operands[1] = gen_rtx_PLUS (Pmode, base,
17641 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17642 operands[5] = base;
17644 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17645 if (op1mode != Pmode)
17646 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17647 operands[0] = dest;
17650 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17651 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17652 ;; caught for use by garbage collectors and the like. Using an insn that
17653 ;; maps to SIGILL makes it more likely the program will rightfully die.
17654 ;; Keeping with tradition, "6" is in honor of #UD.
17655 (define_insn "trap"
17656 [(trap_if (const_int 1) (const_int 6))]
17658 { return ASM_SHORT "0x0b0f"; }
17659 [(set_attr "length" "2")])
17661 (define_expand "prefetch"
17662 [(prefetch (match_operand 0 "address_operand" "")
17663 (match_operand:SI 1 "const_int_operand" "")
17664 (match_operand:SI 2 "const_int_operand" ""))]
17665 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17667 int rw = INTVAL (operands[1]);
17668 int locality = INTVAL (operands[2]);
17670 gcc_assert (rw == 0 || rw == 1);
17671 gcc_assert (IN_RANGE (locality, 0, 3));
17673 if (TARGET_PREFETCHW && rw)
17674 operands[2] = GEN_INT (3);
17675 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17676 supported by SSE counterpart or the SSE prefetch is not available
17677 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17679 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17680 operands[2] = GEN_INT (3);
17682 operands[1] = const0_rtx;
17685 (define_insn "*prefetch_sse"
17686 [(prefetch (match_operand 0 "address_operand" "p")
17688 (match_operand:SI 1 "const_int_operand" ""))]
17689 "TARGET_PREFETCH_SSE"
17691 static const char * const patterns[4] = {
17692 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17695 int locality = INTVAL (operands[1]);
17696 gcc_assert (IN_RANGE (locality, 0, 3));
17698 return patterns[locality];
17700 [(set_attr "type" "sse")
17701 (set_attr "atom_sse_attr" "prefetch")
17702 (set (attr "length_address")
17703 (symbol_ref "memory_address_length (operands[0])"))
17704 (set_attr "memory" "none")])
17706 (define_insn "*prefetch_3dnow"
17707 [(prefetch (match_operand 0 "address_operand" "p")
17708 (match_operand:SI 1 "const_int_operand" "n")
17710 "TARGET_3DNOW || TARGET_PREFETCHW"
17712 if (INTVAL (operands[1]) == 0)
17713 return "prefetch\t%a0";
17715 return "prefetchw\t%a0";
17717 [(set_attr "type" "mmx")
17718 (set (attr "length_address")
17719 (symbol_ref "memory_address_length (operands[0])"))
17720 (set_attr "memory" "none")])
17722 (define_expand "stack_protect_set"
17723 [(match_operand 0 "memory_operand" "")
17724 (match_operand 1 "memory_operand" "")]
17725 "!TARGET_HAS_BIONIC"
17727 rtx (*insn)(rtx, rtx);
17729 #ifdef TARGET_THREAD_SSP_OFFSET
17730 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17731 insn = (TARGET_LP64
17732 ? gen_stack_tls_protect_set_di
17733 : gen_stack_tls_protect_set_si);
17735 insn = (TARGET_LP64
17736 ? gen_stack_protect_set_di
17737 : gen_stack_protect_set_si);
17740 emit_insn (insn (operands[0], operands[1]));
17744 (define_insn "stack_protect_set_<mode>"
17745 [(set (match_operand:PTR 0 "memory_operand" "=m")
17746 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17748 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17749 (clobber (reg:CC FLAGS_REG))]
17750 "!TARGET_HAS_BIONIC"
17751 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17752 [(set_attr "type" "multi")])
17754 (define_insn "stack_tls_protect_set_<mode>"
17755 [(set (match_operand:PTR 0 "memory_operand" "=m")
17756 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17757 UNSPEC_SP_TLS_SET))
17758 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17759 (clobber (reg:CC FLAGS_REG))]
17761 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17762 [(set_attr "type" "multi")])
17764 (define_expand "stack_protect_test"
17765 [(match_operand 0 "memory_operand" "")
17766 (match_operand 1 "memory_operand" "")
17767 (match_operand 2 "" "")]
17768 "!TARGET_HAS_BIONIC"
17770 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17772 rtx (*insn)(rtx, rtx, rtx);
17774 #ifdef TARGET_THREAD_SSP_OFFSET
17775 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17776 insn = (TARGET_LP64
17777 ? gen_stack_tls_protect_test_di
17778 : gen_stack_tls_protect_test_si);
17780 insn = (TARGET_LP64
17781 ? gen_stack_protect_test_di
17782 : gen_stack_protect_test_si);
17785 emit_insn (insn (flags, operands[0], operands[1]));
17787 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17788 flags, const0_rtx, operands[2]));
17792 (define_insn "stack_protect_test_<mode>"
17793 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17794 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17795 (match_operand:PTR 2 "memory_operand" "m")]
17797 (clobber (match_scratch:PTR 3 "=&r"))]
17798 "!TARGET_HAS_BIONIC"
17799 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17800 [(set_attr "type" "multi")])
17802 (define_insn "stack_tls_protect_test_<mode>"
17803 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17804 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17805 (match_operand:PTR 2 "const_int_operand" "i")]
17806 UNSPEC_SP_TLS_TEST))
17807 (clobber (match_scratch:PTR 3 "=r"))]
17809 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17810 [(set_attr "type" "multi")])
17812 (define_insn "sse4_2_crc32<mode>"
17813 [(set (match_operand:SI 0 "register_operand" "=r")
17815 [(match_operand:SI 1 "register_operand" "0")
17816 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17818 "TARGET_SSE4_2 || TARGET_CRC32"
17819 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17820 [(set_attr "type" "sselog1")
17821 (set_attr "prefix_rep" "1")
17822 (set_attr "prefix_extra" "1")
17823 (set (attr "prefix_data16")
17824 (if_then_else (match_operand:HI 2 "" "")
17826 (const_string "*")))
17827 (set (attr "prefix_rex")
17828 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17830 (const_string "*")))
17831 (set_attr "mode" "SI")])
17833 (define_insn "sse4_2_crc32di"
17834 [(set (match_operand:DI 0 "register_operand" "=r")
17836 [(match_operand:DI 1 "register_operand" "0")
17837 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17839 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17840 "crc32{q}\t{%2, %0|%0, %2}"
17841 [(set_attr "type" "sselog1")
17842 (set_attr "prefix_rep" "1")
17843 (set_attr "prefix_extra" "1")
17844 (set_attr "mode" "DI")])
17846 (define_expand "rdpmc"
17847 [(match_operand:DI 0 "register_operand" "")
17848 (match_operand:SI 1 "register_operand" "")]
17851 rtx reg = gen_reg_rtx (DImode);
17854 /* Force operand 1 into ECX. */
17855 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17856 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17857 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17862 rtvec vec = rtvec_alloc (2);
17863 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17864 rtx upper = gen_reg_rtx (DImode);
17865 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17866 gen_rtvec (1, const0_rtx),
17868 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17869 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17871 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17872 NULL, 1, OPTAB_DIRECT);
17873 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17877 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17878 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17882 (define_insn "*rdpmc"
17883 [(set (match_operand:DI 0 "register_operand" "=A")
17884 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17888 [(set_attr "type" "other")
17889 (set_attr "length" "2")])
17891 (define_insn "*rdpmc_rex64"
17892 [(set (match_operand:DI 0 "register_operand" "=a")
17893 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17895 (set (match_operand:DI 1 "register_operand" "=d")
17896 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17899 [(set_attr "type" "other")
17900 (set_attr "length" "2")])
17902 (define_expand "rdtsc"
17903 [(set (match_operand:DI 0 "register_operand" "")
17904 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17909 rtvec vec = rtvec_alloc (2);
17910 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17911 rtx upper = gen_reg_rtx (DImode);
17912 rtx lower = gen_reg_rtx (DImode);
17913 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17914 gen_rtvec (1, const0_rtx),
17916 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17917 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17919 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17920 NULL, 1, OPTAB_DIRECT);
17921 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17923 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17928 (define_insn "*rdtsc"
17929 [(set (match_operand:DI 0 "register_operand" "=A")
17930 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17933 [(set_attr "type" "other")
17934 (set_attr "length" "2")])
17936 (define_insn "*rdtsc_rex64"
17937 [(set (match_operand:DI 0 "register_operand" "=a")
17938 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17939 (set (match_operand:DI 1 "register_operand" "=d")
17940 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17943 [(set_attr "type" "other")
17944 (set_attr "length" "2")])
17946 (define_expand "rdtscp"
17947 [(match_operand:DI 0 "register_operand" "")
17948 (match_operand:SI 1 "memory_operand" "")]
17951 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17952 gen_rtvec (1, const0_rtx),
17954 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17955 gen_rtvec (1, const0_rtx),
17957 rtx reg = gen_reg_rtx (DImode);
17958 rtx tmp = gen_reg_rtx (SImode);
17962 rtvec vec = rtvec_alloc (3);
17963 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17964 rtx upper = gen_reg_rtx (DImode);
17965 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17966 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17967 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17969 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17970 NULL, 1, OPTAB_DIRECT);
17971 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17976 rtvec vec = rtvec_alloc (2);
17977 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17978 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17979 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17982 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17983 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17987 (define_insn "*rdtscp"
17988 [(set (match_operand:DI 0 "register_operand" "=A")
17989 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17990 (set (match_operand:SI 1 "register_operand" "=c")
17991 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17994 [(set_attr "type" "other")
17995 (set_attr "length" "3")])
17997 (define_insn "*rdtscp_rex64"
17998 [(set (match_operand:DI 0 "register_operand" "=a")
17999 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18000 (set (match_operand:DI 1 "register_operand" "=d")
18001 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18002 (set (match_operand:SI 2 "register_operand" "=c")
18003 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18006 [(set_attr "type" "other")
18007 (set_attr "length" "3")])
18009 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18011 ;; LWP instructions
18013 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18015 (define_expand "lwp_llwpcb"
18016 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18017 UNSPECV_LLWP_INTRINSIC)]
18020 (define_insn "*lwp_llwpcb<mode>1"
18021 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18022 UNSPECV_LLWP_INTRINSIC)]
18025 [(set_attr "type" "lwp")
18026 (set_attr "mode" "<MODE>")
18027 (set_attr "length" "5")])
18029 (define_expand "lwp_slwpcb"
18030 [(set (match_operand 0 "register_operand" "=r")
18031 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18036 insn = (TARGET_64BIT
18038 : gen_lwp_slwpcbsi);
18040 emit_insn (insn (operands[0]));
18044 (define_insn "lwp_slwpcb<mode>"
18045 [(set (match_operand:P 0 "register_operand" "=r")
18046 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18049 [(set_attr "type" "lwp")
18050 (set_attr "mode" "<MODE>")
18051 (set_attr "length" "5")])
18053 (define_expand "lwp_lwpval<mode>3"
18054 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18055 (match_operand:SI 2 "nonimmediate_operand" "rm")
18056 (match_operand:SI 3 "const_int_operand" "i")]
18057 UNSPECV_LWPVAL_INTRINSIC)]
18059 ;; Avoid unused variable warning.
18060 "(void) operands[0];")
18062 (define_insn "*lwp_lwpval<mode>3_1"
18063 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18064 (match_operand:SI 1 "nonimmediate_operand" "rm")
18065 (match_operand:SI 2 "const_int_operand" "i")]
18066 UNSPECV_LWPVAL_INTRINSIC)]
18068 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18069 [(set_attr "type" "lwp")
18070 (set_attr "mode" "<MODE>")
18071 (set (attr "length")
18072 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18074 (define_expand "lwp_lwpins<mode>3"
18075 [(set (reg:CCC FLAGS_REG)
18076 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18077 (match_operand:SI 2 "nonimmediate_operand" "rm")
18078 (match_operand:SI 3 "const_int_operand" "i")]
18079 UNSPECV_LWPINS_INTRINSIC))
18080 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18081 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18084 (define_insn "*lwp_lwpins<mode>3_1"
18085 [(set (reg:CCC FLAGS_REG)
18086 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18087 (match_operand:SI 1 "nonimmediate_operand" "rm")
18088 (match_operand:SI 2 "const_int_operand" "i")]
18089 UNSPECV_LWPINS_INTRINSIC))]
18091 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18092 [(set_attr "type" "lwp")
18093 (set_attr "mode" "<MODE>")
18094 (set (attr "length")
18095 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18097 (define_insn "rdfsbase<mode>"
18098 [(set (match_operand:SWI48 0 "register_operand" "=r")
18099 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18100 "TARGET_64BIT && TARGET_FSGSBASE"
18102 [(set_attr "type" "other")
18103 (set_attr "prefix_extra" "2")])
18105 (define_insn "rdgsbase<mode>"
18106 [(set (match_operand:SWI48 0 "register_operand" "=r")
18107 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18108 "TARGET_64BIT && TARGET_FSGSBASE"
18110 [(set_attr "type" "other")
18111 (set_attr "prefix_extra" "2")])
18113 (define_insn "wrfsbase<mode>"
18114 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18116 "TARGET_64BIT && TARGET_FSGSBASE"
18118 [(set_attr "type" "other")
18119 (set_attr "prefix_extra" "2")])
18121 (define_insn "wrgsbase<mode>"
18122 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18124 "TARGET_64BIT && TARGET_FSGSBASE"
18126 [(set_attr "type" "other")
18127 (set_attr "prefix_extra" "2")])
18129 (define_insn "rdrand<mode>_1"
18130 [(set (match_operand:SWI248 0 "register_operand" "=r")
18131 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18132 (set (reg:CCC FLAGS_REG)
18133 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18136 [(set_attr "type" "other")
18137 (set_attr "prefix_extra" "1")])
18139 (define_expand "pause"
18140 [(set (match_dup 0)
18141 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18144 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18145 MEM_VOLATILE_P (operands[0]) = 1;
18148 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18149 ;; They have the same encoding.
18150 (define_insn "*pause"
18151 [(set (match_operand:BLK 0 "" "")
18152 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18155 [(set_attr "length" "2")
18156 (set_attr "memory" "unknown")])
18160 (include "sync.md")