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
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
66 [; Relocation specifiers
77 (UNSPEC_MACHOPIC_OFFSET 10)
80 (UNSPEC_STACK_ALLOC 11)
82 (UNSPEC_SSE_PROLOGUE_SAVE 13)
86 (UNSPEC_SET_GOT_OFFSET 17)
87 (UNSPEC_MEMORY_BLOCKAGE 18)
92 (UNSPEC_TLS_LD_BASE 22)
95 ; Other random patterns
100 (UNSPEC_ADD_CARRY 34)
103 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
104 (UNSPEC_TRUNC_NOOP 39)
106 ; For SSE/MMX support:
107 (UNSPEC_FIX_NOTRUNC 40)
124 (UNSPEC_MS_TO_SYSV_CALL 48)
126 ; Generic math support
128 (UNSPEC_IEEE_MIN 51) ; not commutative
129 (UNSPEC_IEEE_MAX 52) ; not commutative
144 (UNSPEC_FRNDINT_FLOOR 70)
145 (UNSPEC_FRNDINT_CEIL 71)
146 (UNSPEC_FRNDINT_TRUNC 72)
147 (UNSPEC_FRNDINT_MASK_PM 73)
148 (UNSPEC_FIST_FLOOR 74)
149 (UNSPEC_FIST_CEIL 75)
151 ; x87 Double output FP
152 (UNSPEC_SINCOS_COS 80)
153 (UNSPEC_SINCOS_SIN 81)
154 (UNSPEC_XTRACT_FRACT 84)
155 (UNSPEC_XTRACT_EXP 85)
156 (UNSPEC_FSCALE_FRACT 86)
157 (UNSPEC_FSCALE_EXP 87)
169 (UNSPEC_SP_TLS_SET 102)
170 (UNSPEC_SP_TLS_TEST 103)
180 (UNSPEC_INSERTQI 132)
185 (UNSPEC_INSERTPS 135)
187 (UNSPEC_MOVNTDQA 137)
189 (UNSPEC_PHMINPOSUW 139)
195 (UNSPEC_PCMPESTR 144)
196 (UNSPEC_PCMPISTR 145)
199 (UNSPEC_FMA4_INTRINSIC 150)
200 (UNSPEC_FMA4_FMADDSUB 151)
201 (UNSPEC_FMA4_FMSUBADD 152)
202 (UNSPEC_XOP_UNSIGNED_CMP 151)
203 (UNSPEC_XOP_TRUEFALSE 152)
204 (UNSPEC_XOP_PERMUTE 153)
209 (UNSPEC_AESENCLAST 160)
211 (UNSPEC_AESDECLAST 162)
213 (UNSPEC_AESKEYGENASSIST 164)
221 (UNSPEC_VPERMIL2 168)
222 (UNSPEC_VPERMIL2F128 169)
223 (UNSPEC_MASKLOAD 170)
224 (UNSPEC_MASKSTORE 171)
230 [(UNSPECV_BLOCKAGE 0)
231 (UNSPECV_STACK_PROBE 1)
243 (UNSPECV_PROLOGUE_USE 14)
245 (UNSPECV_VZEROALL 16)
246 (UNSPECV_VZEROUPPER 17)
250 (UNSPECV_VSWAPMOV 21)
251 (UNSPECV_LLWP_INTRINSIC 22)
252 (UNSPECV_SLWP_INTRINSIC 23)
253 (UNSPECV_LWPVAL_INTRINSIC 24)
254 (UNSPECV_LWPINS_INTRINSIC 25)
257 ;; Constants to represent pcomtrue/pcomfalse variants
267 ;; Constants used in the XOP pperm instruction
269 [(PPERM_SRC 0x00) /* copy source */
270 (PPERM_INVERT 0x20) /* invert source */
271 (PPERM_REVERSE 0x40) /* bit reverse source */
272 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
273 (PPERM_ZERO 0x80) /* all 0's */
274 (PPERM_ONES 0xa0) /* all 1's */
275 (PPERM_SIGN 0xc0) /* propagate sign bit */
276 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
277 (PPERM_SRC1 0x00) /* use first source byte */
278 (PPERM_SRC2 0x10) /* use second source byte */
281 ;; Registers by name.
334 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
337 ;; In C guard expressions, put expressions which may be compile-time
338 ;; constants first. This allows for better optimization. For
339 ;; example, write "TARGET_64BIT && reload_completed", not
340 ;; "reload_completed && TARGET_64BIT".
344 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
346 (const (symbol_ref "ix86_schedule")))
348 ;; A basic instruction type. Refinements due to arguments to be
349 ;; provided in other attributes.
352 alu,alu1,negnot,imov,imovx,lea,
353 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
354 icmp,test,ibr,setcc,icmov,
355 push,pop,call,callv,leave,
357 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
358 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
359 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
360 ssemuladd,sse4arg,lwp,
361 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
362 (const_string "other"))
364 ;; Main data type used by the insn
366 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
367 (const_string "unknown"))
369 ;; The CPU unit operations uses.
370 (define_attr "unit" "integer,i387,sse,mmx,unknown"
371 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
372 (const_string "i387")
373 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
374 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
375 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
377 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
379 (eq_attr "type" "other")
380 (const_string "unknown")]
381 (const_string "integer")))
383 ;; The (bounding maximum) length of an instruction immediate.
384 (define_attr "length_immediate" ""
385 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
388 (eq_attr "unit" "i387,sse,mmx")
390 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
392 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
393 (eq_attr "type" "imov,test")
394 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
395 (eq_attr "type" "call")
396 (if_then_else (match_operand 0 "constant_call_address_operand" "")
399 (eq_attr "type" "callv")
400 (if_then_else (match_operand 1 "constant_call_address_operand" "")
403 ;; We don't know the size before shorten_branches. Expect
404 ;; the instruction to fit for better scheduling.
405 (eq_attr "type" "ibr")
408 (symbol_ref "/* Update immediate_length and other attributes! */
409 gcc_unreachable (),1")))
411 ;; The (bounding maximum) length of an instruction address.
412 (define_attr "length_address" ""
413 (cond [(eq_attr "type" "str,other,multi,fxch")
415 (and (eq_attr "type" "call")
416 (match_operand 0 "constant_call_address_operand" ""))
418 (and (eq_attr "type" "callv")
419 (match_operand 1 "constant_call_address_operand" ""))
422 (symbol_ref "ix86_attr_length_address_default (insn)")))
424 ;; Set when length prefix is used.
425 (define_attr "prefix_data16" ""
426 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
428 (eq_attr "mode" "HI")
430 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
435 ;; Set when string REP prefix is used.
436 (define_attr "prefix_rep" ""
437 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
439 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
444 ;; Set when 0f opcode prefix is used.
445 (define_attr "prefix_0f" ""
447 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
448 (eq_attr "unit" "sse,mmx"))
452 ;; Set when REX opcode prefix is used.
453 (define_attr "prefix_rex" ""
454 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
456 (and (eq_attr "mode" "DI")
457 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
458 (eq_attr "unit" "!mmx")))
460 (and (eq_attr "mode" "QI")
461 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
464 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
467 (and (eq_attr "type" "imovx")
468 (match_operand:QI 1 "ext_QIreg_operand" ""))
473 ;; There are also additional prefixes in 3DNOW, SSSE3.
474 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
475 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
476 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
477 (define_attr "prefix_extra" ""
478 (cond [(eq_attr "type" "ssemuladd,sse4arg")
480 (eq_attr "type" "sseiadd1,ssecvt1")
485 ;; Prefix used: original, VEX or maybe VEX.
486 (define_attr "prefix" "orig,vex,maybe_vex"
487 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
489 (const_string "orig")))
491 ;; VEX W bit is used.
492 (define_attr "prefix_vex_w" "" (const_int 0))
494 ;; The length of VEX prefix
495 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
496 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
497 ;; still prefix_0f 1, with prefix_extra 1.
498 (define_attr "length_vex" ""
499 (if_then_else (and (eq_attr "prefix_0f" "1")
500 (eq_attr "prefix_extra" "0"))
501 (if_then_else (eq_attr "prefix_vex_w" "1")
502 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
503 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
504 (if_then_else (eq_attr "prefix_vex_w" "1")
505 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
506 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
508 ;; Set when modrm byte is used.
509 (define_attr "modrm" ""
510 (cond [(eq_attr "type" "str,leave")
512 (eq_attr "unit" "i387")
514 (and (eq_attr "type" "incdec")
515 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
516 (ior (match_operand:SI 1 "register_operand" "")
517 (match_operand:HI 1 "register_operand" ""))))
519 (and (eq_attr "type" "push")
520 (not (match_operand 1 "memory_operand" "")))
522 (and (eq_attr "type" "pop")
523 (not (match_operand 0 "memory_operand" "")))
525 (and (eq_attr "type" "imov")
526 (and (not (eq_attr "mode" "DI"))
527 (ior (and (match_operand 0 "register_operand" "")
528 (match_operand 1 "immediate_operand" ""))
529 (ior (and (match_operand 0 "ax_reg_operand" "")
530 (match_operand 1 "memory_displacement_only_operand" ""))
531 (and (match_operand 0 "memory_displacement_only_operand" "")
532 (match_operand 1 "ax_reg_operand" ""))))))
534 (and (eq_attr "type" "call")
535 (match_operand 0 "constant_call_address_operand" ""))
537 (and (eq_attr "type" "callv")
538 (match_operand 1 "constant_call_address_operand" ""))
540 (and (eq_attr "type" "alu,alu1,icmp,test")
541 (match_operand 0 "ax_reg_operand" ""))
542 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
546 ;; The (bounding maximum) length of an instruction in bytes.
547 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
548 ;; Later we may want to split them and compute proper length as for
550 (define_attr "length" ""
551 (cond [(eq_attr "type" "other,multi,fistp,frndint")
553 (eq_attr "type" "fcmp")
555 (eq_attr "unit" "i387")
557 (plus (attr "prefix_data16")
558 (attr "length_address")))
559 (ior (eq_attr "prefix" "vex")
560 (and (eq_attr "prefix" "maybe_vex")
561 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
562 (plus (attr "length_vex")
563 (plus (attr "length_immediate")
565 (attr "length_address"))))]
566 (plus (plus (attr "modrm")
567 (plus (attr "prefix_0f")
568 (plus (attr "prefix_rex")
569 (plus (attr "prefix_extra")
571 (plus (attr "prefix_rep")
572 (plus (attr "prefix_data16")
573 (plus (attr "length_immediate")
574 (attr "length_address")))))))
576 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
577 ;; `store' if there is a simple memory reference therein, or `unknown'
578 ;; if the instruction is complex.
580 (define_attr "memory" "none,load,store,both,unknown"
581 (cond [(eq_attr "type" "other,multi,str,lwp")
582 (const_string "unknown")
583 (eq_attr "type" "lea,fcmov,fpspc")
584 (const_string "none")
585 (eq_attr "type" "fistp,leave")
586 (const_string "both")
587 (eq_attr "type" "frndint")
588 (const_string "load")
589 (eq_attr "type" "push")
590 (if_then_else (match_operand 1 "memory_operand" "")
591 (const_string "both")
592 (const_string "store"))
593 (eq_attr "type" "pop")
594 (if_then_else (match_operand 0 "memory_operand" "")
595 (const_string "both")
596 (const_string "load"))
597 (eq_attr "type" "setcc")
598 (if_then_else (match_operand 0 "memory_operand" "")
599 (const_string "store")
600 (const_string "none"))
601 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
602 (if_then_else (ior (match_operand 0 "memory_operand" "")
603 (match_operand 1 "memory_operand" ""))
604 (const_string "load")
605 (const_string "none"))
606 (eq_attr "type" "ibr")
607 (if_then_else (match_operand 0 "memory_operand" "")
608 (const_string "load")
609 (const_string "none"))
610 (eq_attr "type" "call")
611 (if_then_else (match_operand 0 "constant_call_address_operand" "")
612 (const_string "none")
613 (const_string "load"))
614 (eq_attr "type" "callv")
615 (if_then_else (match_operand 1 "constant_call_address_operand" "")
616 (const_string "none")
617 (const_string "load"))
618 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
619 (match_operand 1 "memory_operand" ""))
620 (const_string "both")
621 (and (match_operand 0 "memory_operand" "")
622 (match_operand 1 "memory_operand" ""))
623 (const_string "both")
624 (match_operand 0 "memory_operand" "")
625 (const_string "store")
626 (match_operand 1 "memory_operand" "")
627 (const_string "load")
629 "!alu1,negnot,ishift1,
630 imov,imovx,icmp,test,bitmanip,
632 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
633 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
634 (match_operand 2 "memory_operand" ""))
635 (const_string "load")
636 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
637 (match_operand 3 "memory_operand" ""))
638 (const_string "load")
640 (const_string "none")))
642 ;; Indicates if an instruction has both an immediate and a displacement.
644 (define_attr "imm_disp" "false,true,unknown"
645 (cond [(eq_attr "type" "other,multi")
646 (const_string "unknown")
647 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
648 (and (match_operand 0 "memory_displacement_operand" "")
649 (match_operand 1 "immediate_operand" "")))
650 (const_string "true")
651 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
652 (and (match_operand 0 "memory_displacement_operand" "")
653 (match_operand 2 "immediate_operand" "")))
654 (const_string "true")
656 (const_string "false")))
658 ;; Indicates if an FP operation has an integer source.
660 (define_attr "fp_int_src" "false,true"
661 (const_string "false"))
663 ;; Defines rounding mode of an FP operation.
665 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
666 (const_string "any"))
668 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
669 (define_attr "use_carry" "0,1" (const_string "0"))
671 ;; Define attribute to indicate unaligned ssemov insns
672 (define_attr "movu" "0,1" (const_string "0"))
674 ;; Describe a user's asm statement.
675 (define_asm_attributes
676 [(set_attr "length" "128")
677 (set_attr "type" "multi")])
679 ;; All integer comparison codes.
680 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
682 ;; All floating-point comparison codes.
683 (define_code_iterator fp_cond [unordered ordered
684 uneq unge ungt unle unlt ltgt])
686 (define_code_iterator plusminus [plus minus])
688 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
690 ;; Base name for define_insn
691 (define_code_attr plusminus_insn
692 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
693 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
695 ;; Base name for insn mnemonic.
696 (define_code_attr plusminus_mnemonic
697 [(plus "add") (ss_plus "adds") (us_plus "addus")
698 (minus "sub") (ss_minus "subs") (us_minus "subus")])
699 (define_code_attr plusminus_carry_mnemonic
700 [(plus "adc") (minus "sbb")])
702 ;; Mark commutative operators as such in constraints.
703 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
704 (minus "") (ss_minus "") (us_minus "")])
706 ;; Mapping of signed max and min
707 (define_code_iterator smaxmin [smax smin])
709 ;; Mapping of unsigned max and min
710 (define_code_iterator umaxmin [umax umin])
712 ;; Mapping of signed/unsigned max and min
713 (define_code_iterator maxmin [smax smin umax umin])
715 ;; Base name for integer and FP insn mnemonic
716 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
717 (umax "maxu") (umin "minu")])
718 (define_code_attr maxmin_float [(smax "max") (smin "min")])
720 ;; Mapping of logic operators
721 (define_code_iterator any_logic [and ior xor])
722 (define_code_iterator any_or [ior xor])
724 ;; Base name for insn mnemonic.
725 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
727 ;; Mapping of shift-right operators
728 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
730 ;; Base name for define_insn
731 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
733 ;; Base name for insn mnemonic.
734 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
736 ;; Mapping of rotate operators
737 (define_code_iterator any_rotate [rotate rotatert])
739 ;; Base name for define_insn
740 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
742 ;; Base name for insn mnemonic.
743 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
745 ;; Mapping of abs neg operators
746 (define_code_iterator absneg [abs neg])
748 ;; Base name for x87 insn mnemonic.
749 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
751 ;; Used in signed and unsigned widening multiplications.
752 (define_code_iterator any_extend [sign_extend zero_extend])
754 ;; Various insn prefixes for signed and unsigned operations.
755 (define_code_attr u [(sign_extend "") (zero_extend "u")
756 (div "") (udiv "u")])
757 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
759 ;; Used in signed and unsigned divisions.
760 (define_code_iterator any_div [div udiv])
762 ;; Instruction prefix for signed and unsigned operations.
763 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
764 (div "i") (udiv "")])
766 ;; All single word integer modes.
767 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
769 ;; Single word integer modes without DImode.
770 (define_mode_iterator SWI124 [QI HI SI])
772 ;; Single word integer modes without QImode.
773 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
775 ;; Single word integer modes without QImode and HImode.
776 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
778 ;; All math-dependant single and double word integer modes.
779 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
780 (HI "TARGET_HIMODE_MATH")
781 SI DI (TI "TARGET_64BIT")])
783 ;; Math-dependant single word integer modes.
784 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
785 (HI "TARGET_HIMODE_MATH")
786 SI (DI "TARGET_64BIT")])
788 ;; Math-dependant single word integer modes without DImode.
789 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
790 (HI "TARGET_HIMODE_MATH")
793 ;; Math-dependant single word integer modes without QImode.
794 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
795 SI (DI "TARGET_64BIT")])
797 ;; Double word integer modes.
798 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
799 (TI "TARGET_64BIT")])
801 ;; Double word integer modes as mode attribute.
802 (define_mode_attr DWI [(SI "DI") (DI "TI")])
803 (define_mode_attr dwi [(SI "di") (DI "ti")])
805 ;; Half mode for double word integer modes.
806 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
807 (DI "TARGET_64BIT")])
809 ;; Instruction suffix for integer modes.
810 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
812 ;; Register class for integer modes.
813 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
815 ;; Immediate operand constraint for integer modes.
816 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
818 ;; General operand constraint for word modes.
819 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
821 ;; Immediate operand constraint for double integer modes.
822 (define_mode_attr di [(SI "iF") (DI "e")])
824 ;; Immediate operand constraint for shifts.
825 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
827 ;; General operand predicate for integer modes.
828 (define_mode_attr general_operand
829 [(QI "general_operand")
830 (HI "general_operand")
831 (SI "general_operand")
832 (DI "x86_64_general_operand")
833 (TI "x86_64_general_operand")])
835 ;; General sign/zero extend operand predicate for integer modes.
836 (define_mode_attr general_szext_operand
837 [(QI "general_operand")
838 (HI "general_operand")
839 (SI "general_operand")
840 (DI "x86_64_szext_general_operand")])
842 ;; Operand predicate for shifts.
843 (define_mode_attr shift_operand
844 [(QI "nonimmediate_operand")
845 (HI "nonimmediate_operand")
846 (SI "nonimmediate_operand")
847 (DI "shiftdi_operand")
848 (TI "register_operand")])
850 ;; Operand predicate for shift argument.
851 (define_mode_attr shift_immediate_operand
852 [(QI "const_1_to_31_operand")
853 (HI "const_1_to_31_operand")
854 (SI "const_1_to_31_operand")
855 (DI "const_1_to_63_operand")])
857 ;; Input operand predicate for arithmetic left shifts.
858 (define_mode_attr ashl_input_operand
859 [(QI "nonimmediate_operand")
860 (HI "nonimmediate_operand")
861 (SI "nonimmediate_operand")
862 (DI "ashldi_input_operand")
863 (TI "reg_or_pm1_operand")])
865 ;; SSE and x87 SFmode and DFmode floating point modes
866 (define_mode_iterator MODEF [SF DF])
868 ;; All x87 floating point modes
869 (define_mode_iterator X87MODEF [SF DF XF])
871 ;; All integer modes handled by x87 fisttp operator.
872 (define_mode_iterator X87MODEI [HI SI DI])
874 ;; All integer modes handled by integer x87 operators.
875 (define_mode_iterator X87MODEI12 [HI SI])
877 ;; All integer modes handled by SSE cvtts?2si* operators.
878 (define_mode_iterator SSEMODEI24 [SI DI])
880 ;; SSE asm suffix for floating point modes
881 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
883 ;; SSE vector mode corresponding to a scalar mode
884 (define_mode_attr ssevecmode
885 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
887 ;; Instruction suffix for REX 64bit operators.
888 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
890 ;; This mode iterator allows :P to be used for patterns that operate on
891 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
892 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
894 ;; Scheduling descriptions
896 (include "pentium.md")
899 (include "athlon.md")
904 ;; Operand and operator predicates and constraints
906 (include "predicates.md")
907 (include "constraints.md")
910 ;; Compare and branch/compare and store instructions.
912 (define_expand "cbranch<mode>4"
913 [(set (reg:CC FLAGS_REG)
914 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
915 (match_operand:SDWIM 2 "<general_operand>" "")))
916 (set (pc) (if_then_else
917 (match_operator 0 "comparison_operator"
918 [(reg:CC FLAGS_REG) (const_int 0)])
919 (label_ref (match_operand 3 "" ""))
923 if (MEM_P (operands[1]) && MEM_P (operands[2]))
924 operands[1] = force_reg (<MODE>mode, operands[1]);
925 ix86_compare_op0 = operands[1];
926 ix86_compare_op1 = operands[2];
927 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
931 (define_expand "cstore<mode>4"
932 [(set (reg:CC FLAGS_REG)
933 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
934 (match_operand:SWIM 3 "<general_operand>" "")))
935 (set (match_operand:QI 0 "register_operand" "")
936 (match_operator 1 "comparison_operator"
937 [(reg:CC FLAGS_REG) (const_int 0)]))]
940 if (MEM_P (operands[2]) && MEM_P (operands[3]))
941 operands[2] = force_reg (<MODE>mode, operands[2]);
942 ix86_compare_op0 = operands[2];
943 ix86_compare_op1 = operands[3];
944 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
948 (define_expand "cmp<mode>_1"
949 [(set (reg:CC FLAGS_REG)
950 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
951 (match_operand:SWI48 1 "<general_operand>" "")))]
955 (define_insn "*cmp<mode>_ccno_1"
956 [(set (reg FLAGS_REG)
957 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
958 (match_operand:SWI 1 "const0_operand" "")))]
959 "ix86_match_ccmode (insn, CCNOmode)"
961 test{<imodesuffix>}\t%0, %0
962 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
963 [(set_attr "type" "test,icmp")
964 (set_attr "length_immediate" "0,1")
965 (set_attr "mode" "<MODE>")])
967 (define_insn "*cmp<mode>_1"
968 [(set (reg FLAGS_REG)
969 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
970 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
971 "ix86_match_ccmode (insn, CCmode)"
972 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
973 [(set_attr "type" "icmp")
974 (set_attr "mode" "<MODE>")])
976 (define_insn "*cmp<mode>_minus_1"
977 [(set (reg FLAGS_REG)
979 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
980 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
982 "ix86_match_ccmode (insn, CCGOCmode)"
983 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
984 [(set_attr "type" "icmp")
985 (set_attr "mode" "<MODE>")])
987 (define_insn "*cmpqi_ext_1"
988 [(set (reg FLAGS_REG)
990 (match_operand:QI 0 "general_operand" "Qm")
993 (match_operand 1 "ext_register_operand" "Q")
996 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
997 "cmp{b}\t{%h1, %0|%0, %h1}"
998 [(set_attr "type" "icmp")
999 (set_attr "mode" "QI")])
1001 (define_insn "*cmpqi_ext_1_rex64"
1002 [(set (reg FLAGS_REG)
1004 (match_operand:QI 0 "register_operand" "Q")
1007 (match_operand 1 "ext_register_operand" "Q")
1009 (const_int 8)) 0)))]
1010 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1011 "cmp{b}\t{%h1, %0|%0, %h1}"
1012 [(set_attr "type" "icmp")
1013 (set_attr "mode" "QI")])
1015 (define_insn "*cmpqi_ext_2"
1016 [(set (reg FLAGS_REG)
1020 (match_operand 0 "ext_register_operand" "Q")
1023 (match_operand:QI 1 "const0_operand" "")))]
1024 "ix86_match_ccmode (insn, CCNOmode)"
1026 [(set_attr "type" "test")
1027 (set_attr "length_immediate" "0")
1028 (set_attr "mode" "QI")])
1030 (define_expand "cmpqi_ext_3"
1031 [(set (reg:CC FLAGS_REG)
1035 (match_operand 0 "ext_register_operand" "")
1038 (match_operand:QI 1 "immediate_operand" "")))]
1042 (define_insn "*cmpqi_ext_3_insn"
1043 [(set (reg FLAGS_REG)
1047 (match_operand 0 "ext_register_operand" "Q")
1050 (match_operand:QI 1 "general_operand" "Qmn")))]
1051 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1052 "cmp{b}\t{%1, %h0|%h0, %1}"
1053 [(set_attr "type" "icmp")
1054 (set_attr "modrm" "1")
1055 (set_attr "mode" "QI")])
1057 (define_insn "*cmpqi_ext_3_insn_rex64"
1058 [(set (reg FLAGS_REG)
1062 (match_operand 0 "ext_register_operand" "Q")
1065 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1066 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1067 "cmp{b}\t{%1, %h0|%h0, %1}"
1068 [(set_attr "type" "icmp")
1069 (set_attr "modrm" "1")
1070 (set_attr "mode" "QI")])
1072 (define_insn "*cmpqi_ext_4"
1073 [(set (reg FLAGS_REG)
1077 (match_operand 0 "ext_register_operand" "Q")
1082 (match_operand 1 "ext_register_operand" "Q")
1084 (const_int 8)) 0)))]
1085 "ix86_match_ccmode (insn, CCmode)"
1086 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1087 [(set_attr "type" "icmp")
1088 (set_attr "mode" "QI")])
1090 ;; These implement float point compares.
1091 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1092 ;; which would allow mix and match FP modes on the compares. Which is what
1093 ;; the old patterns did, but with many more of them.
1095 (define_expand "cbranchxf4"
1096 [(set (reg:CC FLAGS_REG)
1097 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1098 (match_operand:XF 2 "nonmemory_operand" "")))
1099 (set (pc) (if_then_else
1100 (match_operator 0 "ix86_fp_comparison_operator"
1103 (label_ref (match_operand 3 "" ""))
1107 ix86_compare_op0 = operands[1];
1108 ix86_compare_op1 = operands[2];
1109 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1113 (define_expand "cstorexf4"
1114 [(set (reg:CC FLAGS_REG)
1115 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1116 (match_operand:XF 3 "nonmemory_operand" "")))
1117 (set (match_operand:QI 0 "register_operand" "")
1118 (match_operator 1 "ix86_fp_comparison_operator"
1123 ix86_compare_op0 = operands[2];
1124 ix86_compare_op1 = operands[3];
1125 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1129 (define_expand "cbranch<mode>4"
1130 [(set (reg:CC FLAGS_REG)
1131 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1132 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1133 (set (pc) (if_then_else
1134 (match_operator 0 "ix86_fp_comparison_operator"
1137 (label_ref (match_operand 3 "" ""))
1139 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1141 ix86_compare_op0 = operands[1];
1142 ix86_compare_op1 = operands[2];
1143 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1147 (define_expand "cstore<mode>4"
1148 [(set (reg:CC FLAGS_REG)
1149 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1150 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1151 (set (match_operand:QI 0 "register_operand" "")
1152 (match_operator 1 "ix86_fp_comparison_operator"
1155 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1157 ix86_compare_op0 = operands[2];
1158 ix86_compare_op1 = operands[3];
1159 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1163 (define_expand "cbranchcc4"
1164 [(set (pc) (if_then_else
1165 (match_operator 0 "comparison_operator"
1166 [(match_operand 1 "flags_reg_operand" "")
1167 (match_operand 2 "const0_operand" "")])
1168 (label_ref (match_operand 3 "" ""))
1172 ix86_compare_op0 = operands[1];
1173 ix86_compare_op1 = operands[2];
1174 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1178 (define_expand "cstorecc4"
1179 [(set (match_operand:QI 0 "register_operand" "")
1180 (match_operator 1 "comparison_operator"
1181 [(match_operand 2 "flags_reg_operand" "")
1182 (match_operand 3 "const0_operand" "")]))]
1185 ix86_compare_op0 = operands[2];
1186 ix86_compare_op1 = operands[3];
1187 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1192 ;; FP compares, step 1:
1193 ;; Set the FP condition codes.
1195 ;; CCFPmode compare with exceptions
1196 ;; CCFPUmode compare with no exceptions
1198 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1199 ;; used to manage the reg stack popping would not be preserved.
1201 (define_insn "*cmpfp_0"
1202 [(set (match_operand:HI 0 "register_operand" "=a")
1205 (match_operand 1 "register_operand" "f")
1206 (match_operand 2 "const0_operand" ""))]
1208 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1209 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1210 "* return output_fp_compare (insn, operands, 0, 0);"
1211 [(set_attr "type" "multi")
1212 (set_attr "unit" "i387")
1214 (cond [(match_operand:SF 1 "" "")
1216 (match_operand:DF 1 "" "")
1219 (const_string "XF")))])
1221 (define_insn_and_split "*cmpfp_0_cc"
1222 [(set (reg:CCFP FLAGS_REG)
1224 (match_operand 1 "register_operand" "f")
1225 (match_operand 2 "const0_operand" "")))
1226 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1227 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1228 && TARGET_SAHF && !TARGET_CMOVE
1229 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1231 "&& reload_completed"
1234 [(compare:CCFP (match_dup 1)(match_dup 2))]
1236 (set (reg:CC FLAGS_REG)
1237 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1239 [(set_attr "type" "multi")
1240 (set_attr "unit" "i387")
1242 (cond [(match_operand:SF 1 "" "")
1244 (match_operand:DF 1 "" "")
1247 (const_string "XF")))])
1249 (define_insn "*cmpfp_xf"
1250 [(set (match_operand:HI 0 "register_operand" "=a")
1253 (match_operand:XF 1 "register_operand" "f")
1254 (match_operand:XF 2 "register_operand" "f"))]
1257 "* return output_fp_compare (insn, operands, 0, 0);"
1258 [(set_attr "type" "multi")
1259 (set_attr "unit" "i387")
1260 (set_attr "mode" "XF")])
1262 (define_insn_and_split "*cmpfp_xf_cc"
1263 [(set (reg:CCFP FLAGS_REG)
1265 (match_operand:XF 1 "register_operand" "f")
1266 (match_operand:XF 2 "register_operand" "f")))
1267 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1269 && TARGET_SAHF && !TARGET_CMOVE"
1271 "&& reload_completed"
1274 [(compare:CCFP (match_dup 1)(match_dup 2))]
1276 (set (reg:CC FLAGS_REG)
1277 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1279 [(set_attr "type" "multi")
1280 (set_attr "unit" "i387")
1281 (set_attr "mode" "XF")])
1283 (define_insn "*cmpfp_<mode>"
1284 [(set (match_operand:HI 0 "register_operand" "=a")
1287 (match_operand:MODEF 1 "register_operand" "f")
1288 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1291 "* return output_fp_compare (insn, operands, 0, 0);"
1292 [(set_attr "type" "multi")
1293 (set_attr "unit" "i387")
1294 (set_attr "mode" "<MODE>")])
1296 (define_insn_and_split "*cmpfp_<mode>_cc"
1297 [(set (reg:CCFP FLAGS_REG)
1299 (match_operand:MODEF 1 "register_operand" "f")
1300 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1301 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1303 && TARGET_SAHF && !TARGET_CMOVE"
1305 "&& reload_completed"
1308 [(compare:CCFP (match_dup 1)(match_dup 2))]
1310 (set (reg:CC FLAGS_REG)
1311 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1313 [(set_attr "type" "multi")
1314 (set_attr "unit" "i387")
1315 (set_attr "mode" "<MODE>")])
1317 (define_insn "*cmpfp_u"
1318 [(set (match_operand:HI 0 "register_operand" "=a")
1321 (match_operand 1 "register_operand" "f")
1322 (match_operand 2 "register_operand" "f"))]
1324 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1325 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1326 "* return output_fp_compare (insn, operands, 0, 1);"
1327 [(set_attr "type" "multi")
1328 (set_attr "unit" "i387")
1330 (cond [(match_operand:SF 1 "" "")
1332 (match_operand:DF 1 "" "")
1335 (const_string "XF")))])
1337 (define_insn_and_split "*cmpfp_u_cc"
1338 [(set (reg:CCFPU FLAGS_REG)
1340 (match_operand 1 "register_operand" "f")
1341 (match_operand 2 "register_operand" "f")))
1342 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1343 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1344 && TARGET_SAHF && !TARGET_CMOVE
1345 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1347 "&& reload_completed"
1350 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1352 (set (reg:CC FLAGS_REG)
1353 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1355 [(set_attr "type" "multi")
1356 (set_attr "unit" "i387")
1358 (cond [(match_operand:SF 1 "" "")
1360 (match_operand:DF 1 "" "")
1363 (const_string "XF")))])
1365 (define_insn "*cmpfp_<mode>"
1366 [(set (match_operand:HI 0 "register_operand" "=a")
1369 (match_operand 1 "register_operand" "f")
1370 (match_operator 3 "float_operator"
1371 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1373 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1374 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1375 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1376 "* return output_fp_compare (insn, operands, 0, 0);"
1377 [(set_attr "type" "multi")
1378 (set_attr "unit" "i387")
1379 (set_attr "fp_int_src" "true")
1380 (set_attr "mode" "<MODE>")])
1382 (define_insn_and_split "*cmpfp_<mode>_cc"
1383 [(set (reg:CCFP FLAGS_REG)
1385 (match_operand 1 "register_operand" "f")
1386 (match_operator 3 "float_operator"
1387 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1388 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1389 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1390 && TARGET_SAHF && !TARGET_CMOVE
1391 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1392 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1394 "&& reload_completed"
1399 (match_op_dup 3 [(match_dup 2)]))]
1401 (set (reg:CC FLAGS_REG)
1402 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1404 [(set_attr "type" "multi")
1405 (set_attr "unit" "i387")
1406 (set_attr "fp_int_src" "true")
1407 (set_attr "mode" "<MODE>")])
1409 ;; FP compares, step 2
1410 ;; Move the fpsw to ax.
1412 (define_insn "x86_fnstsw_1"
1413 [(set (match_operand:HI 0 "register_operand" "=a")
1414 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1417 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1418 (set_attr "mode" "SI")
1419 (set_attr "unit" "i387")])
1421 ;; FP compares, step 3
1422 ;; Get ax into flags, general case.
1424 (define_insn "x86_sahf_1"
1425 [(set (reg:CC FLAGS_REG)
1426 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1430 #ifdef HAVE_AS_IX86_SAHF
1433 return ASM_BYTE "0x9e";
1436 [(set_attr "length" "1")
1437 (set_attr "athlon_decode" "vector")
1438 (set_attr "amdfam10_decode" "direct")
1439 (set_attr "mode" "SI")])
1441 ;; Pentium Pro can do steps 1 through 3 in one go.
1442 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1443 (define_insn "*cmpfp_i_mixed"
1444 [(set (reg:CCFP FLAGS_REG)
1445 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1446 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1447 "TARGET_MIX_SSE_I387
1448 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1449 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1450 "* return output_fp_compare (insn, operands, 1, 0);"
1451 [(set_attr "type" "fcmp,ssecomi")
1452 (set_attr "prefix" "orig,maybe_vex")
1454 (if_then_else (match_operand:SF 1 "" "")
1456 (const_string "DF")))
1457 (set (attr "prefix_rep")
1458 (if_then_else (eq_attr "type" "ssecomi")
1460 (const_string "*")))
1461 (set (attr "prefix_data16")
1462 (cond [(eq_attr "type" "fcmp")
1464 (eq_attr "mode" "DF")
1467 (const_string "0")))
1468 (set_attr "athlon_decode" "vector")
1469 (set_attr "amdfam10_decode" "direct")])
1471 (define_insn "*cmpfp_i_sse"
1472 [(set (reg:CCFP FLAGS_REG)
1473 (compare:CCFP (match_operand 0 "register_operand" "x")
1474 (match_operand 1 "nonimmediate_operand" "xm")))]
1476 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1477 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1478 "* return output_fp_compare (insn, operands, 1, 0);"
1479 [(set_attr "type" "ssecomi")
1480 (set_attr "prefix" "maybe_vex")
1482 (if_then_else (match_operand:SF 1 "" "")
1484 (const_string "DF")))
1485 (set_attr "prefix_rep" "0")
1486 (set (attr "prefix_data16")
1487 (if_then_else (eq_attr "mode" "DF")
1489 (const_string "0")))
1490 (set_attr "athlon_decode" "vector")
1491 (set_attr "amdfam10_decode" "direct")])
1493 (define_insn "*cmpfp_i_i387"
1494 [(set (reg:CCFP FLAGS_REG)
1495 (compare:CCFP (match_operand 0 "register_operand" "f")
1496 (match_operand 1 "register_operand" "f")))]
1497 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1499 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1500 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1501 "* return output_fp_compare (insn, operands, 1, 0);"
1502 [(set_attr "type" "fcmp")
1504 (cond [(match_operand:SF 1 "" "")
1506 (match_operand:DF 1 "" "")
1509 (const_string "XF")))
1510 (set_attr "athlon_decode" "vector")
1511 (set_attr "amdfam10_decode" "direct")])
1513 (define_insn "*cmpfp_iu_mixed"
1514 [(set (reg:CCFPU FLAGS_REG)
1515 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1516 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1517 "TARGET_MIX_SSE_I387
1518 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1519 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1520 "* return output_fp_compare (insn, operands, 1, 1);"
1521 [(set_attr "type" "fcmp,ssecomi")
1522 (set_attr "prefix" "orig,maybe_vex")
1524 (if_then_else (match_operand:SF 1 "" "")
1526 (const_string "DF")))
1527 (set (attr "prefix_rep")
1528 (if_then_else (eq_attr "type" "ssecomi")
1530 (const_string "*")))
1531 (set (attr "prefix_data16")
1532 (cond [(eq_attr "type" "fcmp")
1534 (eq_attr "mode" "DF")
1537 (const_string "0")))
1538 (set_attr "athlon_decode" "vector")
1539 (set_attr "amdfam10_decode" "direct")])
1541 (define_insn "*cmpfp_iu_sse"
1542 [(set (reg:CCFPU FLAGS_REG)
1543 (compare:CCFPU (match_operand 0 "register_operand" "x")
1544 (match_operand 1 "nonimmediate_operand" "xm")))]
1546 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1547 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1548 "* return output_fp_compare (insn, operands, 1, 1);"
1549 [(set_attr "type" "ssecomi")
1550 (set_attr "prefix" "maybe_vex")
1552 (if_then_else (match_operand:SF 1 "" "")
1554 (const_string "DF")))
1555 (set_attr "prefix_rep" "0")
1556 (set (attr "prefix_data16")
1557 (if_then_else (eq_attr "mode" "DF")
1559 (const_string "0")))
1560 (set_attr "athlon_decode" "vector")
1561 (set_attr "amdfam10_decode" "direct")])
1563 (define_insn "*cmpfp_iu_387"
1564 [(set (reg:CCFPU FLAGS_REG)
1565 (compare:CCFPU (match_operand 0 "register_operand" "f")
1566 (match_operand 1 "register_operand" "f")))]
1567 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1569 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1570 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1571 "* return output_fp_compare (insn, operands, 1, 1);"
1572 [(set_attr "type" "fcmp")
1574 (cond [(match_operand:SF 1 "" "")
1576 (match_operand:DF 1 "" "")
1579 (const_string "XF")))
1580 (set_attr "athlon_decode" "vector")
1581 (set_attr "amdfam10_decode" "direct")])
1583 ;; Move instructions.
1585 ;; General case of fullword move.
1587 (define_expand "movsi"
1588 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1589 (match_operand:SI 1 "general_operand" ""))]
1591 "ix86_expand_move (SImode, operands); DONE;")
1593 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1596 ;; %%% We don't use a post-inc memory reference because x86 is not a
1597 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1598 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1599 ;; targets without our curiosities, and it is just as easy to represent
1600 ;; this differently.
1602 (define_insn "*pushsi2"
1603 [(set (match_operand:SI 0 "push_operand" "=<")
1604 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1607 [(set_attr "type" "push")
1608 (set_attr "mode" "SI")])
1610 ;; For 64BIT abi we always round up to 8 bytes.
1611 (define_insn "*pushsi2_rex64"
1612 [(set (match_operand:SI 0 "push_operand" "=X")
1613 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1616 [(set_attr "type" "push")
1617 (set_attr "mode" "SI")])
1619 (define_insn "*pushsi2_prologue"
1620 [(set (match_operand:SI 0 "push_operand" "=<")
1621 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1622 (clobber (mem:BLK (scratch)))]
1625 [(set_attr "type" "push")
1626 (set_attr "mode" "SI")])
1628 (define_insn "*popsi1_epilogue"
1629 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1630 (mem:SI (reg:SI SP_REG)))
1631 (set (reg:SI SP_REG)
1632 (plus:SI (reg:SI SP_REG) (const_int 4)))
1633 (clobber (mem:BLK (scratch)))]
1636 [(set_attr "type" "pop")
1637 (set_attr "mode" "SI")])
1639 (define_insn "popsi1"
1640 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1641 (mem:SI (reg:SI SP_REG)))
1642 (set (reg:SI SP_REG)
1643 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1646 [(set_attr "type" "pop")
1647 (set_attr "mode" "SI")])
1649 (define_insn "*movsi_xor"
1650 [(set (match_operand:SI 0 "register_operand" "=r")
1651 (match_operand:SI 1 "const0_operand" ""))
1652 (clobber (reg:CC FLAGS_REG))]
1655 [(set_attr "type" "alu1")
1656 (set_attr "mode" "SI")
1657 (set_attr "length_immediate" "0")])
1659 (define_insn "*movsi_or"
1660 [(set (match_operand:SI 0 "register_operand" "=r")
1661 (match_operand:SI 1 "immediate_operand" "i"))
1662 (clobber (reg:CC FLAGS_REG))]
1664 && operands[1] == constm1_rtx"
1666 operands[1] = constm1_rtx;
1667 return "or{l}\t{%1, %0|%0, %1}";
1669 [(set_attr "type" "alu1")
1670 (set_attr "mode" "SI")
1671 (set_attr "length_immediate" "1")])
1673 (define_insn "*movsi_1"
1674 [(set (match_operand:SI 0 "nonimmediate_operand"
1675 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1676 (match_operand:SI 1 "general_operand"
1677 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1678 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1680 switch (get_attr_type (insn))
1683 if (get_attr_mode (insn) == MODE_TI)
1684 return "%vpxor\t%0, %d0";
1685 return "%vxorps\t%0, %d0";
1688 switch (get_attr_mode (insn))
1691 return "%vmovdqa\t{%1, %0|%0, %1}";
1693 return "%vmovaps\t{%1, %0|%0, %1}";
1695 return "%vmovd\t{%1, %0|%0, %1}";
1697 return "%vmovss\t{%1, %0|%0, %1}";
1703 return "pxor\t%0, %0";
1706 if (get_attr_mode (insn) == MODE_DI)
1707 return "movq\t{%1, %0|%0, %1}";
1708 return "movd\t{%1, %0|%0, %1}";
1711 return "lea{l}\t{%1, %0|%0, %1}";
1714 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1715 return "mov{l}\t{%1, %0|%0, %1}";
1719 (cond [(eq_attr "alternative" "2")
1720 (const_string "mmx")
1721 (eq_attr "alternative" "3,4,5")
1722 (const_string "mmxmov")
1723 (eq_attr "alternative" "6")
1724 (const_string "sselog1")
1725 (eq_attr "alternative" "7,8,9,10,11")
1726 (const_string "ssemov")
1727 (match_operand:DI 1 "pic_32bit_operand" "")
1728 (const_string "lea")
1730 (const_string "imov")))
1731 (set (attr "prefix")
1732 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1733 (const_string "orig")
1734 (const_string "maybe_vex")))
1735 (set (attr "prefix_data16")
1736 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1738 (const_string "*")))
1740 (cond [(eq_attr "alternative" "2,3")
1742 (eq_attr "alternative" "6,7")
1744 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1745 (const_string "V4SF")
1746 (const_string "TI"))
1747 (and (eq_attr "alternative" "8,9,10,11")
1748 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1751 (const_string "SI")))])
1753 ;; Stores and loads of ax to arbitrary constant address.
1754 ;; We fake an second form of instruction to force reload to load address
1755 ;; into register when rax is not available
1756 (define_insn "*movabssi_1_rex64"
1757 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1758 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1759 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1761 movabs{l}\t{%1, %P0|%P0, %1}
1762 mov{l}\t{%1, %a0|%a0, %1}"
1763 [(set_attr "type" "imov")
1764 (set_attr "modrm" "0,*")
1765 (set_attr "length_address" "8,0")
1766 (set_attr "length_immediate" "0,*")
1767 (set_attr "memory" "store")
1768 (set_attr "mode" "SI")])
1770 (define_insn "*movabssi_2_rex64"
1771 [(set (match_operand:SI 0 "register_operand" "=a,r")
1772 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1773 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1775 movabs{l}\t{%P1, %0|%0, %P1}
1776 mov{l}\t{%a1, %0|%0, %a1}"
1777 [(set_attr "type" "imov")
1778 (set_attr "modrm" "0,*")
1779 (set_attr "length_address" "8,0")
1780 (set_attr "length_immediate" "0")
1781 (set_attr "memory" "load")
1782 (set_attr "mode" "SI")])
1784 (define_insn "*swapsi"
1785 [(set (match_operand:SI 0 "register_operand" "+r")
1786 (match_operand:SI 1 "register_operand" "+r"))
1791 [(set_attr "type" "imov")
1792 (set_attr "mode" "SI")
1793 (set_attr "pent_pair" "np")
1794 (set_attr "athlon_decode" "vector")
1795 (set_attr "amdfam10_decode" "double")])
1797 (define_expand "movhi"
1798 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1799 (match_operand:HI 1 "general_operand" ""))]
1801 "ix86_expand_move (HImode, operands); DONE;")
1803 (define_insn "*pushhi2"
1804 [(set (match_operand:HI 0 "push_operand" "=X")
1805 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1808 [(set_attr "type" "push")
1809 (set_attr "mode" "SI")])
1811 ;; For 64BIT abi we always round up to 8 bytes.
1812 (define_insn "*pushhi2_rex64"
1813 [(set (match_operand:HI 0 "push_operand" "=X")
1814 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1817 [(set_attr "type" "push")
1818 (set_attr "mode" "DI")])
1820 (define_insn "*movhi_1"
1821 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1822 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1823 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1825 switch (get_attr_type (insn))
1828 /* movzwl is faster than movw on p2 due to partial word stalls,
1829 though not as fast as an aligned movl. */
1830 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1832 if (get_attr_mode (insn) == MODE_SI)
1833 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1835 return "mov{w}\t{%1, %0|%0, %1}";
1839 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1840 (const_string "imov")
1841 (and (eq_attr "alternative" "0")
1842 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1844 (eq (symbol_ref "TARGET_HIMODE_MATH")
1846 (const_string "imov")
1847 (and (eq_attr "alternative" "1,2")
1848 (match_operand:HI 1 "aligned_operand" ""))
1849 (const_string "imov")
1850 (and (ne (symbol_ref "TARGET_MOVX")
1852 (eq_attr "alternative" "0,2"))
1853 (const_string "imovx")
1855 (const_string "imov")))
1857 (cond [(eq_attr "type" "imovx")
1859 (and (eq_attr "alternative" "1,2")
1860 (match_operand:HI 1 "aligned_operand" ""))
1862 (and (eq_attr "alternative" "0")
1863 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1865 (eq (symbol_ref "TARGET_HIMODE_MATH")
1869 (const_string "HI")))])
1871 ;; Stores and loads of ax to arbitrary constant address.
1872 ;; We fake an second form of instruction to force reload to load address
1873 ;; into register when rax is not available
1874 (define_insn "*movabshi_1_rex64"
1875 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1876 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1877 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1879 movabs{w}\t{%1, %P0|%P0, %1}
1880 mov{w}\t{%1, %a0|%a0, %1}"
1881 [(set_attr "type" "imov")
1882 (set_attr "modrm" "0,*")
1883 (set_attr "length_address" "8,0")
1884 (set_attr "length_immediate" "0,*")
1885 (set_attr "memory" "store")
1886 (set_attr "mode" "HI")])
1888 (define_insn "*movabshi_2_rex64"
1889 [(set (match_operand:HI 0 "register_operand" "=a,r")
1890 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1891 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1893 movabs{w}\t{%P1, %0|%0, %P1}
1894 mov{w}\t{%a1, %0|%0, %a1}"
1895 [(set_attr "type" "imov")
1896 (set_attr "modrm" "0,*")
1897 (set_attr "length_address" "8,0")
1898 (set_attr "length_immediate" "0")
1899 (set_attr "memory" "load")
1900 (set_attr "mode" "HI")])
1902 (define_insn "*swaphi_1"
1903 [(set (match_operand:HI 0 "register_operand" "+r")
1904 (match_operand:HI 1 "register_operand" "+r"))
1907 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1909 [(set_attr "type" "imov")
1910 (set_attr "mode" "SI")
1911 (set_attr "pent_pair" "np")
1912 (set_attr "athlon_decode" "vector")
1913 (set_attr "amdfam10_decode" "double")])
1915 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1916 (define_insn "*swaphi_2"
1917 [(set (match_operand:HI 0 "register_operand" "+r")
1918 (match_operand:HI 1 "register_operand" "+r"))
1921 "TARGET_PARTIAL_REG_STALL"
1923 [(set_attr "type" "imov")
1924 (set_attr "mode" "HI")
1925 (set_attr "pent_pair" "np")
1926 (set_attr "athlon_decode" "vector")])
1928 (define_expand "movstricthi"
1929 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1930 (match_operand:HI 1 "general_operand" ""))]
1933 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1935 /* Don't generate memory->memory moves, go through a register */
1936 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1937 operands[1] = force_reg (HImode, operands[1]);
1940 (define_insn "*movstricthi_1"
1941 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1942 (match_operand:HI 1 "general_operand" "rn,m"))]
1943 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1944 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1945 "mov{w}\t{%1, %0|%0, %1}"
1946 [(set_attr "type" "imov")
1947 (set_attr "mode" "HI")])
1949 (define_insn "*movstricthi_xor"
1950 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1951 (match_operand:HI 1 "const0_operand" ""))
1952 (clobber (reg:CC FLAGS_REG))]
1955 [(set_attr "type" "alu1")
1956 (set_attr "mode" "HI")
1957 (set_attr "length_immediate" "0")])
1959 (define_expand "movqi"
1960 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1961 (match_operand:QI 1 "general_operand" ""))]
1963 "ix86_expand_move (QImode, operands); DONE;")
1965 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1966 ;; "push a byte". But actually we use pushl, which has the effect
1967 ;; of rounding the amount pushed up to a word.
1969 (define_insn "*pushqi2"
1970 [(set (match_operand:QI 0 "push_operand" "=X")
1971 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1974 [(set_attr "type" "push")
1975 (set_attr "mode" "SI")])
1977 ;; For 64BIT abi we always round up to 8 bytes.
1978 (define_insn "*pushqi2_rex64"
1979 [(set (match_operand:QI 0 "push_operand" "=X")
1980 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1983 [(set_attr "type" "push")
1984 (set_attr "mode" "DI")])
1986 ;; Situation is quite tricky about when to choose full sized (SImode) move
1987 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1988 ;; partial register dependency machines (such as AMD Athlon), where QImode
1989 ;; moves issue extra dependency and for partial register stalls machines
1990 ;; that don't use QImode patterns (and QImode move cause stall on the next
1993 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1994 ;; register stall machines with, where we use QImode instructions, since
1995 ;; partial register stall can be caused there. Then we use movzx.
1996 (define_insn "*movqi_1"
1997 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1998 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1999 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2001 switch (get_attr_type (insn))
2004 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2005 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2007 if (get_attr_mode (insn) == MODE_SI)
2008 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2010 return "mov{b}\t{%1, %0|%0, %1}";
2014 (cond [(and (eq_attr "alternative" "5")
2015 (not (match_operand:QI 1 "aligned_operand" "")))
2016 (const_string "imovx")
2017 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2018 (const_string "imov")
2019 (and (eq_attr "alternative" "3")
2020 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2022 (eq (symbol_ref "TARGET_QIMODE_MATH")
2024 (const_string "imov")
2025 (eq_attr "alternative" "3,5")
2026 (const_string "imovx")
2027 (and (ne (symbol_ref "TARGET_MOVX")
2029 (eq_attr "alternative" "2"))
2030 (const_string "imovx")
2032 (const_string "imov")))
2034 (cond [(eq_attr "alternative" "3,4,5")
2036 (eq_attr "alternative" "6")
2038 (eq_attr "type" "imovx")
2040 (and (eq_attr "type" "imov")
2041 (and (eq_attr "alternative" "0,1")
2042 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2044 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2046 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2049 ;; Avoid partial register stalls when not using QImode arithmetic
2050 (and (eq_attr "type" "imov")
2051 (and (eq_attr "alternative" "0,1")
2052 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2054 (eq (symbol_ref "TARGET_QIMODE_MATH")
2058 (const_string "QI")))])
2060 (define_insn "*swapqi_1"
2061 [(set (match_operand:QI 0 "register_operand" "+r")
2062 (match_operand:QI 1 "register_operand" "+r"))
2065 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2067 [(set_attr "type" "imov")
2068 (set_attr "mode" "SI")
2069 (set_attr "pent_pair" "np")
2070 (set_attr "athlon_decode" "vector")
2071 (set_attr "amdfam10_decode" "vector")])
2073 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2074 (define_insn "*swapqi_2"
2075 [(set (match_operand:QI 0 "register_operand" "+q")
2076 (match_operand:QI 1 "register_operand" "+q"))
2079 "TARGET_PARTIAL_REG_STALL"
2081 [(set_attr "type" "imov")
2082 (set_attr "mode" "QI")
2083 (set_attr "pent_pair" "np")
2084 (set_attr "athlon_decode" "vector")])
2086 (define_expand "movstrictqi"
2087 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2088 (match_operand:QI 1 "general_operand" ""))]
2091 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2093 /* Don't generate memory->memory moves, go through a register. */
2094 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2095 operands[1] = force_reg (QImode, operands[1]);
2098 (define_insn "*movstrictqi_1"
2099 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2100 (match_operand:QI 1 "general_operand" "*qn,m"))]
2101 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2102 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2103 "mov{b}\t{%1, %0|%0, %1}"
2104 [(set_attr "type" "imov")
2105 (set_attr "mode" "QI")])
2107 (define_insn "*movstrictqi_xor"
2108 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2109 (match_operand:QI 1 "const0_operand" ""))
2110 (clobber (reg:CC FLAGS_REG))]
2113 [(set_attr "type" "alu1")
2114 (set_attr "mode" "QI")
2115 (set_attr "length_immediate" "0")])
2117 (define_insn "*movsi_extv_1"
2118 [(set (match_operand:SI 0 "register_operand" "=R")
2119 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2123 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2124 [(set_attr "type" "imovx")
2125 (set_attr "mode" "SI")])
2127 (define_insn "*movhi_extv_1"
2128 [(set (match_operand:HI 0 "register_operand" "=R")
2129 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2133 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2134 [(set_attr "type" "imovx")
2135 (set_attr "mode" "SI")])
2137 (define_insn "*movqi_extv_1"
2138 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2139 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2144 switch (get_attr_type (insn))
2147 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2149 return "mov{b}\t{%h1, %0|%0, %h1}";
2153 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2154 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2155 (ne (symbol_ref "TARGET_MOVX")
2157 (const_string "imovx")
2158 (const_string "imov")))
2160 (if_then_else (eq_attr "type" "imovx")
2162 (const_string "QI")))])
2164 (define_insn "*movqi_extv_1_rex64"
2165 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2166 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2171 switch (get_attr_type (insn))
2174 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2176 return "mov{b}\t{%h1, %0|%0, %h1}";
2180 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2181 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2182 (ne (symbol_ref "TARGET_MOVX")
2184 (const_string "imovx")
2185 (const_string "imov")))
2187 (if_then_else (eq_attr "type" "imovx")
2189 (const_string "QI")))])
2191 ;; Stores and loads of ax to arbitrary constant address.
2192 ;; We fake an second form of instruction to force reload to load address
2193 ;; into register when rax is not available
2194 (define_insn "*movabsqi_1_rex64"
2195 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2196 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2197 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2199 movabs{b}\t{%1, %P0|%P0, %1}
2200 mov{b}\t{%1, %a0|%a0, %1}"
2201 [(set_attr "type" "imov")
2202 (set_attr "modrm" "0,*")
2203 (set_attr "length_address" "8,0")
2204 (set_attr "length_immediate" "0,*")
2205 (set_attr "memory" "store")
2206 (set_attr "mode" "QI")])
2208 (define_insn "*movabsqi_2_rex64"
2209 [(set (match_operand:QI 0 "register_operand" "=a,r")
2210 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2211 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2213 movabs{b}\t{%P1, %0|%0, %P1}
2214 mov{b}\t{%a1, %0|%0, %a1}"
2215 [(set_attr "type" "imov")
2216 (set_attr "modrm" "0,*")
2217 (set_attr "length_address" "8,0")
2218 (set_attr "length_immediate" "0")
2219 (set_attr "memory" "load")
2220 (set_attr "mode" "QI")])
2222 (define_insn "*movdi_extzv_1"
2223 [(set (match_operand:DI 0 "register_operand" "=R")
2224 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2228 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2229 [(set_attr "type" "imovx")
2230 (set_attr "mode" "SI")])
2232 (define_insn "*movsi_extzv_1"
2233 [(set (match_operand:SI 0 "register_operand" "=R")
2234 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2238 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2239 [(set_attr "type" "imovx")
2240 (set_attr "mode" "SI")])
2242 (define_insn "*movqi_extzv_2"
2243 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2244 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2249 switch (get_attr_type (insn))
2252 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2254 return "mov{b}\t{%h1, %0|%0, %h1}";
2258 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2259 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2260 (ne (symbol_ref "TARGET_MOVX")
2262 (const_string "imovx")
2263 (const_string "imov")))
2265 (if_then_else (eq_attr "type" "imovx")
2267 (const_string "QI")))])
2269 (define_insn "*movqi_extzv_2_rex64"
2270 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2271 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2276 switch (get_attr_type (insn))
2279 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2281 return "mov{b}\t{%h1, %0|%0, %h1}";
2285 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2286 (ne (symbol_ref "TARGET_MOVX")
2288 (const_string "imovx")
2289 (const_string "imov")))
2291 (if_then_else (eq_attr "type" "imovx")
2293 (const_string "QI")))])
2295 (define_insn "movsi_insv_1"
2296 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2299 (match_operand:SI 1 "general_operand" "Qmn"))]
2301 "mov{b}\t{%b1, %h0|%h0, %b1}"
2302 [(set_attr "type" "imov")
2303 (set_attr "mode" "QI")])
2305 (define_insn "*movsi_insv_1_rex64"
2306 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2309 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2311 "mov{b}\t{%b1, %h0|%h0, %b1}"
2312 [(set_attr "type" "imov")
2313 (set_attr "mode" "QI")])
2315 (define_insn "movdi_insv_1_rex64"
2316 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2319 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2321 "mov{b}\t{%b1, %h0|%h0, %b1}"
2322 [(set_attr "type" "imov")
2323 (set_attr "mode" "QI")])
2325 (define_insn "*movqi_insv_2"
2326 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2329 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2332 "mov{b}\t{%h1, %h0|%h0, %h1}"
2333 [(set_attr "type" "imov")
2334 (set_attr "mode" "QI")])
2336 (define_expand "movdi"
2337 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2338 (match_operand:DI 1 "general_operand" ""))]
2340 "ix86_expand_move (DImode, operands); DONE;")
2342 (define_insn "*pushdi"
2343 [(set (match_operand:DI 0 "push_operand" "=<")
2344 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2348 (define_insn "*pushdi2_rex64"
2349 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2350 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2355 [(set_attr "type" "push,multi")
2356 (set_attr "mode" "DI")])
2358 ;; Convert impossible pushes of immediate to existing instructions.
2359 ;; First try to get scratch register and go through it. In case this
2360 ;; fails, push sign extended lower part first and then overwrite
2361 ;; upper part by 32bit move.
2363 [(match_scratch:DI 2 "r")
2364 (set (match_operand:DI 0 "push_operand" "")
2365 (match_operand:DI 1 "immediate_operand" ""))]
2366 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2367 && !x86_64_immediate_operand (operands[1], DImode)"
2368 [(set (match_dup 2) (match_dup 1))
2369 (set (match_dup 0) (match_dup 2))]
2372 ;; We need to define this as both peepholer and splitter for case
2373 ;; peephole2 pass is not run.
2374 ;; "&& 1" is needed to keep it from matching the previous pattern.
2376 [(set (match_operand:DI 0 "push_operand" "")
2377 (match_operand:DI 1 "immediate_operand" ""))]
2378 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2379 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2380 [(set (match_dup 0) (match_dup 1))
2381 (set (match_dup 2) (match_dup 3))]
2382 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2383 operands[1] = gen_lowpart (DImode, operands[2]);
2384 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2389 [(set (match_operand:DI 0 "push_operand" "")
2390 (match_operand:DI 1 "immediate_operand" ""))]
2391 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2392 ? epilogue_completed : reload_completed)
2393 && !symbolic_operand (operands[1], DImode)
2394 && !x86_64_immediate_operand (operands[1], DImode)"
2395 [(set (match_dup 0) (match_dup 1))
2396 (set (match_dup 2) (match_dup 3))]
2397 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2398 operands[1] = gen_lowpart (DImode, operands[2]);
2399 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2403 (define_insn "*pushdi2_prologue_rex64"
2404 [(set (match_operand:DI 0 "push_operand" "=<")
2405 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2406 (clobber (mem:BLK (scratch)))]
2409 [(set_attr "type" "push")
2410 (set_attr "mode" "DI")])
2412 (define_insn "*popdi1_epilogue_rex64"
2413 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2414 (mem:DI (reg:DI SP_REG)))
2415 (set (reg:DI SP_REG)
2416 (plus:DI (reg:DI SP_REG) (const_int 8)))
2417 (clobber (mem:BLK (scratch)))]
2420 [(set_attr "type" "pop")
2421 (set_attr "mode" "DI")])
2423 (define_insn "popdi1"
2424 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2425 (mem:DI (reg:DI SP_REG)))
2426 (set (reg:DI SP_REG)
2427 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2430 [(set_attr "type" "pop")
2431 (set_attr "mode" "DI")])
2433 (define_insn "*movdi_xor_rex64"
2434 [(set (match_operand:DI 0 "register_operand" "=r")
2435 (match_operand:DI 1 "const0_operand" ""))
2436 (clobber (reg:CC FLAGS_REG))]
2438 && reload_completed"
2440 [(set_attr "type" "alu1")
2441 (set_attr "mode" "SI")
2442 (set_attr "length_immediate" "0")])
2444 (define_insn "*movdi_or_rex64"
2445 [(set (match_operand:DI 0 "register_operand" "=r")
2446 (match_operand:DI 1 "const_int_operand" "i"))
2447 (clobber (reg:CC FLAGS_REG))]
2450 && operands[1] == constm1_rtx"
2452 operands[1] = constm1_rtx;
2453 return "or{q}\t{%1, %0|%0, %1}";
2455 [(set_attr "type" "alu1")
2456 (set_attr "mode" "DI")
2457 (set_attr "length_immediate" "1")])
2459 (define_insn "*movdi_2"
2460 [(set (match_operand:DI 0 "nonimmediate_operand"
2461 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2462 (match_operand:DI 1 "general_operand"
2463 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2464 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2469 movq\t{%1, %0|%0, %1}
2470 movq\t{%1, %0|%0, %1}
2472 %vmovq\t{%1, %0|%0, %1}
2473 %vmovdqa\t{%1, %0|%0, %1}
2474 %vmovq\t{%1, %0|%0, %1}
2476 movlps\t{%1, %0|%0, %1}
2477 movaps\t{%1, %0|%0, %1}
2478 movlps\t{%1, %0|%0, %1}"
2479 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2480 (set (attr "prefix")
2481 (if_then_else (eq_attr "alternative" "5,6,7,8")
2482 (const_string "vex")
2483 (const_string "orig")))
2484 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2487 [(set (match_operand:DI 0 "push_operand" "")
2488 (match_operand:DI 1 "general_operand" ""))]
2489 "!TARGET_64BIT && reload_completed
2490 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2492 "ix86_split_long_move (operands); DONE;")
2494 ;; %%% This multiword shite has got to go.
2496 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2497 (match_operand:DI 1 "general_operand" ""))]
2498 "!TARGET_64BIT && reload_completed
2499 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2500 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2502 "ix86_split_long_move (operands); DONE;")
2504 (define_insn "*movdi_1_rex64"
2505 [(set (match_operand:DI 0 "nonimmediate_operand"
2506 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2507 (match_operand:DI 1 "general_operand"
2508 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2509 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2511 switch (get_attr_type (insn))
2514 if (SSE_REG_P (operands[0]))
2515 return "movq2dq\t{%1, %0|%0, %1}";
2517 return "movdq2q\t{%1, %0|%0, %1}";
2522 if (get_attr_mode (insn) == MODE_TI)
2523 return "vmovdqa\t{%1, %0|%0, %1}";
2525 return "vmovq\t{%1, %0|%0, %1}";
2528 if (get_attr_mode (insn) == MODE_TI)
2529 return "movdqa\t{%1, %0|%0, %1}";
2533 /* Moves from and into integer register is done using movd
2534 opcode with REX prefix. */
2535 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2536 return "movd\t{%1, %0|%0, %1}";
2537 return "movq\t{%1, %0|%0, %1}";
2540 return "%vpxor\t%0, %d0";
2543 return "pxor\t%0, %0";
2549 return "lea{q}\t{%a1, %0|%0, %a1}";
2552 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2553 if (get_attr_mode (insn) == MODE_SI)
2554 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2555 else if (which_alternative == 2)
2556 return "movabs{q}\t{%1, %0|%0, %1}";
2558 return "mov{q}\t{%1, %0|%0, %1}";
2562 (cond [(eq_attr "alternative" "5")
2563 (const_string "mmx")
2564 (eq_attr "alternative" "6,7,8,9,10")
2565 (const_string "mmxmov")
2566 (eq_attr "alternative" "11")
2567 (const_string "sselog1")
2568 (eq_attr "alternative" "12,13,14,15,16")
2569 (const_string "ssemov")
2570 (eq_attr "alternative" "17,18")
2571 (const_string "ssecvt")
2572 (eq_attr "alternative" "4")
2573 (const_string "multi")
2574 (match_operand:DI 1 "pic_32bit_operand" "")
2575 (const_string "lea")
2577 (const_string "imov")))
2580 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2582 (const_string "*")))
2583 (set (attr "length_immediate")
2585 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2587 (const_string "*")))
2588 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2589 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2590 (set (attr "prefix")
2591 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2592 (const_string "maybe_vex")
2593 (const_string "orig")))
2594 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2596 ;; Stores and loads of ax to arbitrary constant address.
2597 ;; We fake an second form of instruction to force reload to load address
2598 ;; into register when rax is not available
2599 (define_insn "*movabsdi_1_rex64"
2600 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2601 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2602 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2604 movabs{q}\t{%1, %P0|%P0, %1}
2605 mov{q}\t{%1, %a0|%a0, %1}"
2606 [(set_attr "type" "imov")
2607 (set_attr "modrm" "0,*")
2608 (set_attr "length_address" "8,0")
2609 (set_attr "length_immediate" "0,*")
2610 (set_attr "memory" "store")
2611 (set_attr "mode" "DI")])
2613 (define_insn "*movabsdi_2_rex64"
2614 [(set (match_operand:DI 0 "register_operand" "=a,r")
2615 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2616 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2618 movabs{q}\t{%P1, %0|%0, %P1}
2619 mov{q}\t{%a1, %0|%0, %a1}"
2620 [(set_attr "type" "imov")
2621 (set_attr "modrm" "0,*")
2622 (set_attr "length_address" "8,0")
2623 (set_attr "length_immediate" "0")
2624 (set_attr "memory" "load")
2625 (set_attr "mode" "DI")])
2627 ;; Convert impossible stores of immediate to existing instructions.
2628 ;; First try to get scratch register and go through it. In case this
2629 ;; fails, move by 32bit parts.
2631 [(match_scratch:DI 2 "r")
2632 (set (match_operand:DI 0 "memory_operand" "")
2633 (match_operand:DI 1 "immediate_operand" ""))]
2634 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2635 && !x86_64_immediate_operand (operands[1], DImode)"
2636 [(set (match_dup 2) (match_dup 1))
2637 (set (match_dup 0) (match_dup 2))]
2640 ;; We need to define this as both peepholer and splitter for case
2641 ;; peephole2 pass is not run.
2642 ;; "&& 1" is needed to keep it from matching the previous pattern.
2644 [(set (match_operand:DI 0 "memory_operand" "")
2645 (match_operand:DI 1 "immediate_operand" ""))]
2646 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2647 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2648 [(set (match_dup 2) (match_dup 3))
2649 (set (match_dup 4) (match_dup 5))]
2650 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2653 [(set (match_operand:DI 0 "memory_operand" "")
2654 (match_operand:DI 1 "immediate_operand" ""))]
2655 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2656 ? epilogue_completed : reload_completed)
2657 && !symbolic_operand (operands[1], DImode)
2658 && !x86_64_immediate_operand (operands[1], DImode)"
2659 [(set (match_dup 2) (match_dup 3))
2660 (set (match_dup 4) (match_dup 5))]
2661 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2663 (define_insn "*swapdi_rex64"
2664 [(set (match_operand:DI 0 "register_operand" "+r")
2665 (match_operand:DI 1 "register_operand" "+r"))
2670 [(set_attr "type" "imov")
2671 (set_attr "mode" "DI")
2672 (set_attr "pent_pair" "np")
2673 (set_attr "athlon_decode" "vector")
2674 (set_attr "amdfam10_decode" "double")])
2676 (define_expand "movoi"
2677 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2678 (match_operand:OI 1 "general_operand" ""))]
2680 "ix86_expand_move (OImode, operands); DONE;")
2682 (define_insn "*movoi_internal"
2683 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2684 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2686 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2688 switch (which_alternative)
2691 return "vxorps\t%0, %0, %0";
2694 if (misaligned_operand (operands[0], OImode)
2695 || misaligned_operand (operands[1], OImode))
2696 return "vmovdqu\t{%1, %0|%0, %1}";
2698 return "vmovdqa\t{%1, %0|%0, %1}";
2703 [(set_attr "type" "sselog1,ssemov,ssemov")
2704 (set_attr "prefix" "vex")
2705 (set_attr "mode" "OI")])
2707 (define_expand "movti"
2708 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2709 (match_operand:TI 1 "nonimmediate_operand" ""))]
2710 "TARGET_SSE || TARGET_64BIT"
2713 ix86_expand_move (TImode, operands);
2714 else if (push_operand (operands[0], TImode))
2715 ix86_expand_push (TImode, operands[1]);
2717 ix86_expand_vector_move (TImode, operands);
2721 (define_insn "*movti_internal"
2722 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2723 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2724 "TARGET_SSE && !TARGET_64BIT
2725 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2727 switch (which_alternative)
2730 if (get_attr_mode (insn) == MODE_V4SF)
2731 return "%vxorps\t%0, %d0";
2733 return "%vpxor\t%0, %d0";
2736 /* TDmode values are passed as TImode on the stack. Moving them
2737 to stack may result in unaligned memory access. */
2738 if (misaligned_operand (operands[0], TImode)
2739 || misaligned_operand (operands[1], TImode))
2741 if (get_attr_mode (insn) == MODE_V4SF)
2742 return "%vmovups\t{%1, %0|%0, %1}";
2744 return "%vmovdqu\t{%1, %0|%0, %1}";
2748 if (get_attr_mode (insn) == MODE_V4SF)
2749 return "%vmovaps\t{%1, %0|%0, %1}";
2751 return "%vmovdqa\t{%1, %0|%0, %1}";
2757 [(set_attr "type" "sselog1,ssemov,ssemov")
2758 (set_attr "prefix" "maybe_vex")
2760 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2761 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2762 (const_string "V4SF")
2763 (and (eq_attr "alternative" "2")
2764 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2766 (const_string "V4SF")]
2767 (const_string "TI")))])
2769 (define_insn "*movti_rex64"
2770 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2771 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2773 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2775 switch (which_alternative)
2781 if (get_attr_mode (insn) == MODE_V4SF)
2782 return "%vxorps\t%0, %d0";
2784 return "%vpxor\t%0, %d0";
2787 /* TDmode values are passed as TImode on the stack. Moving them
2788 to stack may result in unaligned memory access. */
2789 if (misaligned_operand (operands[0], TImode)
2790 || misaligned_operand (operands[1], TImode))
2792 if (get_attr_mode (insn) == MODE_V4SF)
2793 return "%vmovups\t{%1, %0|%0, %1}";
2795 return "%vmovdqu\t{%1, %0|%0, %1}";
2799 if (get_attr_mode (insn) == MODE_V4SF)
2800 return "%vmovaps\t{%1, %0|%0, %1}";
2802 return "%vmovdqa\t{%1, %0|%0, %1}";
2808 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2809 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2811 (cond [(eq_attr "alternative" "2,3")
2813 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2815 (const_string "V4SF")
2816 (const_string "TI"))
2817 (eq_attr "alternative" "4")
2819 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2821 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2823 (const_string "V4SF")
2824 (const_string "TI"))]
2825 (const_string "DI")))])
2828 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2829 (match_operand:TI 1 "general_operand" ""))]
2830 "reload_completed && !SSE_REG_P (operands[0])
2831 && !SSE_REG_P (operands[1])"
2833 "ix86_split_long_move (operands); DONE;")
2835 ;; This expands to what emit_move_complex would generate if we didn't
2836 ;; have a movti pattern. Having this avoids problems with reload on
2837 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2838 ;; to have around all the time.
2839 (define_expand "movcdi"
2840 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2841 (match_operand:CDI 1 "general_operand" ""))]
2844 if (push_operand (operands[0], CDImode))
2845 emit_move_complex_push (CDImode, operands[0], operands[1]);
2847 emit_move_complex_parts (operands[0], operands[1]);
2851 (define_expand "movsf"
2852 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2853 (match_operand:SF 1 "general_operand" ""))]
2855 "ix86_expand_move (SFmode, operands); DONE;")
2857 (define_insn "*pushsf"
2858 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2859 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2862 /* Anything else should be already split before reg-stack. */
2863 gcc_assert (which_alternative == 1);
2864 return "push{l}\t%1";
2866 [(set_attr "type" "multi,push,multi")
2867 (set_attr "unit" "i387,*,*")
2868 (set_attr "mode" "SF,SI,SF")])
2870 (define_insn "*pushsf_rex64"
2871 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2872 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2875 /* Anything else should be already split before reg-stack. */
2876 gcc_assert (which_alternative == 1);
2877 return "push{q}\t%q1";
2879 [(set_attr "type" "multi,push,multi")
2880 (set_attr "unit" "i387,*,*")
2881 (set_attr "mode" "SF,DI,SF")])
2884 [(set (match_operand:SF 0 "push_operand" "")
2885 (match_operand:SF 1 "memory_operand" ""))]
2887 && MEM_P (operands[1])
2888 && (operands[2] = find_constant_src (insn))"
2892 ;; %%% Kill this when call knows how to work this out.
2894 [(set (match_operand:SF 0 "push_operand" "")
2895 (match_operand:SF 1 "any_fp_register_operand" ""))]
2897 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2898 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2901 [(set (match_operand:SF 0 "push_operand" "")
2902 (match_operand:SF 1 "any_fp_register_operand" ""))]
2904 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2905 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2907 (define_insn "*movsf_1"
2908 [(set (match_operand:SF 0 "nonimmediate_operand"
2909 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2910 (match_operand:SF 1 "general_operand"
2911 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2912 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2913 && (reload_in_progress || reload_completed
2914 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2915 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2916 && standard_80387_constant_p (operands[1]))
2917 || GET_CODE (operands[1]) != CONST_DOUBLE
2918 || memory_operand (operands[0], SFmode))"
2920 switch (which_alternative)
2924 return output_387_reg_move (insn, operands);
2927 return standard_80387_constant_opcode (operands[1]);
2931 return "mov{l}\t{%1, %0|%0, %1}";
2933 if (get_attr_mode (insn) == MODE_TI)
2934 return "%vpxor\t%0, %d0";
2936 return "%vxorps\t%0, %d0";
2938 if (get_attr_mode (insn) == MODE_V4SF)
2939 return "%vmovaps\t{%1, %0|%0, %1}";
2941 return "%vmovss\t{%1, %d0|%d0, %1}";
2944 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2945 : "vmovss\t{%1, %0|%0, %1}";
2947 return "movss\t{%1, %0|%0, %1}";
2949 return "%vmovss\t{%1, %0|%0, %1}";
2951 case 9: case 10: case 14: case 15:
2952 return "movd\t{%1, %0|%0, %1}";
2954 return "%vmovd\t{%1, %0|%0, %1}";
2957 return "movq\t{%1, %0|%0, %1}";
2963 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2964 (set (attr "prefix")
2965 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2966 (const_string "maybe_vex")
2967 (const_string "orig")))
2969 (cond [(eq_attr "alternative" "3,4,9,10")
2971 (eq_attr "alternative" "5")
2973 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2975 (ne (symbol_ref "TARGET_SSE2")
2977 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2980 (const_string "V4SF"))
2981 /* For architectures resolving dependencies on
2982 whole SSE registers use APS move to break dependency
2983 chains, otherwise use short move to avoid extra work.
2985 Do the same for architectures resolving dependencies on
2986 the parts. While in DF mode it is better to always handle
2987 just register parts, the SF mode is different due to lack
2988 of instructions to load just part of the register. It is
2989 better to maintain the whole registers in single format
2990 to avoid problems on using packed logical operations. */
2991 (eq_attr "alternative" "6")
2993 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2995 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2997 (const_string "V4SF")
2998 (const_string "SF"))
2999 (eq_attr "alternative" "11")
3000 (const_string "DI")]
3001 (const_string "SF")))])
3003 (define_insn "*swapsf"
3004 [(set (match_operand:SF 0 "fp_register_operand" "+f")
3005 (match_operand:SF 1 "fp_register_operand" "+f"))
3008 "reload_completed || TARGET_80387"
3010 if (STACK_TOP_P (operands[0]))
3015 [(set_attr "type" "fxch")
3016 (set_attr "mode" "SF")])
3018 (define_expand "movdf"
3019 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3020 (match_operand:DF 1 "general_operand" ""))]
3022 "ix86_expand_move (DFmode, operands); DONE;")
3024 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3025 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3026 ;; On the average, pushdf using integers can be still shorter. Allow this
3027 ;; pattern for optimize_size too.
3029 (define_insn "*pushdf_nointeger"
3030 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3031 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3032 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3034 /* This insn should be already split before reg-stack. */
3037 [(set_attr "type" "multi")
3038 (set_attr "unit" "i387,*,*,*")
3039 (set_attr "mode" "DF,SI,SI,DF")])
3041 (define_insn "*pushdf_integer"
3042 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3043 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3044 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3046 /* This insn should be already split before reg-stack. */
3049 [(set_attr "type" "multi")
3050 (set_attr "unit" "i387,*,*")
3051 (set_attr "mode" "DF,SI,DF")])
3053 ;; %%% Kill this when call knows how to work this out.
3055 [(set (match_operand:DF 0 "push_operand" "")
3056 (match_operand:DF 1 "any_fp_register_operand" ""))]
3058 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3059 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3063 [(set (match_operand:DF 0 "push_operand" "")
3064 (match_operand:DF 1 "general_operand" ""))]
3067 "ix86_split_long_move (operands); DONE;")
3069 ;; Moving is usually shorter when only FP registers are used. This separate
3070 ;; movdf pattern avoids the use of integer registers for FP operations
3071 ;; when optimizing for size.
3073 (define_insn "*movdf_nointeger"
3074 [(set (match_operand:DF 0 "nonimmediate_operand"
3075 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3076 (match_operand:DF 1 "general_operand"
3077 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3078 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3079 && ((optimize_function_for_size_p (cfun)
3080 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3081 && (reload_in_progress || reload_completed
3082 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3083 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3084 && optimize_function_for_size_p (cfun)
3085 && !memory_operand (operands[0], DFmode)
3086 && standard_80387_constant_p (operands[1]))
3087 || GET_CODE (operands[1]) != CONST_DOUBLE
3088 || ((optimize_function_for_size_p (cfun)
3089 || !TARGET_MEMORY_MISMATCH_STALL
3090 || reload_in_progress || reload_completed)
3091 && memory_operand (operands[0], DFmode)))"
3093 switch (which_alternative)
3097 return output_387_reg_move (insn, operands);
3100 return standard_80387_constant_opcode (operands[1]);
3106 switch (get_attr_mode (insn))
3109 return "%vxorps\t%0, %d0";
3111 return "%vxorpd\t%0, %d0";
3113 return "%vpxor\t%0, %d0";
3120 switch (get_attr_mode (insn))
3123 return "%vmovaps\t{%1, %0|%0, %1}";
3125 return "%vmovapd\t{%1, %0|%0, %1}";
3127 return "%vmovdqa\t{%1, %0|%0, %1}";
3129 return "%vmovq\t{%1, %0|%0, %1}";
3133 if (REG_P (operands[0]) && REG_P (operands[1]))
3134 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3136 return "vmovsd\t{%1, %0|%0, %1}";
3139 return "movsd\t{%1, %0|%0, %1}";
3143 if (REG_P (operands[0]))
3144 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3146 return "vmovlpd\t{%1, %0|%0, %1}";
3149 return "movlpd\t{%1, %0|%0, %1}";
3153 if (REG_P (operands[0]))
3154 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3156 return "vmovlps\t{%1, %0|%0, %1}";
3159 return "movlps\t{%1, %0|%0, %1}";
3168 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3169 (set (attr "prefix")
3170 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3171 (const_string "orig")
3172 (const_string "maybe_vex")))
3173 (set (attr "prefix_data16")
3174 (if_then_else (eq_attr "mode" "V1DF")
3176 (const_string "*")))
3178 (cond [(eq_attr "alternative" "0,1,2")
3180 (eq_attr "alternative" "3,4")
3183 /* For SSE1, we have many fewer alternatives. */
3184 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3185 (cond [(eq_attr "alternative" "5,6")
3186 (const_string "V4SF")
3188 (const_string "V2SF"))
3190 /* xorps is one byte shorter. */
3191 (eq_attr "alternative" "5")
3192 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3194 (const_string "V4SF")
3195 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3199 (const_string "V2DF"))
3201 /* For architectures resolving dependencies on
3202 whole SSE registers use APD move to break dependency
3203 chains, otherwise use short move to avoid extra work.
3205 movaps encodes one byte shorter. */
3206 (eq_attr "alternative" "6")
3208 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3210 (const_string "V4SF")
3211 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3213 (const_string "V2DF")
3215 (const_string "DF"))
3216 /* For architectures resolving dependencies on register
3217 parts we may avoid extra work to zero out upper part
3219 (eq_attr "alternative" "7")
3221 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3223 (const_string "V1DF")
3224 (const_string "DF"))
3226 (const_string "DF")))])
3228 (define_insn "*movdf_integer_rex64"
3229 [(set (match_operand:DF 0 "nonimmediate_operand"
3230 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3231 (match_operand:DF 1 "general_operand"
3232 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3233 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3234 && (reload_in_progress || reload_completed
3235 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3236 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3237 && optimize_function_for_size_p (cfun)
3238 && standard_80387_constant_p (operands[1]))
3239 || GET_CODE (operands[1]) != CONST_DOUBLE
3240 || memory_operand (operands[0], DFmode))"
3242 switch (which_alternative)
3246 return output_387_reg_move (insn, operands);
3249 return standard_80387_constant_opcode (operands[1]);
3256 switch (get_attr_mode (insn))
3259 return "%vxorps\t%0, %d0";
3261 return "%vxorpd\t%0, %d0";
3263 return "%vpxor\t%0, %d0";
3270 switch (get_attr_mode (insn))
3273 return "%vmovaps\t{%1, %0|%0, %1}";
3275 return "%vmovapd\t{%1, %0|%0, %1}";
3277 return "%vmovdqa\t{%1, %0|%0, %1}";
3279 return "%vmovq\t{%1, %0|%0, %1}";
3283 if (REG_P (operands[0]) && REG_P (operands[1]))
3284 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3286 return "vmovsd\t{%1, %0|%0, %1}";
3289 return "movsd\t{%1, %0|%0, %1}";
3291 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3293 return "%vmovlps\t{%1, %d0|%d0, %1}";
3300 return "%vmovd\t{%1, %0|%0, %1}";
3306 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3307 (set (attr "prefix")
3308 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3309 (const_string "orig")
3310 (const_string "maybe_vex")))
3311 (set (attr "prefix_data16")
3312 (if_then_else (eq_attr "mode" "V1DF")
3314 (const_string "*")))
3316 (cond [(eq_attr "alternative" "0,1,2")
3318 (eq_attr "alternative" "3,4,9,10")
3321 /* For SSE1, we have many fewer alternatives. */
3322 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3323 (cond [(eq_attr "alternative" "5,6")
3324 (const_string "V4SF")
3326 (const_string "V2SF"))
3328 /* xorps is one byte shorter. */
3329 (eq_attr "alternative" "5")
3330 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3332 (const_string "V4SF")
3333 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3337 (const_string "V2DF"))
3339 /* For architectures resolving dependencies on
3340 whole SSE registers use APD move to break dependency
3341 chains, otherwise use short move to avoid extra work.
3343 movaps encodes one byte shorter. */
3344 (eq_attr "alternative" "6")
3346 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3348 (const_string "V4SF")
3349 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3351 (const_string "V2DF")
3353 (const_string "DF"))
3354 /* For architectures resolving dependencies on register
3355 parts we may avoid extra work to zero out upper part
3357 (eq_attr "alternative" "7")
3359 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3361 (const_string "V1DF")
3362 (const_string "DF"))
3364 (const_string "DF")))])
3366 (define_insn "*movdf_integer"
3367 [(set (match_operand:DF 0 "nonimmediate_operand"
3368 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3369 (match_operand:DF 1 "general_operand"
3370 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3371 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3372 && optimize_function_for_speed_p (cfun)
3373 && TARGET_INTEGER_DFMODE_MOVES
3374 && (reload_in_progress || reload_completed
3375 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3376 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3377 && optimize_function_for_size_p (cfun)
3378 && standard_80387_constant_p (operands[1]))
3379 || GET_CODE (operands[1]) != CONST_DOUBLE
3380 || memory_operand (operands[0], DFmode))"
3382 switch (which_alternative)
3386 return output_387_reg_move (insn, operands);
3389 return standard_80387_constant_opcode (operands[1]);
3396 switch (get_attr_mode (insn))
3399 return "xorps\t%0, %0";
3401 return "xorpd\t%0, %0";
3403 return "pxor\t%0, %0";
3410 switch (get_attr_mode (insn))
3413 return "movaps\t{%1, %0|%0, %1}";
3415 return "movapd\t{%1, %0|%0, %1}";
3417 return "movdqa\t{%1, %0|%0, %1}";
3419 return "movq\t{%1, %0|%0, %1}";
3421 return "movsd\t{%1, %0|%0, %1}";
3423 return "movlpd\t{%1, %0|%0, %1}";
3425 return "movlps\t{%1, %0|%0, %1}";
3434 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3435 (set (attr "prefix_data16")
3436 (if_then_else (eq_attr "mode" "V1DF")
3438 (const_string "*")))
3440 (cond [(eq_attr "alternative" "0,1,2")
3442 (eq_attr "alternative" "3,4")
3445 /* For SSE1, we have many fewer alternatives. */
3446 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3447 (cond [(eq_attr "alternative" "5,6")
3448 (const_string "V4SF")
3450 (const_string "V2SF"))
3452 /* xorps is one byte shorter. */
3453 (eq_attr "alternative" "5")
3454 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3456 (const_string "V4SF")
3457 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3461 (const_string "V2DF"))
3463 /* For architectures resolving dependencies on
3464 whole SSE registers use APD move to break dependency
3465 chains, otherwise use short move to avoid extra work.
3467 movaps encodes one byte shorter. */
3468 (eq_attr "alternative" "6")
3470 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3472 (const_string "V4SF")
3473 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3475 (const_string "V2DF")
3477 (const_string "DF"))
3478 /* For architectures resolving dependencies on register
3479 parts we may avoid extra work to zero out upper part
3481 (eq_attr "alternative" "7")
3483 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3485 (const_string "V1DF")
3486 (const_string "DF"))
3488 (const_string "DF")))])
3491 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3492 (match_operand:DF 1 "general_operand" ""))]
3494 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3495 && ! (ANY_FP_REG_P (operands[0]) ||
3496 (GET_CODE (operands[0]) == SUBREG
3497 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3498 && ! (ANY_FP_REG_P (operands[1]) ||
3499 (GET_CODE (operands[1]) == SUBREG
3500 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3502 "ix86_split_long_move (operands); DONE;")
3504 (define_insn "*swapdf"
3505 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3506 (match_operand:DF 1 "fp_register_operand" "+f"))
3509 "reload_completed || TARGET_80387"
3511 if (STACK_TOP_P (operands[0]))
3516 [(set_attr "type" "fxch")
3517 (set_attr "mode" "DF")])
3519 (define_expand "movxf"
3520 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3521 (match_operand:XF 1 "general_operand" ""))]
3523 "ix86_expand_move (XFmode, operands); DONE;")
3525 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3526 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3527 ;; Pushing using integer instructions is longer except for constants
3528 ;; and direct memory references.
3529 ;; (assuming that any given constant is pushed only once, but this ought to be
3530 ;; handled elsewhere).
3532 (define_insn "*pushxf_nointeger"
3533 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3534 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3535 "optimize_function_for_size_p (cfun)"
3537 /* This insn should be already split before reg-stack. */
3540 [(set_attr "type" "multi")
3541 (set_attr "unit" "i387,*,*")
3542 (set_attr "mode" "XF,SI,SI")])
3544 (define_insn "*pushxf_integer"
3545 [(set (match_operand:XF 0 "push_operand" "=<,<")
3546 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3547 "optimize_function_for_speed_p (cfun)"
3549 /* This insn should be already split before reg-stack. */
3552 [(set_attr "type" "multi")
3553 (set_attr "unit" "i387,*")
3554 (set_attr "mode" "XF,SI")])
3557 [(set (match_operand 0 "push_operand" "")
3558 (match_operand 1 "general_operand" ""))]
3560 && (GET_MODE (operands[0]) == XFmode
3561 || GET_MODE (operands[0]) == DFmode)
3562 && !ANY_FP_REG_P (operands[1])"
3564 "ix86_split_long_move (operands); DONE;")
3567 [(set (match_operand:XF 0 "push_operand" "")
3568 (match_operand:XF 1 "any_fp_register_operand" ""))]
3570 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3571 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3572 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3574 ;; Do not use integer registers when optimizing for size
3575 (define_insn "*movxf_nointeger"
3576 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3577 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3578 "optimize_function_for_size_p (cfun)
3579 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3580 && (reload_in_progress || reload_completed
3581 || standard_80387_constant_p (operands[1])
3582 || GET_CODE (operands[1]) != CONST_DOUBLE
3583 || memory_operand (operands[0], XFmode))"
3585 switch (which_alternative)
3589 return output_387_reg_move (insn, operands);
3592 return standard_80387_constant_opcode (operands[1]);
3600 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3601 (set_attr "mode" "XF,XF,XF,SI,SI")])
3603 (define_insn "*movxf_integer"
3604 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3605 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3606 "optimize_function_for_speed_p (cfun)
3607 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3608 && (reload_in_progress || reload_completed
3609 || GET_CODE (operands[1]) != CONST_DOUBLE
3610 || memory_operand (operands[0], XFmode))"
3612 switch (which_alternative)
3616 return output_387_reg_move (insn, operands);
3619 return standard_80387_constant_opcode (operands[1]);
3628 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3629 (set_attr "mode" "XF,XF,XF,SI,SI")])
3631 (define_expand "movtf"
3632 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3633 (match_operand:TF 1 "nonimmediate_operand" ""))]
3636 ix86_expand_move (TFmode, operands);
3640 (define_insn "*movtf_internal"
3641 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3642 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3644 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3646 switch (which_alternative)
3650 if (get_attr_mode (insn) == MODE_V4SF)
3651 return "%vmovaps\t{%1, %0|%0, %1}";
3653 return "%vmovdqa\t{%1, %0|%0, %1}";
3655 if (get_attr_mode (insn) == MODE_V4SF)
3656 return "%vxorps\t%0, %d0";
3658 return "%vpxor\t%0, %d0";
3666 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3667 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3669 (cond [(eq_attr "alternative" "0,2")
3671 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3673 (const_string "V4SF")
3674 (const_string "TI"))
3675 (eq_attr "alternative" "1")
3677 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3679 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3681 (const_string "V4SF")
3682 (const_string "TI"))]
3683 (const_string "DI")))])
3685 (define_insn "*pushtf_sse"
3686 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3687 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3690 /* This insn should be already split before reg-stack. */
3693 [(set_attr "type" "multi")
3694 (set_attr "unit" "sse,*,*")
3695 (set_attr "mode" "TF,SI,SI")])
3698 [(set (match_operand:TF 0 "push_operand" "")
3699 (match_operand:TF 1 "general_operand" ""))]
3700 "TARGET_SSE2 && reload_completed
3701 && !SSE_REG_P (operands[1])"
3703 "ix86_split_long_move (operands); DONE;")
3706 [(set (match_operand:TF 0 "push_operand" "")
3707 (match_operand:TF 1 "any_fp_register_operand" ""))]
3709 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3710 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3714 [(set (match_operand 0 "nonimmediate_operand" "")
3715 (match_operand 1 "general_operand" ""))]
3717 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3718 && GET_MODE (operands[0]) == XFmode
3719 && ! (ANY_FP_REG_P (operands[0]) ||
3720 (GET_CODE (operands[0]) == SUBREG
3721 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3722 && ! (ANY_FP_REG_P (operands[1]) ||
3723 (GET_CODE (operands[1]) == SUBREG
3724 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3726 "ix86_split_long_move (operands); DONE;")
3729 [(set (match_operand 0 "register_operand" "")
3730 (match_operand 1 "memory_operand" ""))]
3732 && MEM_P (operands[1])
3733 && (GET_MODE (operands[0]) == TFmode
3734 || GET_MODE (operands[0]) == XFmode
3735 || GET_MODE (operands[0]) == SFmode
3736 || GET_MODE (operands[0]) == DFmode)
3737 && (operands[2] = find_constant_src (insn))"
3738 [(set (match_dup 0) (match_dup 2))]
3740 rtx c = operands[2];
3741 rtx r = operands[0];
3743 if (GET_CODE (r) == SUBREG)
3748 if (!standard_sse_constant_p (c))
3751 else if (FP_REG_P (r))
3753 if (!standard_80387_constant_p (c))
3756 else if (MMX_REG_P (r))
3761 [(set (match_operand 0 "register_operand" "")
3762 (float_extend (match_operand 1 "memory_operand" "")))]
3764 && MEM_P (operands[1])
3765 && (GET_MODE (operands[0]) == TFmode
3766 || GET_MODE (operands[0]) == XFmode
3767 || GET_MODE (operands[0]) == SFmode
3768 || GET_MODE (operands[0]) == DFmode)
3769 && (operands[2] = find_constant_src (insn))"
3770 [(set (match_dup 0) (match_dup 2))]
3772 rtx c = operands[2];
3773 rtx r = operands[0];
3775 if (GET_CODE (r) == SUBREG)
3780 if (!standard_sse_constant_p (c))
3783 else if (FP_REG_P (r))
3785 if (!standard_80387_constant_p (c))
3788 else if (MMX_REG_P (r))
3792 (define_insn "swapxf"
3793 [(set (match_operand:XF 0 "register_operand" "+f")
3794 (match_operand:XF 1 "register_operand" "+f"))
3799 if (STACK_TOP_P (operands[0]))
3804 [(set_attr "type" "fxch")
3805 (set_attr "mode" "XF")])
3807 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3809 [(set (match_operand:X87MODEF 0 "register_operand" "")
3810 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3811 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3812 && (standard_80387_constant_p (operands[1]) == 8
3813 || standard_80387_constant_p (operands[1]) == 9)"
3814 [(set (match_dup 0)(match_dup 1))
3816 (neg:X87MODEF (match_dup 0)))]
3820 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3821 if (real_isnegzero (&r))
3822 operands[1] = CONST0_RTX (<MODE>mode);
3824 operands[1] = CONST1_RTX (<MODE>mode);
3828 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3829 (match_operand:TF 1 "general_operand" ""))]
3831 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3833 "ix86_split_long_move (operands); DONE;")
3835 ;; Zero extension instructions
3837 (define_expand "zero_extendhisi2"
3838 [(set (match_operand:SI 0 "register_operand" "")
3839 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3842 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3844 operands[1] = force_reg (HImode, operands[1]);
3845 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3850 (define_insn "zero_extendhisi2_and"
3851 [(set (match_operand:SI 0 "register_operand" "=r")
3852 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3853 (clobber (reg:CC FLAGS_REG))]
3854 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3856 [(set_attr "type" "alu1")
3857 (set_attr "mode" "SI")])
3860 [(set (match_operand:SI 0 "register_operand" "")
3861 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3862 (clobber (reg:CC FLAGS_REG))]
3863 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3864 && optimize_function_for_speed_p (cfun)"
3865 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3866 (clobber (reg:CC FLAGS_REG))])]
3869 (define_insn "*zero_extendhisi2_movzwl"
3870 [(set (match_operand:SI 0 "register_operand" "=r")
3871 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3872 "!TARGET_ZERO_EXTEND_WITH_AND
3873 || optimize_function_for_size_p (cfun)"
3874 "movz{wl|x}\t{%1, %0|%0, %1}"
3875 [(set_attr "type" "imovx")
3876 (set_attr "mode" "SI")])
3878 (define_expand "zero_extendqihi2"
3880 [(set (match_operand:HI 0 "register_operand" "")
3881 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3882 (clobber (reg:CC FLAGS_REG))])]
3886 (define_insn "*zero_extendqihi2_and"
3887 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3888 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3889 (clobber (reg:CC FLAGS_REG))]
3890 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3892 [(set_attr "type" "alu1")
3893 (set_attr "mode" "HI")])
3895 (define_insn "*zero_extendqihi2_movzbw_and"
3896 [(set (match_operand:HI 0 "register_operand" "=r,r")
3897 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3898 (clobber (reg:CC FLAGS_REG))]
3899 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3901 [(set_attr "type" "imovx,alu1")
3902 (set_attr "mode" "HI")])
3904 ; zero extend to SImode here to avoid partial register stalls
3905 (define_insn "*zero_extendqihi2_movzbl"
3906 [(set (match_operand:HI 0 "register_operand" "=r")
3907 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3908 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3909 && reload_completed"
3910 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3911 [(set_attr "type" "imovx")
3912 (set_attr "mode" "SI")])
3914 ;; For the movzbw case strip only the clobber
3916 [(set (match_operand:HI 0 "register_operand" "")
3917 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3918 (clobber (reg:CC FLAGS_REG))]
3920 && (!TARGET_ZERO_EXTEND_WITH_AND
3921 || optimize_function_for_size_p (cfun))
3922 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3923 [(set (match_operand:HI 0 "register_operand" "")
3924 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3926 ;; When source and destination does not overlap, clear destination
3927 ;; first and then do the movb
3929 [(set (match_operand:HI 0 "register_operand" "")
3930 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3931 (clobber (reg:CC FLAGS_REG))]
3933 && ANY_QI_REG_P (operands[0])
3934 && (TARGET_ZERO_EXTEND_WITH_AND
3935 && optimize_function_for_speed_p (cfun))
3936 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3937 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3939 operands[2] = gen_lowpart (QImode, operands[0]);
3940 ix86_expand_clear (operands[0]);
3943 ;; Rest is handled by single and.
3945 [(set (match_operand:HI 0 "register_operand" "")
3946 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3947 (clobber (reg:CC FLAGS_REG))]
3949 && true_regnum (operands[0]) == true_regnum (operands[1])"
3950 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3951 (clobber (reg:CC FLAGS_REG))])]
3954 (define_expand "zero_extendqisi2"
3956 [(set (match_operand:SI 0 "register_operand" "")
3957 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3958 (clobber (reg:CC FLAGS_REG))])]
3962 (define_insn "*zero_extendqisi2_and"
3963 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3964 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3965 (clobber (reg:CC FLAGS_REG))]
3966 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3968 [(set_attr "type" "alu1")
3969 (set_attr "mode" "SI")])
3971 (define_insn "*zero_extendqisi2_movzbl_and"
3972 [(set (match_operand:SI 0 "register_operand" "=r,r")
3973 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3974 (clobber (reg:CC FLAGS_REG))]
3975 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3977 [(set_attr "type" "imovx,alu1")
3978 (set_attr "mode" "SI")])
3980 (define_insn "*zero_extendqisi2_movzbl"
3981 [(set (match_operand:SI 0 "register_operand" "=r")
3982 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3983 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3984 && reload_completed"
3985 "movz{bl|x}\t{%1, %0|%0, %1}"
3986 [(set_attr "type" "imovx")
3987 (set_attr "mode" "SI")])
3989 ;; For the movzbl case strip only the clobber
3991 [(set (match_operand:SI 0 "register_operand" "")
3992 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3993 (clobber (reg:CC FLAGS_REG))]
3995 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3996 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3998 (zero_extend:SI (match_dup 1)))])
4000 ;; When source and destination does not overlap, clear destination
4001 ;; first and then do the movb
4003 [(set (match_operand:SI 0 "register_operand" "")
4004 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4005 (clobber (reg:CC FLAGS_REG))]
4007 && ANY_QI_REG_P (operands[0])
4008 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4009 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4010 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4011 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
4013 operands[2] = gen_lowpart (QImode, operands[0]);
4014 ix86_expand_clear (operands[0]);
4017 ;; Rest is handled by single and.
4019 [(set (match_operand:SI 0 "register_operand" "")
4020 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4021 (clobber (reg:CC FLAGS_REG))]
4023 && true_regnum (operands[0]) == true_regnum (operands[1])"
4024 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4025 (clobber (reg:CC FLAGS_REG))])]
4028 ;; %%% Kill me once multi-word ops are sane.
4029 (define_expand "zero_extendsidi2"
4030 [(set (match_operand:DI 0 "register_operand" "")
4031 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4036 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4041 (define_insn "zero_extendsidi2_32"
4042 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4044 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
4045 (clobber (reg:CC FLAGS_REG))]
4051 movd\t{%1, %0|%0, %1}
4052 movd\t{%1, %0|%0, %1}
4053 %vmovd\t{%1, %0|%0, %1}
4054 %vmovd\t{%1, %0|%0, %1}"
4055 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4056 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4057 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4059 (define_insn "zero_extendsidi2_rex64"
4060 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4062 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4065 mov\t{%k1, %k0|%k0, %k1}
4067 movd\t{%1, %0|%0, %1}
4068 movd\t{%1, %0|%0, %1}
4069 %vmovd\t{%1, %0|%0, %1}
4070 %vmovd\t{%1, %0|%0, %1}"
4071 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4072 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4073 (set_attr "prefix_0f" "0,*,*,*,*,*")
4074 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4077 [(set (match_operand:DI 0 "memory_operand" "")
4078 (zero_extend:DI (match_dup 0)))]
4080 [(set (match_dup 4) (const_int 0))]
4081 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4084 [(set (match_operand:DI 0 "register_operand" "")
4085 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4086 (clobber (reg:CC FLAGS_REG))]
4087 "!TARGET_64BIT && reload_completed
4088 && true_regnum (operands[0]) == true_regnum (operands[1])"
4089 [(set (match_dup 4) (const_int 0))]
4090 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4093 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4094 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4095 (clobber (reg:CC FLAGS_REG))]
4096 "!TARGET_64BIT && reload_completed
4097 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4098 [(set (match_dup 3) (match_dup 1))
4099 (set (match_dup 4) (const_int 0))]
4100 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4102 (define_insn "zero_extendhidi2"
4103 [(set (match_operand:DI 0 "register_operand" "=r")
4104 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4106 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4107 [(set_attr "type" "imovx")
4108 (set_attr "mode" "SI")])
4110 (define_insn "zero_extendqidi2"
4111 [(set (match_operand:DI 0 "register_operand" "=r")
4112 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4114 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4115 [(set_attr "type" "imovx")
4116 (set_attr "mode" "SI")])
4118 ;; Sign extension instructions
4120 (define_expand "extendsidi2"
4121 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4122 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4123 (clobber (reg:CC FLAGS_REG))
4124 (clobber (match_scratch:SI 2 ""))])]
4129 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4134 (define_insn "*extendsidi2_1"
4135 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4136 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4137 (clobber (reg:CC FLAGS_REG))
4138 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4142 (define_insn "extendsidi2_rex64"
4143 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4144 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4148 movs{lq|x}\t{%1, %0|%0, %1}"
4149 [(set_attr "type" "imovx")
4150 (set_attr "mode" "DI")
4151 (set_attr "prefix_0f" "0")
4152 (set_attr "modrm" "0,1")])
4154 (define_insn "extendhidi2"
4155 [(set (match_operand:DI 0 "register_operand" "=r")
4156 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4158 "movs{wq|x}\t{%1, %0|%0, %1}"
4159 [(set_attr "type" "imovx")
4160 (set_attr "mode" "DI")])
4162 (define_insn "extendqidi2"
4163 [(set (match_operand:DI 0 "register_operand" "=r")
4164 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4166 "movs{bq|x}\t{%1, %0|%0, %1}"
4167 [(set_attr "type" "imovx")
4168 (set_attr "mode" "DI")])
4170 ;; Extend to memory case when source register does die.
4172 [(set (match_operand:DI 0 "memory_operand" "")
4173 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4174 (clobber (reg:CC FLAGS_REG))
4175 (clobber (match_operand:SI 2 "register_operand" ""))]
4177 && dead_or_set_p (insn, operands[1])
4178 && !reg_mentioned_p (operands[1], operands[0]))"
4179 [(set (match_dup 3) (match_dup 1))
4180 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4181 (clobber (reg:CC FLAGS_REG))])
4182 (set (match_dup 4) (match_dup 1))]
4183 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4185 ;; Extend to memory case when source register does not die.
4187 [(set (match_operand:DI 0 "memory_operand" "")
4188 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4189 (clobber (reg:CC FLAGS_REG))
4190 (clobber (match_operand:SI 2 "register_operand" ""))]
4194 split_di (&operands[0], 1, &operands[3], &operands[4]);
4196 emit_move_insn (operands[3], operands[1]);
4198 /* Generate a cltd if possible and doing so it profitable. */
4199 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4200 && true_regnum (operands[1]) == AX_REG
4201 && true_regnum (operands[2]) == DX_REG)
4203 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4207 emit_move_insn (operands[2], operands[1]);
4208 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4210 emit_move_insn (operands[4], operands[2]);
4214 ;; Extend to register case. Optimize case where source and destination
4215 ;; registers match and cases where we can use cltd.
4217 [(set (match_operand:DI 0 "register_operand" "")
4218 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4219 (clobber (reg:CC FLAGS_REG))
4220 (clobber (match_scratch:SI 2 ""))]
4224 split_di (&operands[0], 1, &operands[3], &operands[4]);
4226 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4227 emit_move_insn (operands[3], operands[1]);
4229 /* Generate a cltd if possible and doing so it profitable. */
4230 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4231 && true_regnum (operands[3]) == AX_REG
4232 && true_regnum (operands[4]) == DX_REG)
4234 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4238 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4239 emit_move_insn (operands[4], operands[1]);
4241 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4245 (define_insn "extendhisi2"
4246 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4247 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4250 switch (get_attr_prefix_0f (insn))
4253 return "{cwtl|cwde}";
4255 return "movs{wl|x}\t{%1, %0|%0, %1}";
4258 [(set_attr "type" "imovx")
4259 (set_attr "mode" "SI")
4260 (set (attr "prefix_0f")
4261 ;; movsx is short decodable while cwtl is vector decoded.
4262 (if_then_else (and (eq_attr "cpu" "!k6")
4263 (eq_attr "alternative" "0"))
4265 (const_string "1")))
4267 (if_then_else (eq_attr "prefix_0f" "0")
4269 (const_string "1")))])
4271 (define_insn "*extendhisi2_zext"
4272 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4274 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4277 switch (get_attr_prefix_0f (insn))
4280 return "{cwtl|cwde}";
4282 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4285 [(set_attr "type" "imovx")
4286 (set_attr "mode" "SI")
4287 (set (attr "prefix_0f")
4288 ;; movsx is short decodable while cwtl is vector decoded.
4289 (if_then_else (and (eq_attr "cpu" "!k6")
4290 (eq_attr "alternative" "0"))
4292 (const_string "1")))
4294 (if_then_else (eq_attr "prefix_0f" "0")
4296 (const_string "1")))])
4298 (define_insn "extendqihi2"
4299 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4300 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4303 switch (get_attr_prefix_0f (insn))
4306 return "{cbtw|cbw}";
4308 return "movs{bw|x}\t{%1, %0|%0, %1}";
4311 [(set_attr "type" "imovx")
4312 (set_attr "mode" "HI")
4313 (set (attr "prefix_0f")
4314 ;; movsx is short decodable while cwtl is vector decoded.
4315 (if_then_else (and (eq_attr "cpu" "!k6")
4316 (eq_attr "alternative" "0"))
4318 (const_string "1")))
4320 (if_then_else (eq_attr "prefix_0f" "0")
4322 (const_string "1")))])
4324 (define_insn "extendqisi2"
4325 [(set (match_operand:SI 0 "register_operand" "=r")
4326 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4328 "movs{bl|x}\t{%1, %0|%0, %1}"
4329 [(set_attr "type" "imovx")
4330 (set_attr "mode" "SI")])
4332 (define_insn "*extendqisi2_zext"
4333 [(set (match_operand:DI 0 "register_operand" "=r")
4335 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4337 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4338 [(set_attr "type" "imovx")
4339 (set_attr "mode" "SI")])
4341 ;; Conversions between float and double.
4343 ;; These are all no-ops in the model used for the 80387. So just
4346 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4347 (define_insn "*dummy_extendsfdf2"
4348 [(set (match_operand:DF 0 "push_operand" "=<")
4349 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4354 [(set (match_operand:DF 0 "push_operand" "")
4355 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4357 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4358 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4360 (define_insn "*dummy_extendsfxf2"
4361 [(set (match_operand:XF 0 "push_operand" "=<")
4362 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4367 [(set (match_operand:XF 0 "push_operand" "")
4368 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4370 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4371 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4372 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4375 [(set (match_operand:XF 0 "push_operand" "")
4376 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4378 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4379 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4380 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4382 (define_expand "extendsfdf2"
4383 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4384 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4385 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4387 /* ??? Needed for compress_float_constant since all fp constants
4388 are LEGITIMATE_CONSTANT_P. */
4389 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4391 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4392 && standard_80387_constant_p (operands[1]) > 0)
4394 operands[1] = simplify_const_unary_operation
4395 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4396 emit_move_insn_1 (operands[0], operands[1]);
4399 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4403 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4405 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4407 We do the conversion post reload to avoid producing of 128bit spills
4408 that might lead to ICE on 32bit target. The sequence unlikely combine
4411 [(set (match_operand:DF 0 "register_operand" "")
4413 (match_operand:SF 1 "nonimmediate_operand" "")))]
4414 "TARGET_USE_VECTOR_FP_CONVERTS
4415 && optimize_insn_for_speed_p ()
4416 && reload_completed && SSE_REG_P (operands[0])"
4421 (parallel [(const_int 0) (const_int 1)]))))]
4423 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4424 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4425 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4426 Try to avoid move when unpacking can be done in source. */
4427 if (REG_P (operands[1]))
4429 /* If it is unsafe to overwrite upper half of source, we need
4430 to move to destination and unpack there. */
4431 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4432 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4433 && true_regnum (operands[0]) != true_regnum (operands[1]))
4435 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4436 emit_move_insn (tmp, operands[1]);
4439 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4440 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4444 emit_insn (gen_vec_setv4sf_0 (operands[3],
4445 CONST0_RTX (V4SFmode), operands[1]));
4448 (define_insn "*extendsfdf2_mixed"
4449 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4451 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4452 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4454 switch (which_alternative)
4458 return output_387_reg_move (insn, operands);
4461 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4467 [(set_attr "type" "fmov,fmov,ssecvt")
4468 (set_attr "prefix" "orig,orig,maybe_vex")
4469 (set_attr "mode" "SF,XF,DF")])
4471 (define_insn "*extendsfdf2_sse"
4472 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4473 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4474 "TARGET_SSE2 && TARGET_SSE_MATH"
4475 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4476 [(set_attr "type" "ssecvt")
4477 (set_attr "prefix" "maybe_vex")
4478 (set_attr "mode" "DF")])
4480 (define_insn "*extendsfdf2_i387"
4481 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4482 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4484 "* return output_387_reg_move (insn, operands);"
4485 [(set_attr "type" "fmov")
4486 (set_attr "mode" "SF,XF")])
4488 (define_expand "extend<mode>xf2"
4489 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4490 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4493 /* ??? Needed for compress_float_constant since all fp constants
4494 are LEGITIMATE_CONSTANT_P. */
4495 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4497 if (standard_80387_constant_p (operands[1]) > 0)
4499 operands[1] = simplify_const_unary_operation
4500 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4501 emit_move_insn_1 (operands[0], operands[1]);
4504 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4508 (define_insn "*extend<mode>xf2_i387"
4509 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4511 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4513 "* return output_387_reg_move (insn, operands);"
4514 [(set_attr "type" "fmov")
4515 (set_attr "mode" "<MODE>,XF")])
4517 ;; %%% This seems bad bad news.
4518 ;; This cannot output into an f-reg because there is no way to be sure
4519 ;; of truncating in that case. Otherwise this is just like a simple move
4520 ;; insn. So we pretend we can output to a reg in order to get better
4521 ;; register preferencing, but we really use a stack slot.
4523 ;; Conversion from DFmode to SFmode.
4525 (define_expand "truncdfsf2"
4526 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4528 (match_operand:DF 1 "nonimmediate_operand" "")))]
4529 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4531 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4533 else if (flag_unsafe_math_optimizations)
4537 enum ix86_stack_slot slot = (virtuals_instantiated
4540 rtx temp = assign_386_stack_local (SFmode, slot);
4541 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4546 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4548 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4550 We do the conversion post reload to avoid producing of 128bit spills
4551 that might lead to ICE on 32bit target. The sequence unlikely combine
4554 [(set (match_operand:SF 0 "register_operand" "")
4556 (match_operand:DF 1 "nonimmediate_operand" "")))]
4557 "TARGET_USE_VECTOR_FP_CONVERTS
4558 && optimize_insn_for_speed_p ()
4559 && reload_completed && SSE_REG_P (operands[0])"
4562 (float_truncate:V2SF
4566 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4567 operands[3] = CONST0_RTX (V2SFmode);
4568 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4569 /* Use movsd for loading from memory, unpcklpd for registers.
4570 Try to avoid move when unpacking can be done in source, or SSE3
4571 movddup is available. */
4572 if (REG_P (operands[1]))
4575 && true_regnum (operands[0]) != true_regnum (operands[1])
4576 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4577 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4579 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4580 emit_move_insn (tmp, operands[1]);
4583 else if (!TARGET_SSE3)
4584 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4585 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4588 emit_insn (gen_sse2_loadlpd (operands[4],
4589 CONST0_RTX (V2DFmode), operands[1]));
4592 (define_expand "truncdfsf2_with_temp"
4593 [(parallel [(set (match_operand:SF 0 "" "")
4594 (float_truncate:SF (match_operand:DF 1 "" "")))
4595 (clobber (match_operand:SF 2 "" ""))])]
4598 (define_insn "*truncdfsf_fast_mixed"
4599 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4601 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4602 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4604 switch (which_alternative)
4607 return output_387_reg_move (insn, operands);
4609 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4614 [(set_attr "type" "fmov,ssecvt")
4615 (set_attr "prefix" "orig,maybe_vex")
4616 (set_attr "mode" "SF")])
4618 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4619 ;; because nothing we do here is unsafe.
4620 (define_insn "*truncdfsf_fast_sse"
4621 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4623 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4624 "TARGET_SSE2 && TARGET_SSE_MATH"
4625 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4626 [(set_attr "type" "ssecvt")
4627 (set_attr "prefix" "maybe_vex")
4628 (set_attr "mode" "SF")])
4630 (define_insn "*truncdfsf_fast_i387"
4631 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4633 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4634 "TARGET_80387 && flag_unsafe_math_optimizations"
4635 "* return output_387_reg_move (insn, operands);"
4636 [(set_attr "type" "fmov")
4637 (set_attr "mode" "SF")])
4639 (define_insn "*truncdfsf_mixed"
4640 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4642 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4643 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4644 "TARGET_MIX_SSE_I387"
4646 switch (which_alternative)
4649 return output_387_reg_move (insn, operands);
4651 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4657 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4658 (set_attr "unit" "*,*,i387,i387,i387")
4659 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4660 (set_attr "mode" "SF")])
4662 (define_insn "*truncdfsf_i387"
4663 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4665 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4666 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4669 switch (which_alternative)
4672 return output_387_reg_move (insn, operands);
4678 [(set_attr "type" "fmov,multi,multi,multi")
4679 (set_attr "unit" "*,i387,i387,i387")
4680 (set_attr "mode" "SF")])
4682 (define_insn "*truncdfsf2_i387_1"
4683 [(set (match_operand:SF 0 "memory_operand" "=m")
4685 (match_operand:DF 1 "register_operand" "f")))]
4687 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4688 && !TARGET_MIX_SSE_I387"
4689 "* return output_387_reg_move (insn, operands);"
4690 [(set_attr "type" "fmov")
4691 (set_attr "mode" "SF")])
4694 [(set (match_operand:SF 0 "register_operand" "")
4696 (match_operand:DF 1 "fp_register_operand" "")))
4697 (clobber (match_operand 2 "" ""))]
4699 [(set (match_dup 2) (match_dup 1))
4700 (set (match_dup 0) (match_dup 2))]
4702 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4705 ;; Conversion from XFmode to {SF,DF}mode
4707 (define_expand "truncxf<mode>2"
4708 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4709 (float_truncate:MODEF
4710 (match_operand:XF 1 "register_operand" "")))
4711 (clobber (match_dup 2))])]
4714 if (flag_unsafe_math_optimizations)
4716 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4717 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4718 if (reg != operands[0])
4719 emit_move_insn (operands[0], reg);
4724 enum ix86_stack_slot slot = (virtuals_instantiated
4727 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4731 (define_insn "*truncxfsf2_mixed"
4732 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4734 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4735 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4738 gcc_assert (!which_alternative);
4739 return output_387_reg_move (insn, operands);
4741 [(set_attr "type" "fmov,multi,multi,multi")
4742 (set_attr "unit" "*,i387,i387,i387")
4743 (set_attr "mode" "SF")])
4745 (define_insn "*truncxfdf2_mixed"
4746 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4748 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4749 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4752 gcc_assert (!which_alternative);
4753 return output_387_reg_move (insn, operands);
4755 [(set_attr "type" "fmov,multi,multi,multi")
4756 (set_attr "unit" "*,i387,i387,i387")
4757 (set_attr "mode" "DF")])
4759 (define_insn "truncxf<mode>2_i387_noop"
4760 [(set (match_operand:MODEF 0 "register_operand" "=f")
4761 (float_truncate:MODEF
4762 (match_operand:XF 1 "register_operand" "f")))]
4763 "TARGET_80387 && flag_unsafe_math_optimizations"
4764 "* return output_387_reg_move (insn, operands);"
4765 [(set_attr "type" "fmov")
4766 (set_attr "mode" "<MODE>")])
4768 (define_insn "*truncxf<mode>2_i387"
4769 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4770 (float_truncate:MODEF
4771 (match_operand:XF 1 "register_operand" "f")))]
4773 "* return output_387_reg_move (insn, operands);"
4774 [(set_attr "type" "fmov")
4775 (set_attr "mode" "<MODE>")])
4778 [(set (match_operand:MODEF 0 "register_operand" "")
4779 (float_truncate:MODEF
4780 (match_operand:XF 1 "register_operand" "")))
4781 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4782 "TARGET_80387 && reload_completed"
4783 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4784 (set (match_dup 0) (match_dup 2))]
4788 [(set (match_operand:MODEF 0 "memory_operand" "")
4789 (float_truncate:MODEF
4790 (match_operand:XF 1 "register_operand" "")))
4791 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4793 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4796 ;; Signed conversion to DImode.
4798 (define_expand "fix_truncxfdi2"
4799 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4800 (fix:DI (match_operand:XF 1 "register_operand" "")))
4801 (clobber (reg:CC FLAGS_REG))])]
4806 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4811 (define_expand "fix_trunc<mode>di2"
4812 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4813 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4814 (clobber (reg:CC FLAGS_REG))])]
4815 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4818 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4820 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4823 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4825 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4826 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4827 if (out != operands[0])
4828 emit_move_insn (operands[0], out);
4833 ;; Signed conversion to SImode.
4835 (define_expand "fix_truncxfsi2"
4836 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4837 (fix:SI (match_operand:XF 1 "register_operand" "")))
4838 (clobber (reg:CC FLAGS_REG))])]
4843 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4848 (define_expand "fix_trunc<mode>si2"
4849 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4850 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4851 (clobber (reg:CC FLAGS_REG))])]
4852 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4855 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4857 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4860 if (SSE_FLOAT_MODE_P (<MODE>mode))
4862 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4863 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4864 if (out != operands[0])
4865 emit_move_insn (operands[0], out);
4870 ;; Signed conversion to HImode.
4872 (define_expand "fix_trunc<mode>hi2"
4873 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4874 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4875 (clobber (reg:CC FLAGS_REG))])]
4877 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4881 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4886 ;; Unsigned conversion to SImode.
4888 (define_expand "fixuns_trunc<mode>si2"
4890 [(set (match_operand:SI 0 "register_operand" "")
4892 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4894 (clobber (match_scratch:<ssevecmode> 3 ""))
4895 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4896 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4898 enum machine_mode mode = <MODE>mode;
4899 enum machine_mode vecmode = <ssevecmode>mode;
4900 REAL_VALUE_TYPE TWO31r;
4903 if (optimize_insn_for_size_p ())
4906 real_ldexp (&TWO31r, &dconst1, 31);
4907 two31 = const_double_from_real_value (TWO31r, mode);
4908 two31 = ix86_build_const_vector (mode, true, two31);
4909 operands[2] = force_reg (vecmode, two31);
4912 (define_insn_and_split "*fixuns_trunc<mode>_1"
4913 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4915 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4916 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4917 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4918 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4919 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4920 && optimize_function_for_speed_p (cfun)"
4922 "&& reload_completed"
4925 ix86_split_convert_uns_si_sse (operands);
4929 ;; Unsigned conversion to HImode.
4930 ;; Without these patterns, we'll try the unsigned SI conversion which
4931 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4933 (define_expand "fixuns_trunc<mode>hi2"
4935 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4936 (set (match_operand:HI 0 "nonimmediate_operand" "")
4937 (subreg:HI (match_dup 2) 0))]
4938 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4939 "operands[2] = gen_reg_rtx (SImode);")
4941 ;; When SSE is available, it is always faster to use it!
4942 (define_insn "fix_trunc<mode>di_sse"
4943 [(set (match_operand:DI 0 "register_operand" "=r,r")
4944 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4945 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4946 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4947 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4948 [(set_attr "type" "sseicvt")
4949 (set_attr "prefix" "maybe_vex")
4950 (set_attr "prefix_rex" "1")
4951 (set_attr "mode" "<MODE>")
4952 (set_attr "athlon_decode" "double,vector")
4953 (set_attr "amdfam10_decode" "double,double")])
4955 (define_insn "fix_trunc<mode>si_sse"
4956 [(set (match_operand:SI 0 "register_operand" "=r,r")
4957 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4958 "SSE_FLOAT_MODE_P (<MODE>mode)
4959 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4960 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4961 [(set_attr "type" "sseicvt")
4962 (set_attr "prefix" "maybe_vex")
4963 (set_attr "mode" "<MODE>")
4964 (set_attr "athlon_decode" "double,vector")
4965 (set_attr "amdfam10_decode" "double,double")])
4967 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4969 [(set (match_operand:MODEF 0 "register_operand" "")
4970 (match_operand:MODEF 1 "memory_operand" ""))
4971 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4972 (fix:SSEMODEI24 (match_dup 0)))]
4973 "TARGET_SHORTEN_X87_SSE
4974 && peep2_reg_dead_p (2, operands[0])"
4975 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4978 ;; Avoid vector decoded forms of the instruction.
4980 [(match_scratch:DF 2 "Y2")
4981 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4982 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4983 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4984 [(set (match_dup 2) (match_dup 1))
4985 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4989 [(match_scratch:SF 2 "x")
4990 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4991 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4992 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4993 [(set (match_dup 2) (match_dup 1))
4994 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4997 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4998 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4999 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5000 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5002 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5003 && (TARGET_64BIT || <MODE>mode != DImode))
5005 && can_create_pseudo_p ()"
5010 if (memory_operand (operands[0], VOIDmode))
5011 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5014 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5015 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5021 [(set_attr "type" "fisttp")
5022 (set_attr "mode" "<MODE>")])
5024 (define_insn "fix_trunc<mode>_i387_fisttp"
5025 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5026 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5027 (clobber (match_scratch:XF 2 "=&1f"))]
5028 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5030 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5031 && (TARGET_64BIT || <MODE>mode != DImode))
5032 && TARGET_SSE_MATH)"
5033 "* return output_fix_trunc (insn, operands, 1);"
5034 [(set_attr "type" "fisttp")
5035 (set_attr "mode" "<MODE>")])
5037 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5038 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5039 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5040 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5041 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5042 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5044 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5045 && (TARGET_64BIT || <MODE>mode != DImode))
5046 && TARGET_SSE_MATH)"
5048 [(set_attr "type" "fisttp")
5049 (set_attr "mode" "<MODE>")])
5052 [(set (match_operand:X87MODEI 0 "register_operand" "")
5053 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5054 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5055 (clobber (match_scratch 3 ""))]
5057 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5058 (clobber (match_dup 3))])
5059 (set (match_dup 0) (match_dup 2))]
5063 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5064 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5065 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5066 (clobber (match_scratch 3 ""))]
5068 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5069 (clobber (match_dup 3))])]
5072 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5073 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5074 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5075 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5076 ;; function in i386.c.
5077 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5078 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5079 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5080 (clobber (reg:CC FLAGS_REG))]
5081 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5083 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5084 && (TARGET_64BIT || <MODE>mode != DImode))
5085 && can_create_pseudo_p ()"
5090 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5092 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5093 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5094 if (memory_operand (operands[0], VOIDmode))
5095 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5096 operands[2], operands[3]));
5099 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5100 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5101 operands[2], operands[3],
5106 [(set_attr "type" "fistp")
5107 (set_attr "i387_cw" "trunc")
5108 (set_attr "mode" "<MODE>")])
5110 (define_insn "fix_truncdi_i387"
5111 [(set (match_operand:DI 0 "memory_operand" "=m")
5112 (fix:DI (match_operand 1 "register_operand" "f")))
5113 (use (match_operand:HI 2 "memory_operand" "m"))
5114 (use (match_operand:HI 3 "memory_operand" "m"))
5115 (clobber (match_scratch:XF 4 "=&1f"))]
5116 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5118 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5119 "* return output_fix_trunc (insn, operands, 0);"
5120 [(set_attr "type" "fistp")
5121 (set_attr "i387_cw" "trunc")
5122 (set_attr "mode" "DI")])
5124 (define_insn "fix_truncdi_i387_with_temp"
5125 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5126 (fix:DI (match_operand 1 "register_operand" "f,f")))
5127 (use (match_operand:HI 2 "memory_operand" "m,m"))
5128 (use (match_operand:HI 3 "memory_operand" "m,m"))
5129 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5130 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5131 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5133 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5135 [(set_attr "type" "fistp")
5136 (set_attr "i387_cw" "trunc")
5137 (set_attr "mode" "DI")])
5140 [(set (match_operand:DI 0 "register_operand" "")
5141 (fix:DI (match_operand 1 "register_operand" "")))
5142 (use (match_operand:HI 2 "memory_operand" ""))
5143 (use (match_operand:HI 3 "memory_operand" ""))
5144 (clobber (match_operand:DI 4 "memory_operand" ""))
5145 (clobber (match_scratch 5 ""))]
5147 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5150 (clobber (match_dup 5))])
5151 (set (match_dup 0) (match_dup 4))]
5155 [(set (match_operand:DI 0 "memory_operand" "")
5156 (fix:DI (match_operand 1 "register_operand" "")))
5157 (use (match_operand:HI 2 "memory_operand" ""))
5158 (use (match_operand:HI 3 "memory_operand" ""))
5159 (clobber (match_operand:DI 4 "memory_operand" ""))
5160 (clobber (match_scratch 5 ""))]
5162 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5165 (clobber (match_dup 5))])]
5168 (define_insn "fix_trunc<mode>_i387"
5169 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5170 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5171 (use (match_operand:HI 2 "memory_operand" "m"))
5172 (use (match_operand:HI 3 "memory_operand" "m"))]
5173 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5175 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5176 "* return output_fix_trunc (insn, operands, 0);"
5177 [(set_attr "type" "fistp")
5178 (set_attr "i387_cw" "trunc")
5179 (set_attr "mode" "<MODE>")])
5181 (define_insn "fix_trunc<mode>_i387_with_temp"
5182 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5183 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5184 (use (match_operand:HI 2 "memory_operand" "m,m"))
5185 (use (match_operand:HI 3 "memory_operand" "m,m"))
5186 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5187 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5189 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5191 [(set_attr "type" "fistp")
5192 (set_attr "i387_cw" "trunc")
5193 (set_attr "mode" "<MODE>")])
5196 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5197 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5198 (use (match_operand:HI 2 "memory_operand" ""))
5199 (use (match_operand:HI 3 "memory_operand" ""))
5200 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5202 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5204 (use (match_dup 3))])
5205 (set (match_dup 0) (match_dup 4))]
5209 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5210 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5211 (use (match_operand:HI 2 "memory_operand" ""))
5212 (use (match_operand:HI 3 "memory_operand" ""))
5213 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5215 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5217 (use (match_dup 3))])]
5220 (define_insn "x86_fnstcw_1"
5221 [(set (match_operand:HI 0 "memory_operand" "=m")
5222 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5225 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5226 (set_attr "mode" "HI")
5227 (set_attr "unit" "i387")])
5229 (define_insn "x86_fldcw_1"
5230 [(set (reg:HI FPCR_REG)
5231 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5234 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5235 (set_attr "mode" "HI")
5236 (set_attr "unit" "i387")
5237 (set_attr "athlon_decode" "vector")
5238 (set_attr "amdfam10_decode" "vector")])
5240 ;; Conversion between fixed point and floating point.
5242 ;; Even though we only accept memory inputs, the backend _really_
5243 ;; wants to be able to do this between registers.
5245 (define_expand "floathi<mode>2"
5246 [(set (match_operand:X87MODEF 0 "register_operand" "")
5247 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5249 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5250 || TARGET_MIX_SSE_I387)"
5253 ;; Pre-reload splitter to add memory clobber to the pattern.
5254 (define_insn_and_split "*floathi<mode>2_1"
5255 [(set (match_operand:X87MODEF 0 "register_operand" "")
5256 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5258 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5259 || TARGET_MIX_SSE_I387)
5260 && can_create_pseudo_p ()"
5263 [(parallel [(set (match_dup 0)
5264 (float:X87MODEF (match_dup 1)))
5265 (clobber (match_dup 2))])]
5266 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5268 (define_insn "*floathi<mode>2_i387_with_temp"
5269 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5270 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5271 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5273 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5274 || TARGET_MIX_SSE_I387)"
5276 [(set_attr "type" "fmov,multi")
5277 (set_attr "mode" "<MODE>")
5278 (set_attr "unit" "*,i387")
5279 (set_attr "fp_int_src" "true")])
5281 (define_insn "*floathi<mode>2_i387"
5282 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5283 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5285 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5286 || TARGET_MIX_SSE_I387)"
5288 [(set_attr "type" "fmov")
5289 (set_attr "mode" "<MODE>")
5290 (set_attr "fp_int_src" "true")])
5293 [(set (match_operand:X87MODEF 0 "register_operand" "")
5294 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5295 (clobber (match_operand:HI 2 "memory_operand" ""))]
5297 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5298 || TARGET_MIX_SSE_I387)
5299 && reload_completed"
5300 [(set (match_dup 2) (match_dup 1))
5301 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5305 [(set (match_operand:X87MODEF 0 "register_operand" "")
5306 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5307 (clobber (match_operand:HI 2 "memory_operand" ""))]
5309 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5310 || TARGET_MIX_SSE_I387)
5311 && reload_completed"
5312 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5315 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5316 [(set (match_operand:X87MODEF 0 "register_operand" "")
5318 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5320 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5321 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5323 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5324 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5325 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5327 rtx reg = gen_reg_rtx (XFmode);
5330 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5332 if (<X87MODEF:MODE>mode == SFmode)
5333 insn = gen_truncxfsf2 (operands[0], reg);
5334 else if (<X87MODEF:MODE>mode == DFmode)
5335 insn = gen_truncxfdf2 (operands[0], reg);
5344 ;; Pre-reload splitter to add memory clobber to the pattern.
5345 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5346 [(set (match_operand:X87MODEF 0 "register_operand" "")
5347 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5349 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5350 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5351 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5352 || TARGET_MIX_SSE_I387))
5353 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5354 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5355 && ((<SSEMODEI24:MODE>mode == SImode
5356 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5357 && optimize_function_for_speed_p (cfun)
5358 && flag_trapping_math)
5359 || !(TARGET_INTER_UNIT_CONVERSIONS
5360 || optimize_function_for_size_p (cfun)))))
5361 && can_create_pseudo_p ()"
5364 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5365 (clobber (match_dup 2))])]
5367 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5369 /* Avoid store forwarding (partial memory) stall penalty
5370 by passing DImode value through XMM registers. */
5371 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5372 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5373 && optimize_function_for_speed_p (cfun))
5375 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5382 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5383 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5385 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5386 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5387 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5388 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5390 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5391 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5392 (set_attr "unit" "*,i387,*,*,*")
5393 (set_attr "athlon_decode" "*,*,double,direct,double")
5394 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5395 (set_attr "fp_int_src" "true")])
5397 (define_insn "*floatsi<mode>2_vector_mixed"
5398 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5399 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5400 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5401 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5405 [(set_attr "type" "fmov,sseicvt")
5406 (set_attr "mode" "<MODE>,<ssevecmode>")
5407 (set_attr "unit" "i387,*")
5408 (set_attr "athlon_decode" "*,direct")
5409 (set_attr "amdfam10_decode" "*,double")
5410 (set_attr "fp_int_src" "true")])
5412 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5413 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5415 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5416 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5417 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5418 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5420 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5421 (set_attr "mode" "<MODEF:MODE>")
5422 (set_attr "unit" "*,i387,*,*")
5423 (set_attr "athlon_decode" "*,*,double,direct")
5424 (set_attr "amdfam10_decode" "*,*,vector,double")
5425 (set_attr "fp_int_src" "true")])
5428 [(set (match_operand:MODEF 0 "register_operand" "")
5429 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5430 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5431 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5432 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5433 && TARGET_INTER_UNIT_CONVERSIONS
5435 && (SSE_REG_P (operands[0])
5436 || (GET_CODE (operands[0]) == SUBREG
5437 && SSE_REG_P (operands[0])))"
5438 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5442 [(set (match_operand:MODEF 0 "register_operand" "")
5443 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5444 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5445 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5446 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5447 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5449 && (SSE_REG_P (operands[0])
5450 || (GET_CODE (operands[0]) == SUBREG
5451 && SSE_REG_P (operands[0])))"
5452 [(set (match_dup 2) (match_dup 1))
5453 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5456 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5457 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5459 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5460 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5461 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5462 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5465 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5466 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5467 [(set_attr "type" "fmov,sseicvt,sseicvt")
5468 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5469 (set_attr "mode" "<MODEF:MODE>")
5470 (set (attr "prefix_rex")
5472 (and (eq_attr "prefix" "maybe_vex")
5473 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5475 (const_string "*")))
5476 (set_attr "unit" "i387,*,*")
5477 (set_attr "athlon_decode" "*,double,direct")
5478 (set_attr "amdfam10_decode" "*,vector,double")
5479 (set_attr "fp_int_src" "true")])
5481 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5482 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5484 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5485 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5486 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5487 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5490 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5491 [(set_attr "type" "fmov,sseicvt")
5492 (set_attr "prefix" "orig,maybe_vex")
5493 (set_attr "mode" "<MODEF:MODE>")
5494 (set (attr "prefix_rex")
5496 (and (eq_attr "prefix" "maybe_vex")
5497 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5499 (const_string "*")))
5500 (set_attr "athlon_decode" "*,direct")
5501 (set_attr "amdfam10_decode" "*,double")
5502 (set_attr "fp_int_src" "true")])
5504 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5505 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5507 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5508 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5509 "TARGET_SSE2 && TARGET_SSE_MATH
5510 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5512 [(set_attr "type" "sseicvt")
5513 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5514 (set_attr "athlon_decode" "double,direct,double")
5515 (set_attr "amdfam10_decode" "vector,double,double")
5516 (set_attr "fp_int_src" "true")])
5518 (define_insn "*floatsi<mode>2_vector_sse"
5519 [(set (match_operand:MODEF 0 "register_operand" "=x")
5520 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5521 "TARGET_SSE2 && TARGET_SSE_MATH
5522 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5524 [(set_attr "type" "sseicvt")
5525 (set_attr "mode" "<MODE>")
5526 (set_attr "athlon_decode" "direct")
5527 (set_attr "amdfam10_decode" "double")
5528 (set_attr "fp_int_src" "true")])
5531 [(set (match_operand:MODEF 0 "register_operand" "")
5532 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5533 (clobber (match_operand:SI 2 "memory_operand" ""))]
5534 "TARGET_SSE2 && TARGET_SSE_MATH
5535 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5537 && (SSE_REG_P (operands[0])
5538 || (GET_CODE (operands[0]) == SUBREG
5539 && SSE_REG_P (operands[0])))"
5542 rtx op1 = operands[1];
5544 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5546 if (GET_CODE (op1) == SUBREG)
5547 op1 = SUBREG_REG (op1);
5549 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5551 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5552 emit_insn (gen_sse2_loadld (operands[4],
5553 CONST0_RTX (V4SImode), operands[1]));
5555 /* We can ignore possible trapping value in the
5556 high part of SSE register for non-trapping math. */
5557 else if (SSE_REG_P (op1) && !flag_trapping_math)
5558 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5561 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5562 emit_move_insn (operands[2], operands[1]);
5563 emit_insn (gen_sse2_loadld (operands[4],
5564 CONST0_RTX (V4SImode), operands[2]));
5567 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5572 [(set (match_operand:MODEF 0 "register_operand" "")
5573 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5574 (clobber (match_operand:SI 2 "memory_operand" ""))]
5575 "TARGET_SSE2 && TARGET_SSE_MATH
5576 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5578 && (SSE_REG_P (operands[0])
5579 || (GET_CODE (operands[0]) == SUBREG
5580 && SSE_REG_P (operands[0])))"
5583 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5585 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5587 emit_insn (gen_sse2_loadld (operands[4],
5588 CONST0_RTX (V4SImode), operands[1]));
5590 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5595 [(set (match_operand:MODEF 0 "register_operand" "")
5596 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5597 "TARGET_SSE2 && TARGET_SSE_MATH
5598 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5600 && (SSE_REG_P (operands[0])
5601 || (GET_CODE (operands[0]) == SUBREG
5602 && SSE_REG_P (operands[0])))"
5605 rtx op1 = operands[1];
5607 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5609 if (GET_CODE (op1) == SUBREG)
5610 op1 = SUBREG_REG (op1);
5612 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5614 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5615 emit_insn (gen_sse2_loadld (operands[4],
5616 CONST0_RTX (V4SImode), operands[1]));
5618 /* We can ignore possible trapping value in the
5619 high part of SSE register for non-trapping math. */
5620 else if (SSE_REG_P (op1) && !flag_trapping_math)
5621 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5625 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5630 [(set (match_operand:MODEF 0 "register_operand" "")
5631 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5632 "TARGET_SSE2 && TARGET_SSE_MATH
5633 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5635 && (SSE_REG_P (operands[0])
5636 || (GET_CODE (operands[0]) == SUBREG
5637 && SSE_REG_P (operands[0])))"
5640 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5642 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5644 emit_insn (gen_sse2_loadld (operands[4],
5645 CONST0_RTX (V4SImode), operands[1]));
5647 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5651 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5652 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5654 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5655 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5656 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5657 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5659 [(set_attr "type" "sseicvt")
5660 (set_attr "mode" "<MODEF:MODE>")
5661 (set_attr "athlon_decode" "double,direct")
5662 (set_attr "amdfam10_decode" "vector,double")
5663 (set_attr "fp_int_src" "true")])
5665 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5666 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5668 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5669 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5670 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5671 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5672 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5673 [(set_attr "type" "sseicvt")
5674 (set_attr "prefix" "maybe_vex")
5675 (set_attr "mode" "<MODEF:MODE>")
5676 (set (attr "prefix_rex")
5678 (and (eq_attr "prefix" "maybe_vex")
5679 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5681 (const_string "*")))
5682 (set_attr "athlon_decode" "double,direct")
5683 (set_attr "amdfam10_decode" "vector,double")
5684 (set_attr "fp_int_src" "true")])
5687 [(set (match_operand:MODEF 0 "register_operand" "")
5688 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5689 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5690 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5691 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5692 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5694 && (SSE_REG_P (operands[0])
5695 || (GET_CODE (operands[0]) == SUBREG
5696 && SSE_REG_P (operands[0])))"
5697 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5700 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5701 [(set (match_operand:MODEF 0 "register_operand" "=x")
5703 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5704 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5705 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5706 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5707 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5708 [(set_attr "type" "sseicvt")
5709 (set_attr "prefix" "maybe_vex")
5710 (set_attr "mode" "<MODEF:MODE>")
5711 (set (attr "prefix_rex")
5713 (and (eq_attr "prefix" "maybe_vex")
5714 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5716 (const_string "*")))
5717 (set_attr "athlon_decode" "direct")
5718 (set_attr "amdfam10_decode" "double")
5719 (set_attr "fp_int_src" "true")])
5722 [(set (match_operand:MODEF 0 "register_operand" "")
5723 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5724 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5725 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5726 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5727 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5729 && (SSE_REG_P (operands[0])
5730 || (GET_CODE (operands[0]) == SUBREG
5731 && SSE_REG_P (operands[0])))"
5732 [(set (match_dup 2) (match_dup 1))
5733 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5737 [(set (match_operand:MODEF 0 "register_operand" "")
5738 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5739 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5740 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5741 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5743 && (SSE_REG_P (operands[0])
5744 || (GET_CODE (operands[0]) == SUBREG
5745 && SSE_REG_P (operands[0])))"
5746 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5749 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5750 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5752 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5753 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5755 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5759 [(set_attr "type" "fmov,multi")
5760 (set_attr "mode" "<X87MODEF:MODE>")
5761 (set_attr "unit" "*,i387")
5762 (set_attr "fp_int_src" "true")])
5764 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5765 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5767 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5769 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5771 [(set_attr "type" "fmov")
5772 (set_attr "mode" "<X87MODEF:MODE>")
5773 (set_attr "fp_int_src" "true")])
5776 [(set (match_operand:X87MODEF 0 "register_operand" "")
5777 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5778 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5780 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5782 && FP_REG_P (operands[0])"
5783 [(set (match_dup 2) (match_dup 1))
5784 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5788 [(set (match_operand:X87MODEF 0 "register_operand" "")
5789 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5790 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5792 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5794 && FP_REG_P (operands[0])"
5795 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5798 ;; Avoid store forwarding (partial memory) stall penalty
5799 ;; by passing DImode value through XMM registers. */
5801 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5802 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5804 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5805 (clobber (match_scratch:V4SI 3 "=X,x"))
5806 (clobber (match_scratch:V4SI 4 "=X,x"))
5807 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5808 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5809 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5810 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5812 [(set_attr "type" "multi")
5813 (set_attr "mode" "<X87MODEF:MODE>")
5814 (set_attr "unit" "i387")
5815 (set_attr "fp_int_src" "true")])
5818 [(set (match_operand:X87MODEF 0 "register_operand" "")
5819 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5820 (clobber (match_scratch:V4SI 3 ""))
5821 (clobber (match_scratch:V4SI 4 ""))
5822 (clobber (match_operand:DI 2 "memory_operand" ""))]
5823 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5824 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5825 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5827 && FP_REG_P (operands[0])"
5828 [(set (match_dup 2) (match_dup 3))
5829 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5831 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5832 Assemble the 64-bit DImode value in an xmm register. */
5833 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5834 gen_rtx_SUBREG (SImode, operands[1], 0)));
5835 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5836 gen_rtx_SUBREG (SImode, operands[1], 4)));
5837 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5840 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5844 [(set (match_operand:X87MODEF 0 "register_operand" "")
5845 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5846 (clobber (match_scratch:V4SI 3 ""))
5847 (clobber (match_scratch:V4SI 4 ""))
5848 (clobber (match_operand:DI 2 "memory_operand" ""))]
5849 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5850 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5851 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5853 && FP_REG_P (operands[0])"
5854 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5857 ;; Avoid store forwarding (partial memory) stall penalty by extending
5858 ;; SImode value to DImode through XMM register instead of pushing two
5859 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5860 ;; targets benefit from this optimization. Also note that fild
5861 ;; loads from memory only.
5863 (define_insn "*floatunssi<mode>2_1"
5864 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5865 (unsigned_float:X87MODEF
5866 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5867 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5868 (clobber (match_scratch:SI 3 "=X,x"))]
5870 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5873 [(set_attr "type" "multi")
5874 (set_attr "mode" "<MODE>")])
5877 [(set (match_operand:X87MODEF 0 "register_operand" "")
5878 (unsigned_float:X87MODEF
5879 (match_operand:SI 1 "register_operand" "")))
5880 (clobber (match_operand:DI 2 "memory_operand" ""))
5881 (clobber (match_scratch:SI 3 ""))]
5883 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5885 && reload_completed"
5886 [(set (match_dup 2) (match_dup 1))
5888 (float:X87MODEF (match_dup 2)))]
5889 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5892 [(set (match_operand:X87MODEF 0 "register_operand" "")
5893 (unsigned_float:X87MODEF
5894 (match_operand:SI 1 "memory_operand" "")))
5895 (clobber (match_operand:DI 2 "memory_operand" ""))
5896 (clobber (match_scratch:SI 3 ""))]
5898 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5900 && reload_completed"
5901 [(set (match_dup 2) (match_dup 3))
5903 (float:X87MODEF (match_dup 2)))]
5905 emit_move_insn (operands[3], operands[1]);
5906 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5909 (define_expand "floatunssi<mode>2"
5911 [(set (match_operand:X87MODEF 0 "register_operand" "")
5912 (unsigned_float:X87MODEF
5913 (match_operand:SI 1 "nonimmediate_operand" "")))
5914 (clobber (match_dup 2))
5915 (clobber (match_scratch:SI 3 ""))])]
5917 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5919 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5921 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5923 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5928 enum ix86_stack_slot slot = (virtuals_instantiated
5931 operands[2] = assign_386_stack_local (DImode, slot);
5935 (define_expand "floatunsdisf2"
5936 [(use (match_operand:SF 0 "register_operand" ""))
5937 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5938 "TARGET_64BIT && TARGET_SSE_MATH"
5939 "x86_emit_floatuns (operands); DONE;")
5941 (define_expand "floatunsdidf2"
5942 [(use (match_operand:DF 0 "register_operand" ""))
5943 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5944 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5945 && TARGET_SSE2 && TARGET_SSE_MATH"
5948 x86_emit_floatuns (operands);
5950 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5956 (define_expand "add<mode>3"
5957 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5958 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5959 (match_operand:SDWIM 2 "<general_operand>" "")))]
5961 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5963 (define_insn_and_split "*add<dwi>3_doubleword"
5964 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5966 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5967 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5968 (clobber (reg:CC FLAGS_REG))]
5969 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5972 [(parallel [(set (reg:CC FLAGS_REG)
5973 (unspec:CC [(match_dup 1) (match_dup 2)]
5976 (plus:DWIH (match_dup 1) (match_dup 2)))])
5977 (parallel [(set (match_dup 3)
5981 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5983 (clobber (reg:CC FLAGS_REG))])]
5984 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5986 (define_insn "*add<mode>3_cc"
5987 [(set (reg:CC FLAGS_REG)
5989 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5990 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5992 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5993 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5994 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5995 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5996 [(set_attr "type" "alu")
5997 (set_attr "mode" "<MODE>")])
5999 (define_insn "addqi3_cc"
6000 [(set (reg:CC FLAGS_REG)
6002 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6003 (match_operand:QI 2 "general_operand" "qn,qm")]
6005 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6006 (plus:QI (match_dup 1) (match_dup 2)))]
6007 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6008 "add{b}\t{%2, %0|%0, %2}"
6009 [(set_attr "type" "alu")
6010 (set_attr "mode" "QI")])
6012 (define_insn "*lea_1"
6013 [(set (match_operand:DWIH 0 "register_operand" "=r")
6014 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
6016 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
6017 [(set_attr "type" "lea")
6018 (set_attr "mode" "<MODE>")])
6020 (define_insn "*lea_2"
6021 [(set (match_operand:SI 0 "register_operand" "=r")
6022 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6024 "lea{l}\t{%a1, %0|%0, %a1}"
6025 [(set_attr "type" "lea")
6026 (set_attr "mode" "SI")])
6028 (define_insn "*lea_2_zext"
6029 [(set (match_operand:DI 0 "register_operand" "=r")
6031 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6033 "lea{l}\t{%a1, %k0|%k0, %a1}"
6034 [(set_attr "type" "lea")
6035 (set_attr "mode" "SI")])
6037 (define_insn "*add<mode>_1"
6038 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6040 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6041 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6042 (clobber (reg:CC FLAGS_REG))]
6043 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6045 switch (get_attr_type (insn))
6048 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6049 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6052 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6053 if (operands[2] == const1_rtx)
6054 return "inc{<imodesuffix>}\t%0";
6057 gcc_assert (operands[2] == constm1_rtx);
6058 return "dec{<imodesuffix>}\t%0";
6062 /* Use add as much as possible to replace lea for AGU optimization. */
6063 if (which_alternative == 2 && TARGET_OPT_AGU)
6064 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6066 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6067 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6068 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6070 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6074 (cond [(and (eq_attr "alternative" "2")
6075 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6076 (const_string "lea")
6077 (eq_attr "alternative" "3")
6078 (const_string "lea")
6079 ; Current assemblers are broken and do not allow @GOTOFF in
6080 ; ought but a memory context.
6081 (match_operand:SWI48 2 "pic_symbolic_operand" "")
6082 (const_string "lea")
6083 (match_operand:SWI48 2 "incdec_operand" "")
6084 (const_string "incdec")
6086 (const_string "alu")))
6087 (set (attr "length_immediate")
6089 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6091 (const_string "*")))
6092 (set_attr "mode" "<MODE>")])
6094 ;; It may seem that nonimmediate operand is proper one for operand 1.
6095 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6096 ;; we take care in ix86_binary_operator_ok to not allow two memory
6097 ;; operands so proper swapping will be done in reload. This allow
6098 ;; patterns constructed from addsi_1 to match.
6100 (define_insn "*addsi_1_zext"
6101 [(set (match_operand:DI 0 "register_operand" "=r,r")
6103 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6104 (match_operand:SI 2 "general_operand" "g,li"))))
6105 (clobber (reg:CC FLAGS_REG))]
6106 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6108 switch (get_attr_type (insn))
6111 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6112 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6115 if (operands[2] == const1_rtx)
6116 return "inc{l}\t%k0";
6119 gcc_assert (operands[2] == constm1_rtx);
6120 return "dec{l}\t%k0";
6124 if (x86_maybe_negate_const_int (&operands[2], SImode))
6125 return "sub{l}\t{%2, %k0|%k0, %2}";
6127 return "add{l}\t{%2, %k0|%k0, %2}";
6131 (cond [(eq_attr "alternative" "1")
6132 (const_string "lea")
6133 ; Current assemblers are broken and do not allow @GOTOFF in
6134 ; ought but a memory context.
6135 (match_operand:SI 2 "pic_symbolic_operand" "")
6136 (const_string "lea")
6137 (match_operand:SI 2 "incdec_operand" "")
6138 (const_string "incdec")
6140 (const_string "alu")))
6141 (set (attr "length_immediate")
6143 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6145 (const_string "*")))
6146 (set_attr "mode" "SI")])
6148 (define_insn "*addhi_1"
6149 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6150 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6151 (match_operand:HI 2 "general_operand" "rn,rm")))
6152 (clobber (reg:CC FLAGS_REG))]
6153 "TARGET_PARTIAL_REG_STALL
6154 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6156 switch (get_attr_type (insn))
6159 if (operands[2] == const1_rtx)
6160 return "inc{w}\t%0";
6163 gcc_assert (operands[2] == constm1_rtx);
6164 return "dec{w}\t%0";
6168 if (x86_maybe_negate_const_int (&operands[2], HImode))
6169 return "sub{w}\t{%2, %0|%0, %2}";
6171 return "add{w}\t{%2, %0|%0, %2}";
6175 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6176 (const_string "incdec")
6177 (const_string "alu")))
6178 (set (attr "length_immediate")
6180 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6182 (const_string "*")))
6183 (set_attr "mode" "HI")])
6185 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6186 ;; type optimizations enabled by define-splits. This is not important
6187 ;; for PII, and in fact harmful because of partial register stalls.
6189 (define_insn "*addhi_1_lea"
6190 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6191 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6192 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6193 (clobber (reg:CC FLAGS_REG))]
6194 "!TARGET_PARTIAL_REG_STALL
6195 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6197 switch (get_attr_type (insn))
6202 if (operands[2] == const1_rtx)
6203 return "inc{w}\t%0";
6206 gcc_assert (operands[2] == constm1_rtx);
6207 return "dec{w}\t%0";
6211 if (x86_maybe_negate_const_int (&operands[2], HImode))
6212 return "sub{w}\t{%2, %0|%0, %2}";
6214 return "add{w}\t{%2, %0|%0, %2}";
6218 (if_then_else (eq_attr "alternative" "2")
6219 (const_string "lea")
6220 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6221 (const_string "incdec")
6222 (const_string "alu"))))
6223 (set (attr "length_immediate")
6225 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6227 (const_string "*")))
6228 (set_attr "mode" "HI,HI,SI")])
6230 (define_insn "*addqi_1"
6231 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6232 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6233 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6234 (clobber (reg:CC FLAGS_REG))]
6235 "TARGET_PARTIAL_REG_STALL
6236 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6238 int widen = (which_alternative == 2);
6239 switch (get_attr_type (insn))
6242 if (operands[2] == const1_rtx)
6243 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6246 gcc_assert (operands[2] == constm1_rtx);
6247 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6251 if (x86_maybe_negate_const_int (&operands[2], QImode))
6254 return "sub{l}\t{%2, %k0|%k0, %2}";
6256 return "sub{b}\t{%2, %0|%0, %2}";
6259 return "add{l}\t{%k2, %k0|%k0, %k2}";
6261 return "add{b}\t{%2, %0|%0, %2}";
6265 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6266 (const_string "incdec")
6267 (const_string "alu")))
6268 (set (attr "length_immediate")
6270 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6272 (const_string "*")))
6273 (set_attr "mode" "QI,QI,SI")])
6275 ;; %%% Potential partial reg stall on alternative 2. What to do?
6276 (define_insn "*addqi_1_lea"
6277 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6278 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6279 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6280 (clobber (reg:CC FLAGS_REG))]
6281 "!TARGET_PARTIAL_REG_STALL
6282 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6284 int widen = (which_alternative == 2);
6285 switch (get_attr_type (insn))
6290 if (operands[2] == const1_rtx)
6291 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6294 gcc_assert (operands[2] == constm1_rtx);
6295 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6299 if (x86_maybe_negate_const_int (&operands[2], QImode))
6302 return "sub{l}\t{%2, %k0|%k0, %2}";
6304 return "sub{b}\t{%2, %0|%0, %2}";
6307 return "add{l}\t{%k2, %k0|%k0, %k2}";
6309 return "add{b}\t{%2, %0|%0, %2}";
6313 (if_then_else (eq_attr "alternative" "3")
6314 (const_string "lea")
6315 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6316 (const_string "incdec")
6317 (const_string "alu"))))
6318 (set (attr "length_immediate")
6320 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6322 (const_string "*")))
6323 (set_attr "mode" "QI,QI,SI,SI")])
6325 (define_insn "*addqi_1_slp"
6326 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6327 (plus:QI (match_dup 0)
6328 (match_operand:QI 1 "general_operand" "qn,qnm")))
6329 (clobber (reg:CC FLAGS_REG))]
6330 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6331 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6333 switch (get_attr_type (insn))
6336 if (operands[1] == const1_rtx)
6337 return "inc{b}\t%0";
6340 gcc_assert (operands[1] == constm1_rtx);
6341 return "dec{b}\t%0";
6345 if (x86_maybe_negate_const_int (&operands[1], QImode))
6346 return "sub{b}\t{%1, %0|%0, %1}";
6348 return "add{b}\t{%1, %0|%0, %1}";
6352 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6353 (const_string "incdec")
6354 (const_string "alu1")))
6355 (set (attr "memory")
6356 (if_then_else (match_operand 1 "memory_operand" "")
6357 (const_string "load")
6358 (const_string "none")))
6359 (set_attr "mode" "QI")])
6361 (define_insn "*add<mode>_2"
6362 [(set (reg FLAGS_REG)
6365 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6366 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6368 (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6369 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6370 "ix86_match_ccmode (insn, CCGOCmode)
6371 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6372 /* Current assemblers are broken and do not allow @GOTOFF in
6373 ought but a memory context. */
6374 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6376 switch (get_attr_type (insn))
6379 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6380 if (operands[2] == const1_rtx)
6381 return "inc{<imodesuffix>}\t%0";
6384 gcc_assert (operands[2] == constm1_rtx);
6385 return "dec{<imodesuffix>}\t%0";
6389 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6390 /* ???? In DImode, we ought to handle there the 32bit case too
6391 - do we need new constraint? */
6392 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6393 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6395 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6399 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6400 (const_string "incdec")
6401 (const_string "alu")))
6402 (set (attr "length_immediate")
6404 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6406 (const_string "*")))
6407 (set_attr "mode" "<MODE>")])
6409 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6410 (define_insn "*addsi_2_zext"
6411 [(set (reg FLAGS_REG)
6413 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6414 (match_operand:SI 2 "general_operand" "g"))
6416 (set (match_operand:DI 0 "register_operand" "=r")
6417 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6418 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6419 && ix86_binary_operator_ok (PLUS, SImode, operands)
6420 /* Current assemblers are broken and do not allow @GOTOFF in
6421 ought but a memory context. */
6422 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6424 switch (get_attr_type (insn))
6427 if (operands[2] == const1_rtx)
6428 return "inc{l}\t%k0";
6431 gcc_assert (operands[2] == constm1_rtx);
6432 return "dec{l}\t%k0";
6436 if (x86_maybe_negate_const_int (&operands[2], SImode))
6437 return "sub{l}\t{%2, %k0|%k0, %2}";
6439 return "add{l}\t{%2, %k0|%k0, %2}";
6443 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6444 (const_string "incdec")
6445 (const_string "alu")))
6446 (set (attr "length_immediate")
6448 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6450 (const_string "*")))
6451 (set_attr "mode" "SI")])
6453 (define_insn "*addhi_2"
6454 [(set (reg FLAGS_REG)
6456 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6457 (match_operand:HI 2 "general_operand" "rmn,rn"))
6459 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6460 (plus:HI (match_dup 1) (match_dup 2)))]
6461 "ix86_match_ccmode (insn, CCGOCmode)
6462 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6464 switch (get_attr_type (insn))
6467 if (operands[2] == const1_rtx)
6468 return "inc{w}\t%0";
6471 gcc_assert (operands[2] == constm1_rtx);
6472 return "dec{w}\t%0";
6476 if (x86_maybe_negate_const_int (&operands[2], HImode))
6477 return "sub{w}\t{%2, %0|%0, %2}";
6479 return "add{w}\t{%2, %0|%0, %2}";
6483 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6484 (const_string "incdec")
6485 (const_string "alu")))
6486 (set (attr "length_immediate")
6488 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6490 (const_string "*")))
6491 (set_attr "mode" "HI")])
6493 (define_insn "*addqi_2"
6494 [(set (reg FLAGS_REG)
6496 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6497 (match_operand:QI 2 "general_operand" "qmn,qn"))
6499 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6500 (plus:QI (match_dup 1) (match_dup 2)))]
6501 "ix86_match_ccmode (insn, CCGOCmode)
6502 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6504 switch (get_attr_type (insn))
6507 if (operands[2] == const1_rtx)
6508 return "inc{b}\t%0";
6511 gcc_assert (operands[2] == constm1_rtx
6512 || (CONST_INT_P (operands[2])
6513 && INTVAL (operands[2]) == 255));
6514 return "dec{b}\t%0";
6518 if (x86_maybe_negate_const_int (&operands[2], QImode))
6519 return "sub{b}\t{%2, %0|%0, %2}";
6521 return "add{b}\t{%2, %0|%0, %2}";
6525 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6526 (const_string "incdec")
6527 (const_string "alu")))
6528 (set_attr "mode" "QI")])
6530 (define_insn "*add<mode>_3"
6531 [(set (reg FLAGS_REG)
6533 (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6534 (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6535 (clobber (match_scratch:SWI48 0 "=r"))]
6536 "ix86_match_ccmode (insn, CCZmode)
6537 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6538 /* Current assemblers are broken and do not allow @GOTOFF in
6539 ought but a memory context. */
6540 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6542 switch (get_attr_type (insn))
6545 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6546 if (operands[2] == const1_rtx)
6547 return "inc{<imodesuffix>}\t%0";
6550 gcc_assert (operands[2] == constm1_rtx);
6551 return "dec{<imodesuffix>}\t%0";
6555 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6556 /* ???? In DImode, we ought to handle there the 32bit case too
6557 - do we need new constraint? */
6558 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6559 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6561 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6565 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6566 (const_string "incdec")
6567 (const_string "alu")))
6568 (set (attr "length_immediate")
6570 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6572 (const_string "*")))
6573 (set_attr "mode" "<MODE>")])
6575 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6576 (define_insn "*addsi_3_zext"
6577 [(set (reg FLAGS_REG)
6579 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6580 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6581 (set (match_operand:DI 0 "register_operand" "=r")
6582 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6583 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6584 && ix86_binary_operator_ok (PLUS, SImode, operands)
6585 /* Current assemblers are broken and do not allow @GOTOFF in
6586 ought but a memory context. */
6587 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6589 switch (get_attr_type (insn))
6592 if (operands[2] == const1_rtx)
6593 return "inc{l}\t%k0";
6596 gcc_assert (operands[2] == constm1_rtx);
6597 return "dec{l}\t%k0";
6601 if (x86_maybe_negate_const_int (&operands[2], SImode))
6602 return "sub{l}\t{%2, %k0|%k0, %2}";
6604 return "add{l}\t{%2, %k0|%k0, %2}";
6608 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6609 (const_string "incdec")
6610 (const_string "alu")))
6611 (set (attr "length_immediate")
6613 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6615 (const_string "*")))
6616 (set_attr "mode" "SI")])
6618 (define_insn "*addhi_3"
6619 [(set (reg FLAGS_REG)
6621 (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6622 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6623 (clobber (match_scratch:HI 0 "=r"))]
6624 "ix86_match_ccmode (insn, CCZmode)
6625 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6627 switch (get_attr_type (insn))
6630 if (operands[2] == const1_rtx)
6631 return "inc{w}\t%0";
6634 gcc_assert (operands[2] == constm1_rtx);
6635 return "dec{w}\t%0";
6639 if (x86_maybe_negate_const_int (&operands[2], HImode))
6640 return "sub{w}\t{%2, %0|%0, %2}";
6642 return "add{w}\t{%2, %0|%0, %2}";
6646 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6647 (const_string "incdec")
6648 (const_string "alu")))
6649 (set (attr "length_immediate")
6651 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6653 (const_string "*")))
6654 (set_attr "mode" "HI")])
6656 (define_insn "*addqi_3"
6657 [(set (reg FLAGS_REG)
6659 (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6660 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6661 (clobber (match_scratch:QI 0 "=q"))]
6662 "ix86_match_ccmode (insn, CCZmode)
6663 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6665 switch (get_attr_type (insn))
6668 if (operands[2] == const1_rtx)
6669 return "inc{b}\t%0";
6672 gcc_assert (operands[2] == constm1_rtx
6673 || (CONST_INT_P (operands[2])
6674 && INTVAL (operands[2]) == 255));
6675 return "dec{b}\t%0";
6679 if (x86_maybe_negate_const_int (&operands[2], QImode))
6680 return "sub{b}\t{%2, %0|%0, %2}";
6682 return "add{b}\t{%2, %0|%0, %2}";
6686 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6687 (const_string "incdec")
6688 (const_string "alu")))
6689 (set_attr "mode" "QI")])
6691 ; For comparisons against 1, -1 and 128, we may generate better code
6692 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6693 ; is matched then. We can't accept general immediate, because for
6694 ; case of overflows, the result is messed up.
6695 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6696 ; only for comparisons not depending on it.
6698 (define_insn "*adddi_4"
6699 [(set (reg FLAGS_REG)
6701 (match_operand:DI 1 "nonimmediate_operand" "0")
6702 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6703 (clobber (match_scratch:DI 0 "=rm"))]
6705 && ix86_match_ccmode (insn, CCGCmode)"
6707 switch (get_attr_type (insn))
6710 if (operands[2] == constm1_rtx)
6711 return "inc{q}\t%0";
6714 gcc_assert (operands[2] == const1_rtx);
6715 return "dec{q}\t%0";
6719 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6720 if (x86_maybe_negate_const_int (&operands[2], DImode))
6721 return "add{q}\t{%2, %0|%0, %2}";
6723 return "sub{q}\t{%2, %0|%0, %2}";
6727 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6728 (const_string "incdec")
6729 (const_string "alu")))
6730 (set (attr "length_immediate")
6732 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6734 (const_string "*")))
6735 (set_attr "mode" "DI")])
6737 ; For comparisons against 1, -1 and 128, we may generate better code
6738 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6739 ; is matched then. We can't accept general immediate, because for
6740 ; case of overflows, the result is messed up.
6741 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6742 ; only for comparisons not depending on it.
6744 (define_insn "*addsi_4"
6745 [(set (reg FLAGS_REG)
6747 (match_operand:SI 1 "nonimmediate_operand" "0")
6748 (match_operand:SI 2 "const_int_operand" "n")))
6749 (clobber (match_scratch:SI 0 "=rm"))]
6750 "ix86_match_ccmode (insn, CCGCmode)"
6752 switch (get_attr_type (insn))
6755 if (operands[2] == constm1_rtx)
6756 return "inc{l}\t%0";
6759 gcc_assert (operands[2] == const1_rtx);
6760 return "dec{l}\t%0";
6764 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6765 if (x86_maybe_negate_const_int (&operands[2], SImode))
6766 return "add{l}\t{%2, %0|%0, %2}";
6768 return "sub{l}\t{%2, %0|%0, %2}";
6772 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6773 (const_string "incdec")
6774 (const_string "alu")))
6775 (set (attr "length_immediate")
6777 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6779 (const_string "*")))
6780 (set_attr "mode" "SI")])
6782 ; See comments above addsi_4 for details.
6784 (define_insn "*addhi_4"
6785 [(set (reg FLAGS_REG)
6787 (match_operand:HI 1 "nonimmediate_operand" "0")
6788 (match_operand:HI 2 "const_int_operand" "n")))
6789 (clobber (match_scratch:HI 0 "=rm"))]
6790 "ix86_match_ccmode (insn, CCGCmode)"
6792 switch (get_attr_type (insn))
6795 if (operands[2] == constm1_rtx)
6796 return "inc{w}\t%0";
6799 gcc_assert (operands[2] == const1_rtx);
6800 return "dec{w}\t%0";
6804 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6805 if (x86_maybe_negate_const_int (&operands[2], HImode))
6806 return "add{w}\t{%2, %0|%0, %2}";
6808 return "sub{w}\t{%2, %0|%0, %2}";
6812 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6813 (const_string "incdec")
6814 (const_string "alu")))
6815 (set (attr "length_immediate")
6817 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6819 (const_string "*")))
6820 (set_attr "mode" "HI")])
6822 ; See comments above addsi_4 for details.
6824 (define_insn "*addqi_4"
6825 [(set (reg FLAGS_REG)
6827 (match_operand:QI 1 "nonimmediate_operand" "0")
6828 (match_operand:QI 2 "const_int_operand" "n")))
6829 (clobber (match_scratch:QI 0 "=qm"))]
6830 "ix86_match_ccmode (insn, CCGCmode)"
6832 switch (get_attr_type (insn))
6835 if (operands[2] == constm1_rtx
6836 || (CONST_INT_P (operands[2])
6837 && INTVAL (operands[2]) == 255))
6838 return "inc{b}\t%0";
6841 gcc_assert (operands[2] == const1_rtx);
6842 return "dec{b}\t%0";
6846 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6847 if (x86_maybe_negate_const_int (&operands[2], QImode))
6848 return "add{b}\t{%2, %0|%0, %2}";
6850 return "sub{b}\t{%2, %0|%0, %2}";
6854 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6855 (const_string "incdec")
6856 (const_string "alu")))
6857 (set_attr "mode" "QI")])
6859 (define_insn "*add<mode>_5"
6860 [(set (reg FLAGS_REG)
6863 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6864 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6866 (clobber (match_scratch:SWI48 0 "=r"))]
6867 "ix86_match_ccmode (insn, CCGOCmode)
6868 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6869 /* Current assemblers are broken and do not allow @GOTOFF in
6870 ought but a memory context. */
6871 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6873 switch (get_attr_type (insn))
6876 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6877 if (operands[2] == const1_rtx)
6878 return "inc{<imodesuffix>}\t%0";
6881 gcc_assert (operands[2] == constm1_rtx);
6882 return "dec{<imodesuffix>}\t%0";
6886 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6887 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6888 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6890 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6894 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6895 (const_string "incdec")
6896 (const_string "alu")))
6897 (set (attr "length_immediate")
6899 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6901 (const_string "*")))
6902 (set_attr "mode" "<MODE>")])
6904 (define_insn "*addhi_5"
6905 [(set (reg FLAGS_REG)
6907 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6908 (match_operand:HI 2 "general_operand" "rmn"))
6910 (clobber (match_scratch:HI 0 "=r"))]
6911 "ix86_match_ccmode (insn, CCGOCmode)
6912 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6914 switch (get_attr_type (insn))
6917 if (operands[2] == const1_rtx)
6918 return "inc{w}\t%0";
6921 gcc_assert (operands[2] == constm1_rtx);
6922 return "dec{w}\t%0";
6926 if (x86_maybe_negate_const_int (&operands[2], HImode))
6927 return "sub{w}\t{%2, %0|%0, %2}";
6929 return "add{w}\t{%2, %0|%0, %2}";
6933 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6934 (const_string "incdec")
6935 (const_string "alu")))
6936 (set (attr "length_immediate")
6938 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6940 (const_string "*")))
6941 (set_attr "mode" "HI")])
6943 (define_insn "*addqi_5"
6944 [(set (reg FLAGS_REG)
6946 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6947 (match_operand:QI 2 "general_operand" "qmn"))
6949 (clobber (match_scratch:QI 0 "=q"))]
6950 "ix86_match_ccmode (insn, CCGOCmode)
6951 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6953 switch (get_attr_type (insn))
6956 if (operands[2] == const1_rtx)
6957 return "inc{b}\t%0";
6960 gcc_assert (operands[2] == constm1_rtx
6961 || (CONST_INT_P (operands[2])
6962 && INTVAL (operands[2]) == 255));
6963 return "dec{b}\t%0";
6967 if (x86_maybe_negate_const_int (&operands[2], QImode))
6968 return "sub{b}\t{%2, %0|%0, %2}";
6970 return "add{b}\t{%2, %0|%0, %2}";
6974 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6975 (const_string "incdec")
6976 (const_string "alu")))
6977 (set_attr "mode" "QI")])
6979 (define_insn "*addqi_ext_1_rex64"
6980 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6985 (match_operand 1 "ext_register_operand" "0")
6988 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6989 (clobber (reg:CC FLAGS_REG))]
6992 switch (get_attr_type (insn))
6995 if (operands[2] == const1_rtx)
6996 return "inc{b}\t%h0";
6999 gcc_assert (operands[2] == constm1_rtx
7000 || (CONST_INT_P (operands[2])
7001 && INTVAL (operands[2]) == 255));
7002 return "dec{b}\t%h0";
7006 return "add{b}\t{%2, %h0|%h0, %2}";
7010 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7011 (const_string "incdec")
7012 (const_string "alu")))
7013 (set_attr "modrm" "1")
7014 (set_attr "mode" "QI")])
7016 (define_insn "addqi_ext_1"
7017 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7022 (match_operand 1 "ext_register_operand" "0")
7025 (match_operand:QI 2 "general_operand" "Qmn")))
7026 (clobber (reg:CC FLAGS_REG))]
7029 switch (get_attr_type (insn))
7032 if (operands[2] == const1_rtx)
7033 return "inc{b}\t%h0";
7036 gcc_assert (operands[2] == constm1_rtx
7037 || (CONST_INT_P (operands[2])
7038 && INTVAL (operands[2]) == 255));
7039 return "dec{b}\t%h0";
7043 return "add{b}\t{%2, %h0|%h0, %2}";
7047 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7048 (const_string "incdec")
7049 (const_string "alu")))
7050 (set_attr "modrm" "1")
7051 (set_attr "mode" "QI")])
7053 (define_insn "*addqi_ext_2"
7054 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7059 (match_operand 1 "ext_register_operand" "%0")
7063 (match_operand 2 "ext_register_operand" "Q")
7066 (clobber (reg:CC FLAGS_REG))]
7068 "add{b}\t{%h2, %h0|%h0, %h2}"
7069 [(set_attr "type" "alu")
7070 (set_attr "mode" "QI")])
7072 ;; The lea patterns for non-Pmodes needs to be matched by
7073 ;; several insns converted to real lea by splitters.
7075 (define_insn_and_split "*lea_general_1"
7076 [(set (match_operand 0 "register_operand" "=r")
7077 (plus (plus (match_operand 1 "index_register_operand" "l")
7078 (match_operand 2 "register_operand" "r"))
7079 (match_operand 3 "immediate_operand" "i")))]
7080 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7081 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7082 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7083 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7084 && GET_MODE (operands[0]) == GET_MODE (operands[2])
7085 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7086 || GET_MODE (operands[3]) == VOIDmode)"
7088 "&& reload_completed"
7092 operands[0] = gen_lowpart (SImode, operands[0]);
7093 operands[1] = gen_lowpart (Pmode, operands[1]);
7094 operands[2] = gen_lowpart (Pmode, operands[2]);
7095 operands[3] = gen_lowpart (Pmode, operands[3]);
7096 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7098 if (Pmode != SImode)
7099 pat = gen_rtx_SUBREG (SImode, pat, 0);
7100 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7103 [(set_attr "type" "lea")
7104 (set_attr "mode" "SI")])
7106 (define_insn_and_split "*lea_general_1_zext"
7107 [(set (match_operand:DI 0 "register_operand" "=r")
7110 (match_operand:SI 1 "index_register_operand" "l")
7111 (match_operand:SI 2 "register_operand" "r"))
7112 (match_operand:SI 3 "immediate_operand" "i"))))]
7115 "&& reload_completed"
7117 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7119 (match_dup 3)) 0)))]
7121 operands[1] = gen_lowpart (Pmode, operands[1]);
7122 operands[2] = gen_lowpart (Pmode, operands[2]);
7123 operands[3] = gen_lowpart (Pmode, operands[3]);
7125 [(set_attr "type" "lea")
7126 (set_attr "mode" "SI")])
7128 (define_insn_and_split "*lea_general_2"
7129 [(set (match_operand 0 "register_operand" "=r")
7130 (plus (mult (match_operand 1 "index_register_operand" "l")
7131 (match_operand 2 "const248_operand" "i"))
7132 (match_operand 3 "nonmemory_operand" "ri")))]
7133 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7134 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7135 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7136 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7137 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7138 || GET_MODE (operands[3]) == VOIDmode)"
7140 "&& reload_completed"
7144 operands[0] = gen_lowpart (SImode, operands[0]);
7145 operands[1] = gen_lowpart (Pmode, operands[1]);
7146 operands[3] = gen_lowpart (Pmode, operands[3]);
7147 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7149 if (Pmode != SImode)
7150 pat = gen_rtx_SUBREG (SImode, pat, 0);
7151 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7154 [(set_attr "type" "lea")
7155 (set_attr "mode" "SI")])
7157 (define_insn_and_split "*lea_general_2_zext"
7158 [(set (match_operand:DI 0 "register_operand" "=r")
7161 (match_operand:SI 1 "index_register_operand" "l")
7162 (match_operand:SI 2 "const248_operand" "n"))
7163 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7166 "&& reload_completed"
7168 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7170 (match_dup 3)) 0)))]
7172 operands[1] = gen_lowpart (Pmode, operands[1]);
7173 operands[3] = gen_lowpart (Pmode, operands[3]);
7175 [(set_attr "type" "lea")
7176 (set_attr "mode" "SI")])
7178 (define_insn_and_split "*lea_general_3"
7179 [(set (match_operand 0 "register_operand" "=r")
7180 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7181 (match_operand 2 "const248_operand" "i"))
7182 (match_operand 3 "register_operand" "r"))
7183 (match_operand 4 "immediate_operand" "i")))]
7184 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7185 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7186 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7187 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7188 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7190 "&& reload_completed"
7194 operands[0] = gen_lowpart (SImode, operands[0]);
7195 operands[1] = gen_lowpart (Pmode, operands[1]);
7196 operands[3] = gen_lowpart (Pmode, operands[3]);
7197 operands[4] = gen_lowpart (Pmode, operands[4]);
7198 pat = gen_rtx_PLUS (Pmode,
7199 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7203 if (Pmode != SImode)
7204 pat = gen_rtx_SUBREG (SImode, pat, 0);
7205 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7208 [(set_attr "type" "lea")
7209 (set_attr "mode" "SI")])
7211 (define_insn_and_split "*lea_general_3_zext"
7212 [(set (match_operand:DI 0 "register_operand" "=r")
7216 (match_operand:SI 1 "index_register_operand" "l")
7217 (match_operand:SI 2 "const248_operand" "n"))
7218 (match_operand:SI 3 "register_operand" "r"))
7219 (match_operand:SI 4 "immediate_operand" "i"))))]
7222 "&& reload_completed"
7224 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7227 (match_dup 4)) 0)))]
7229 operands[1] = gen_lowpart (Pmode, operands[1]);
7230 operands[3] = gen_lowpart (Pmode, operands[3]);
7231 operands[4] = gen_lowpart (Pmode, operands[4]);
7233 [(set_attr "type" "lea")
7234 (set_attr "mode" "SI")])
7236 ;; Convert lea to the lea pattern to avoid flags dependency.
7238 [(set (match_operand:DI 0 "register_operand" "")
7239 (plus:DI (match_operand:DI 1 "register_operand" "")
7240 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7241 (clobber (reg:CC FLAGS_REG))]
7242 "TARGET_64BIT && reload_completed
7243 && ix86_lea_for_add_ok (PLUS, insn, operands)"
7245 (plus:DI (match_dup 1)
7249 ;; Convert lea to the lea pattern to avoid flags dependency.
7251 [(set (match_operand 0 "register_operand" "")
7252 (plus (match_operand 1 "register_operand" "")
7253 (match_operand 2 "nonmemory_operand" "")))
7254 (clobber (reg:CC FLAGS_REG))]
7255 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
7259 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7260 may confuse gen_lowpart. */
7261 if (GET_MODE (operands[0]) != Pmode)
7263 operands[1] = gen_lowpart (Pmode, operands[1]);
7264 operands[2] = gen_lowpart (Pmode, operands[2]);
7266 operands[0] = gen_lowpart (SImode, operands[0]);
7267 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7268 if (Pmode != SImode)
7269 pat = gen_rtx_SUBREG (SImode, pat, 0);
7270 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7274 ;; Convert lea to the lea pattern to avoid flags dependency.
7276 [(set (match_operand:DI 0 "register_operand" "")
7278 (plus:SI (match_operand:SI 1 "register_operand" "")
7279 (match_operand:SI 2 "nonmemory_operand" ""))))
7280 (clobber (reg:CC FLAGS_REG))]
7281 "TARGET_64BIT && reload_completed
7282 && true_regnum (operands[0]) != true_regnum (operands[1])"
7284 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7286 operands[1] = gen_lowpart (Pmode, operands[1]);
7287 operands[2] = gen_lowpart (Pmode, operands[2]);
7290 ;; Subtract instructions
7292 (define_expand "sub<mode>3"
7293 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7294 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7295 (match_operand:SDWIM 2 "<general_operand>" "")))]
7297 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7299 (define_insn_and_split "*sub<dwi>3_doubleword"
7300 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7302 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7303 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7304 (clobber (reg:CC FLAGS_REG))]
7305 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7308 [(parallel [(set (reg:CC FLAGS_REG)
7309 (compare:CC (match_dup 1) (match_dup 2)))
7311 (minus:DWIH (match_dup 1) (match_dup 2)))])
7312 (parallel [(set (match_dup 3)
7316 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7318 (clobber (reg:CC FLAGS_REG))])]
7319 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7321 (define_insn "*sub<mode>_1"
7322 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7324 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7325 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7326 (clobber (reg:CC FLAGS_REG))]
7327 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7328 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7329 [(set_attr "type" "alu")
7330 (set_attr "mode" "<MODE>")])
7332 (define_insn "*subsi_1_zext"
7333 [(set (match_operand:DI 0 "register_operand" "=r")
7335 (minus:SI (match_operand:SI 1 "register_operand" "0")
7336 (match_operand:SI 2 "general_operand" "g"))))
7337 (clobber (reg:CC FLAGS_REG))]
7338 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7339 "sub{l}\t{%2, %k0|%k0, %2}"
7340 [(set_attr "type" "alu")
7341 (set_attr "mode" "SI")])
7343 (define_insn "*subqi_1_slp"
7344 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7345 (minus:QI (match_dup 0)
7346 (match_operand:QI 1 "general_operand" "qn,qm")))
7347 (clobber (reg:CC FLAGS_REG))]
7348 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7349 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7350 "sub{b}\t{%1, %0|%0, %1}"
7351 [(set_attr "type" "alu1")
7352 (set_attr "mode" "QI")])
7354 (define_insn "*sub<mode>_2"
7355 [(set (reg FLAGS_REG)
7358 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7359 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7361 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7362 (minus:SWI (match_dup 1) (match_dup 2)))]
7363 "ix86_match_ccmode (insn, CCGOCmode)
7364 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7365 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7366 [(set_attr "type" "alu")
7367 (set_attr "mode" "<MODE>")])
7369 (define_insn "*subsi_2_zext"
7370 [(set (reg FLAGS_REG)
7372 (minus:SI (match_operand:SI 1 "register_operand" "0")
7373 (match_operand:SI 2 "general_operand" "g"))
7375 (set (match_operand:DI 0 "register_operand" "=r")
7377 (minus:SI (match_dup 1)
7379 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7380 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7381 "sub{l}\t{%2, %k0|%k0, %2}"
7382 [(set_attr "type" "alu")
7383 (set_attr "mode" "SI")])
7385 (define_insn "*sub<mode>_3"
7386 [(set (reg FLAGS_REG)
7387 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7388 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7389 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7390 (minus:SWI (match_dup 1) (match_dup 2)))]
7391 "ix86_match_ccmode (insn, CCmode)
7392 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7393 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7394 [(set_attr "type" "alu")
7395 (set_attr "mode" "<MODE>")])
7397 (define_insn "*subsi_3_zext"
7398 [(set (reg FLAGS_REG)
7399 (compare (match_operand:SI 1 "register_operand" "0")
7400 (match_operand:SI 2 "general_operand" "g")))
7401 (set (match_operand:DI 0 "register_operand" "=r")
7403 (minus:SI (match_dup 1)
7405 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7406 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7407 "sub{l}\t{%2, %1|%1, %2}"
7408 [(set_attr "type" "alu")
7409 (set_attr "mode" "SI")])
7411 ;; Add with carry and subtract with borrow
7413 (define_expand "<plusminus_insn><mode>3_carry"
7415 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7417 (match_operand:SWI 1 "nonimmediate_operand" "")
7418 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7419 [(match_operand 3 "flags_reg_operand" "")
7421 (match_operand:SWI 2 "<general_operand>" ""))))
7422 (clobber (reg:CC FLAGS_REG))])]
7423 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7426 (define_insn "*<plusminus_insn><mode>3_carry"
7427 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7429 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7431 (match_operator 3 "ix86_carry_flag_operator"
7432 [(reg FLAGS_REG) (const_int 0)])
7433 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7434 (clobber (reg:CC FLAGS_REG))]
7435 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7436 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7437 [(set_attr "type" "alu")
7438 (set_attr "use_carry" "1")
7439 (set_attr "pent_pair" "pu")
7440 (set_attr "mode" "<MODE>")])
7442 (define_insn "*addsi3_carry_zext"
7443 [(set (match_operand:DI 0 "register_operand" "=r")
7445 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7446 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7447 [(reg FLAGS_REG) (const_int 0)])
7448 (match_operand:SI 2 "general_operand" "g")))))
7449 (clobber (reg:CC FLAGS_REG))]
7450 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7451 "adc{l}\t{%2, %k0|%k0, %2}"
7452 [(set_attr "type" "alu")
7453 (set_attr "use_carry" "1")
7454 (set_attr "pent_pair" "pu")
7455 (set_attr "mode" "SI")])
7457 (define_insn "*subsi3_carry_zext"
7458 [(set (match_operand:DI 0 "register_operand" "=r")
7460 (minus:SI (match_operand:SI 1 "register_operand" "0")
7461 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7462 [(reg FLAGS_REG) (const_int 0)])
7463 (match_operand:SI 2 "general_operand" "g")))))
7464 (clobber (reg:CC FLAGS_REG))]
7465 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7466 "sbb{l}\t{%2, %k0|%k0, %2}"
7467 [(set_attr "type" "alu")
7468 (set_attr "pent_pair" "pu")
7469 (set_attr "mode" "SI")])
7471 ;; Overflow setting add and subtract instructions
7473 (define_insn "*add<mode>3_cconly_overflow"
7474 [(set (reg:CCC FLAGS_REG)
7477 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7478 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7480 (clobber (match_scratch:SWI 0 "=<r>"))]
7481 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7482 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7483 [(set_attr "type" "alu")
7484 (set_attr "mode" "<MODE>")])
7486 (define_insn "*sub<mode>3_cconly_overflow"
7487 [(set (reg:CCC FLAGS_REG)
7490 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7491 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7494 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7495 [(set_attr "type" "icmp")
7496 (set_attr "mode" "<MODE>")])
7498 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7499 [(set (reg:CCC FLAGS_REG)
7502 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7503 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7505 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7506 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7507 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7508 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7509 [(set_attr "type" "alu")
7510 (set_attr "mode" "<MODE>")])
7512 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7513 [(set (reg:CCC FLAGS_REG)
7516 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7517 (match_operand:SI 2 "general_operand" "g"))
7519 (set (match_operand:DI 0 "register_operand" "=r")
7520 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7521 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7522 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7523 [(set_attr "type" "alu")
7524 (set_attr "mode" "SI")])
7526 ;; The patterns that match these are at the end of this file.
7528 (define_expand "<plusminus_insn>xf3"
7529 [(set (match_operand:XF 0 "register_operand" "")
7531 (match_operand:XF 1 "register_operand" "")
7532 (match_operand:XF 2 "register_operand" "")))]
7536 (define_expand "<plusminus_insn><mode>3"
7537 [(set (match_operand:MODEF 0 "register_operand" "")
7539 (match_operand:MODEF 1 "register_operand" "")
7540 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7541 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7542 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7545 ;; Multiply instructions
7547 (define_expand "mul<mode>3"
7548 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7550 (match_operand:SWIM248 1 "register_operand" "")
7551 (match_operand:SWIM248 2 "<general_operand>" "")))
7552 (clobber (reg:CC FLAGS_REG))])]
7556 (define_expand "mulqi3"
7557 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7559 (match_operand:QI 1 "register_operand" "")
7560 (match_operand:QI 2 "nonimmediate_operand" "")))
7561 (clobber (reg:CC FLAGS_REG))])]
7562 "TARGET_QIMODE_MATH"
7566 ;; IMUL reg32/64, reg32/64, imm8 Direct
7567 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7568 ;; IMUL reg32/64, reg32/64, imm32 Direct
7569 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7570 ;; IMUL reg32/64, reg32/64 Direct
7571 ;; IMUL reg32/64, mem32/64 Direct
7573 (define_insn "*mul<mode>3_1"
7574 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7576 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7577 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7578 (clobber (reg:CC FLAGS_REG))]
7579 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7581 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7582 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7583 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7584 [(set_attr "type" "imul")
7585 (set_attr "prefix_0f" "0,0,1")
7586 (set (attr "athlon_decode")
7587 (cond [(eq_attr "cpu" "athlon")
7588 (const_string "vector")
7589 (eq_attr "alternative" "1")
7590 (const_string "vector")
7591 (and (eq_attr "alternative" "2")
7592 (match_operand 1 "memory_operand" ""))
7593 (const_string "vector")]
7594 (const_string "direct")))
7595 (set (attr "amdfam10_decode")
7596 (cond [(and (eq_attr "alternative" "0,1")
7597 (match_operand 1 "memory_operand" ""))
7598 (const_string "vector")]
7599 (const_string "direct")))
7600 (set_attr "mode" "<MODE>")])
7602 (define_insn "*mulsi3_1_zext"
7603 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7605 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7606 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7607 (clobber (reg:CC FLAGS_REG))]
7609 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7611 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7612 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7613 imul{l}\t{%2, %k0|%k0, %2}"
7614 [(set_attr "type" "imul")
7615 (set_attr "prefix_0f" "0,0,1")
7616 (set (attr "athlon_decode")
7617 (cond [(eq_attr "cpu" "athlon")
7618 (const_string "vector")
7619 (eq_attr "alternative" "1")
7620 (const_string "vector")
7621 (and (eq_attr "alternative" "2")
7622 (match_operand 1 "memory_operand" ""))
7623 (const_string "vector")]
7624 (const_string "direct")))
7625 (set (attr "amdfam10_decode")
7626 (cond [(and (eq_attr "alternative" "0,1")
7627 (match_operand 1 "memory_operand" ""))
7628 (const_string "vector")]
7629 (const_string "direct")))
7630 (set_attr "mode" "SI")])
7633 ;; IMUL reg16, reg16, imm8 VectorPath
7634 ;; IMUL reg16, mem16, imm8 VectorPath
7635 ;; IMUL reg16, reg16, imm16 VectorPath
7636 ;; IMUL reg16, mem16, imm16 VectorPath
7637 ;; IMUL reg16, reg16 Direct
7638 ;; IMUL reg16, mem16 Direct
7640 (define_insn "*mulhi3_1"
7641 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7642 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7643 (match_operand:HI 2 "general_operand" "K,n,mr")))
7644 (clobber (reg:CC FLAGS_REG))]
7646 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7648 imul{w}\t{%2, %1, %0|%0, %1, %2}
7649 imul{w}\t{%2, %1, %0|%0, %1, %2}
7650 imul{w}\t{%2, %0|%0, %2}"
7651 [(set_attr "type" "imul")
7652 (set_attr "prefix_0f" "0,0,1")
7653 (set (attr "athlon_decode")
7654 (cond [(eq_attr "cpu" "athlon")
7655 (const_string "vector")
7656 (eq_attr "alternative" "1,2")
7657 (const_string "vector")]
7658 (const_string "direct")))
7659 (set (attr "amdfam10_decode")
7660 (cond [(eq_attr "alternative" "0,1")
7661 (const_string "vector")]
7662 (const_string "direct")))
7663 (set_attr "mode" "HI")])
7669 (define_insn "*mulqi3_1"
7670 [(set (match_operand:QI 0 "register_operand" "=a")
7671 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7672 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7673 (clobber (reg:CC FLAGS_REG))]
7675 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7677 [(set_attr "type" "imul")
7678 (set_attr "length_immediate" "0")
7679 (set (attr "athlon_decode")
7680 (if_then_else (eq_attr "cpu" "athlon")
7681 (const_string "vector")
7682 (const_string "direct")))
7683 (set_attr "amdfam10_decode" "direct")
7684 (set_attr "mode" "QI")])
7686 (define_expand "<u>mul<mode><dwi>3"
7687 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7690 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7692 (match_operand:DWIH 2 "register_operand" ""))))
7693 (clobber (reg:CC FLAGS_REG))])]
7697 (define_expand "<u>mulqihi3"
7698 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7701 (match_operand:QI 1 "nonimmediate_operand" ""))
7703 (match_operand:QI 2 "register_operand" ""))))
7704 (clobber (reg:CC FLAGS_REG))])]
7705 "TARGET_QIMODE_MATH"
7708 (define_insn "*<u>mul<mode><dwi>3_1"
7709 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7712 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7714 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7715 (clobber (reg:CC FLAGS_REG))]
7716 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7717 "<sgnprefix>mul{<imodesuffix>}\t%2"
7718 [(set_attr "type" "imul")
7719 (set_attr "length_immediate" "0")
7720 (set (attr "athlon_decode")
7721 (if_then_else (eq_attr "cpu" "athlon")
7722 (const_string "vector")
7723 (const_string "double")))
7724 (set_attr "amdfam10_decode" "double")
7725 (set_attr "mode" "<MODE>")])
7727 (define_insn "*<u>mulqihi3_1"
7728 [(set (match_operand:HI 0 "register_operand" "=a")
7731 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7733 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7734 (clobber (reg:CC FLAGS_REG))]
7736 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7737 "<sgnprefix>mul{b}\t%2"
7738 [(set_attr "type" "imul")
7739 (set_attr "length_immediate" "0")
7740 (set (attr "athlon_decode")
7741 (if_then_else (eq_attr "cpu" "athlon")
7742 (const_string "vector")
7743 (const_string "direct")))
7744 (set_attr "amdfam10_decode" "direct")
7745 (set_attr "mode" "QI")])
7747 (define_expand "<s>mul<mode>3_highpart"
7748 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7753 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7755 (match_operand:SWI48 2 "register_operand" "")))
7757 (clobber (match_scratch:SWI48 3 ""))
7758 (clobber (reg:CC FLAGS_REG))])]
7760 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7762 (define_insn "*<s>muldi3_highpart_1"
7763 [(set (match_operand:DI 0 "register_operand" "=d")
7768 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7770 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7772 (clobber (match_scratch:DI 3 "=1"))
7773 (clobber (reg:CC FLAGS_REG))]
7775 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7776 "<sgnprefix>mul{q}\t%2"
7777 [(set_attr "type" "imul")
7778 (set_attr "length_immediate" "0")
7779 (set (attr "athlon_decode")
7780 (if_then_else (eq_attr "cpu" "athlon")
7781 (const_string "vector")
7782 (const_string "double")))
7783 (set_attr "amdfam10_decode" "double")
7784 (set_attr "mode" "DI")])
7786 (define_insn "*<s>mulsi3_highpart_1"
7787 [(set (match_operand:SI 0 "register_operand" "=d")
7792 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7794 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7796 (clobber (match_scratch:SI 3 "=1"))
7797 (clobber (reg:CC FLAGS_REG))]
7798 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7799 "<sgnprefix>mul{l}\t%2"
7800 [(set_attr "type" "imul")
7801 (set_attr "length_immediate" "0")
7802 (set (attr "athlon_decode")
7803 (if_then_else (eq_attr "cpu" "athlon")
7804 (const_string "vector")
7805 (const_string "double")))
7806 (set_attr "amdfam10_decode" "double")
7807 (set_attr "mode" "SI")])
7809 (define_insn "*<s>mulsi3_highpart_zext"
7810 [(set (match_operand:DI 0 "register_operand" "=d")
7811 (zero_extend:DI (truncate:SI
7813 (mult:DI (any_extend:DI
7814 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7816 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7818 (clobber (match_scratch:SI 3 "=1"))
7819 (clobber (reg:CC FLAGS_REG))]
7821 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7822 "<sgnprefix>mul{l}\t%2"
7823 [(set_attr "type" "imul")
7824 (set_attr "length_immediate" "0")
7825 (set (attr "athlon_decode")
7826 (if_then_else (eq_attr "cpu" "athlon")
7827 (const_string "vector")
7828 (const_string "double")))
7829 (set_attr "amdfam10_decode" "double")
7830 (set_attr "mode" "SI")])
7832 ;; The patterns that match these are at the end of this file.
7834 (define_expand "mulxf3"
7835 [(set (match_operand:XF 0 "register_operand" "")
7836 (mult:XF (match_operand:XF 1 "register_operand" "")
7837 (match_operand:XF 2 "register_operand" "")))]
7841 (define_expand "mul<mode>3"
7842 [(set (match_operand:MODEF 0 "register_operand" "")
7843 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7844 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7845 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7846 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7849 ;; Divide instructions
7851 (define_insn "<u>divqi3"
7852 [(set (match_operand:QI 0 "register_operand" "=a")
7854 (match_operand:HI 1 "register_operand" "0")
7855 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7856 (clobber (reg:CC FLAGS_REG))]
7857 "TARGET_QIMODE_MATH"
7858 "<sgnprefix>div{b}\t%2"
7859 [(set_attr "type" "idiv")
7860 (set_attr "mode" "QI")])
7862 ;; The patterns that match these are at the end of this file.
7864 (define_expand "divxf3"
7865 [(set (match_operand:XF 0 "register_operand" "")
7866 (div:XF (match_operand:XF 1 "register_operand" "")
7867 (match_operand:XF 2 "register_operand" "")))]
7871 (define_expand "divdf3"
7872 [(set (match_operand:DF 0 "register_operand" "")
7873 (div:DF (match_operand:DF 1 "register_operand" "")
7874 (match_operand:DF 2 "nonimmediate_operand" "")))]
7875 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7876 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7879 (define_expand "divsf3"
7880 [(set (match_operand:SF 0 "register_operand" "")
7881 (div:SF (match_operand:SF 1 "register_operand" "")
7882 (match_operand:SF 2 "nonimmediate_operand" "")))]
7883 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7886 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7887 && flag_finite_math_only && !flag_trapping_math
7888 && flag_unsafe_math_optimizations)
7890 ix86_emit_swdivsf (operands[0], operands[1],
7891 operands[2], SFmode);
7896 ;; Divmod instructions.
7898 (define_expand "divmod<mode>4"
7899 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7901 (match_operand:SWIM248 1 "register_operand" "")
7902 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7903 (set (match_operand:SWIM248 3 "register_operand" "")
7904 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7905 (clobber (reg:CC FLAGS_REG))])]
7909 (define_insn_and_split "*divmod<mode>4"
7910 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7911 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7912 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7913 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7914 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7915 (clobber (reg:CC FLAGS_REG))]
7918 "&& reload_completed"
7919 [(parallel [(set (match_dup 1)
7920 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7921 (clobber (reg:CC FLAGS_REG))])
7922 (parallel [(set (match_dup 0)
7923 (div:SWIM248 (match_dup 2) (match_dup 3)))
7925 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7927 (clobber (reg:CC FLAGS_REG))])]
7929 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
7931 if (<MODE>mode != HImode
7932 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7933 operands[4] = operands[2];
7936 /* Avoid use of cltd in favor of a mov+shift. */
7937 emit_move_insn (operands[1], operands[2]);
7938 operands[4] = operands[1];
7941 [(set_attr "type" "multi")
7942 (set_attr "mode" "<MODE>")])
7944 (define_insn "*divmod<mode>4_noext"
7945 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7946 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7947 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7948 (set (match_operand:SWIM248 1 "register_operand" "=d")
7949 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7950 (use (match_operand:SWIM248 4 "register_operand" "1"))
7951 (clobber (reg:CC FLAGS_REG))]
7953 "idiv{<imodesuffix>}\t%3"
7954 [(set_attr "type" "idiv")
7955 (set_attr "mode" "<MODE>")])
7957 (define_expand "udivmod<mode>4"
7958 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7960 (match_operand:SWIM248 1 "register_operand" "")
7961 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7962 (set (match_operand:SWIM248 3 "register_operand" "")
7963 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7964 (clobber (reg:CC FLAGS_REG))])]
7968 (define_insn_and_split "*udivmod<mode>4"
7969 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7970 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7971 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7972 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7973 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7974 (clobber (reg:CC FLAGS_REG))]
7977 "&& reload_completed"
7978 [(set (match_dup 1) (const_int 0))
7979 (parallel [(set (match_dup 0)
7980 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7982 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7984 (clobber (reg:CC FLAGS_REG))])]
7986 [(set_attr "type" "multi")
7987 (set_attr "mode" "<MODE>")])
7989 (define_insn "*udivmod<mode>4_noext"
7990 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7991 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7992 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7993 (set (match_operand:SWIM248 1 "register_operand" "=d")
7994 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7995 (use (match_operand:SWIM248 4 "register_operand" "1"))
7996 (clobber (reg:CC FLAGS_REG))]
7998 "div{<imodesuffix>}\t%3"
7999 [(set_attr "type" "idiv")
8000 (set_attr "mode" "<MODE>")])
8002 ;; We cannot use div/idiv for double division, because it causes
8003 ;; "division by zero" on the overflow and that's not what we expect
8004 ;; from truncate. Because true (non truncating) double division is
8005 ;; never generated, we can't create this insn anyway.
8008 ; [(set (match_operand:SI 0 "register_operand" "=a")
8010 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8012 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8013 ; (set (match_operand:SI 3 "register_operand" "=d")
8015 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8016 ; (clobber (reg:CC FLAGS_REG))]
8018 ; "div{l}\t{%2, %0|%0, %2}"
8019 ; [(set_attr "type" "idiv")])
8021 ;;- Logical AND instructions
8023 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8024 ;; Note that this excludes ah.
8026 (define_expand "testsi_ccno_1"
8027 [(set (reg:CCNO FLAGS_REG)
8029 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8030 (match_operand:SI 1 "nonmemory_operand" ""))
8035 (define_expand "testqi_ccz_1"
8036 [(set (reg:CCZ FLAGS_REG)
8037 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8038 (match_operand:QI 1 "nonmemory_operand" ""))
8043 (define_insn "*testdi_1"
8044 [(set (reg FLAGS_REG)
8047 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8048 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8050 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8051 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8053 test{l}\t{%k1, %k0|%k0, %k1}
8054 test{l}\t{%k1, %k0|%k0, %k1}
8055 test{q}\t{%1, %0|%0, %1}
8056 test{q}\t{%1, %0|%0, %1}
8057 test{q}\t{%1, %0|%0, %1}"
8058 [(set_attr "type" "test")
8059 (set_attr "modrm" "0,1,0,1,1")
8060 (set_attr "mode" "SI,SI,DI,DI,DI")])
8062 (define_insn "*testqi_1_maybe_si"
8063 [(set (reg FLAGS_REG)
8066 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8067 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8069 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8070 && ix86_match_ccmode (insn,
8071 CONST_INT_P (operands[1])
8072 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8074 if (which_alternative == 3)
8076 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8077 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8078 return "test{l}\t{%1, %k0|%k0, %1}";
8080 return "test{b}\t{%1, %0|%0, %1}";
8082 [(set_attr "type" "test")
8083 (set_attr "modrm" "0,1,1,1")
8084 (set_attr "mode" "QI,QI,QI,SI")
8085 (set_attr "pent_pair" "uv,np,uv,np")])
8087 (define_insn "*test<mode>_1"
8088 [(set (reg FLAGS_REG)
8091 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8092 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8094 "ix86_match_ccmode (insn, CCNOmode)
8095 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8096 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8097 [(set_attr "type" "test")
8098 (set_attr "modrm" "0,1,1")
8099 (set_attr "mode" "<MODE>")
8100 (set_attr "pent_pair" "uv,np,uv")])
8102 (define_expand "testqi_ext_ccno_0"
8103 [(set (reg:CCNO FLAGS_REG)
8107 (match_operand 0 "ext_register_operand" "")
8110 (match_operand 1 "const_int_operand" ""))
8115 (define_insn "*testqi_ext_0"
8116 [(set (reg FLAGS_REG)
8120 (match_operand 0 "ext_register_operand" "Q")
8123 (match_operand 1 "const_int_operand" "n"))
8125 "ix86_match_ccmode (insn, CCNOmode)"
8126 "test{b}\t{%1, %h0|%h0, %1}"
8127 [(set_attr "type" "test")
8128 (set_attr "mode" "QI")
8129 (set_attr "length_immediate" "1")
8130 (set_attr "modrm" "1")
8131 (set_attr "pent_pair" "np")])
8133 (define_insn "*testqi_ext_1_rex64"
8134 [(set (reg FLAGS_REG)
8138 (match_operand 0 "ext_register_operand" "Q")
8142 (match_operand:QI 1 "register_operand" "Q")))
8144 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8145 "test{b}\t{%1, %h0|%h0, %1}"
8146 [(set_attr "type" "test")
8147 (set_attr "mode" "QI")])
8149 (define_insn "*testqi_ext_1"
8150 [(set (reg FLAGS_REG)
8154 (match_operand 0 "ext_register_operand" "Q")
8158 (match_operand:QI 1 "general_operand" "Qm")))
8160 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8161 "test{b}\t{%1, %h0|%h0, %1}"
8162 [(set_attr "type" "test")
8163 (set_attr "mode" "QI")])
8165 (define_insn "*testqi_ext_2"
8166 [(set (reg FLAGS_REG)
8170 (match_operand 0 "ext_register_operand" "Q")
8174 (match_operand 1 "ext_register_operand" "Q")
8178 "ix86_match_ccmode (insn, CCNOmode)"
8179 "test{b}\t{%h1, %h0|%h0, %h1}"
8180 [(set_attr "type" "test")
8181 (set_attr "mode" "QI")])
8183 (define_insn "*testqi_ext_3_rex64"
8184 [(set (reg FLAGS_REG)
8185 (compare (zero_extract:DI
8186 (match_operand 0 "nonimmediate_operand" "rm")
8187 (match_operand:DI 1 "const_int_operand" "")
8188 (match_operand:DI 2 "const_int_operand" ""))
8191 && ix86_match_ccmode (insn, CCNOmode)
8192 && INTVAL (operands[1]) > 0
8193 && INTVAL (operands[2]) >= 0
8194 /* Ensure that resulting mask is zero or sign extended operand. */
8195 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8196 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8197 && INTVAL (operands[1]) > 32))
8198 && (GET_MODE (operands[0]) == SImode
8199 || GET_MODE (operands[0]) == DImode
8200 || GET_MODE (operands[0]) == HImode
8201 || GET_MODE (operands[0]) == QImode)"
8204 ;; Combine likes to form bit extractions for some tests. Humor it.
8205 (define_insn "*testqi_ext_3"
8206 [(set (reg FLAGS_REG)
8207 (compare (zero_extract:SI
8208 (match_operand 0 "nonimmediate_operand" "rm")
8209 (match_operand:SI 1 "const_int_operand" "")
8210 (match_operand:SI 2 "const_int_operand" ""))
8212 "ix86_match_ccmode (insn, CCNOmode)
8213 && INTVAL (operands[1]) > 0
8214 && INTVAL (operands[2]) >= 0
8215 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8216 && (GET_MODE (operands[0]) == SImode
8217 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8218 || GET_MODE (operands[0]) == HImode
8219 || GET_MODE (operands[0]) == QImode)"
8223 [(set (match_operand 0 "flags_reg_operand" "")
8224 (match_operator 1 "compare_operator"
8226 (match_operand 2 "nonimmediate_operand" "")
8227 (match_operand 3 "const_int_operand" "")
8228 (match_operand 4 "const_int_operand" ""))
8230 "ix86_match_ccmode (insn, CCNOmode)"
8231 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8233 rtx val = operands[2];
8234 HOST_WIDE_INT len = INTVAL (operands[3]);
8235 HOST_WIDE_INT pos = INTVAL (operands[4]);
8237 enum machine_mode mode, submode;
8239 mode = GET_MODE (val);
8242 /* ??? Combine likes to put non-volatile mem extractions in QImode
8243 no matter the size of the test. So find a mode that works. */
8244 if (! MEM_VOLATILE_P (val))
8246 mode = smallest_mode_for_size (pos + len, MODE_INT);
8247 val = adjust_address (val, mode, 0);
8250 else if (GET_CODE (val) == SUBREG
8251 && (submode = GET_MODE (SUBREG_REG (val)),
8252 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8253 && pos + len <= GET_MODE_BITSIZE (submode)
8254 && GET_MODE_CLASS (submode) == MODE_INT)
8256 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8258 val = SUBREG_REG (val);
8260 else if (mode == HImode && pos + len <= 8)
8262 /* Small HImode tests can be converted to QImode. */
8264 val = gen_lowpart (QImode, val);
8267 if (len == HOST_BITS_PER_WIDE_INT)
8270 mask = ((HOST_WIDE_INT)1 << len) - 1;
8273 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8276 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8277 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8278 ;; this is relatively important trick.
8279 ;; Do the conversion only post-reload to avoid limiting of the register class
8282 [(set (match_operand 0 "flags_reg_operand" "")
8283 (match_operator 1 "compare_operator"
8284 [(and (match_operand 2 "register_operand" "")
8285 (match_operand 3 "const_int_operand" ""))
8288 && QI_REG_P (operands[2])
8289 && GET_MODE (operands[2]) != QImode
8290 && ((ix86_match_ccmode (insn, CCZmode)
8291 && !(INTVAL (operands[3]) & ~(255 << 8)))
8292 || (ix86_match_ccmode (insn, CCNOmode)
8293 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8296 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8299 "operands[2] = gen_lowpart (SImode, operands[2]);
8300 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8303 [(set (match_operand 0 "flags_reg_operand" "")
8304 (match_operator 1 "compare_operator"
8305 [(and (match_operand 2 "nonimmediate_operand" "")
8306 (match_operand 3 "const_int_operand" ""))
8309 && GET_MODE (operands[2]) != QImode
8310 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8311 && ((ix86_match_ccmode (insn, CCZmode)
8312 && !(INTVAL (operands[3]) & ~255))
8313 || (ix86_match_ccmode (insn, CCNOmode)
8314 && !(INTVAL (operands[3]) & ~127)))"
8316 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8318 "operands[2] = gen_lowpart (QImode, operands[2]);
8319 operands[3] = gen_lowpart (QImode, operands[3]);")
8321 ;; %%% This used to optimize known byte-wide and operations to memory,
8322 ;; and sometimes to QImode registers. If this is considered useful,
8323 ;; it should be done with splitters.
8325 (define_expand "and<mode>3"
8326 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8327 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8328 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8330 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8332 (define_insn "*anddi_1"
8333 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8335 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8336 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8337 (clobber (reg:CC FLAGS_REG))]
8338 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8340 switch (get_attr_type (insn))
8344 enum machine_mode mode;
8346 gcc_assert (CONST_INT_P (operands[2]));
8347 if (INTVAL (operands[2]) == 0xff)
8351 gcc_assert (INTVAL (operands[2]) == 0xffff);
8355 operands[1] = gen_lowpart (mode, operands[1]);
8357 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8359 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8363 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8364 if (get_attr_mode (insn) == MODE_SI)
8365 return "and{l}\t{%k2, %k0|%k0, %k2}";
8367 return "and{q}\t{%2, %0|%0, %2}";
8370 [(set_attr "type" "alu,alu,alu,imovx")
8371 (set_attr "length_immediate" "*,*,*,0")
8372 (set (attr "prefix_rex")
8374 (and (eq_attr "type" "imovx")
8375 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8376 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8378 (const_string "*")))
8379 (set_attr "mode" "SI,DI,DI,SI")])
8381 (define_insn "*andsi_1"
8382 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8383 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8384 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8385 (clobber (reg:CC FLAGS_REG))]
8386 "ix86_binary_operator_ok (AND, SImode, operands)"
8388 switch (get_attr_type (insn))
8392 enum machine_mode mode;
8394 gcc_assert (CONST_INT_P (operands[2]));
8395 if (INTVAL (operands[2]) == 0xff)
8399 gcc_assert (INTVAL (operands[2]) == 0xffff);
8403 operands[1] = gen_lowpart (mode, operands[1]);
8405 return "movz{bl|x}\t{%1, %0|%0, %1}";
8407 return "movz{wl|x}\t{%1, %0|%0, %1}";
8411 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8412 return "and{l}\t{%2, %0|%0, %2}";
8415 [(set_attr "type" "alu,alu,imovx")
8416 (set (attr "prefix_rex")
8418 (and (eq_attr "type" "imovx")
8419 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8420 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8422 (const_string "*")))
8423 (set_attr "length_immediate" "*,*,0")
8424 (set_attr "mode" "SI")])
8426 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8427 (define_insn "*andsi_1_zext"
8428 [(set (match_operand:DI 0 "register_operand" "=r")
8430 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8431 (match_operand:SI 2 "general_operand" "g"))))
8432 (clobber (reg:CC FLAGS_REG))]
8433 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8434 "and{l}\t{%2, %k0|%k0, %2}"
8435 [(set_attr "type" "alu")
8436 (set_attr "mode" "SI")])
8438 (define_insn "*andhi_1"
8439 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8440 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8441 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8442 (clobber (reg:CC FLAGS_REG))]
8443 "ix86_binary_operator_ok (AND, HImode, operands)"
8445 switch (get_attr_type (insn))
8448 gcc_assert (CONST_INT_P (operands[2]));
8449 gcc_assert (INTVAL (operands[2]) == 0xff);
8450 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8453 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8455 return "and{w}\t{%2, %0|%0, %2}";
8458 [(set_attr "type" "alu,alu,imovx")
8459 (set_attr "length_immediate" "*,*,0")
8460 (set (attr "prefix_rex")
8462 (and (eq_attr "type" "imovx")
8463 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8465 (const_string "*")))
8466 (set_attr "mode" "HI,HI,SI")])
8468 ;; %%% Potential partial reg stall on alternative 2. What to do?
8469 (define_insn "*andqi_1"
8470 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8471 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8472 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8473 (clobber (reg:CC FLAGS_REG))]
8474 "ix86_binary_operator_ok (AND, QImode, operands)"
8476 and{b}\t{%2, %0|%0, %2}
8477 and{b}\t{%2, %0|%0, %2}
8478 and{l}\t{%k2, %k0|%k0, %k2}"
8479 [(set_attr "type" "alu")
8480 (set_attr "mode" "QI,QI,SI")])
8482 (define_insn "*andqi_1_slp"
8483 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8484 (and:QI (match_dup 0)
8485 (match_operand:QI 1 "general_operand" "qn,qmn")))
8486 (clobber (reg:CC FLAGS_REG))]
8487 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8488 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8489 "and{b}\t{%1, %0|%0, %1}"
8490 [(set_attr "type" "alu1")
8491 (set_attr "mode" "QI")])
8494 [(set (match_operand 0 "register_operand" "")
8496 (const_int -65536)))
8497 (clobber (reg:CC FLAGS_REG))]
8498 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8499 || optimize_function_for_size_p (cfun)"
8500 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8501 "operands[1] = gen_lowpart (HImode, operands[0]);")
8504 [(set (match_operand 0 "ext_register_operand" "")
8507 (clobber (reg:CC FLAGS_REG))]
8508 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8509 && reload_completed"
8510 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8511 "operands[1] = gen_lowpart (QImode, operands[0]);")
8514 [(set (match_operand 0 "ext_register_operand" "")
8516 (const_int -65281)))
8517 (clobber (reg:CC FLAGS_REG))]
8518 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8519 && reload_completed"
8520 [(parallel [(set (zero_extract:SI (match_dup 0)
8524 (zero_extract:SI (match_dup 0)
8527 (zero_extract:SI (match_dup 0)
8530 (clobber (reg:CC FLAGS_REG))])]
8531 "operands[0] = gen_lowpart (SImode, operands[0]);")
8533 (define_insn "*anddi_2"
8534 [(set (reg FLAGS_REG)
8537 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8538 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8540 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8541 (and:DI (match_dup 1) (match_dup 2)))]
8542 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8543 && ix86_binary_operator_ok (AND, DImode, operands)"
8545 and{l}\t{%k2, %k0|%k0, %k2}
8546 and{q}\t{%2, %0|%0, %2}
8547 and{q}\t{%2, %0|%0, %2}"
8548 [(set_attr "type" "alu")
8549 (set_attr "mode" "SI,DI,DI")])
8551 (define_insn "*andqi_2_maybe_si"
8552 [(set (reg FLAGS_REG)
8554 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8555 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8557 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8558 (and:QI (match_dup 1) (match_dup 2)))]
8559 "ix86_binary_operator_ok (AND, QImode, operands)
8560 && ix86_match_ccmode (insn,
8561 CONST_INT_P (operands[2])
8562 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8564 if (which_alternative == 2)
8566 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8567 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8568 return "and{l}\t{%2, %k0|%k0, %2}";
8570 return "and{b}\t{%2, %0|%0, %2}";
8572 [(set_attr "type" "alu")
8573 (set_attr "mode" "QI,QI,SI")])
8575 (define_insn "*and<mode>_2"
8576 [(set (reg FLAGS_REG)
8577 (compare (and:SWI124
8578 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8579 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8581 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8582 (and:SWI124 (match_dup 1) (match_dup 2)))]
8583 "ix86_match_ccmode (insn, CCNOmode)
8584 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8585 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8586 [(set_attr "type" "alu")
8587 (set_attr "mode" "<MODE>")])
8589 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8590 (define_insn "*andsi_2_zext"
8591 [(set (reg FLAGS_REG)
8593 (match_operand:SI 1 "nonimmediate_operand" "%0")
8594 (match_operand:SI 2 "general_operand" "g"))
8596 (set (match_operand:DI 0 "register_operand" "=r")
8597 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8598 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8599 && ix86_binary_operator_ok (AND, SImode, operands)"
8600 "and{l}\t{%2, %k0|%k0, %2}"
8601 [(set_attr "type" "alu")
8602 (set_attr "mode" "SI")])
8604 (define_insn "*andqi_2_slp"
8605 [(set (reg FLAGS_REG)
8607 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8608 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8610 (set (strict_low_part (match_dup 0))
8611 (and:QI (match_dup 0) (match_dup 1)))]
8612 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8613 && ix86_match_ccmode (insn, CCNOmode)
8614 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8615 "and{b}\t{%1, %0|%0, %1}"
8616 [(set_attr "type" "alu1")
8617 (set_attr "mode" "QI")])
8619 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8620 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8621 ;; for a QImode operand, which of course failed.
8622 (define_insn "andqi_ext_0"
8623 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8628 (match_operand 1 "ext_register_operand" "0")
8631 (match_operand 2 "const_int_operand" "n")))
8632 (clobber (reg:CC FLAGS_REG))]
8634 "and{b}\t{%2, %h0|%h0, %2}"
8635 [(set_attr "type" "alu")
8636 (set_attr "length_immediate" "1")
8637 (set_attr "modrm" "1")
8638 (set_attr "mode" "QI")])
8640 ;; Generated by peephole translating test to and. This shows up
8641 ;; often in fp comparisons.
8642 (define_insn "*andqi_ext_0_cc"
8643 [(set (reg FLAGS_REG)
8647 (match_operand 1 "ext_register_operand" "0")
8650 (match_operand 2 "const_int_operand" "n"))
8652 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8661 "ix86_match_ccmode (insn, CCNOmode)"
8662 "and{b}\t{%2, %h0|%h0, %2}"
8663 [(set_attr "type" "alu")
8664 (set_attr "length_immediate" "1")
8665 (set_attr "modrm" "1")
8666 (set_attr "mode" "QI")])
8668 (define_insn "*andqi_ext_1_rex64"
8669 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8674 (match_operand 1 "ext_register_operand" "0")
8678 (match_operand 2 "ext_register_operand" "Q"))))
8679 (clobber (reg:CC FLAGS_REG))]
8681 "and{b}\t{%2, %h0|%h0, %2}"
8682 [(set_attr "type" "alu")
8683 (set_attr "length_immediate" "0")
8684 (set_attr "mode" "QI")])
8686 (define_insn "*andqi_ext_1"
8687 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8692 (match_operand 1 "ext_register_operand" "0")
8696 (match_operand:QI 2 "general_operand" "Qm"))))
8697 (clobber (reg:CC FLAGS_REG))]
8699 "and{b}\t{%2, %h0|%h0, %2}"
8700 [(set_attr "type" "alu")
8701 (set_attr "length_immediate" "0")
8702 (set_attr "mode" "QI")])
8704 (define_insn "*andqi_ext_2"
8705 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8710 (match_operand 1 "ext_register_operand" "%0")
8714 (match_operand 2 "ext_register_operand" "Q")
8717 (clobber (reg:CC FLAGS_REG))]
8719 "and{b}\t{%h2, %h0|%h0, %h2}"
8720 [(set_attr "type" "alu")
8721 (set_attr "length_immediate" "0")
8722 (set_attr "mode" "QI")])
8724 ;; Convert wide AND instructions with immediate operand to shorter QImode
8725 ;; equivalents when possible.
8726 ;; Don't do the splitting with memory operands, since it introduces risk
8727 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8728 ;; for size, but that can (should?) be handled by generic code instead.
8730 [(set (match_operand 0 "register_operand" "")
8731 (and (match_operand 1 "register_operand" "")
8732 (match_operand 2 "const_int_operand" "")))
8733 (clobber (reg:CC FLAGS_REG))]
8735 && QI_REG_P (operands[0])
8736 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8737 && !(~INTVAL (operands[2]) & ~(255 << 8))
8738 && GET_MODE (operands[0]) != QImode"
8739 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8740 (and:SI (zero_extract:SI (match_dup 1)
8741 (const_int 8) (const_int 8))
8743 (clobber (reg:CC FLAGS_REG))])]
8744 "operands[0] = gen_lowpart (SImode, operands[0]);
8745 operands[1] = gen_lowpart (SImode, operands[1]);
8746 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8748 ;; Since AND can be encoded with sign extended immediate, this is only
8749 ;; profitable when 7th bit is not set.
8751 [(set (match_operand 0 "register_operand" "")
8752 (and (match_operand 1 "general_operand" "")
8753 (match_operand 2 "const_int_operand" "")))
8754 (clobber (reg:CC FLAGS_REG))]
8756 && ANY_QI_REG_P (operands[0])
8757 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8758 && !(~INTVAL (operands[2]) & ~255)
8759 && !(INTVAL (operands[2]) & 128)
8760 && GET_MODE (operands[0]) != QImode"
8761 [(parallel [(set (strict_low_part (match_dup 0))
8762 (and:QI (match_dup 1)
8764 (clobber (reg:CC FLAGS_REG))])]
8765 "operands[0] = gen_lowpart (QImode, operands[0]);
8766 operands[1] = gen_lowpart (QImode, operands[1]);
8767 operands[2] = gen_lowpart (QImode, operands[2]);")
8769 ;; Logical inclusive and exclusive OR instructions
8771 ;; %%% This used to optimize known byte-wide and operations to memory.
8772 ;; If this is considered useful, it should be done with splitters.
8774 (define_expand "<code><mode>3"
8775 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8776 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8777 (match_operand:SWIM 2 "<general_operand>" "")))]
8779 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8781 (define_insn "*<code><mode>_1"
8782 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8784 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8785 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8786 (clobber (reg:CC FLAGS_REG))]
8787 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8788 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8789 [(set_attr "type" "alu")
8790 (set_attr "mode" "<MODE>")])
8792 ;; %%% Potential partial reg stall on alternative 2. What to do?
8793 (define_insn "*<code>qi_1"
8794 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8795 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8796 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8797 (clobber (reg:CC FLAGS_REG))]
8798 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8800 <logic>{b}\t{%2, %0|%0, %2}
8801 <logic>{b}\t{%2, %0|%0, %2}
8802 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8803 [(set_attr "type" "alu")
8804 (set_attr "mode" "QI,QI,SI")])
8806 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8807 (define_insn "*<code>si_1_zext"
8808 [(set (match_operand:DI 0 "register_operand" "=r")
8810 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8811 (match_operand:SI 2 "general_operand" "g"))))
8812 (clobber (reg:CC FLAGS_REG))]
8813 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8814 "<logic>{l}\t{%2, %k0|%k0, %2}"
8815 [(set_attr "type" "alu")
8816 (set_attr "mode" "SI")])
8818 (define_insn "*<code>si_1_zext_imm"
8819 [(set (match_operand:DI 0 "register_operand" "=r")
8821 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8822 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8823 (clobber (reg:CC FLAGS_REG))]
8824 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8825 "<logic>{l}\t{%2, %k0|%k0, %2}"
8826 [(set_attr "type" "alu")
8827 (set_attr "mode" "SI")])
8829 (define_insn "*<code>qi_1_slp"
8830 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8831 (any_or:QI (match_dup 0)
8832 (match_operand:QI 1 "general_operand" "qmn,qn")))
8833 (clobber (reg:CC FLAGS_REG))]
8834 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8835 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8836 "<logic>{b}\t{%1, %0|%0, %1}"
8837 [(set_attr "type" "alu1")
8838 (set_attr "mode" "QI")])
8840 (define_insn "*<code><mode>_2"
8841 [(set (reg FLAGS_REG)
8842 (compare (any_or:SWI
8843 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8844 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8846 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8847 (any_or:SWI (match_dup 1) (match_dup 2)))]
8848 "ix86_match_ccmode (insn, CCNOmode)
8849 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8850 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8851 [(set_attr "type" "alu")
8852 (set_attr "mode" "<MODE>")])
8854 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8855 ;; ??? Special case for immediate operand is missing - it is tricky.
8856 (define_insn "*<code>si_2_zext"
8857 [(set (reg FLAGS_REG)
8858 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8859 (match_operand:SI 2 "general_operand" "g"))
8861 (set (match_operand:DI 0 "register_operand" "=r")
8862 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8863 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8864 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8865 "<logic>{l}\t{%2, %k0|%k0, %2}"
8866 [(set_attr "type" "alu")
8867 (set_attr "mode" "SI")])
8869 (define_insn "*<code>si_2_zext_imm"
8870 [(set (reg FLAGS_REG)
8872 (match_operand:SI 1 "nonimmediate_operand" "%0")
8873 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8875 (set (match_operand:DI 0 "register_operand" "=r")
8876 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8877 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8878 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8879 "<logic>{l}\t{%2, %k0|%k0, %2}"
8880 [(set_attr "type" "alu")
8881 (set_attr "mode" "SI")])
8883 (define_insn "*<code>qi_2_slp"
8884 [(set (reg FLAGS_REG)
8885 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8886 (match_operand:QI 1 "general_operand" "qmn,qn"))
8888 (set (strict_low_part (match_dup 0))
8889 (any_or:QI (match_dup 0) (match_dup 1)))]
8890 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8891 && ix86_match_ccmode (insn, CCNOmode)
8892 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8893 "<logic>{b}\t{%1, %0|%0, %1}"
8894 [(set_attr "type" "alu1")
8895 (set_attr "mode" "QI")])
8897 (define_insn "*<code><mode>_3"
8898 [(set (reg FLAGS_REG)
8899 (compare (any_or:SWI
8900 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8901 (match_operand:SWI 2 "<general_operand>" "<g>"))
8903 (clobber (match_scratch:SWI 0 "=<r>"))]
8904 "ix86_match_ccmode (insn, CCNOmode)
8905 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8906 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8907 [(set_attr "type" "alu")
8908 (set_attr "mode" "<MODE>")])
8910 (define_insn "*<code>qi_ext_0"
8911 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8916 (match_operand 1 "ext_register_operand" "0")
8919 (match_operand 2 "const_int_operand" "n")))
8920 (clobber (reg:CC FLAGS_REG))]
8921 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8922 "<logic>{b}\t{%2, %h0|%h0, %2}"
8923 [(set_attr "type" "alu")
8924 (set_attr "length_immediate" "1")
8925 (set_attr "modrm" "1")
8926 (set_attr "mode" "QI")])
8928 (define_insn "*<code>qi_ext_1_rex64"
8929 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8934 (match_operand 1 "ext_register_operand" "0")
8938 (match_operand 2 "ext_register_operand" "Q"))))
8939 (clobber (reg:CC FLAGS_REG))]
8941 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8942 "<logic>{b}\t{%2, %h0|%h0, %2}"
8943 [(set_attr "type" "alu")
8944 (set_attr "length_immediate" "0")
8945 (set_attr "mode" "QI")])
8947 (define_insn "*<code>qi_ext_1"
8948 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8953 (match_operand 1 "ext_register_operand" "0")
8957 (match_operand:QI 2 "general_operand" "Qm"))))
8958 (clobber (reg:CC FLAGS_REG))]
8960 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8961 "<logic>{b}\t{%2, %h0|%h0, %2}"
8962 [(set_attr "type" "alu")
8963 (set_attr "length_immediate" "0")
8964 (set_attr "mode" "QI")])
8966 (define_insn "*<code>qi_ext_2"
8967 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8971 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8974 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8977 (clobber (reg:CC FLAGS_REG))]
8978 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8979 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8980 [(set_attr "type" "alu")
8981 (set_attr "length_immediate" "0")
8982 (set_attr "mode" "QI")])
8985 [(set (match_operand 0 "register_operand" "")
8986 (any_or (match_operand 1 "register_operand" "")
8987 (match_operand 2 "const_int_operand" "")))
8988 (clobber (reg:CC FLAGS_REG))]
8990 && QI_REG_P (operands[0])
8991 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8992 && !(INTVAL (operands[2]) & ~(255 << 8))
8993 && GET_MODE (operands[0]) != QImode"
8994 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8995 (any_or:SI (zero_extract:SI (match_dup 1)
8996 (const_int 8) (const_int 8))
8998 (clobber (reg:CC FLAGS_REG))])]
8999 "operands[0] = gen_lowpart (SImode, operands[0]);
9000 operands[1] = gen_lowpart (SImode, operands[1]);
9001 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9003 ;; Since OR can be encoded with sign extended immediate, this is only
9004 ;; profitable when 7th bit is set.
9006 [(set (match_operand 0 "register_operand" "")
9007 (any_or (match_operand 1 "general_operand" "")
9008 (match_operand 2 "const_int_operand" "")))
9009 (clobber (reg:CC FLAGS_REG))]
9011 && ANY_QI_REG_P (operands[0])
9012 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9013 && !(INTVAL (operands[2]) & ~255)
9014 && (INTVAL (operands[2]) & 128)
9015 && GET_MODE (operands[0]) != QImode"
9016 [(parallel [(set (strict_low_part (match_dup 0))
9017 (any_or:QI (match_dup 1)
9019 (clobber (reg:CC FLAGS_REG))])]
9020 "operands[0] = gen_lowpart (QImode, operands[0]);
9021 operands[1] = gen_lowpart (QImode, operands[1]);
9022 operands[2] = gen_lowpart (QImode, operands[2]);")
9024 (define_expand "xorqi_cc_ext_1"
9026 (set (reg:CCNO FLAGS_REG)
9030 (match_operand 1 "ext_register_operand" "")
9033 (match_operand:QI 2 "general_operand" ""))
9035 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9047 (define_insn "*xorqi_cc_ext_1_rex64"
9048 [(set (reg FLAGS_REG)
9052 (match_operand 1 "ext_register_operand" "0")
9055 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9057 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9066 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9067 "xor{b}\t{%2, %h0|%h0, %2}"
9068 [(set_attr "type" "alu")
9069 (set_attr "modrm" "1")
9070 (set_attr "mode" "QI")])
9072 (define_insn "*xorqi_cc_ext_1"
9073 [(set (reg FLAGS_REG)
9077 (match_operand 1 "ext_register_operand" "0")
9080 (match_operand:QI 2 "general_operand" "qmn"))
9082 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9091 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9092 "xor{b}\t{%2, %h0|%h0, %2}"
9093 [(set_attr "type" "alu")
9094 (set_attr "modrm" "1")
9095 (set_attr "mode" "QI")])
9097 ;; Negation instructions
9099 (define_expand "neg<mode>2"
9100 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9101 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9103 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9105 (define_insn_and_split "*neg<dwi>2_doubleword"
9106 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9107 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9108 (clobber (reg:CC FLAGS_REG))]
9109 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9113 [(set (reg:CCZ FLAGS_REG)
9114 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9115 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9118 (plus:DWIH (match_dup 3)
9119 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9121 (clobber (reg:CC FLAGS_REG))])
9124 (neg:DWIH (match_dup 2)))
9125 (clobber (reg:CC FLAGS_REG))])]
9126 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9128 (define_insn "*neg<mode>2_1"
9129 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9130 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9131 (clobber (reg:CC FLAGS_REG))]
9132 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9133 "neg{<imodesuffix>}\t%0"
9134 [(set_attr "type" "negnot")
9135 (set_attr "mode" "<MODE>")])
9137 ;; Combine is quite creative about this pattern.
9138 (define_insn "*negsi2_1_zext"
9139 [(set (match_operand:DI 0 "register_operand" "=r")
9141 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9144 (clobber (reg:CC FLAGS_REG))]
9145 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9147 [(set_attr "type" "negnot")
9148 (set_attr "mode" "SI")])
9150 ;; The problem with neg is that it does not perform (compare x 0),
9151 ;; it really performs (compare 0 x), which leaves us with the zero
9152 ;; flag being the only useful item.
9154 (define_insn "*neg<mode>2_cmpz"
9155 [(set (reg:CCZ FLAGS_REG)
9157 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9159 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9160 (neg:SWI (match_dup 1)))]
9161 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9162 "neg{<imodesuffix>}\t%0"
9163 [(set_attr "type" "negnot")
9164 (set_attr "mode" "<MODE>")])
9166 (define_insn "*negsi2_cmpz_zext"
9167 [(set (reg:CCZ FLAGS_REG)
9171 (match_operand:DI 1 "register_operand" "0")
9175 (set (match_operand:DI 0 "register_operand" "=r")
9176 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9179 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9181 [(set_attr "type" "negnot")
9182 (set_attr "mode" "SI")])
9184 ;; Changing of sign for FP values is doable using integer unit too.
9186 (define_expand "<code><mode>2"
9187 [(set (match_operand:X87MODEF 0 "register_operand" "")
9188 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9189 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9190 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9192 (define_insn "*absneg<mode>2_mixed"
9193 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9194 (match_operator:MODEF 3 "absneg_operator"
9195 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9196 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9197 (clobber (reg:CC FLAGS_REG))]
9198 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9201 (define_insn "*absneg<mode>2_sse"
9202 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9203 (match_operator:MODEF 3 "absneg_operator"
9204 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9205 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9206 (clobber (reg:CC FLAGS_REG))]
9207 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9210 (define_insn "*absneg<mode>2_i387"
9211 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9212 (match_operator:X87MODEF 3 "absneg_operator"
9213 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9214 (use (match_operand 2 "" ""))
9215 (clobber (reg:CC FLAGS_REG))]
9216 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9219 (define_expand "<code>tf2"
9220 [(set (match_operand:TF 0 "register_operand" "")
9221 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9223 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9225 (define_insn "*absnegtf2_sse"
9226 [(set (match_operand:TF 0 "register_operand" "=x,x")
9227 (match_operator:TF 3 "absneg_operator"
9228 [(match_operand:TF 1 "register_operand" "0,x")]))
9229 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9230 (clobber (reg:CC FLAGS_REG))]
9234 ;; Splitters for fp abs and neg.
9237 [(set (match_operand 0 "fp_register_operand" "")
9238 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9239 (use (match_operand 2 "" ""))
9240 (clobber (reg:CC FLAGS_REG))]
9242 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9245 [(set (match_operand 0 "register_operand" "")
9246 (match_operator 3 "absneg_operator"
9247 [(match_operand 1 "register_operand" "")]))
9248 (use (match_operand 2 "nonimmediate_operand" ""))
9249 (clobber (reg:CC FLAGS_REG))]
9250 "reload_completed && SSE_REG_P (operands[0])"
9251 [(set (match_dup 0) (match_dup 3))]
9253 enum machine_mode mode = GET_MODE (operands[0]);
9254 enum machine_mode vmode = GET_MODE (operands[2]);
9257 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9258 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9259 if (operands_match_p (operands[0], operands[2]))
9262 operands[1] = operands[2];
9265 if (GET_CODE (operands[3]) == ABS)
9266 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9268 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9273 [(set (match_operand:SF 0 "register_operand" "")
9274 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9275 (use (match_operand:V4SF 2 "" ""))
9276 (clobber (reg:CC FLAGS_REG))]
9278 [(parallel [(set (match_dup 0) (match_dup 1))
9279 (clobber (reg:CC FLAGS_REG))])]
9282 operands[0] = gen_lowpart (SImode, operands[0]);
9283 if (GET_CODE (operands[1]) == ABS)
9285 tmp = gen_int_mode (0x7fffffff, SImode);
9286 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9290 tmp = gen_int_mode (0x80000000, SImode);
9291 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9297 [(set (match_operand:DF 0 "register_operand" "")
9298 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9299 (use (match_operand 2 "" ""))
9300 (clobber (reg:CC FLAGS_REG))]
9302 [(parallel [(set (match_dup 0) (match_dup 1))
9303 (clobber (reg:CC FLAGS_REG))])]
9308 tmp = gen_lowpart (DImode, operands[0]);
9309 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9312 if (GET_CODE (operands[1]) == ABS)
9315 tmp = gen_rtx_NOT (DImode, tmp);
9319 operands[0] = gen_highpart (SImode, operands[0]);
9320 if (GET_CODE (operands[1]) == ABS)
9322 tmp = gen_int_mode (0x7fffffff, SImode);
9323 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9327 tmp = gen_int_mode (0x80000000, SImode);
9328 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9335 [(set (match_operand:XF 0 "register_operand" "")
9336 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9337 (use (match_operand 2 "" ""))
9338 (clobber (reg:CC FLAGS_REG))]
9340 [(parallel [(set (match_dup 0) (match_dup 1))
9341 (clobber (reg:CC FLAGS_REG))])]
9344 operands[0] = gen_rtx_REG (SImode,
9345 true_regnum (operands[0])
9346 + (TARGET_64BIT ? 1 : 2));
9347 if (GET_CODE (operands[1]) == ABS)
9349 tmp = GEN_INT (0x7fff);
9350 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9354 tmp = GEN_INT (0x8000);
9355 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9360 ;; Conditionalize these after reload. If they match before reload, we
9361 ;; lose the clobber and ability to use integer instructions.
9363 (define_insn "*<code><mode>2_1"
9364 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9365 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9367 && (reload_completed
9368 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9369 "f<absneg_mnemonic>"
9370 [(set_attr "type" "fsgn")
9371 (set_attr "mode" "<MODE>")])
9373 (define_insn "*<code>extendsfdf2"
9374 [(set (match_operand:DF 0 "register_operand" "=f")
9375 (absneg:DF (float_extend:DF
9376 (match_operand:SF 1 "register_operand" "0"))))]
9377 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9378 "f<absneg_mnemonic>"
9379 [(set_attr "type" "fsgn")
9380 (set_attr "mode" "DF")])
9382 (define_insn "*<code>extendsfxf2"
9383 [(set (match_operand:XF 0 "register_operand" "=f")
9384 (absneg:XF (float_extend:XF
9385 (match_operand:SF 1 "register_operand" "0"))))]
9387 "f<absneg_mnemonic>"
9388 [(set_attr "type" "fsgn")
9389 (set_attr "mode" "XF")])
9391 (define_insn "*<code>extenddfxf2"
9392 [(set (match_operand:XF 0 "register_operand" "=f")
9393 (absneg:XF (float_extend:XF
9394 (match_operand:DF 1 "register_operand" "0"))))]
9396 "f<absneg_mnemonic>"
9397 [(set_attr "type" "fsgn")
9398 (set_attr "mode" "XF")])
9400 ;; Copysign instructions
9402 (define_mode_iterator CSGNMODE [SF DF TF])
9403 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9405 (define_expand "copysign<mode>3"
9406 [(match_operand:CSGNMODE 0 "register_operand" "")
9407 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9408 (match_operand:CSGNMODE 2 "register_operand" "")]
9409 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9410 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9412 ix86_expand_copysign (operands);
9416 (define_insn_and_split "copysign<mode>3_const"
9417 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9419 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9420 (match_operand:CSGNMODE 2 "register_operand" "0")
9421 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9423 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9424 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9426 "&& reload_completed"
9429 ix86_split_copysign_const (operands);
9433 (define_insn "copysign<mode>3_var"
9434 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9436 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9437 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9438 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9439 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9441 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9442 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9443 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9447 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9449 [(match_operand:CSGNMODE 2 "register_operand" "")
9450 (match_operand:CSGNMODE 3 "register_operand" "")
9451 (match_operand:<CSGNVMODE> 4 "" "")
9452 (match_operand:<CSGNVMODE> 5 "" "")]
9454 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9455 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9456 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9457 && reload_completed"
9460 ix86_split_copysign_var (operands);
9464 ;; One complement instructions
9466 (define_expand "one_cmpl<mode>2"
9467 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9468 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9470 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9472 (define_insn "*one_cmpl<mode>2_1"
9473 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9474 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9475 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9476 "not{<imodesuffix>}\t%0"
9477 [(set_attr "type" "negnot")
9478 (set_attr "mode" "<MODE>")])
9480 ;; %%% Potential partial reg stall on alternative 1. What to do?
9481 (define_insn "*one_cmplqi2_1"
9482 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9483 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9484 "ix86_unary_operator_ok (NOT, QImode, operands)"
9488 [(set_attr "type" "negnot")
9489 (set_attr "mode" "QI,SI")])
9491 ;; ??? Currently never generated - xor is used instead.
9492 (define_insn "*one_cmplsi2_1_zext"
9493 [(set (match_operand:DI 0 "register_operand" "=r")
9495 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9496 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9498 [(set_attr "type" "negnot")
9499 (set_attr "mode" "SI")])
9501 (define_insn "*one_cmpl<mode>2_2"
9502 [(set (reg FLAGS_REG)
9503 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9505 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9506 (not:SWI (match_dup 1)))]
9507 "ix86_match_ccmode (insn, CCNOmode)
9508 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9510 [(set_attr "type" "alu1")
9511 (set_attr "mode" "<MODE>")])
9514 [(set (match_operand 0 "flags_reg_operand" "")
9515 (match_operator 2 "compare_operator"
9516 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9518 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9519 (not:SWI (match_dup 3)))]
9520 "ix86_match_ccmode (insn, CCNOmode)"
9521 [(parallel [(set (match_dup 0)
9522 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9525 (xor:SWI (match_dup 3) (const_int -1)))])]
9528 ;; ??? Currently never generated - xor is used instead.
9529 (define_insn "*one_cmplsi2_2_zext"
9530 [(set (reg FLAGS_REG)
9531 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9533 (set (match_operand:DI 0 "register_operand" "=r")
9534 (zero_extend:DI (not:SI (match_dup 1))))]
9535 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9536 && ix86_unary_operator_ok (NOT, SImode, operands)"
9538 [(set_attr "type" "alu1")
9539 (set_attr "mode" "SI")])
9542 [(set (match_operand 0 "flags_reg_operand" "")
9543 (match_operator 2 "compare_operator"
9544 [(not:SI (match_operand:SI 3 "register_operand" ""))
9546 (set (match_operand:DI 1 "register_operand" "")
9547 (zero_extend:DI (not:SI (match_dup 3))))]
9548 "ix86_match_ccmode (insn, CCNOmode)"
9549 [(parallel [(set (match_dup 0)
9550 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9553 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9556 ;; Shift instructions
9558 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9559 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9560 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9561 ;; from the assembler input.
9563 ;; This instruction shifts the target reg/mem as usual, but instead of
9564 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9565 ;; is a left shift double, bits are taken from the high order bits of
9566 ;; reg, else if the insn is a shift right double, bits are taken from the
9567 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9568 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9570 ;; Since sh[lr]d does not change the `reg' operand, that is done
9571 ;; separately, making all shifts emit pairs of shift double and normal
9572 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9573 ;; support a 63 bit shift, each shift where the count is in a reg expands
9574 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9576 ;; If the shift count is a constant, we need never emit more than one
9577 ;; shift pair, instead using moves and sign extension for counts greater
9580 (define_expand "ashl<mode>3"
9581 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9582 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9583 (match_operand:QI 2 "nonmemory_operand" "")))]
9585 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9587 (define_insn "*ashl<mode>3_doubleword"
9588 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9589 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9590 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9591 (clobber (reg:CC FLAGS_REG))]
9594 [(set_attr "type" "multi")])
9597 [(set (match_operand:DWI 0 "register_operand" "")
9598 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9599 (match_operand:QI 2 "nonmemory_operand" "")))
9600 (clobber (reg:CC FLAGS_REG))]
9601 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9603 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9605 ;; By default we don't ask for a scratch register, because when DWImode
9606 ;; values are manipulated, registers are already at a premium. But if
9607 ;; we have one handy, we won't turn it away.
9610 [(match_scratch:DWIH 3 "r")
9611 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9613 (match_operand:<DWI> 1 "nonmemory_operand" "")
9614 (match_operand:QI 2 "nonmemory_operand" "")))
9615 (clobber (reg:CC FLAGS_REG))])
9619 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9621 (define_insn "x86_64_shld"
9622 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9623 (ior:DI (ashift:DI (match_dup 0)
9624 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9625 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9626 (minus:QI (const_int 64) (match_dup 2)))))
9627 (clobber (reg:CC FLAGS_REG))]
9629 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9630 [(set_attr "type" "ishift")
9631 (set_attr "prefix_0f" "1")
9632 (set_attr "mode" "DI")
9633 (set_attr "athlon_decode" "vector")
9634 (set_attr "amdfam10_decode" "vector")])
9636 (define_insn "x86_shld"
9637 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9638 (ior:SI (ashift:SI (match_dup 0)
9639 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9640 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9641 (minus:QI (const_int 32) (match_dup 2)))))
9642 (clobber (reg:CC FLAGS_REG))]
9644 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9645 [(set_attr "type" "ishift")
9646 (set_attr "prefix_0f" "1")
9647 (set_attr "mode" "SI")
9648 (set_attr "pent_pair" "np")
9649 (set_attr "athlon_decode" "vector")
9650 (set_attr "amdfam10_decode" "vector")])
9652 (define_expand "x86_shift<mode>_adj_1"
9653 [(set (reg:CCZ FLAGS_REG)
9654 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9657 (set (match_operand:SWI48 0 "register_operand" "")
9658 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9659 (match_operand:SWI48 1 "register_operand" "")
9662 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9663 (match_operand:SWI48 3 "register_operand" "r")
9666 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9668 (define_expand "x86_shift<mode>_adj_2"
9669 [(use (match_operand:SWI48 0 "register_operand" ""))
9670 (use (match_operand:SWI48 1 "register_operand" ""))
9671 (use (match_operand:QI 2 "register_operand" ""))]
9674 rtx label = gen_label_rtx ();
9677 emit_insn (gen_testqi_ccz_1 (operands[2],
9678 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9680 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9681 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9682 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9683 gen_rtx_LABEL_REF (VOIDmode, label),
9685 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9686 JUMP_LABEL (tmp) = label;
9688 emit_move_insn (operands[0], operands[1]);
9689 ix86_expand_clear (operands[1]);
9692 LABEL_NUSES (label) = 1;
9697 (define_insn "*ashl<mode>3_1"
9698 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9699 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9700 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9701 (clobber (reg:CC FLAGS_REG))]
9702 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9704 switch (get_attr_type (insn))
9710 gcc_assert (operands[2] == const1_rtx);
9711 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9712 return "add{<imodesuffix>}\t%0, %0";
9715 if (operands[2] == const1_rtx
9716 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9717 return "sal{<imodesuffix>}\t%0";
9719 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9723 (cond [(eq_attr "alternative" "1")
9724 (const_string "lea")
9725 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9727 (match_operand 0 "register_operand" ""))
9728 (match_operand 2 "const1_operand" ""))
9729 (const_string "alu")
9731 (const_string "ishift")))
9732 (set (attr "length_immediate")
9734 (ior (eq_attr "type" "alu")
9735 (and (eq_attr "type" "ishift")
9736 (and (match_operand 2 "const1_operand" "")
9737 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9740 (const_string "*")))
9741 (set_attr "mode" "<MODE>")])
9743 (define_insn "*ashlsi3_1_zext"
9744 [(set (match_operand:DI 0 "register_operand" "=r,r")
9746 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9747 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9748 (clobber (reg:CC FLAGS_REG))]
9749 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9751 switch (get_attr_type (insn))
9757 gcc_assert (operands[2] == const1_rtx);
9758 return "add{l}\t%k0, %k0";
9761 if (operands[2] == const1_rtx
9762 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9763 return "sal{l}\t%k0";
9765 return "sal{l}\t{%2, %k0|%k0, %2}";
9769 (cond [(eq_attr "alternative" "1")
9770 (const_string "lea")
9771 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9773 (match_operand 2 "const1_operand" ""))
9774 (const_string "alu")
9776 (const_string "ishift")))
9777 (set (attr "length_immediate")
9779 (ior (eq_attr "type" "alu")
9780 (and (eq_attr "type" "ishift")
9781 (and (match_operand 2 "const1_operand" "")
9782 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9785 (const_string "*")))
9786 (set_attr "mode" "SI")])
9788 (define_insn "*ashlhi3_1"
9789 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9790 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9791 (match_operand:QI 2 "nonmemory_operand" "cI")))
9792 (clobber (reg:CC FLAGS_REG))]
9793 "TARGET_PARTIAL_REG_STALL
9794 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9796 switch (get_attr_type (insn))
9799 gcc_assert (operands[2] == const1_rtx);
9800 return "add{w}\t%0, %0";
9803 if (operands[2] == const1_rtx
9804 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9805 return "sal{w}\t%0";
9807 return "sal{w}\t{%2, %0|%0, %2}";
9811 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9813 (match_operand 0 "register_operand" ""))
9814 (match_operand 2 "const1_operand" ""))
9815 (const_string "alu")
9817 (const_string "ishift")))
9818 (set (attr "length_immediate")
9820 (ior (eq_attr "type" "alu")
9821 (and (eq_attr "type" "ishift")
9822 (and (match_operand 2 "const1_operand" "")
9823 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9826 (const_string "*")))
9827 (set_attr "mode" "HI")])
9829 (define_insn "*ashlhi3_1_lea"
9830 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9831 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9832 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9833 (clobber (reg:CC FLAGS_REG))]
9834 "!TARGET_PARTIAL_REG_STALL
9835 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9837 switch (get_attr_type (insn))
9843 gcc_assert (operands[2] == const1_rtx);
9844 return "add{w}\t%0, %0";
9847 if (operands[2] == const1_rtx
9848 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9849 return "sal{w}\t%0";
9851 return "sal{w}\t{%2, %0|%0, %2}";
9855 (cond [(eq_attr "alternative" "1")
9856 (const_string "lea")
9857 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9859 (match_operand 0 "register_operand" ""))
9860 (match_operand 2 "const1_operand" ""))
9861 (const_string "alu")
9863 (const_string "ishift")))
9864 (set (attr "length_immediate")
9866 (ior (eq_attr "type" "alu")
9867 (and (eq_attr "type" "ishift")
9868 (and (match_operand 2 "const1_operand" "")
9869 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9872 (const_string "*")))
9873 (set_attr "mode" "HI,SI")])
9875 (define_insn "*ashlqi3_1"
9876 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9877 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9878 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9879 (clobber (reg:CC FLAGS_REG))]
9880 "TARGET_PARTIAL_REG_STALL
9881 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9883 switch (get_attr_type (insn))
9886 gcc_assert (operands[2] == const1_rtx);
9887 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9888 return "add{l}\t%k0, %k0";
9890 return "add{b}\t%0, %0";
9893 if (operands[2] == const1_rtx
9894 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9896 if (get_attr_mode (insn) == MODE_SI)
9897 return "sal{l}\t%k0";
9899 return "sal{b}\t%0";
9903 if (get_attr_mode (insn) == MODE_SI)
9904 return "sal{l}\t{%2, %k0|%k0, %2}";
9906 return "sal{b}\t{%2, %0|%0, %2}";
9911 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9913 (match_operand 0 "register_operand" ""))
9914 (match_operand 2 "const1_operand" ""))
9915 (const_string "alu")
9917 (const_string "ishift")))
9918 (set (attr "length_immediate")
9920 (ior (eq_attr "type" "alu")
9921 (and (eq_attr "type" "ishift")
9922 (and (match_operand 2 "const1_operand" "")
9923 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9926 (const_string "*")))
9927 (set_attr "mode" "QI,SI")])
9929 ;; %%% Potential partial reg stall on alternative 2. What to do?
9930 (define_insn "*ashlqi3_1_lea"
9931 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9932 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9933 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9934 (clobber (reg:CC FLAGS_REG))]
9935 "!TARGET_PARTIAL_REG_STALL
9936 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9938 switch (get_attr_type (insn))
9944 gcc_assert (operands[2] == const1_rtx);
9945 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9946 return "add{l}\t%k0, %k0";
9948 return "add{b}\t%0, %0";
9951 if (operands[2] == const1_rtx
9952 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9954 if (get_attr_mode (insn) == MODE_SI)
9955 return "sal{l}\t%k0";
9957 return "sal{b}\t%0";
9961 if (get_attr_mode (insn) == MODE_SI)
9962 return "sal{l}\t{%2, %k0|%k0, %2}";
9964 return "sal{b}\t{%2, %0|%0, %2}";
9969 (cond [(eq_attr "alternative" "2")
9970 (const_string "lea")
9971 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9973 (match_operand 0 "register_operand" ""))
9974 (match_operand 2 "const1_operand" ""))
9975 (const_string "alu")
9977 (const_string "ishift")))
9978 (set (attr "length_immediate")
9980 (ior (eq_attr "type" "alu")
9981 (and (eq_attr "type" "ishift")
9982 (and (match_operand 2 "const1_operand" "")
9983 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9986 (const_string "*")))
9987 (set_attr "mode" "QI,SI,SI")])
9989 (define_insn "*ashlqi3_1_slp"
9990 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9991 (ashift:QI (match_dup 0)
9992 (match_operand:QI 1 "nonmemory_operand" "cI")))
9993 (clobber (reg:CC FLAGS_REG))]
9994 "(optimize_function_for_size_p (cfun)
9995 || !TARGET_PARTIAL_FLAG_REG_STALL
9996 || (operands[1] == const1_rtx
9998 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10000 switch (get_attr_type (insn))
10003 gcc_assert (operands[1] == const1_rtx);
10004 return "add{b}\t%0, %0";
10007 if (operands[1] == const1_rtx
10008 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10009 return "sal{b}\t%0";
10011 return "sal{b}\t{%1, %0|%0, %1}";
10014 [(set (attr "type")
10015 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10017 (match_operand 0 "register_operand" ""))
10018 (match_operand 1 "const1_operand" ""))
10019 (const_string "alu")
10021 (const_string "ishift1")))
10022 (set (attr "length_immediate")
10024 (ior (eq_attr "type" "alu")
10025 (and (eq_attr "type" "ishift1")
10026 (and (match_operand 1 "const1_operand" "")
10027 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10030 (const_string "*")))
10031 (set_attr "mode" "QI")])
10033 ;; Convert lea to the lea pattern to avoid flags dependency.
10035 [(set (match_operand:DI 0 "register_operand" "")
10036 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10037 (match_operand:QI 2 "const_int_operand" "")))
10038 (clobber (reg:CC FLAGS_REG))]
10039 "TARGET_64BIT && reload_completed
10040 && true_regnum (operands[0]) != true_regnum (operands[1])"
10041 [(set (match_dup 0)
10042 (mult:DI (match_dup 1)
10044 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10046 ;; Convert lea to the lea pattern to avoid flags dependency.
10048 [(set (match_operand 0 "register_operand" "")
10049 (ashift (match_operand 1 "index_register_operand" "")
10050 (match_operand:QI 2 "const_int_operand" "")))
10051 (clobber (reg:CC FLAGS_REG))]
10053 && true_regnum (operands[0]) != true_regnum (operands[1])
10054 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10058 enum machine_mode mode = GET_MODE (operands[0]);
10060 if (GET_MODE_SIZE (mode) < 4)
10061 operands[0] = gen_lowpart (SImode, operands[0]);
10063 operands[1] = gen_lowpart (Pmode, operands[1]);
10064 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10066 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10067 if (Pmode != SImode)
10068 pat = gen_rtx_SUBREG (SImode, pat, 0);
10069 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10073 ;; Rare case of shifting RSP is handled by generating move and shift
10075 [(set (match_operand 0 "register_operand" "")
10076 (ashift (match_operand 1 "register_operand" "")
10077 (match_operand:QI 2 "const_int_operand" "")))
10078 (clobber (reg:CC FLAGS_REG))]
10080 && true_regnum (operands[0]) != true_regnum (operands[1])"
10084 emit_move_insn (operands[0], operands[1]);
10085 pat = gen_rtx_SET (VOIDmode, operands[0],
10086 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10087 operands[0], operands[2]));
10088 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10089 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10093 ;; Convert lea to the lea pattern to avoid flags dependency.
10095 [(set (match_operand:DI 0 "register_operand" "")
10097 (ashift:SI (match_operand:SI 1 "register_operand" "")
10098 (match_operand:QI 2 "const_int_operand" ""))))
10099 (clobber (reg:CC FLAGS_REG))]
10100 "TARGET_64BIT && reload_completed
10101 && true_regnum (operands[0]) != true_regnum (operands[1])"
10102 [(set (match_dup 0)
10103 (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10105 operands[1] = gen_lowpart (Pmode, operands[1]);
10106 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10109 ;; This pattern can't accept a variable shift count, since shifts by
10110 ;; zero don't affect the flags. We assume that shifts by constant
10111 ;; zero are optimized away.
10112 (define_insn "*ashl<mode>3_cmp"
10113 [(set (reg FLAGS_REG)
10115 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10116 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10118 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10119 (ashift:SWI (match_dup 1) (match_dup 2)))]
10120 "(optimize_function_for_size_p (cfun)
10121 || !TARGET_PARTIAL_FLAG_REG_STALL
10122 || (operands[2] == const1_rtx
10124 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10125 && ix86_match_ccmode (insn, CCGOCmode)
10126 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10128 switch (get_attr_type (insn))
10131 gcc_assert (operands[2] == const1_rtx);
10132 return "add{<imodesuffix>}\t%0, %0";
10135 if (operands[2] == const1_rtx
10136 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10137 return "sal{<imodesuffix>}\t%0";
10139 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10142 [(set (attr "type")
10143 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10145 (match_operand 0 "register_operand" ""))
10146 (match_operand 2 "const1_operand" ""))
10147 (const_string "alu")
10149 (const_string "ishift")))
10150 (set (attr "length_immediate")
10152 (ior (eq_attr "type" "alu")
10153 (and (eq_attr "type" "ishift")
10154 (and (match_operand 2 "const1_operand" "")
10155 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10158 (const_string "*")))
10159 (set_attr "mode" "<MODE>")])
10161 (define_insn "*ashlsi3_cmp_zext"
10162 [(set (reg FLAGS_REG)
10164 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10165 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10167 (set (match_operand:DI 0 "register_operand" "=r")
10168 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10170 && (optimize_function_for_size_p (cfun)
10171 || !TARGET_PARTIAL_FLAG_REG_STALL
10172 || (operands[2] == const1_rtx
10174 || TARGET_DOUBLE_WITH_ADD)))
10175 && ix86_match_ccmode (insn, CCGOCmode)
10176 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10178 switch (get_attr_type (insn))
10181 gcc_assert (operands[2] == const1_rtx);
10182 return "add{l}\t%k0, %k0";
10185 if (operands[2] == const1_rtx
10186 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10187 return "sal{l}\t%k0";
10189 return "sal{l}\t{%2, %k0|%k0, %2}";
10192 [(set (attr "type")
10193 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10195 (match_operand 2 "const1_operand" ""))
10196 (const_string "alu")
10198 (const_string "ishift")))
10199 (set (attr "length_immediate")
10201 (ior (eq_attr "type" "alu")
10202 (and (eq_attr "type" "ishift")
10203 (and (match_operand 2 "const1_operand" "")
10204 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10207 (const_string "*")))
10208 (set_attr "mode" "SI")])
10210 (define_insn "*ashl<mode>3_cconly"
10211 [(set (reg FLAGS_REG)
10213 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10214 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10216 (clobber (match_scratch:SWI 0 "=<r>"))]
10217 "(optimize_function_for_size_p (cfun)
10218 || !TARGET_PARTIAL_FLAG_REG_STALL
10219 || (operands[2] == const1_rtx
10221 || TARGET_DOUBLE_WITH_ADD)))
10222 && ix86_match_ccmode (insn, CCGOCmode)
10223 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10225 switch (get_attr_type (insn))
10228 gcc_assert (operands[2] == const1_rtx);
10229 return "add{<imodesuffix>}\t%0, %0";
10232 if (operands[2] == const1_rtx
10233 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10234 return "sal{<imodesuffix>}\t%0";
10236 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10239 [(set (attr "type")
10240 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10242 (match_operand 0 "register_operand" ""))
10243 (match_operand 2 "const1_operand" ""))
10244 (const_string "alu")
10246 (const_string "ishift")))
10247 (set (attr "length_immediate")
10249 (ior (eq_attr "type" "alu")
10250 (and (eq_attr "type" "ishift")
10251 (and (match_operand 2 "const1_operand" "")
10252 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10255 (const_string "*")))
10256 (set_attr "mode" "<MODE>")])
10258 ;; See comment above `ashl<mode>3' about how this works.
10260 (define_expand "<shiftrt_insn><mode>3"
10261 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
10262 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
10263 (match_operand:QI 2 "nonmemory_operand" "")))]
10265 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10267 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
10268 [(set (match_operand:DWI 0 "register_operand" "=r")
10269 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10270 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10271 (clobber (reg:CC FLAGS_REG))]
10274 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10276 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10277 [(set_attr "type" "multi")])
10279 ;; By default we don't ask for a scratch register, because when DWImode
10280 ;; values are manipulated, registers are already at a premium. But if
10281 ;; we have one handy, we won't turn it away.
10284 [(match_scratch:DWIH 3 "r")
10285 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
10287 (match_operand:<DWI> 1 "register_operand" "")
10288 (match_operand:QI 2 "nonmemory_operand" "")))
10289 (clobber (reg:CC FLAGS_REG))])
10293 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
10295 (define_insn "x86_64_shrd"
10296 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10297 (ior:DI (ashiftrt:DI (match_dup 0)
10298 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10299 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10300 (minus:QI (const_int 64) (match_dup 2)))))
10301 (clobber (reg:CC FLAGS_REG))]
10303 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10304 [(set_attr "type" "ishift")
10305 (set_attr "prefix_0f" "1")
10306 (set_attr "mode" "DI")
10307 (set_attr "athlon_decode" "vector")
10308 (set_attr "amdfam10_decode" "vector")])
10310 (define_insn "x86_shrd"
10311 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10312 (ior:SI (ashiftrt:SI (match_dup 0)
10313 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10314 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10315 (minus:QI (const_int 32) (match_dup 2)))))
10316 (clobber (reg:CC FLAGS_REG))]
10318 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10319 [(set_attr "type" "ishift")
10320 (set_attr "prefix_0f" "1")
10321 (set_attr "pent_pair" "np")
10322 (set_attr "mode" "SI")])
10324 (define_insn "ashrdi3_cvt"
10325 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10326 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10327 (match_operand:QI 2 "const_int_operand" "")))
10328 (clobber (reg:CC FLAGS_REG))]
10329 "TARGET_64BIT && INTVAL (operands[2]) == 63
10330 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10331 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10334 sar{q}\t{%2, %0|%0, %2}"
10335 [(set_attr "type" "imovx,ishift")
10336 (set_attr "prefix_0f" "0,*")
10337 (set_attr "length_immediate" "0,*")
10338 (set_attr "modrm" "0,1")
10339 (set_attr "mode" "DI")])
10341 (define_insn "ashrsi3_cvt"
10342 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10343 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10344 (match_operand:QI 2 "const_int_operand" "")))
10345 (clobber (reg:CC FLAGS_REG))]
10346 "INTVAL (operands[2]) == 31
10347 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10348 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10351 sar{l}\t{%2, %0|%0, %2}"
10352 [(set_attr "type" "imovx,ishift")
10353 (set_attr "prefix_0f" "0,*")
10354 (set_attr "length_immediate" "0,*")
10355 (set_attr "modrm" "0,1")
10356 (set_attr "mode" "SI")])
10358 (define_insn "*ashrsi3_cvt_zext"
10359 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10361 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10362 (match_operand:QI 2 "const_int_operand" ""))))
10363 (clobber (reg:CC FLAGS_REG))]
10364 "TARGET_64BIT && INTVAL (operands[2]) == 31
10365 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10366 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10369 sar{l}\t{%2, %k0|%k0, %2}"
10370 [(set_attr "type" "imovx,ishift")
10371 (set_attr "prefix_0f" "0,*")
10372 (set_attr "length_immediate" "0,*")
10373 (set_attr "modrm" "0,1")
10374 (set_attr "mode" "SI")])
10376 (define_expand "x86_shift<mode>_adj_3"
10377 [(use (match_operand:SWI48 0 "register_operand" ""))
10378 (use (match_operand:SWI48 1 "register_operand" ""))
10379 (use (match_operand:QI 2 "register_operand" ""))]
10382 rtx label = gen_label_rtx ();
10385 emit_insn (gen_testqi_ccz_1 (operands[2],
10386 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10388 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10389 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10390 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10391 gen_rtx_LABEL_REF (VOIDmode, label),
10393 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10394 JUMP_LABEL (tmp) = label;
10396 emit_move_insn (operands[0], operands[1]);
10397 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10398 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10399 emit_label (label);
10400 LABEL_NUSES (label) = 1;
10405 (define_insn "*<shiftrt_insn><mode>3_1"
10406 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10407 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10408 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10409 (clobber (reg:CC FLAGS_REG))]
10410 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10412 if (operands[2] == const1_rtx
10413 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10414 return "<shiftrt>{<imodesuffix>}\t%0";
10416 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10418 [(set_attr "type" "ishift")
10419 (set (attr "length_immediate")
10421 (and (match_operand 2 "const1_operand" "")
10422 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10425 (const_string "*")))
10426 (set_attr "mode" "<MODE>")])
10428 (define_insn "*<shiftrt_insn>si3_1_zext"
10429 [(set (match_operand:DI 0 "register_operand" "=r")
10431 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10432 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10433 (clobber (reg:CC FLAGS_REG))]
10434 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10436 if (operands[2] == const1_rtx
10437 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10438 return "<shiftrt>{l}\t%k0";
10440 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10442 [(set_attr "type" "ishift")
10443 (set (attr "length_immediate")
10445 (and (match_operand 2 "const1_operand" "")
10446 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10449 (const_string "*")))
10450 (set_attr "mode" "SI")])
10452 (define_insn "*<shiftrt_insn>qi3_1_slp"
10453 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10454 (any_shiftrt:QI (match_dup 0)
10455 (match_operand:QI 1 "nonmemory_operand" "cI")))
10456 (clobber (reg:CC FLAGS_REG))]
10457 "(optimize_function_for_size_p (cfun)
10458 || !TARGET_PARTIAL_REG_STALL
10459 || (operands[1] == const1_rtx
10460 && TARGET_SHIFT1))"
10462 if (operands[1] == const1_rtx
10463 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10464 return "<shiftrt>{b}\t%0";
10466 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10468 [(set_attr "type" "ishift1")
10469 (set (attr "length_immediate")
10471 (and (match_operand 1 "const1_operand" "")
10472 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10475 (const_string "*")))
10476 (set_attr "mode" "QI")])
10478 ;; This pattern can't accept a variable shift count, since shifts by
10479 ;; zero don't affect the flags. We assume that shifts by constant
10480 ;; zero are optimized away.
10481 (define_insn "*<shiftrt_insn><mode>3_cmp"
10482 [(set (reg FLAGS_REG)
10485 (match_operand:SWI 1 "nonimmediate_operand" "0")
10486 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10488 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10489 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10490 "(optimize_function_for_size_p (cfun)
10491 || !TARGET_PARTIAL_FLAG_REG_STALL
10492 || (operands[2] == const1_rtx
10494 && ix86_match_ccmode (insn, CCGOCmode)
10495 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10497 if (operands[2] == const1_rtx
10498 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10499 return "<shiftrt>{<imodesuffix>}\t%0";
10501 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10503 [(set_attr "type" "ishift")
10504 (set (attr "length_immediate")
10506 (and (match_operand 2 "const1_operand" "")
10507 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10510 (const_string "*")))
10511 (set_attr "mode" "<MODE>")])
10513 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10514 [(set (reg FLAGS_REG)
10516 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10517 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10519 (set (match_operand:DI 0 "register_operand" "=r")
10520 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10522 && (optimize_function_for_size_p (cfun)
10523 || !TARGET_PARTIAL_FLAG_REG_STALL
10524 || (operands[2] == const1_rtx
10526 && ix86_match_ccmode (insn, CCGOCmode)
10527 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10529 if (operands[2] == const1_rtx
10530 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10531 return "<shiftrt>{l}\t%k0";
10533 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10535 [(set_attr "type" "ishift")
10536 (set (attr "length_immediate")
10538 (and (match_operand 2 "const1_operand" "")
10539 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10542 (const_string "*")))
10543 (set_attr "mode" "SI")])
10545 (define_insn "*<shiftrt_insn><mode>3_cconly"
10546 [(set (reg FLAGS_REG)
10549 (match_operand:SWI 1 "nonimmediate_operand" "0")
10550 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10552 (clobber (match_scratch:SWI 0 "=<r>"))]
10553 "(optimize_function_for_size_p (cfun)
10554 || !TARGET_PARTIAL_FLAG_REG_STALL
10555 || (operands[2] == const1_rtx
10557 && ix86_match_ccmode (insn, CCGOCmode)
10558 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10560 if (operands[2] == const1_rtx
10561 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10562 return "<shiftrt>{<imodesuffix>}\t%0";
10564 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10566 [(set_attr "type" "ishift")
10567 (set (attr "length_immediate")
10569 (and (match_operand 2 "const1_operand" "")
10570 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10573 (const_string "*")))
10574 (set_attr "mode" "<MODE>")])
10576 ;; Rotate instructions
10578 (define_expand "<rotate_insn>ti3"
10579 [(set (match_operand:TI 0 "register_operand" "")
10580 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10581 (match_operand:QI 2 "nonmemory_operand" "")))]
10584 if (const_1_to_63_operand (operands[2], VOIDmode))
10585 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10586 (operands[0], operands[1], operands[2]));
10593 (define_expand "<rotate_insn>di3"
10594 [(set (match_operand:DI 0 "shiftdi_operand" "")
10595 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10596 (match_operand:QI 2 "nonmemory_operand" "")))]
10600 ix86_expand_binary_operator (<CODE>, DImode, operands);
10601 else if (const_1_to_31_operand (operands[2], VOIDmode))
10602 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10603 (operands[0], operands[1], operands[2]));
10610 (define_expand "<rotate_insn><mode>3"
10611 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10612 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10613 (match_operand:QI 2 "nonmemory_operand" "")))]
10615 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10617 ;; Implement rotation using two double-precision
10618 ;; shift instructions and a scratch register.
10620 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10621 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10622 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10623 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10624 (clobber (reg:CC FLAGS_REG))
10625 (clobber (match_scratch:DWIH 3 "=&r"))]
10629 [(set (match_dup 3) (match_dup 4))
10631 [(set (match_dup 4)
10632 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10633 (lshiftrt:DWIH (match_dup 5)
10634 (minus:QI (match_dup 6) (match_dup 2)))))
10635 (clobber (reg:CC FLAGS_REG))])
10637 [(set (match_dup 5)
10638 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10639 (lshiftrt:DWIH (match_dup 3)
10640 (minus:QI (match_dup 6) (match_dup 2)))))
10641 (clobber (reg:CC FLAGS_REG))])]
10643 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10645 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10648 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10649 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10650 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10651 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10652 (clobber (reg:CC FLAGS_REG))
10653 (clobber (match_scratch:DWIH 3 "=&r"))]
10657 [(set (match_dup 3) (match_dup 4))
10659 [(set (match_dup 4)
10660 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10661 (ashift:DWIH (match_dup 5)
10662 (minus:QI (match_dup 6) (match_dup 2)))))
10663 (clobber (reg:CC FLAGS_REG))])
10665 [(set (match_dup 5)
10666 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10667 (ashift:DWIH (match_dup 3)
10668 (minus:QI (match_dup 6) (match_dup 2)))))
10669 (clobber (reg:CC FLAGS_REG))])]
10671 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10673 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10676 (define_insn "*<rotate_insn><mode>3_1"
10677 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10678 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10679 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10680 (clobber (reg:CC FLAGS_REG))]
10681 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10683 if (operands[2] == const1_rtx
10684 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10685 return "<rotate>{<imodesuffix>}\t%0";
10687 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10689 [(set_attr "type" "rotate")
10690 (set (attr "length_immediate")
10692 (and (match_operand 2 "const1_operand" "")
10693 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10696 (const_string "*")))
10697 (set_attr "mode" "<MODE>")])
10699 (define_insn "*<rotate_insn>si3_1_zext"
10700 [(set (match_operand:DI 0 "register_operand" "=r")
10702 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10703 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10704 (clobber (reg:CC FLAGS_REG))]
10705 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10707 if (operands[2] == const1_rtx
10708 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10709 return "<rotate>{l}\t%k0";
10711 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10713 [(set_attr "type" "rotate")
10714 (set (attr "length_immediate")
10716 (and (match_operand 2 "const1_operand" "")
10717 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10720 (const_string "*")))
10721 (set_attr "mode" "SI")])
10723 (define_insn "*<rotate_insn>qi3_1_slp"
10724 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10725 (any_rotate:QI (match_dup 0)
10726 (match_operand:QI 1 "nonmemory_operand" "cI")))
10727 (clobber (reg:CC FLAGS_REG))]
10728 "(optimize_function_for_size_p (cfun)
10729 || !TARGET_PARTIAL_REG_STALL
10730 || (operands[1] == const1_rtx
10731 && TARGET_SHIFT1))"
10733 if (operands[1] == const1_rtx
10734 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10735 return "<rotate>{b}\t%0";
10737 return "<rotate>{b}\t{%1, %0|%0, %1}";
10739 [(set_attr "type" "rotate1")
10740 (set (attr "length_immediate")
10742 (and (match_operand 1 "const1_operand" "")
10743 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10746 (const_string "*")))
10747 (set_attr "mode" "QI")])
10750 [(set (match_operand:HI 0 "register_operand" "")
10751 (any_rotate:HI (match_dup 0) (const_int 8)))
10752 (clobber (reg:CC FLAGS_REG))]
10754 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10755 [(parallel [(set (strict_low_part (match_dup 0))
10756 (bswap:HI (match_dup 0)))
10757 (clobber (reg:CC FLAGS_REG))])]
10760 ;; Bit set / bit test instructions
10762 (define_expand "extv"
10763 [(set (match_operand:SI 0 "register_operand" "")
10764 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10765 (match_operand:SI 2 "const8_operand" "")
10766 (match_operand:SI 3 "const8_operand" "")))]
10769 /* Handle extractions from %ah et al. */
10770 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10773 /* From mips.md: extract_bit_field doesn't verify that our source
10774 matches the predicate, so check it again here. */
10775 if (! ext_register_operand (operands[1], VOIDmode))
10779 (define_expand "extzv"
10780 [(set (match_operand:SI 0 "register_operand" "")
10781 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10782 (match_operand:SI 2 "const8_operand" "")
10783 (match_operand:SI 3 "const8_operand" "")))]
10786 /* Handle extractions from %ah et al. */
10787 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10790 /* From mips.md: extract_bit_field doesn't verify that our source
10791 matches the predicate, so check it again here. */
10792 if (! ext_register_operand (operands[1], VOIDmode))
10796 (define_expand "insv"
10797 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10798 (match_operand 1 "const8_operand" "")
10799 (match_operand 2 "const8_operand" ""))
10800 (match_operand 3 "register_operand" ""))]
10803 /* Handle insertions to %ah et al. */
10804 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10807 /* From mips.md: insert_bit_field doesn't verify that our source
10808 matches the predicate, so check it again here. */
10809 if (! ext_register_operand (operands[0], VOIDmode))
10813 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
10815 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10820 ;; %%% bts, btr, btc, bt.
10821 ;; In general these instructions are *slow* when applied to memory,
10822 ;; since they enforce atomic operation. When applied to registers,
10823 ;; it depends on the cpu implementation. They're never faster than
10824 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10825 ;; no point. But in 64-bit, we can't hold the relevant immediates
10826 ;; within the instruction itself, so operating on bits in the high
10827 ;; 32-bits of a register becomes easier.
10829 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10830 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10831 ;; negdf respectively, so they can never be disabled entirely.
10833 (define_insn "*btsq"
10834 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10836 (match_operand:DI 1 "const_0_to_63_operand" ""))
10838 (clobber (reg:CC FLAGS_REG))]
10839 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10840 "bts{q}\t{%1, %0|%0, %1}"
10841 [(set_attr "type" "alu1")
10842 (set_attr "prefix_0f" "1")
10843 (set_attr "mode" "DI")])
10845 (define_insn "*btrq"
10846 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10848 (match_operand:DI 1 "const_0_to_63_operand" ""))
10850 (clobber (reg:CC FLAGS_REG))]
10851 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10852 "btr{q}\t{%1, %0|%0, %1}"
10853 [(set_attr "type" "alu1")
10854 (set_attr "prefix_0f" "1")
10855 (set_attr "mode" "DI")])
10857 (define_insn "*btcq"
10858 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10860 (match_operand:DI 1 "const_0_to_63_operand" ""))
10861 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10862 (clobber (reg:CC FLAGS_REG))]
10863 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10864 "btc{q}\t{%1, %0|%0, %1}"
10865 [(set_attr "type" "alu1")
10866 (set_attr "prefix_0f" "1")
10867 (set_attr "mode" "DI")])
10869 ;; Allow Nocona to avoid these instructions if a register is available.
10872 [(match_scratch:DI 2 "r")
10873 (parallel [(set (zero_extract:DI
10874 (match_operand:DI 0 "register_operand" "")
10876 (match_operand:DI 1 "const_0_to_63_operand" ""))
10878 (clobber (reg:CC FLAGS_REG))])]
10879 "TARGET_64BIT && !TARGET_USE_BT"
10882 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10885 if (HOST_BITS_PER_WIDE_INT >= 64)
10886 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10887 else if (i < HOST_BITS_PER_WIDE_INT)
10888 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10890 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10892 op1 = immed_double_const (lo, hi, DImode);
10895 emit_move_insn (operands[2], op1);
10899 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10904 [(match_scratch:DI 2 "r")
10905 (parallel [(set (zero_extract:DI
10906 (match_operand:DI 0 "register_operand" "")
10908 (match_operand:DI 1 "const_0_to_63_operand" ""))
10910 (clobber (reg:CC FLAGS_REG))])]
10911 "TARGET_64BIT && !TARGET_USE_BT"
10914 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10917 if (HOST_BITS_PER_WIDE_INT >= 64)
10918 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10919 else if (i < HOST_BITS_PER_WIDE_INT)
10920 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10922 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10924 op1 = immed_double_const (~lo, ~hi, DImode);
10927 emit_move_insn (operands[2], op1);
10931 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10936 [(match_scratch:DI 2 "r")
10937 (parallel [(set (zero_extract:DI
10938 (match_operand:DI 0 "register_operand" "")
10940 (match_operand:DI 1 "const_0_to_63_operand" ""))
10941 (not:DI (zero_extract:DI
10942 (match_dup 0) (const_int 1) (match_dup 1))))
10943 (clobber (reg:CC FLAGS_REG))])]
10944 "TARGET_64BIT && !TARGET_USE_BT"
10947 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10950 if (HOST_BITS_PER_WIDE_INT >= 64)
10951 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10952 else if (i < HOST_BITS_PER_WIDE_INT)
10953 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10955 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10957 op1 = immed_double_const (lo, hi, DImode);
10960 emit_move_insn (operands[2], op1);
10964 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10968 (define_insn "*btdi_rex64"
10969 [(set (reg:CCC FLAGS_REG)
10972 (match_operand:DI 0 "register_operand" "r")
10974 (match_operand:DI 1 "nonmemory_operand" "rN"))
10976 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
10977 "bt{q}\t{%1, %0|%0, %1}"
10978 [(set_attr "type" "alu1")
10979 (set_attr "prefix_0f" "1")
10980 (set_attr "mode" "DI")])
10982 (define_insn "*btsi"
10983 [(set (reg:CCC FLAGS_REG)
10986 (match_operand:SI 0 "register_operand" "r")
10988 (match_operand:SI 1 "nonmemory_operand" "rN"))
10990 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10991 "bt{l}\t{%1, %0|%0, %1}"
10992 [(set_attr "type" "alu1")
10993 (set_attr "prefix_0f" "1")
10994 (set_attr "mode" "SI")])
10996 ;; Store-flag instructions.
10998 ;; For all sCOND expanders, also expand the compare or test insn that
10999 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
11001 (define_insn_and_split "*setcc_di_1"
11002 [(set (match_operand:DI 0 "register_operand" "=q")
11003 (match_operator:DI 1 "ix86_comparison_operator"
11004 [(reg FLAGS_REG) (const_int 0)]))]
11005 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11007 "&& reload_completed"
11008 [(set (match_dup 2) (match_dup 1))
11009 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11011 PUT_MODE (operands[1], QImode);
11012 operands[2] = gen_lowpart (QImode, operands[0]);
11015 (define_insn_and_split "*setcc_si_1_and"
11016 [(set (match_operand:SI 0 "register_operand" "=q")
11017 (match_operator:SI 1 "ix86_comparison_operator"
11018 [(reg FLAGS_REG) (const_int 0)]))
11019 (clobber (reg:CC FLAGS_REG))]
11020 "!TARGET_PARTIAL_REG_STALL
11021 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11023 "&& reload_completed"
11024 [(set (match_dup 2) (match_dup 1))
11025 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11026 (clobber (reg:CC FLAGS_REG))])]
11028 PUT_MODE (operands[1], QImode);
11029 operands[2] = gen_lowpart (QImode, operands[0]);
11032 (define_insn_and_split "*setcc_si_1_movzbl"
11033 [(set (match_operand:SI 0 "register_operand" "=q")
11034 (match_operator:SI 1 "ix86_comparison_operator"
11035 [(reg FLAGS_REG) (const_int 0)]))]
11036 "!TARGET_PARTIAL_REG_STALL
11037 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11039 "&& reload_completed"
11040 [(set (match_dup 2) (match_dup 1))
11041 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11043 PUT_MODE (operands[1], QImode);
11044 operands[2] = gen_lowpart (QImode, operands[0]);
11047 (define_insn "*setcc_qi"
11048 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11049 (match_operator:QI 1 "ix86_comparison_operator"
11050 [(reg FLAGS_REG) (const_int 0)]))]
11053 [(set_attr "type" "setcc")
11054 (set_attr "mode" "QI")])
11056 (define_insn "*setcc_qi_slp"
11057 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11058 (match_operator:QI 1 "ix86_comparison_operator"
11059 [(reg FLAGS_REG) (const_int 0)]))]
11062 [(set_attr "type" "setcc")
11063 (set_attr "mode" "QI")])
11065 ;; In general it is not safe to assume too much about CCmode registers,
11066 ;; so simplify-rtx stops when it sees a second one. Under certain
11067 ;; conditions this is safe on x86, so help combine not create
11074 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11075 (ne:QI (match_operator 1 "ix86_comparison_operator"
11076 [(reg FLAGS_REG) (const_int 0)])
11079 [(set (match_dup 0) (match_dup 1))]
11081 PUT_MODE (operands[1], QImode);
11085 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11086 (ne:QI (match_operator 1 "ix86_comparison_operator"
11087 [(reg FLAGS_REG) (const_int 0)])
11090 [(set (match_dup 0) (match_dup 1))]
11092 PUT_MODE (operands[1], QImode);
11096 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11097 (eq:QI (match_operator 1 "ix86_comparison_operator"
11098 [(reg FLAGS_REG) (const_int 0)])
11101 [(set (match_dup 0) (match_dup 1))]
11103 rtx new_op1 = copy_rtx (operands[1]);
11104 operands[1] = new_op1;
11105 PUT_MODE (new_op1, QImode);
11106 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11107 GET_MODE (XEXP (new_op1, 0))));
11109 /* Make sure that (a) the CCmode we have for the flags is strong
11110 enough for the reversed compare or (b) we have a valid FP compare. */
11111 if (! ix86_comparison_operator (new_op1, VOIDmode))
11116 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11117 (eq:QI (match_operator 1 "ix86_comparison_operator"
11118 [(reg FLAGS_REG) (const_int 0)])
11121 [(set (match_dup 0) (match_dup 1))]
11123 rtx new_op1 = copy_rtx (operands[1]);
11124 operands[1] = new_op1;
11125 PUT_MODE (new_op1, QImode);
11126 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11127 GET_MODE (XEXP (new_op1, 0))));
11129 /* Make sure that (a) the CCmode we have for the flags is strong
11130 enough for the reversed compare or (b) we have a valid FP compare. */
11131 if (! ix86_comparison_operator (new_op1, VOIDmode))
11135 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11136 ;; subsequent logical operations are used to imitate conditional moves.
11137 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11140 (define_insn "*avx_setcc<mode>"
11141 [(set (match_operand:MODEF 0 "register_operand" "=x")
11142 (match_operator:MODEF 1 "avx_comparison_float_operator"
11143 [(match_operand:MODEF 2 "register_operand" "x")
11144 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11146 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
11147 [(set_attr "type" "ssecmp")
11148 (set_attr "prefix" "vex")
11149 (set_attr "length_immediate" "1")
11150 (set_attr "mode" "<MODE>")])
11152 (define_insn "*sse_setcc<mode>"
11153 [(set (match_operand:MODEF 0 "register_operand" "=x")
11154 (match_operator:MODEF 1 "sse_comparison_operator"
11155 [(match_operand:MODEF 2 "register_operand" "0")
11156 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11157 "SSE_FLOAT_MODE_P (<MODE>mode)"
11158 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
11159 [(set_attr "type" "ssecmp")
11160 (set_attr "length_immediate" "1")
11161 (set_attr "mode" "<MODE>")])
11163 ;; Basic conditional jump instructions.
11164 ;; We ignore the overflow flag for signed branch instructions.
11166 (define_insn "*jcc_1"
11168 (if_then_else (match_operator 1 "ix86_comparison_operator"
11169 [(reg FLAGS_REG) (const_int 0)])
11170 (label_ref (match_operand 0 "" ""))
11174 [(set_attr "type" "ibr")
11175 (set_attr "modrm" "0")
11176 (set (attr "length")
11177 (if_then_else (and (ge (minus (match_dup 0) (pc))
11179 (lt (minus (match_dup 0) (pc))
11184 (define_insn "*jcc_2"
11186 (if_then_else (match_operator 1 "ix86_comparison_operator"
11187 [(reg FLAGS_REG) (const_int 0)])
11189 (label_ref (match_operand 0 "" ""))))]
11192 [(set_attr "type" "ibr")
11193 (set_attr "modrm" "0")
11194 (set (attr "length")
11195 (if_then_else (and (ge (minus (match_dup 0) (pc))
11197 (lt (minus (match_dup 0) (pc))
11202 ;; In general it is not safe to assume too much about CCmode registers,
11203 ;; so simplify-rtx stops when it sees a second one. Under certain
11204 ;; conditions this is safe on x86, so help combine not create
11212 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11213 [(reg FLAGS_REG) (const_int 0)])
11215 (label_ref (match_operand 1 "" ""))
11219 (if_then_else (match_dup 0)
11220 (label_ref (match_dup 1))
11223 PUT_MODE (operands[0], VOIDmode);
11228 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11229 [(reg FLAGS_REG) (const_int 0)])
11231 (label_ref (match_operand 1 "" ""))
11235 (if_then_else (match_dup 0)
11236 (label_ref (match_dup 1))
11239 rtx new_op0 = copy_rtx (operands[0]);
11240 operands[0] = new_op0;
11241 PUT_MODE (new_op0, VOIDmode);
11242 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11243 GET_MODE (XEXP (new_op0, 0))));
11245 /* Make sure that (a) the CCmode we have for the flags is strong
11246 enough for the reversed compare or (b) we have a valid FP compare. */
11247 if (! ix86_comparison_operator (new_op0, VOIDmode))
11251 ;; zero_extend in SImode is correct, since this is what combine pass
11252 ;; generates from shift insn with QImode operand. Actually, the mode of
11253 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
11254 ;; appropriate modulo of the bit offset value.
11256 (define_insn_and_split "*jcc_btdi_rex64"
11258 (if_then_else (match_operator 0 "bt_comparison_operator"
11260 (match_operand:DI 1 "register_operand" "r")
11263 (match_operand:QI 2 "register_operand" "r")))
11265 (label_ref (match_operand 3 "" ""))
11267 (clobber (reg:CC FLAGS_REG))]
11268 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
11271 [(set (reg:CCC FLAGS_REG)
11279 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11280 (label_ref (match_dup 3))
11283 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
11285 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11288 ;; avoid useless masking of bit offset operand
11289 (define_insn_and_split "*jcc_btdi_mask_rex64"
11291 (if_then_else (match_operator 0 "bt_comparison_operator"
11293 (match_operand:DI 1 "register_operand" "r")
11296 (match_operand:SI 2 "register_operand" "r")
11297 (match_operand:SI 3 "const_int_operand" "n")))])
11298 (label_ref (match_operand 4 "" ""))
11300 (clobber (reg:CC FLAGS_REG))]
11301 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
11302 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
11305 [(set (reg:CCC FLAGS_REG)
11313 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11314 (label_ref (match_dup 4))
11317 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
11319 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11322 (define_insn_and_split "*jcc_btsi"
11324 (if_then_else (match_operator 0 "bt_comparison_operator"
11326 (match_operand:SI 1 "register_operand" "r")
11329 (match_operand:QI 2 "register_operand" "r")))
11331 (label_ref (match_operand 3 "" ""))
11333 (clobber (reg:CC FLAGS_REG))]
11334 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11337 [(set (reg:CCC FLAGS_REG)
11345 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11346 (label_ref (match_dup 3))
11349 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11351 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11354 ;; avoid useless masking of bit offset operand
11355 (define_insn_and_split "*jcc_btsi_mask"
11357 (if_then_else (match_operator 0 "bt_comparison_operator"
11359 (match_operand:SI 1 "register_operand" "r")
11362 (match_operand:SI 2 "register_operand" "r")
11363 (match_operand:SI 3 "const_int_operand" "n")))])
11364 (label_ref (match_operand 4 "" ""))
11366 (clobber (reg:CC FLAGS_REG))]
11367 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11368 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11371 [(set (reg:CCC FLAGS_REG)
11379 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11380 (label_ref (match_dup 4))
11382 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11384 (define_insn_and_split "*jcc_btsi_1"
11386 (if_then_else (match_operator 0 "bt_comparison_operator"
11389 (match_operand:SI 1 "register_operand" "r")
11390 (match_operand:QI 2 "register_operand" "r"))
11393 (label_ref (match_operand 3 "" ""))
11395 (clobber (reg:CC FLAGS_REG))]
11396 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11399 [(set (reg:CCC FLAGS_REG)
11407 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11408 (label_ref (match_dup 3))
11411 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11413 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11416 ;; avoid useless masking of bit offset operand
11417 (define_insn_and_split "*jcc_btsi_mask_1"
11420 (match_operator 0 "bt_comparison_operator"
11423 (match_operand:SI 1 "register_operand" "r")
11426 (match_operand:SI 2 "register_operand" "r")
11427 (match_operand:SI 3 "const_int_operand" "n")) 0))
11430 (label_ref (match_operand 4 "" ""))
11432 (clobber (reg:CC FLAGS_REG))]
11433 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11434 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11437 [(set (reg:CCC FLAGS_REG)
11445 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11446 (label_ref (match_dup 4))
11448 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11450 ;; Define combination compare-and-branch fp compare instructions to help
11453 (define_insn "*fp_jcc_3_387"
11455 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11456 [(match_operand 1 "register_operand" "f")
11457 (match_operand 2 "nonimmediate_operand" "fm")])
11458 (label_ref (match_operand 3 "" ""))
11460 (clobber (reg:CCFP FPSR_REG))
11461 (clobber (reg:CCFP FLAGS_REG))
11462 (clobber (match_scratch:HI 4 "=a"))]
11464 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11465 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11466 && SELECT_CC_MODE (GET_CODE (operands[0]),
11467 operands[1], operands[2]) == CCFPmode
11471 (define_insn "*fp_jcc_4_387"
11473 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11474 [(match_operand 1 "register_operand" "f")
11475 (match_operand 2 "nonimmediate_operand" "fm")])
11477 (label_ref (match_operand 3 "" ""))))
11478 (clobber (reg:CCFP FPSR_REG))
11479 (clobber (reg:CCFP FLAGS_REG))
11480 (clobber (match_scratch:HI 4 "=a"))]
11482 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11483 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11484 && SELECT_CC_MODE (GET_CODE (operands[0]),
11485 operands[1], operands[2]) == CCFPmode
11489 (define_insn "*fp_jcc_5_387"
11491 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11492 [(match_operand 1 "register_operand" "f")
11493 (match_operand 2 "register_operand" "f")])
11494 (label_ref (match_operand 3 "" ""))
11496 (clobber (reg:CCFP FPSR_REG))
11497 (clobber (reg:CCFP FLAGS_REG))
11498 (clobber (match_scratch:HI 4 "=a"))]
11499 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11500 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11504 (define_insn "*fp_jcc_6_387"
11506 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11507 [(match_operand 1 "register_operand" "f")
11508 (match_operand 2 "register_operand" "f")])
11510 (label_ref (match_operand 3 "" ""))))
11511 (clobber (reg:CCFP FPSR_REG))
11512 (clobber (reg:CCFP FLAGS_REG))
11513 (clobber (match_scratch:HI 4 "=a"))]
11514 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11515 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11519 (define_insn "*fp_jcc_7_387"
11521 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11522 [(match_operand 1 "register_operand" "f")
11523 (match_operand 2 "const0_operand" "")])
11524 (label_ref (match_operand 3 "" ""))
11526 (clobber (reg:CCFP FPSR_REG))
11527 (clobber (reg:CCFP FLAGS_REG))
11528 (clobber (match_scratch:HI 4 "=a"))]
11529 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11530 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11531 && SELECT_CC_MODE (GET_CODE (operands[0]),
11532 operands[1], operands[2]) == CCFPmode
11536 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
11537 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11538 ;; with a precedence over other operators and is always put in the first
11539 ;; place. Swap condition and operands to match ficom instruction.
11541 (define_insn "*fp_jcc_8<mode>_387"
11543 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11544 [(match_operator 1 "float_operator"
11545 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11546 (match_operand 3 "register_operand" "f,f")])
11547 (label_ref (match_operand 4 "" ""))
11549 (clobber (reg:CCFP FPSR_REG))
11550 (clobber (reg:CCFP FLAGS_REG))
11551 (clobber (match_scratch:HI 5 "=a,a"))]
11552 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11553 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11554 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11555 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11561 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11562 [(match_operand 1 "register_operand" "")
11563 (match_operand 2 "nonimmediate_operand" "")])
11564 (match_operand 3 "" "")
11565 (match_operand 4 "" "")))
11566 (clobber (reg:CCFP FPSR_REG))
11567 (clobber (reg:CCFP FLAGS_REG))]
11571 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11572 operands[3], operands[4], NULL_RTX, NULL_RTX);
11578 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11579 [(match_operand 1 "register_operand" "")
11580 (match_operand 2 "general_operand" "")])
11581 (match_operand 3 "" "")
11582 (match_operand 4 "" "")))
11583 (clobber (reg:CCFP FPSR_REG))
11584 (clobber (reg:CCFP FLAGS_REG))
11585 (clobber (match_scratch:HI 5 "=a"))]
11589 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11590 operands[3], operands[4], operands[5], NULL_RTX);
11596 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11597 [(match_operator 1 "float_operator"
11598 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11599 (match_operand 3 "register_operand" "")])
11600 (match_operand 4 "" "")
11601 (match_operand 5 "" "")))
11602 (clobber (reg:CCFP FPSR_REG))
11603 (clobber (reg:CCFP FLAGS_REG))
11604 (clobber (match_scratch:HI 6 "=a"))]
11608 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11609 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11610 operands[3], operands[7],
11611 operands[4], operands[5], operands[6], NULL_RTX);
11615 ;; %%% Kill this when reload knows how to do it.
11618 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11619 [(match_operator 1 "float_operator"
11620 [(match_operand:X87MODEI12 2 "register_operand" "")])
11621 (match_operand 3 "register_operand" "")])
11622 (match_operand 4 "" "")
11623 (match_operand 5 "" "")))
11624 (clobber (reg:CCFP FPSR_REG))
11625 (clobber (reg:CCFP FLAGS_REG))
11626 (clobber (match_scratch:HI 6 "=a"))]
11630 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11631 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11632 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11633 operands[3], operands[7],
11634 operands[4], operands[5], operands[6], operands[2]);
11638 ;; Unconditional and other jump instructions
11640 (define_insn "jump"
11642 (label_ref (match_operand 0 "" "")))]
11645 [(set_attr "type" "ibr")
11646 (set (attr "length")
11647 (if_then_else (and (ge (minus (match_dup 0) (pc))
11649 (lt (minus (match_dup 0) (pc))
11653 (set_attr "modrm" "0")])
11655 (define_expand "indirect_jump"
11656 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11660 (define_insn "*indirect_jump"
11661 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11664 [(set_attr "type" "ibr")
11665 (set_attr "length_immediate" "0")])
11667 (define_expand "tablejump"
11668 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11669 (use (label_ref (match_operand 1 "" "")))])]
11672 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11673 relative. Convert the relative address to an absolute address. */
11677 enum rtx_code code;
11679 /* We can't use @GOTOFF for text labels on VxWorks;
11680 see gotoff_operand. */
11681 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11685 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11687 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11691 op1 = pic_offset_table_rtx;
11696 op0 = pic_offset_table_rtx;
11700 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11705 (define_insn "*tablejump_1"
11706 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11707 (use (label_ref (match_operand 1 "" "")))]
11710 [(set_attr "type" "ibr")
11711 (set_attr "length_immediate" "0")])
11713 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11716 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11717 (set (match_operand:QI 1 "register_operand" "")
11718 (match_operator:QI 2 "ix86_comparison_operator"
11719 [(reg FLAGS_REG) (const_int 0)]))
11720 (set (match_operand 3 "q_regs_operand" "")
11721 (zero_extend (match_dup 1)))]
11722 "(peep2_reg_dead_p (3, operands[1])
11723 || operands_match_p (operands[1], operands[3]))
11724 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11725 [(set (match_dup 4) (match_dup 0))
11726 (set (strict_low_part (match_dup 5))
11729 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11730 operands[5] = gen_lowpart (QImode, operands[3]);
11731 ix86_expand_clear (operands[3]);
11734 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11737 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11738 (set (match_operand:QI 1 "register_operand" "")
11739 (match_operator:QI 2 "ix86_comparison_operator"
11740 [(reg FLAGS_REG) (const_int 0)]))
11741 (parallel [(set (match_operand 3 "q_regs_operand" "")
11742 (zero_extend (match_dup 1)))
11743 (clobber (reg:CC FLAGS_REG))])]
11744 "(peep2_reg_dead_p (3, operands[1])
11745 || operands_match_p (operands[1], operands[3]))
11746 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11747 [(set (match_dup 4) (match_dup 0))
11748 (set (strict_low_part (match_dup 5))
11751 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11752 operands[5] = gen_lowpart (QImode, operands[3]);
11753 ix86_expand_clear (operands[3]);
11756 ;; Call instructions.
11758 ;; The predicates normally associated with named expanders are not properly
11759 ;; checked for calls. This is a bug in the generic code, but it isn't that
11760 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11762 ;; P6 processors will jump to the address after the decrement when %esp
11763 ;; is used as a call operand, so they will execute return address as a code.
11764 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11766 ;; Call subroutine returning no value.
11768 (define_expand "call_pop"
11769 [(parallel [(call (match_operand:QI 0 "" "")
11770 (match_operand:SI 1 "" ""))
11771 (set (reg:SI SP_REG)
11772 (plus:SI (reg:SI SP_REG)
11773 (match_operand:SI 3 "" "")))])]
11776 ix86_expand_call (NULL, operands[0], operands[1],
11777 operands[2], operands[3], 0);
11781 (define_insn "*call_pop_0"
11782 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11783 (match_operand:SI 1 "" ""))
11784 (set (reg:SI SP_REG)
11785 (plus:SI (reg:SI SP_REG)
11786 (match_operand:SI 2 "immediate_operand" "")))]
11789 if (SIBLING_CALL_P (insn))
11792 return "call\t%P0";
11794 [(set_attr "type" "call")])
11796 (define_insn "*call_pop_1"
11797 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11798 (match_operand:SI 1 "" ""))
11799 (set (reg:SI SP_REG)
11800 (plus:SI (reg:SI SP_REG)
11801 (match_operand:SI 2 "immediate_operand" "i")))]
11802 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11804 if (constant_call_address_operand (operands[0], Pmode))
11805 return "call\t%P0";
11806 return "call\t%A0";
11808 [(set_attr "type" "call")])
11810 (define_insn "*sibcall_pop_1"
11811 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11812 (match_operand:SI 1 "" ""))
11813 (set (reg:SI SP_REG)
11814 (plus:SI (reg:SI SP_REG)
11815 (match_operand:SI 2 "immediate_operand" "i,i")))]
11816 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11820 [(set_attr "type" "call")])
11822 (define_expand "call"
11823 [(call (match_operand:QI 0 "" "")
11824 (match_operand 1 "" ""))
11825 (use (match_operand 2 "" ""))]
11828 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11832 (define_expand "sibcall"
11833 [(call (match_operand:QI 0 "" "")
11834 (match_operand 1 "" ""))
11835 (use (match_operand 2 "" ""))]
11838 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11842 (define_insn "*call_0"
11843 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11844 (match_operand 1 "" ""))]
11847 if (SIBLING_CALL_P (insn))
11850 return "call\t%P0";
11852 [(set_attr "type" "call")])
11854 (define_insn "*call_1"
11855 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11856 (match_operand 1 "" ""))]
11857 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11859 if (constant_call_address_operand (operands[0], Pmode))
11860 return "call\t%P0";
11861 return "call\t%A0";
11863 [(set_attr "type" "call")])
11865 (define_insn "*sibcall_1"
11866 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11867 (match_operand 1 "" ""))]
11868 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11872 [(set_attr "type" "call")])
11874 (define_insn "*call_1_rex64"
11875 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11876 (match_operand 1 "" ""))]
11877 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11878 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11880 if (constant_call_address_operand (operands[0], Pmode))
11881 return "call\t%P0";
11882 return "call\t%A0";
11884 [(set_attr "type" "call")])
11886 (define_insn "*call_1_rex64_ms_sysv"
11887 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11888 (match_operand 1 "" ""))
11889 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11890 (clobber (reg:TI XMM6_REG))
11891 (clobber (reg:TI XMM7_REG))
11892 (clobber (reg:TI XMM8_REG))
11893 (clobber (reg:TI XMM9_REG))
11894 (clobber (reg:TI XMM10_REG))
11895 (clobber (reg:TI XMM11_REG))
11896 (clobber (reg:TI XMM12_REG))
11897 (clobber (reg:TI XMM13_REG))
11898 (clobber (reg:TI XMM14_REG))
11899 (clobber (reg:TI XMM15_REG))
11900 (clobber (reg:DI SI_REG))
11901 (clobber (reg:DI DI_REG))]
11902 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11904 if (constant_call_address_operand (operands[0], Pmode))
11905 return "call\t%P0";
11906 return "call\t%A0";
11908 [(set_attr "type" "call")])
11910 (define_insn "*call_1_rex64_large"
11911 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11912 (match_operand 1 "" ""))]
11913 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11915 [(set_attr "type" "call")])
11917 (define_insn "*sibcall_1_rex64"
11918 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11919 (match_operand 1 "" ""))]
11920 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11924 [(set_attr "type" "call")])
11926 ;; Call subroutine, returning value in operand 0
11927 (define_expand "call_value_pop"
11928 [(parallel [(set (match_operand 0 "" "")
11929 (call (match_operand:QI 1 "" "")
11930 (match_operand:SI 2 "" "")))
11931 (set (reg:SI SP_REG)
11932 (plus:SI (reg:SI SP_REG)
11933 (match_operand:SI 4 "" "")))])]
11936 ix86_expand_call (operands[0], operands[1], operands[2],
11937 operands[3], operands[4], 0);
11941 (define_expand "call_value"
11942 [(set (match_operand 0 "" "")
11943 (call (match_operand:QI 1 "" "")
11944 (match_operand:SI 2 "" "")))
11945 (use (match_operand:SI 3 "" ""))]
11946 ;; Operand 3 is not used on the i386.
11949 ix86_expand_call (operands[0], operands[1], operands[2],
11950 operands[3], NULL, 0);
11954 (define_expand "sibcall_value"
11955 [(set (match_operand 0 "" "")
11956 (call (match_operand:QI 1 "" "")
11957 (match_operand:SI 2 "" "")))
11958 (use (match_operand:SI 3 "" ""))]
11959 ;; Operand 3 is not used on the i386.
11962 ix86_expand_call (operands[0], operands[1], operands[2],
11963 operands[3], NULL, 1);
11967 ;; Call subroutine returning any type.
11969 (define_expand "untyped_call"
11970 [(parallel [(call (match_operand 0 "" "")
11972 (match_operand 1 "" "")
11973 (match_operand 2 "" "")])]
11978 /* In order to give reg-stack an easier job in validating two
11979 coprocessor registers as containing a possible return value,
11980 simply pretend the untyped call returns a complex long double
11983 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11984 and should have the default ABI. */
11986 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11987 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11988 operands[0], const0_rtx,
11989 GEN_INT ((TARGET_64BIT
11990 ? (ix86_abi == SYSV_ABI
11991 ? X86_64_SSE_REGPARM_MAX
11992 : X86_64_MS_SSE_REGPARM_MAX)
11993 : X86_32_SSE_REGPARM_MAX)
11997 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11999 rtx set = XVECEXP (operands[2], 0, i);
12000 emit_move_insn (SET_DEST (set), SET_SRC (set));
12003 /* The optimizer does not know that the call sets the function value
12004 registers we stored in the result block. We avoid problems by
12005 claiming that all hard registers are used and clobbered at this
12007 emit_insn (gen_blockage ());
12012 ;; Prologue and epilogue instructions
12014 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12015 ;; all of memory. This blocks insns from being moved across this point.
12017 (define_insn "blockage"
12018 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12021 [(set_attr "length" "0")])
12023 ;; Do not schedule instructions accessing memory across this point.
12025 (define_expand "memory_blockage"
12026 [(set (match_dup 0)
12027 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12030 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12031 MEM_VOLATILE_P (operands[0]) = 1;
12034 (define_insn "*memory_blockage"
12035 [(set (match_operand:BLK 0 "" "")
12036 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12039 [(set_attr "length" "0")])
12041 ;; As USE insns aren't meaningful after reload, this is used instead
12042 ;; to prevent deleting instructions setting registers for PIC code
12043 (define_insn "prologue_use"
12044 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
12047 [(set_attr "length" "0")])
12049 ;; Insn emitted into the body of a function to return from a function.
12050 ;; This is only done if the function's epilogue is known to be simple.
12051 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12053 (define_expand "return"
12055 "ix86_can_use_return_insn_p ()"
12057 if (crtl->args.pops_args)
12059 rtx popc = GEN_INT (crtl->args.pops_args);
12060 emit_jump_insn (gen_return_pop_internal (popc));
12065 (define_insn "return_internal"
12069 [(set_attr "length" "1")
12070 (set_attr "atom_unit" "jeu")
12071 (set_attr "length_immediate" "0")
12072 (set_attr "modrm" "0")])
12074 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12075 ;; instruction Athlon and K8 have.
12077 (define_insn "return_internal_long"
12079 (unspec [(const_int 0)] UNSPEC_REP)]
12082 [(set_attr "length" "2")
12083 (set_attr "atom_unit" "jeu")
12084 (set_attr "length_immediate" "0")
12085 (set_attr "prefix_rep" "1")
12086 (set_attr "modrm" "0")])
12088 (define_insn "return_pop_internal"
12090 (use (match_operand:SI 0 "const_int_operand" ""))]
12093 [(set_attr "length" "3")
12094 (set_attr "atom_unit" "jeu")
12095 (set_attr "length_immediate" "2")
12096 (set_attr "modrm" "0")])
12098 (define_insn "return_indirect_internal"
12100 (use (match_operand:SI 0 "register_operand" "r"))]
12103 [(set_attr "type" "ibr")
12104 (set_attr "length_immediate" "0")])
12110 [(set_attr "length" "1")
12111 (set_attr "length_immediate" "0")
12112 (set_attr "modrm" "0")])
12114 (define_insn "vswapmov"
12115 [(set (match_operand:SI 0 "register_operand" "=r")
12116 (match_operand:SI 1 "register_operand" "r"))
12117 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
12119 "movl.s\t{%1, %0|%0, %1}"
12120 [(set_attr "length" "2")
12121 (set_attr "length_immediate" "0")
12122 (set_attr "modrm" "0")])
12124 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12125 ;; branch prediction penalty for the third jump in a 16-byte
12129 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
12132 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12133 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12135 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12136 The align insn is used to avoid 3 jump instructions in the row to improve
12137 branch prediction and the benefits hardly outweigh the cost of extra 8
12138 nops on the average inserted by full alignment pseudo operation. */
12142 [(set_attr "length" "16")])
12144 (define_expand "prologue"
12147 "ix86_expand_prologue (); DONE;")
12149 (define_insn "set_got"
12150 [(set (match_operand:SI 0 "register_operand" "=r")
12151 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12152 (clobber (reg:CC FLAGS_REG))]
12154 { return output_set_got (operands[0], NULL_RTX); }
12155 [(set_attr "type" "multi")
12156 (set_attr "length" "12")])
12158 (define_insn "set_got_labelled"
12159 [(set (match_operand:SI 0 "register_operand" "=r")
12160 (unspec:SI [(label_ref (match_operand 1 "" ""))]
12162 (clobber (reg:CC FLAGS_REG))]
12164 { return output_set_got (operands[0], operands[1]); }
12165 [(set_attr "type" "multi")
12166 (set_attr "length" "12")])
12168 (define_insn "set_got_rex64"
12169 [(set (match_operand:DI 0 "register_operand" "=r")
12170 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12172 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12173 [(set_attr "type" "lea")
12174 (set_attr "length_address" "4")
12175 (set_attr "mode" "DI")])
12177 (define_insn "set_rip_rex64"
12178 [(set (match_operand:DI 0 "register_operand" "=r")
12179 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
12181 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12182 [(set_attr "type" "lea")
12183 (set_attr "length_address" "4")
12184 (set_attr "mode" "DI")])
12186 (define_insn "set_got_offset_rex64"
12187 [(set (match_operand:DI 0 "register_operand" "=r")
12189 [(label_ref (match_operand 1 "" ""))]
12190 UNSPEC_SET_GOT_OFFSET))]
12192 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12193 [(set_attr "type" "imov")
12194 (set_attr "length_immediate" "0")
12195 (set_attr "length_address" "8")
12196 (set_attr "mode" "DI")])
12198 (define_expand "epilogue"
12201 "ix86_expand_epilogue (1); DONE;")
12203 (define_expand "sibcall_epilogue"
12206 "ix86_expand_epilogue (0); DONE;")
12208 (define_expand "eh_return"
12209 [(use (match_operand 0 "register_operand" ""))]
12212 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12214 /* Tricky bit: we write the address of the handler to which we will
12215 be returning into someone else's stack frame, one word below the
12216 stack address we wish to restore. */
12217 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12218 tmp = plus_constant (tmp, -UNITS_PER_WORD);
12219 tmp = gen_rtx_MEM (Pmode, tmp);
12220 emit_move_insn (tmp, ra);
12222 emit_jump_insn (gen_eh_return_internal ());
12227 (define_insn_and_split "eh_return_internal"
12231 "epilogue_completed"
12233 "ix86_expand_epilogue (2); DONE;")
12235 (define_insn "leave"
12236 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12237 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12238 (clobber (mem:BLK (scratch)))]
12241 [(set_attr "type" "leave")])
12243 (define_insn "leave_rex64"
12244 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12245 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12246 (clobber (mem:BLK (scratch)))]
12249 [(set_attr "type" "leave")])
12251 (define_expand "ffssi2"
12253 [(set (match_operand:SI 0 "register_operand" "")
12254 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
12255 (clobber (match_scratch:SI 2 ""))
12256 (clobber (reg:CC FLAGS_REG))])]
12261 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
12266 (define_expand "ffs_cmove"
12267 [(set (match_dup 2) (const_int -1))
12268 (parallel [(set (reg:CCZ FLAGS_REG)
12269 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
12271 (set (match_operand:SI 0 "register_operand" "")
12272 (ctz:SI (match_dup 1)))])
12273 (set (match_dup 0) (if_then_else:SI
12274 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12277 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12278 (clobber (reg:CC FLAGS_REG))])]
12280 "operands[2] = gen_reg_rtx (SImode);")
12282 (define_insn_and_split "*ffs_no_cmove"
12283 [(set (match_operand:SI 0 "register_operand" "=r")
12284 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12285 (clobber (match_scratch:SI 2 "=&q"))
12286 (clobber (reg:CC FLAGS_REG))]
12289 "&& reload_completed"
12290 [(parallel [(set (reg:CCZ FLAGS_REG)
12291 (compare:CCZ (match_dup 1) (const_int 0)))
12292 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12293 (set (strict_low_part (match_dup 3))
12294 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12295 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12296 (clobber (reg:CC FLAGS_REG))])
12297 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12298 (clobber (reg:CC FLAGS_REG))])
12299 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12300 (clobber (reg:CC FLAGS_REG))])]
12302 operands[3] = gen_lowpart (QImode, operands[2]);
12303 ix86_expand_clear (operands[2]);
12306 (define_insn "*ffssi_1"
12307 [(set (reg:CCZ FLAGS_REG)
12308 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
12310 (set (match_operand:SI 0 "register_operand" "=r")
12311 (ctz:SI (match_dup 1)))]
12313 "bsf{l}\t{%1, %0|%0, %1}"
12314 [(set_attr "type" "alu1")
12315 (set_attr "prefix_0f" "1")
12316 (set_attr "mode" "SI")])
12318 (define_expand "ffsdi2"
12319 [(set (match_dup 2) (const_int -1))
12320 (parallel [(set (reg:CCZ FLAGS_REG)
12321 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
12323 (set (match_operand:DI 0 "register_operand" "")
12324 (ctz:DI (match_dup 1)))])
12325 (set (match_dup 0) (if_then_else:DI
12326 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12329 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
12330 (clobber (reg:CC FLAGS_REG))])]
12332 "operands[2] = gen_reg_rtx (DImode);")
12334 (define_insn "*ffsdi_1"
12335 [(set (reg:CCZ FLAGS_REG)
12336 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
12338 (set (match_operand:DI 0 "register_operand" "=r")
12339 (ctz:DI (match_dup 1)))]
12341 "bsf{q}\t{%1, %0|%0, %1}"
12342 [(set_attr "type" "alu1")
12343 (set_attr "prefix_0f" "1")
12344 (set_attr "mode" "DI")])
12346 (define_insn "ctzsi2"
12347 [(set (match_operand:SI 0 "register_operand" "=r")
12348 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12349 (clobber (reg:CC FLAGS_REG))]
12351 "bsf{l}\t{%1, %0|%0, %1}"
12352 [(set_attr "type" "alu1")
12353 (set_attr "prefix_0f" "1")
12354 (set_attr "mode" "SI")])
12356 (define_insn "ctzdi2"
12357 [(set (match_operand:DI 0 "register_operand" "=r")
12358 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
12359 (clobber (reg:CC FLAGS_REG))]
12361 "bsf{q}\t{%1, %0|%0, %1}"
12362 [(set_attr "type" "alu1")
12363 (set_attr "prefix_0f" "1")
12364 (set_attr "mode" "DI")])
12366 (define_expand "clzsi2"
12368 [(set (match_operand:SI 0 "register_operand" "")
12369 (minus:SI (const_int 31)
12370 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
12371 (clobber (reg:CC FLAGS_REG))])
12373 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
12374 (clobber (reg:CC FLAGS_REG))])]
12379 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
12384 (define_insn "clzsi2_abm"
12385 [(set (match_operand:SI 0 "register_operand" "=r")
12386 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12387 (clobber (reg:CC FLAGS_REG))]
12389 "lzcnt{l}\t{%1, %0|%0, %1}"
12390 [(set_attr "prefix_rep" "1")
12391 (set_attr "type" "bitmanip")
12392 (set_attr "mode" "SI")])
12395 [(set (match_operand:SI 0 "register_operand" "=r")
12396 (minus:SI (const_int 31)
12397 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12398 (clobber (reg:CC FLAGS_REG))]
12400 "bsr{l}\t{%1, %0|%0, %1}"
12401 [(set_attr "type" "alu1")
12402 (set_attr "prefix_0f" "1")
12403 (set_attr "mode" "SI")])
12405 (define_insn "popcount<mode>2"
12406 [(set (match_operand:SWI248 0 "register_operand" "=r")
12408 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12409 (clobber (reg:CC FLAGS_REG))]
12413 return "popcnt\t{%1, %0|%0, %1}";
12415 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12418 [(set_attr "prefix_rep" "1")
12419 (set_attr "type" "bitmanip")
12420 (set_attr "mode" "<MODE>")])
12422 (define_insn "*popcount<mode>2_cmp"
12423 [(set (reg FLAGS_REG)
12426 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12428 (set (match_operand:SWI248 0 "register_operand" "=r")
12429 (popcount:SWI248 (match_dup 1)))]
12430 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12433 return "popcnt\t{%1, %0|%0, %1}";
12435 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12438 [(set_attr "prefix_rep" "1")
12439 (set_attr "type" "bitmanip")
12440 (set_attr "mode" "<MODE>")])
12442 (define_insn "*popcountsi2_cmp_zext"
12443 [(set (reg FLAGS_REG)
12445 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12447 (set (match_operand:DI 0 "register_operand" "=r")
12448 (zero_extend:DI(popcount:SI (match_dup 1))))]
12449 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12452 return "popcnt\t{%1, %0|%0, %1}";
12454 return "popcnt{l}\t{%1, %0|%0, %1}";
12457 [(set_attr "prefix_rep" "1")
12458 (set_attr "type" "bitmanip")
12459 (set_attr "mode" "SI")])
12461 (define_expand "bswapsi2"
12462 [(set (match_operand:SI 0 "register_operand" "")
12463 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
12466 if (!(TARGET_BSWAP || TARGET_MOVBE))
12468 rtx x = operands[0];
12470 emit_move_insn (x, operands[1]);
12471 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12472 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12473 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12478 (define_insn "*bswapsi_movbe"
12479 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
12480 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
12481 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12484 movbe\t{%1, %0|%0, %1}
12485 movbe\t{%1, %0|%0, %1}"
12486 [(set_attr "type" "*,imov,imov")
12487 (set_attr "modrm" "*,1,1")
12488 (set_attr "prefix_0f" "1")
12489 (set_attr "prefix_extra" "*,1,1")
12490 (set_attr "length" "2,*,*")
12491 (set_attr "mode" "SI")])
12493 (define_insn "*bswapsi_1"
12494 [(set (match_operand:SI 0 "register_operand" "=r")
12495 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
12498 [(set_attr "prefix_0f" "1")
12499 (set_attr "length" "2")])
12501 (define_insn "*bswaphi_lowpart_1"
12502 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12503 (bswap:HI (match_dup 0)))
12504 (clobber (reg:CC FLAGS_REG))]
12505 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12507 xchg{b}\t{%h0, %b0|%b0, %h0}
12508 rol{w}\t{$8, %0|%0, 8}"
12509 [(set_attr "length" "2,4")
12510 (set_attr "mode" "QI,HI")])
12512 (define_insn "bswaphi_lowpart"
12513 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12514 (bswap:HI (match_dup 0)))
12515 (clobber (reg:CC FLAGS_REG))]
12517 "rol{w}\t{$8, %0|%0, 8}"
12518 [(set_attr "length" "4")
12519 (set_attr "mode" "HI")])
12521 (define_expand "bswapdi2"
12522 [(set (match_operand:DI 0 "register_operand" "")
12523 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
12527 (define_insn "*bswapdi_movbe"
12528 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12529 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12530 "TARGET_64BIT && TARGET_MOVBE
12531 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12534 movbe\t{%1, %0|%0, %1}
12535 movbe\t{%1, %0|%0, %1}"
12536 [(set_attr "type" "*,imov,imov")
12537 (set_attr "modrm" "*,1,1")
12538 (set_attr "prefix_0f" "1")
12539 (set_attr "prefix_extra" "*,1,1")
12540 (set_attr "length" "3,*,*")
12541 (set_attr "mode" "DI")])
12543 (define_insn "*bswapdi_1"
12544 [(set (match_operand:DI 0 "register_operand" "=r")
12545 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
12548 [(set_attr "prefix_0f" "1")
12549 (set_attr "length" "3")])
12551 (define_expand "clzdi2"
12553 [(set (match_operand:DI 0 "register_operand" "")
12554 (minus:DI (const_int 63)
12555 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
12556 (clobber (reg:CC FLAGS_REG))])
12558 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
12559 (clobber (reg:CC FLAGS_REG))])]
12564 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
12569 (define_insn "clzdi2_abm"
12570 [(set (match_operand:DI 0 "register_operand" "=r")
12571 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
12572 (clobber (reg:CC FLAGS_REG))]
12573 "TARGET_64BIT && TARGET_ABM"
12574 "lzcnt{q}\t{%1, %0|%0, %1}"
12575 [(set_attr "prefix_rep" "1")
12576 (set_attr "type" "bitmanip")
12577 (set_attr "mode" "DI")])
12579 (define_insn "bsr_rex64"
12580 [(set (match_operand:DI 0 "register_operand" "=r")
12581 (minus:DI (const_int 63)
12582 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12583 (clobber (reg:CC FLAGS_REG))]
12585 "bsr{q}\t{%1, %0|%0, %1}"
12586 [(set_attr "type" "alu1")
12587 (set_attr "prefix_0f" "1")
12588 (set_attr "mode" "DI")])
12590 (define_expand "clzhi2"
12592 [(set (match_operand:HI 0 "register_operand" "")
12593 (minus:HI (const_int 15)
12594 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
12595 (clobber (reg:CC FLAGS_REG))])
12597 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
12598 (clobber (reg:CC FLAGS_REG))])]
12603 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
12608 (define_insn "clzhi2_abm"
12609 [(set (match_operand:HI 0 "register_operand" "=r")
12610 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
12611 (clobber (reg:CC FLAGS_REG))]
12613 "lzcnt{w}\t{%1, %0|%0, %1}"
12614 [(set_attr "prefix_rep" "1")
12615 (set_attr "type" "bitmanip")
12616 (set_attr "mode" "HI")])
12618 (define_insn "*bsrhi"
12619 [(set (match_operand:HI 0 "register_operand" "=r")
12620 (minus:HI (const_int 15)
12621 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12622 (clobber (reg:CC FLAGS_REG))]
12624 "bsr{w}\t{%1, %0|%0, %1}"
12625 [(set_attr "type" "alu1")
12626 (set_attr "prefix_0f" "1")
12627 (set_attr "mode" "HI")])
12629 (define_expand "paritydi2"
12630 [(set (match_operand:DI 0 "register_operand" "")
12631 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12634 rtx scratch = gen_reg_rtx (QImode);
12637 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12638 NULL_RTX, operands[1]));
12640 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12641 gen_rtx_REG (CCmode, FLAGS_REG),
12643 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12646 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12649 rtx tmp = gen_reg_rtx (SImode);
12651 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12652 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12657 (define_insn_and_split "paritydi2_cmp"
12658 [(set (reg:CC FLAGS_REG)
12659 (parity:CC (match_operand:DI 3 "register_operand" "0")))
12660 (clobber (match_scratch:DI 0 "=r"))
12661 (clobber (match_scratch:SI 1 "=&r"))
12662 (clobber (match_scratch:HI 2 "=Q"))]
12665 "&& reload_completed"
12667 [(set (match_dup 1)
12668 (xor:SI (match_dup 1) (match_dup 4)))
12669 (clobber (reg:CC FLAGS_REG))])
12671 [(set (reg:CC FLAGS_REG)
12672 (parity:CC (match_dup 1)))
12673 (clobber (match_dup 1))
12674 (clobber (match_dup 2))])]
12676 operands[4] = gen_lowpart (SImode, operands[3]);
12680 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12681 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12684 operands[1] = gen_highpart (SImode, operands[3]);
12687 (define_expand "paritysi2"
12688 [(set (match_operand:SI 0 "register_operand" "")
12689 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12692 rtx scratch = gen_reg_rtx (QImode);
12695 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12697 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12698 gen_rtx_REG (CCmode, FLAGS_REG),
12700 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12702 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12706 (define_insn_and_split "paritysi2_cmp"
12707 [(set (reg:CC FLAGS_REG)
12708 (parity:CC (match_operand:SI 2 "register_operand" "0")))
12709 (clobber (match_scratch:SI 0 "=r"))
12710 (clobber (match_scratch:HI 1 "=&Q"))]
12713 "&& reload_completed"
12715 [(set (match_dup 1)
12716 (xor:HI (match_dup 1) (match_dup 3)))
12717 (clobber (reg:CC FLAGS_REG))])
12719 [(set (reg:CC FLAGS_REG)
12720 (parity:CC (match_dup 1)))
12721 (clobber (match_dup 1))])]
12723 operands[3] = gen_lowpart (HImode, operands[2]);
12725 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12726 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12729 (define_insn "*parityhi2_cmp"
12730 [(set (reg:CC FLAGS_REG)
12731 (parity:CC (match_operand:HI 1 "register_operand" "0")))
12732 (clobber (match_scratch:HI 0 "=Q"))]
12734 "xor{b}\t{%h0, %b0|%b0, %h0}"
12735 [(set_attr "length" "2")
12736 (set_attr "mode" "HI")])
12738 (define_insn "*parityqi2_cmp"
12739 [(set (reg:CC FLAGS_REG)
12740 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
12743 [(set_attr "length" "2")
12744 (set_attr "mode" "QI")])
12746 ;; Thread-local storage patterns for ELF.
12748 ;; Note that these code sequences must appear exactly as shown
12749 ;; in order to allow linker relaxation.
12751 (define_insn "*tls_global_dynamic_32_gnu"
12752 [(set (match_operand:SI 0 "register_operand" "=a")
12753 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12754 (match_operand:SI 2 "tls_symbolic_operand" "")
12755 (match_operand:SI 3 "call_insn_operand" "")]
12757 (clobber (match_scratch:SI 4 "=d"))
12758 (clobber (match_scratch:SI 5 "=c"))
12759 (clobber (reg:CC FLAGS_REG))]
12760 "!TARGET_64BIT && TARGET_GNU_TLS"
12761 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12762 [(set_attr "type" "multi")
12763 (set_attr "length" "12")])
12765 (define_expand "tls_global_dynamic_32"
12766 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12769 (match_operand:SI 1 "tls_symbolic_operand" "")
12772 (clobber (match_scratch:SI 4 ""))
12773 (clobber (match_scratch:SI 5 ""))
12774 (clobber (reg:CC FLAGS_REG))])]
12778 operands[2] = pic_offset_table_rtx;
12781 operands[2] = gen_reg_rtx (Pmode);
12782 emit_insn (gen_set_got (operands[2]));
12784 if (TARGET_GNU2_TLS)
12786 emit_insn (gen_tls_dynamic_gnu2_32
12787 (operands[0], operands[1], operands[2]));
12790 operands[3] = ix86_tls_get_addr ();
12793 (define_insn "*tls_global_dynamic_64"
12794 [(set (match_operand:DI 0 "register_operand" "=a")
12795 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12796 (match_operand:DI 3 "" "")))
12797 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12800 { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
12801 [(set_attr "type" "multi")
12802 (set_attr "length" "16")])
12804 (define_expand "tls_global_dynamic_64"
12805 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12806 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12807 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12811 if (TARGET_GNU2_TLS)
12813 emit_insn (gen_tls_dynamic_gnu2_64
12814 (operands[0], operands[1]));
12817 operands[2] = ix86_tls_get_addr ();
12820 (define_insn "*tls_local_dynamic_base_32_gnu"
12821 [(set (match_operand:SI 0 "register_operand" "=a")
12822 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12823 (match_operand:SI 2 "call_insn_operand" "")]
12824 UNSPEC_TLS_LD_BASE))
12825 (clobber (match_scratch:SI 3 "=d"))
12826 (clobber (match_scratch:SI 4 "=c"))
12827 (clobber (reg:CC FLAGS_REG))]
12828 "!TARGET_64BIT && TARGET_GNU_TLS"
12829 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12830 [(set_attr "type" "multi")
12831 (set_attr "length" "11")])
12833 (define_expand "tls_local_dynamic_base_32"
12834 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12835 (unspec:SI [(match_dup 1) (match_dup 2)]
12836 UNSPEC_TLS_LD_BASE))
12837 (clobber (match_scratch:SI 3 ""))
12838 (clobber (match_scratch:SI 4 ""))
12839 (clobber (reg:CC FLAGS_REG))])]
12843 operands[1] = pic_offset_table_rtx;
12846 operands[1] = gen_reg_rtx (Pmode);
12847 emit_insn (gen_set_got (operands[1]));
12849 if (TARGET_GNU2_TLS)
12851 emit_insn (gen_tls_dynamic_gnu2_32
12852 (operands[0], ix86_tls_module_base (), operands[1]));
12855 operands[2] = ix86_tls_get_addr ();
12858 (define_insn "*tls_local_dynamic_base_64"
12859 [(set (match_operand:DI 0 "register_operand" "=a")
12860 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12861 (match_operand:DI 2 "" "")))
12862 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12864 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12865 [(set_attr "type" "multi")
12866 (set_attr "length" "12")])
12868 (define_expand "tls_local_dynamic_base_64"
12869 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12870 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12871 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12874 if (TARGET_GNU2_TLS)
12876 emit_insn (gen_tls_dynamic_gnu2_64
12877 (operands[0], ix86_tls_module_base ()));
12880 operands[1] = ix86_tls_get_addr ();
12883 ;; Local dynamic of a single variable is a lose. Show combine how
12884 ;; to convert that back to global dynamic.
12886 (define_insn_and_split "*tls_local_dynamic_32_once"
12887 [(set (match_operand:SI 0 "register_operand" "=a")
12888 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12889 (match_operand:SI 2 "call_insn_operand" "")]
12890 UNSPEC_TLS_LD_BASE)
12891 (const:SI (unspec:SI
12892 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12894 (clobber (match_scratch:SI 4 "=d"))
12895 (clobber (match_scratch:SI 5 "=c"))
12896 (clobber (reg:CC FLAGS_REG))]
12900 [(parallel [(set (match_dup 0)
12901 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12903 (clobber (match_dup 4))
12904 (clobber (match_dup 5))
12905 (clobber (reg:CC FLAGS_REG))])]
12908 ;; Load and add the thread base pointer from %gs:0.
12910 (define_insn "*load_tp_si"
12911 [(set (match_operand:SI 0 "register_operand" "=r")
12912 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12914 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12915 [(set_attr "type" "imov")
12916 (set_attr "modrm" "0")
12917 (set_attr "length" "7")
12918 (set_attr "memory" "load")
12919 (set_attr "imm_disp" "false")])
12921 (define_insn "*add_tp_si"
12922 [(set (match_operand:SI 0 "register_operand" "=r")
12923 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12924 (match_operand:SI 1 "register_operand" "0")))
12925 (clobber (reg:CC FLAGS_REG))]
12927 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12928 [(set_attr "type" "alu")
12929 (set_attr "modrm" "0")
12930 (set_attr "length" "7")
12931 (set_attr "memory" "load")
12932 (set_attr "imm_disp" "false")])
12934 (define_insn "*load_tp_di"
12935 [(set (match_operand:DI 0 "register_operand" "=r")
12936 (unspec:DI [(const_int 0)] UNSPEC_TP))]
12938 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12939 [(set_attr "type" "imov")
12940 (set_attr "modrm" "0")
12941 (set_attr "length" "7")
12942 (set_attr "memory" "load")
12943 (set_attr "imm_disp" "false")])
12945 (define_insn "*add_tp_di"
12946 [(set (match_operand:DI 0 "register_operand" "=r")
12947 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12948 (match_operand:DI 1 "register_operand" "0")))
12949 (clobber (reg:CC FLAGS_REG))]
12951 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12952 [(set_attr "type" "alu")
12953 (set_attr "modrm" "0")
12954 (set_attr "length" "7")
12955 (set_attr "memory" "load")
12956 (set_attr "imm_disp" "false")])
12958 ;; GNU2 TLS patterns can be split.
12960 (define_expand "tls_dynamic_gnu2_32"
12961 [(set (match_dup 3)
12962 (plus:SI (match_operand:SI 2 "register_operand" "")
12964 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12967 [(set (match_operand:SI 0 "register_operand" "")
12968 (unspec:SI [(match_dup 1) (match_dup 3)
12969 (match_dup 2) (reg:SI SP_REG)]
12971 (clobber (reg:CC FLAGS_REG))])]
12972 "!TARGET_64BIT && TARGET_GNU2_TLS"
12974 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12975 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12978 (define_insn "*tls_dynamic_lea_32"
12979 [(set (match_operand:SI 0 "register_operand" "=r")
12980 (plus:SI (match_operand:SI 1 "register_operand" "b")
12982 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12983 UNSPEC_TLSDESC))))]
12984 "!TARGET_64BIT && TARGET_GNU2_TLS"
12985 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12986 [(set_attr "type" "lea")
12987 (set_attr "mode" "SI")
12988 (set_attr "length" "6")
12989 (set_attr "length_address" "4")])
12991 (define_insn "*tls_dynamic_call_32"
12992 [(set (match_operand:SI 0 "register_operand" "=a")
12993 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12994 (match_operand:SI 2 "register_operand" "0")
12995 ;; we have to make sure %ebx still points to the GOT
12996 (match_operand:SI 3 "register_operand" "b")
12999 (clobber (reg:CC FLAGS_REG))]
13000 "!TARGET_64BIT && TARGET_GNU2_TLS"
13001 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13002 [(set_attr "type" "call")
13003 (set_attr "length" "2")
13004 (set_attr "length_address" "0")])
13006 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13007 [(set (match_operand:SI 0 "register_operand" "=&a")
13009 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
13010 (match_operand:SI 4 "" "")
13011 (match_operand:SI 2 "register_operand" "b")
13014 (const:SI (unspec:SI
13015 [(match_operand:SI 1 "tls_symbolic_operand" "")]
13017 (clobber (reg:CC FLAGS_REG))]
13018 "!TARGET_64BIT && TARGET_GNU2_TLS"
13021 [(set (match_dup 0) (match_dup 5))]
13023 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13024 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13027 (define_expand "tls_dynamic_gnu2_64"
13028 [(set (match_dup 2)
13029 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13032 [(set (match_operand:DI 0 "register_operand" "")
13033 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13035 (clobber (reg:CC FLAGS_REG))])]
13036 "TARGET_64BIT && TARGET_GNU2_TLS"
13038 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13039 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13042 (define_insn "*tls_dynamic_lea_64"
13043 [(set (match_operand:DI 0 "register_operand" "=r")
13044 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13046 "TARGET_64BIT && TARGET_GNU2_TLS"
13047 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
13048 [(set_attr "type" "lea")
13049 (set_attr "mode" "DI")
13050 (set_attr "length" "7")
13051 (set_attr "length_address" "4")])
13053 (define_insn "*tls_dynamic_call_64"
13054 [(set (match_operand:DI 0 "register_operand" "=a")
13055 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
13056 (match_operand:DI 2 "register_operand" "0")
13059 (clobber (reg:CC FLAGS_REG))]
13060 "TARGET_64BIT && TARGET_GNU2_TLS"
13061 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13062 [(set_attr "type" "call")
13063 (set_attr "length" "2")
13064 (set_attr "length_address" "0")])
13066 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13067 [(set (match_operand:DI 0 "register_operand" "=&a")
13069 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
13070 (match_operand:DI 3 "" "")
13073 (const:DI (unspec:DI
13074 [(match_operand:DI 1 "tls_symbolic_operand" "")]
13076 (clobber (reg:CC FLAGS_REG))]
13077 "TARGET_64BIT && TARGET_GNU2_TLS"
13080 [(set (match_dup 0) (match_dup 4))]
13082 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13083 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13088 ;; These patterns match the binary 387 instructions for addM3, subM3,
13089 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13090 ;; SFmode. The first is the normal insn, the second the same insn but
13091 ;; with one operand a conversion, and the third the same insn but with
13092 ;; the other operand a conversion. The conversion may be SFmode or
13093 ;; SImode if the target mode DFmode, but only SImode if the target mode
13096 ;; Gcc is slightly more smart about handling normal two address instructions
13097 ;; so use special patterns for add and mull.
13099 (define_insn "*fop_<mode>_comm_mixed_avx"
13100 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
13101 (match_operator:MODEF 3 "binary_fp_operator"
13102 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13103 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
13104 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13105 && COMMUTATIVE_ARITH_P (operands[3])
13106 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13107 "* return output_387_binary_op (insn, operands);"
13108 [(set (attr "type")
13109 (if_then_else (eq_attr "alternative" "1")
13110 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13111 (const_string "ssemul")
13112 (const_string "sseadd"))
13113 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13114 (const_string "fmul")
13115 (const_string "fop"))))
13116 (set_attr "prefix" "orig,maybe_vex")
13117 (set_attr "mode" "<MODE>")])
13119 (define_insn "*fop_<mode>_comm_mixed"
13120 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
13121 (match_operator:MODEF 3 "binary_fp_operator"
13122 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
13123 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
13124 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13125 && COMMUTATIVE_ARITH_P (operands[3])
13126 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13127 "* return output_387_binary_op (insn, operands);"
13128 [(set (attr "type")
13129 (if_then_else (eq_attr "alternative" "1")
13130 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13131 (const_string "ssemul")
13132 (const_string "sseadd"))
13133 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13134 (const_string "fmul")
13135 (const_string "fop"))))
13136 (set_attr "mode" "<MODE>")])
13138 (define_insn "*fop_<mode>_comm_avx"
13139 [(set (match_operand:MODEF 0 "register_operand" "=x")
13140 (match_operator:MODEF 3 "binary_fp_operator"
13141 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
13142 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13143 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13144 && COMMUTATIVE_ARITH_P (operands[3])
13145 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13146 "* return output_387_binary_op (insn, operands);"
13147 [(set (attr "type")
13148 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13149 (const_string "ssemul")
13150 (const_string "sseadd")))
13151 (set_attr "prefix" "vex")
13152 (set_attr "mode" "<MODE>")])
13154 (define_insn "*fop_<mode>_comm_sse"
13155 [(set (match_operand:MODEF 0 "register_operand" "=x")
13156 (match_operator:MODEF 3 "binary_fp_operator"
13157 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13158 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13159 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13160 && COMMUTATIVE_ARITH_P (operands[3])
13161 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13162 "* return output_387_binary_op (insn, operands);"
13163 [(set (attr "type")
13164 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13165 (const_string "ssemul")
13166 (const_string "sseadd")))
13167 (set_attr "mode" "<MODE>")])
13169 (define_insn "*fop_<mode>_comm_i387"
13170 [(set (match_operand:MODEF 0 "register_operand" "=f")
13171 (match_operator:MODEF 3 "binary_fp_operator"
13172 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13173 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13174 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13175 && COMMUTATIVE_ARITH_P (operands[3])
13176 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13177 "* return output_387_binary_op (insn, operands);"
13178 [(set (attr "type")
13179 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13180 (const_string "fmul")
13181 (const_string "fop")))
13182 (set_attr "mode" "<MODE>")])
13184 (define_insn "*fop_<mode>_1_mixed_avx"
13185 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13186 (match_operator:MODEF 3 "binary_fp_operator"
13187 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
13188 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13189 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13190 && !COMMUTATIVE_ARITH_P (operands[3])
13191 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13192 "* return output_387_binary_op (insn, operands);"
13193 [(set (attr "type")
13194 (cond [(and (eq_attr "alternative" "2")
13195 (match_operand:MODEF 3 "mult_operator" ""))
13196 (const_string "ssemul")
13197 (and (eq_attr "alternative" "2")
13198 (match_operand:MODEF 3 "div_operator" ""))
13199 (const_string "ssediv")
13200 (eq_attr "alternative" "2")
13201 (const_string "sseadd")
13202 (match_operand:MODEF 3 "mult_operator" "")
13203 (const_string "fmul")
13204 (match_operand:MODEF 3 "div_operator" "")
13205 (const_string "fdiv")
13207 (const_string "fop")))
13208 (set_attr "prefix" "orig,orig,maybe_vex")
13209 (set_attr "mode" "<MODE>")])
13211 (define_insn "*fop_<mode>_1_mixed"
13212 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13213 (match_operator:MODEF 3 "binary_fp_operator"
13214 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
13215 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13216 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13217 && !COMMUTATIVE_ARITH_P (operands[3])
13218 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13219 "* return output_387_binary_op (insn, operands);"
13220 [(set (attr "type")
13221 (cond [(and (eq_attr "alternative" "2")
13222 (match_operand:MODEF 3 "mult_operator" ""))
13223 (const_string "ssemul")
13224 (and (eq_attr "alternative" "2")
13225 (match_operand:MODEF 3 "div_operator" ""))
13226 (const_string "ssediv")
13227 (eq_attr "alternative" "2")
13228 (const_string "sseadd")
13229 (match_operand:MODEF 3 "mult_operator" "")
13230 (const_string "fmul")
13231 (match_operand:MODEF 3 "div_operator" "")
13232 (const_string "fdiv")
13234 (const_string "fop")))
13235 (set_attr "mode" "<MODE>")])
13237 (define_insn "*rcpsf2_sse"
13238 [(set (match_operand:SF 0 "register_operand" "=x")
13239 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13242 "%vrcpss\t{%1, %d0|%d0, %1}"
13243 [(set_attr "type" "sse")
13244 (set_attr "atom_sse_attr" "rcp")
13245 (set_attr "prefix" "maybe_vex")
13246 (set_attr "mode" "SF")])
13248 (define_insn "*fop_<mode>_1_avx"
13249 [(set (match_operand:MODEF 0 "register_operand" "=x")
13250 (match_operator:MODEF 3 "binary_fp_operator"
13251 [(match_operand:MODEF 1 "register_operand" "x")
13252 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13253 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13254 && !COMMUTATIVE_ARITH_P (operands[3])"
13255 "* return output_387_binary_op (insn, operands);"
13256 [(set (attr "type")
13257 (cond [(match_operand:MODEF 3 "mult_operator" "")
13258 (const_string "ssemul")
13259 (match_operand:MODEF 3 "div_operator" "")
13260 (const_string "ssediv")
13262 (const_string "sseadd")))
13263 (set_attr "prefix" "vex")
13264 (set_attr "mode" "<MODE>")])
13266 (define_insn "*fop_<mode>_1_sse"
13267 [(set (match_operand:MODEF 0 "register_operand" "=x")
13268 (match_operator:MODEF 3 "binary_fp_operator"
13269 [(match_operand:MODEF 1 "register_operand" "0")
13270 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13271 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13272 && !COMMUTATIVE_ARITH_P (operands[3])"
13273 "* return output_387_binary_op (insn, operands);"
13274 [(set (attr "type")
13275 (cond [(match_operand:MODEF 3 "mult_operator" "")
13276 (const_string "ssemul")
13277 (match_operand:MODEF 3 "div_operator" "")
13278 (const_string "ssediv")
13280 (const_string "sseadd")))
13281 (set_attr "mode" "<MODE>")])
13283 ;; This pattern is not fully shadowed by the pattern above.
13284 (define_insn "*fop_<mode>_1_i387"
13285 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13286 (match_operator:MODEF 3 "binary_fp_operator"
13287 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13288 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13289 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13290 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13291 && !COMMUTATIVE_ARITH_P (operands[3])
13292 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13293 "* return output_387_binary_op (insn, operands);"
13294 [(set (attr "type")
13295 (cond [(match_operand:MODEF 3 "mult_operator" "")
13296 (const_string "fmul")
13297 (match_operand:MODEF 3 "div_operator" "")
13298 (const_string "fdiv")
13300 (const_string "fop")))
13301 (set_attr "mode" "<MODE>")])
13303 ;; ??? Add SSE splitters for these!
13304 (define_insn "*fop_<MODEF:mode>_2_i387"
13305 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13306 (match_operator:MODEF 3 "binary_fp_operator"
13308 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13309 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13310 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13311 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13312 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13313 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13314 [(set (attr "type")
13315 (cond [(match_operand:MODEF 3 "mult_operator" "")
13316 (const_string "fmul")
13317 (match_operand:MODEF 3 "div_operator" "")
13318 (const_string "fdiv")
13320 (const_string "fop")))
13321 (set_attr "fp_int_src" "true")
13322 (set_attr "mode" "<X87MODEI12:MODE>")])
13324 (define_insn "*fop_<MODEF:mode>_3_i387"
13325 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13326 (match_operator:MODEF 3 "binary_fp_operator"
13327 [(match_operand:MODEF 1 "register_operand" "0,0")
13329 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13330 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13331 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13332 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13333 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13334 [(set (attr "type")
13335 (cond [(match_operand:MODEF 3 "mult_operator" "")
13336 (const_string "fmul")
13337 (match_operand:MODEF 3 "div_operator" "")
13338 (const_string "fdiv")
13340 (const_string "fop")))
13341 (set_attr "fp_int_src" "true")
13342 (set_attr "mode" "<MODE>")])
13344 (define_insn "*fop_df_4_i387"
13345 [(set (match_operand:DF 0 "register_operand" "=f,f")
13346 (match_operator:DF 3 "binary_fp_operator"
13348 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13349 (match_operand:DF 2 "register_operand" "0,f")]))]
13350 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13351 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13352 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13353 "* return output_387_binary_op (insn, operands);"
13354 [(set (attr "type")
13355 (cond [(match_operand:DF 3 "mult_operator" "")
13356 (const_string "fmul")
13357 (match_operand:DF 3 "div_operator" "")
13358 (const_string "fdiv")
13360 (const_string "fop")))
13361 (set_attr "mode" "SF")])
13363 (define_insn "*fop_df_5_i387"
13364 [(set (match_operand:DF 0 "register_operand" "=f,f")
13365 (match_operator:DF 3 "binary_fp_operator"
13366 [(match_operand:DF 1 "register_operand" "0,f")
13368 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13369 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13370 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13371 "* return output_387_binary_op (insn, operands);"
13372 [(set (attr "type")
13373 (cond [(match_operand:DF 3 "mult_operator" "")
13374 (const_string "fmul")
13375 (match_operand:DF 3 "div_operator" "")
13376 (const_string "fdiv")
13378 (const_string "fop")))
13379 (set_attr "mode" "SF")])
13381 (define_insn "*fop_df_6_i387"
13382 [(set (match_operand:DF 0 "register_operand" "=f,f")
13383 (match_operator:DF 3 "binary_fp_operator"
13385 (match_operand:SF 1 "register_operand" "0,f"))
13387 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13388 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13389 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13390 "* return output_387_binary_op (insn, operands);"
13391 [(set (attr "type")
13392 (cond [(match_operand:DF 3 "mult_operator" "")
13393 (const_string "fmul")
13394 (match_operand:DF 3 "div_operator" "")
13395 (const_string "fdiv")
13397 (const_string "fop")))
13398 (set_attr "mode" "SF")])
13400 (define_insn "*fop_xf_comm_i387"
13401 [(set (match_operand:XF 0 "register_operand" "=f")
13402 (match_operator:XF 3 "binary_fp_operator"
13403 [(match_operand:XF 1 "register_operand" "%0")
13404 (match_operand:XF 2 "register_operand" "f")]))]
13406 && COMMUTATIVE_ARITH_P (operands[3])"
13407 "* return output_387_binary_op (insn, operands);"
13408 [(set (attr "type")
13409 (if_then_else (match_operand:XF 3 "mult_operator" "")
13410 (const_string "fmul")
13411 (const_string "fop")))
13412 (set_attr "mode" "XF")])
13414 (define_insn "*fop_xf_1_i387"
13415 [(set (match_operand:XF 0 "register_operand" "=f,f")
13416 (match_operator:XF 3 "binary_fp_operator"
13417 [(match_operand:XF 1 "register_operand" "0,f")
13418 (match_operand:XF 2 "register_operand" "f,0")]))]
13420 && !COMMUTATIVE_ARITH_P (operands[3])"
13421 "* return output_387_binary_op (insn, operands);"
13422 [(set (attr "type")
13423 (cond [(match_operand:XF 3 "mult_operator" "")
13424 (const_string "fmul")
13425 (match_operand:XF 3 "div_operator" "")
13426 (const_string "fdiv")
13428 (const_string "fop")))
13429 (set_attr "mode" "XF")])
13431 (define_insn "*fop_xf_2_i387"
13432 [(set (match_operand:XF 0 "register_operand" "=f,f")
13433 (match_operator:XF 3 "binary_fp_operator"
13435 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13436 (match_operand:XF 2 "register_operand" "0,0")]))]
13437 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13438 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13439 [(set (attr "type")
13440 (cond [(match_operand:XF 3 "mult_operator" "")
13441 (const_string "fmul")
13442 (match_operand:XF 3 "div_operator" "")
13443 (const_string "fdiv")
13445 (const_string "fop")))
13446 (set_attr "fp_int_src" "true")
13447 (set_attr "mode" "<MODE>")])
13449 (define_insn "*fop_xf_3_i387"
13450 [(set (match_operand:XF 0 "register_operand" "=f,f")
13451 (match_operator:XF 3 "binary_fp_operator"
13452 [(match_operand:XF 1 "register_operand" "0,0")
13454 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13455 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13456 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13457 [(set (attr "type")
13458 (cond [(match_operand:XF 3 "mult_operator" "")
13459 (const_string "fmul")
13460 (match_operand:XF 3 "div_operator" "")
13461 (const_string "fdiv")
13463 (const_string "fop")))
13464 (set_attr "fp_int_src" "true")
13465 (set_attr "mode" "<MODE>")])
13467 (define_insn "*fop_xf_4_i387"
13468 [(set (match_operand:XF 0 "register_operand" "=f,f")
13469 (match_operator:XF 3 "binary_fp_operator"
13471 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13472 (match_operand:XF 2 "register_operand" "0,f")]))]
13474 "* return output_387_binary_op (insn, operands);"
13475 [(set (attr "type")
13476 (cond [(match_operand:XF 3 "mult_operator" "")
13477 (const_string "fmul")
13478 (match_operand:XF 3 "div_operator" "")
13479 (const_string "fdiv")
13481 (const_string "fop")))
13482 (set_attr "mode" "<MODE>")])
13484 (define_insn "*fop_xf_5_i387"
13485 [(set (match_operand:XF 0 "register_operand" "=f,f")
13486 (match_operator:XF 3 "binary_fp_operator"
13487 [(match_operand:XF 1 "register_operand" "0,f")
13489 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13491 "* return output_387_binary_op (insn, operands);"
13492 [(set (attr "type")
13493 (cond [(match_operand:XF 3 "mult_operator" "")
13494 (const_string "fmul")
13495 (match_operand:XF 3 "div_operator" "")
13496 (const_string "fdiv")
13498 (const_string "fop")))
13499 (set_attr "mode" "<MODE>")])
13501 (define_insn "*fop_xf_6_i387"
13502 [(set (match_operand:XF 0 "register_operand" "=f,f")
13503 (match_operator:XF 3 "binary_fp_operator"
13505 (match_operand:MODEF 1 "register_operand" "0,f"))
13507 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13509 "* return output_387_binary_op (insn, operands);"
13510 [(set (attr "type")
13511 (cond [(match_operand:XF 3 "mult_operator" "")
13512 (const_string "fmul")
13513 (match_operand:XF 3 "div_operator" "")
13514 (const_string "fdiv")
13516 (const_string "fop")))
13517 (set_attr "mode" "<MODE>")])
13520 [(set (match_operand 0 "register_operand" "")
13521 (match_operator 3 "binary_fp_operator"
13522 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13523 (match_operand 2 "register_operand" "")]))]
13525 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13526 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13529 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13530 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13531 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13532 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13533 GET_MODE (operands[3]),
13536 ix86_free_from_memory (GET_MODE (operands[1]));
13541 [(set (match_operand 0 "register_operand" "")
13542 (match_operator 3 "binary_fp_operator"
13543 [(match_operand 1 "register_operand" "")
13544 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13546 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13547 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13550 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13551 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13552 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13553 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13554 GET_MODE (operands[3]),
13557 ix86_free_from_memory (GET_MODE (operands[2]));
13561 ;; FPU special functions.
13563 ;; This pattern implements a no-op XFmode truncation for
13564 ;; all fancy i386 XFmode math functions.
13566 (define_insn "truncxf<mode>2_i387_noop_unspec"
13567 [(set (match_operand:MODEF 0 "register_operand" "=f")
13568 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13569 UNSPEC_TRUNC_NOOP))]
13570 "TARGET_USE_FANCY_MATH_387"
13571 "* return output_387_reg_move (insn, operands);"
13572 [(set_attr "type" "fmov")
13573 (set_attr "mode" "<MODE>")])
13575 (define_insn "sqrtxf2"
13576 [(set (match_operand:XF 0 "register_operand" "=f")
13577 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13578 "TARGET_USE_FANCY_MATH_387"
13580 [(set_attr "type" "fpspc")
13581 (set_attr "mode" "XF")
13582 (set_attr "athlon_decode" "direct")
13583 (set_attr "amdfam10_decode" "direct")])
13585 (define_insn "sqrt_extend<mode>xf2_i387"
13586 [(set (match_operand:XF 0 "register_operand" "=f")
13589 (match_operand:MODEF 1 "register_operand" "0"))))]
13590 "TARGET_USE_FANCY_MATH_387"
13592 [(set_attr "type" "fpspc")
13593 (set_attr "mode" "XF")
13594 (set_attr "athlon_decode" "direct")
13595 (set_attr "amdfam10_decode" "direct")])
13597 (define_insn "*rsqrtsf2_sse"
13598 [(set (match_operand:SF 0 "register_operand" "=x")
13599 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13602 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13603 [(set_attr "type" "sse")
13604 (set_attr "atom_sse_attr" "rcp")
13605 (set_attr "prefix" "maybe_vex")
13606 (set_attr "mode" "SF")])
13608 (define_expand "rsqrtsf2"
13609 [(set (match_operand:SF 0 "register_operand" "")
13610 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13614 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13618 (define_insn "*sqrt<mode>2_sse"
13619 [(set (match_operand:MODEF 0 "register_operand" "=x")
13621 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13622 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13623 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13624 [(set_attr "type" "sse")
13625 (set_attr "atom_sse_attr" "sqrt")
13626 (set_attr "prefix" "maybe_vex")
13627 (set_attr "mode" "<MODE>")
13628 (set_attr "athlon_decode" "*")
13629 (set_attr "amdfam10_decode" "*")])
13631 (define_expand "sqrt<mode>2"
13632 [(set (match_operand:MODEF 0 "register_operand" "")
13634 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13635 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13636 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13638 if (<MODE>mode == SFmode
13639 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13640 && flag_finite_math_only && !flag_trapping_math
13641 && flag_unsafe_math_optimizations)
13643 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13647 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13649 rtx op0 = gen_reg_rtx (XFmode);
13650 rtx op1 = force_reg (<MODE>mode, operands[1]);
13652 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13653 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13658 (define_insn "fpremxf4_i387"
13659 [(set (match_operand:XF 0 "register_operand" "=f")
13660 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13661 (match_operand:XF 3 "register_operand" "1")]
13663 (set (match_operand:XF 1 "register_operand" "=u")
13664 (unspec:XF [(match_dup 2) (match_dup 3)]
13666 (set (reg:CCFP FPSR_REG)
13667 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13669 "TARGET_USE_FANCY_MATH_387"
13671 [(set_attr "type" "fpspc")
13672 (set_attr "mode" "XF")])
13674 (define_expand "fmodxf3"
13675 [(use (match_operand:XF 0 "register_operand" ""))
13676 (use (match_operand:XF 1 "general_operand" ""))
13677 (use (match_operand:XF 2 "general_operand" ""))]
13678 "TARGET_USE_FANCY_MATH_387"
13680 rtx label = gen_label_rtx ();
13682 rtx op1 = gen_reg_rtx (XFmode);
13683 rtx op2 = gen_reg_rtx (XFmode);
13685 emit_move_insn (op2, operands[2]);
13686 emit_move_insn (op1, operands[1]);
13688 emit_label (label);
13689 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13690 ix86_emit_fp_unordered_jump (label);
13691 LABEL_NUSES (label) = 1;
13693 emit_move_insn (operands[0], op1);
13697 (define_expand "fmod<mode>3"
13698 [(use (match_operand:MODEF 0 "register_operand" ""))
13699 (use (match_operand:MODEF 1 "general_operand" ""))
13700 (use (match_operand:MODEF 2 "general_operand" ""))]
13701 "TARGET_USE_FANCY_MATH_387"
13703 rtx label = gen_label_rtx ();
13705 rtx op1 = gen_reg_rtx (XFmode);
13706 rtx op2 = gen_reg_rtx (XFmode);
13708 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13709 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13711 emit_label (label);
13712 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13713 ix86_emit_fp_unordered_jump (label);
13714 LABEL_NUSES (label) = 1;
13716 /* Truncate the result properly for strict SSE math. */
13717 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13718 && !TARGET_MIX_SSE_I387)
13719 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13721 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13726 (define_insn "fprem1xf4_i387"
13727 [(set (match_operand:XF 0 "register_operand" "=f")
13728 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13729 (match_operand:XF 3 "register_operand" "1")]
13731 (set (match_operand:XF 1 "register_operand" "=u")
13732 (unspec:XF [(match_dup 2) (match_dup 3)]
13734 (set (reg:CCFP FPSR_REG)
13735 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13737 "TARGET_USE_FANCY_MATH_387"
13739 [(set_attr "type" "fpspc")
13740 (set_attr "mode" "XF")])
13742 (define_expand "remainderxf3"
13743 [(use (match_operand:XF 0 "register_operand" ""))
13744 (use (match_operand:XF 1 "general_operand" ""))
13745 (use (match_operand:XF 2 "general_operand" ""))]
13746 "TARGET_USE_FANCY_MATH_387"
13748 rtx label = gen_label_rtx ();
13750 rtx op1 = gen_reg_rtx (XFmode);
13751 rtx op2 = gen_reg_rtx (XFmode);
13753 emit_move_insn (op2, operands[2]);
13754 emit_move_insn (op1, operands[1]);
13756 emit_label (label);
13757 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13758 ix86_emit_fp_unordered_jump (label);
13759 LABEL_NUSES (label) = 1;
13761 emit_move_insn (operands[0], op1);
13765 (define_expand "remainder<mode>3"
13766 [(use (match_operand:MODEF 0 "register_operand" ""))
13767 (use (match_operand:MODEF 1 "general_operand" ""))
13768 (use (match_operand:MODEF 2 "general_operand" ""))]
13769 "TARGET_USE_FANCY_MATH_387"
13771 rtx label = gen_label_rtx ();
13773 rtx op1 = gen_reg_rtx (XFmode);
13774 rtx op2 = gen_reg_rtx (XFmode);
13776 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13777 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13779 emit_label (label);
13781 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13782 ix86_emit_fp_unordered_jump (label);
13783 LABEL_NUSES (label) = 1;
13785 /* Truncate the result properly for strict SSE math. */
13786 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13787 && !TARGET_MIX_SSE_I387)
13788 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13790 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13795 (define_insn "*sinxf2_i387"
13796 [(set (match_operand:XF 0 "register_operand" "=f")
13797 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13798 "TARGET_USE_FANCY_MATH_387
13799 && flag_unsafe_math_optimizations"
13801 [(set_attr "type" "fpspc")
13802 (set_attr "mode" "XF")])
13804 (define_insn "*sin_extend<mode>xf2_i387"
13805 [(set (match_operand:XF 0 "register_operand" "=f")
13806 (unspec:XF [(float_extend:XF
13807 (match_operand:MODEF 1 "register_operand" "0"))]
13809 "TARGET_USE_FANCY_MATH_387
13810 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13811 || TARGET_MIX_SSE_I387)
13812 && flag_unsafe_math_optimizations"
13814 [(set_attr "type" "fpspc")
13815 (set_attr "mode" "XF")])
13817 (define_insn "*cosxf2_i387"
13818 [(set (match_operand:XF 0 "register_operand" "=f")
13819 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13820 "TARGET_USE_FANCY_MATH_387
13821 && flag_unsafe_math_optimizations"
13823 [(set_attr "type" "fpspc")
13824 (set_attr "mode" "XF")])
13826 (define_insn "*cos_extend<mode>xf2_i387"
13827 [(set (match_operand:XF 0 "register_operand" "=f")
13828 (unspec:XF [(float_extend:XF
13829 (match_operand:MODEF 1 "register_operand" "0"))]
13831 "TARGET_USE_FANCY_MATH_387
13832 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13833 || TARGET_MIX_SSE_I387)
13834 && flag_unsafe_math_optimizations"
13836 [(set_attr "type" "fpspc")
13837 (set_attr "mode" "XF")])
13839 ;; When sincos pattern is defined, sin and cos builtin functions will be
13840 ;; expanded to sincos pattern with one of its outputs left unused.
13841 ;; CSE pass will figure out if two sincos patterns can be combined,
13842 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13843 ;; depending on the unused output.
13845 (define_insn "sincosxf3"
13846 [(set (match_operand:XF 0 "register_operand" "=f")
13847 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13848 UNSPEC_SINCOS_COS))
13849 (set (match_operand:XF 1 "register_operand" "=u")
13850 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13851 "TARGET_USE_FANCY_MATH_387
13852 && flag_unsafe_math_optimizations"
13854 [(set_attr "type" "fpspc")
13855 (set_attr "mode" "XF")])
13858 [(set (match_operand:XF 0 "register_operand" "")
13859 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13860 UNSPEC_SINCOS_COS))
13861 (set (match_operand:XF 1 "register_operand" "")
13862 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13863 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13864 && !(reload_completed || reload_in_progress)"
13865 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13869 [(set (match_operand:XF 0 "register_operand" "")
13870 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13871 UNSPEC_SINCOS_COS))
13872 (set (match_operand:XF 1 "register_operand" "")
13873 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13874 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13875 && !(reload_completed || reload_in_progress)"
13876 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13879 (define_insn "sincos_extend<mode>xf3_i387"
13880 [(set (match_operand:XF 0 "register_operand" "=f")
13881 (unspec:XF [(float_extend:XF
13882 (match_operand:MODEF 2 "register_operand" "0"))]
13883 UNSPEC_SINCOS_COS))
13884 (set (match_operand:XF 1 "register_operand" "=u")
13885 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13886 "TARGET_USE_FANCY_MATH_387
13887 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13888 || TARGET_MIX_SSE_I387)
13889 && flag_unsafe_math_optimizations"
13891 [(set_attr "type" "fpspc")
13892 (set_attr "mode" "XF")])
13895 [(set (match_operand:XF 0 "register_operand" "")
13896 (unspec:XF [(float_extend:XF
13897 (match_operand:MODEF 2 "register_operand" ""))]
13898 UNSPEC_SINCOS_COS))
13899 (set (match_operand:XF 1 "register_operand" "")
13900 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13901 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13902 && !(reload_completed || reload_in_progress)"
13903 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13907 [(set (match_operand:XF 0 "register_operand" "")
13908 (unspec:XF [(float_extend:XF
13909 (match_operand:MODEF 2 "register_operand" ""))]
13910 UNSPEC_SINCOS_COS))
13911 (set (match_operand:XF 1 "register_operand" "")
13912 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13913 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13914 && !(reload_completed || reload_in_progress)"
13915 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13918 (define_expand "sincos<mode>3"
13919 [(use (match_operand:MODEF 0 "register_operand" ""))
13920 (use (match_operand:MODEF 1 "register_operand" ""))
13921 (use (match_operand:MODEF 2 "register_operand" ""))]
13922 "TARGET_USE_FANCY_MATH_387
13923 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13924 || TARGET_MIX_SSE_I387)
13925 && flag_unsafe_math_optimizations"
13927 rtx op0 = gen_reg_rtx (XFmode);
13928 rtx op1 = gen_reg_rtx (XFmode);
13930 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13931 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13932 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13936 (define_insn "fptanxf4_i387"
13937 [(set (match_operand:XF 0 "register_operand" "=f")
13938 (match_operand:XF 3 "const_double_operand" "F"))
13939 (set (match_operand:XF 1 "register_operand" "=u")
13940 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13942 "TARGET_USE_FANCY_MATH_387
13943 && flag_unsafe_math_optimizations
13944 && standard_80387_constant_p (operands[3]) == 2"
13946 [(set_attr "type" "fpspc")
13947 (set_attr "mode" "XF")])
13949 (define_insn "fptan_extend<mode>xf4_i387"
13950 [(set (match_operand:MODEF 0 "register_operand" "=f")
13951 (match_operand:MODEF 3 "const_double_operand" "F"))
13952 (set (match_operand:XF 1 "register_operand" "=u")
13953 (unspec:XF [(float_extend:XF
13954 (match_operand:MODEF 2 "register_operand" "0"))]
13956 "TARGET_USE_FANCY_MATH_387
13957 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13958 || TARGET_MIX_SSE_I387)
13959 && flag_unsafe_math_optimizations
13960 && standard_80387_constant_p (operands[3]) == 2"
13962 [(set_attr "type" "fpspc")
13963 (set_attr "mode" "XF")])
13965 (define_expand "tanxf2"
13966 [(use (match_operand:XF 0 "register_operand" ""))
13967 (use (match_operand:XF 1 "register_operand" ""))]
13968 "TARGET_USE_FANCY_MATH_387
13969 && flag_unsafe_math_optimizations"
13971 rtx one = gen_reg_rtx (XFmode);
13972 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13974 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13978 (define_expand "tan<mode>2"
13979 [(use (match_operand:MODEF 0 "register_operand" ""))
13980 (use (match_operand:MODEF 1 "register_operand" ""))]
13981 "TARGET_USE_FANCY_MATH_387
13982 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13983 || TARGET_MIX_SSE_I387)
13984 && flag_unsafe_math_optimizations"
13986 rtx op0 = gen_reg_rtx (XFmode);
13988 rtx one = gen_reg_rtx (<MODE>mode);
13989 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13991 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13992 operands[1], op2));
13993 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13997 (define_insn "*fpatanxf3_i387"
13998 [(set (match_operand:XF 0 "register_operand" "=f")
13999 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14000 (match_operand:XF 2 "register_operand" "u")]
14002 (clobber (match_scratch:XF 3 "=2"))]
14003 "TARGET_USE_FANCY_MATH_387
14004 && flag_unsafe_math_optimizations"
14006 [(set_attr "type" "fpspc")
14007 (set_attr "mode" "XF")])
14009 (define_insn "fpatan_extend<mode>xf3_i387"
14010 [(set (match_operand:XF 0 "register_operand" "=f")
14011 (unspec:XF [(float_extend:XF
14012 (match_operand:MODEF 1 "register_operand" "0"))
14014 (match_operand:MODEF 2 "register_operand" "u"))]
14016 (clobber (match_scratch:XF 3 "=2"))]
14017 "TARGET_USE_FANCY_MATH_387
14018 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14019 || TARGET_MIX_SSE_I387)
14020 && flag_unsafe_math_optimizations"
14022 [(set_attr "type" "fpspc")
14023 (set_attr "mode" "XF")])
14025 (define_expand "atan2xf3"
14026 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14027 (unspec:XF [(match_operand:XF 2 "register_operand" "")
14028 (match_operand:XF 1 "register_operand" "")]
14030 (clobber (match_scratch:XF 3 ""))])]
14031 "TARGET_USE_FANCY_MATH_387
14032 && flag_unsafe_math_optimizations"
14035 (define_expand "atan2<mode>3"
14036 [(use (match_operand:MODEF 0 "register_operand" ""))
14037 (use (match_operand:MODEF 1 "register_operand" ""))
14038 (use (match_operand:MODEF 2 "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 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14047 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14051 (define_expand "atanxf2"
14052 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14053 (unspec:XF [(match_dup 2)
14054 (match_operand:XF 1 "register_operand" "")]
14056 (clobber (match_scratch:XF 3 ""))])]
14057 "TARGET_USE_FANCY_MATH_387
14058 && flag_unsafe_math_optimizations"
14060 operands[2] = gen_reg_rtx (XFmode);
14061 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14064 (define_expand "atan<mode>2"
14065 [(use (match_operand:MODEF 0 "register_operand" ""))
14066 (use (match_operand:MODEF 1 "register_operand" ""))]
14067 "TARGET_USE_FANCY_MATH_387
14068 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14069 || TARGET_MIX_SSE_I387)
14070 && flag_unsafe_math_optimizations"
14072 rtx op0 = gen_reg_rtx (XFmode);
14074 rtx op2 = gen_reg_rtx (<MODE>mode);
14075 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14077 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14078 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14082 (define_expand "asinxf2"
14083 [(set (match_dup 2)
14084 (mult:XF (match_operand:XF 1 "register_operand" "")
14086 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14087 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14088 (parallel [(set (match_operand:XF 0 "register_operand" "")
14089 (unspec:XF [(match_dup 5) (match_dup 1)]
14091 (clobber (match_scratch:XF 6 ""))])]
14092 "TARGET_USE_FANCY_MATH_387
14093 && flag_unsafe_math_optimizations"
14097 if (optimize_insn_for_size_p ())
14100 for (i = 2; i < 6; i++)
14101 operands[i] = gen_reg_rtx (XFmode);
14103 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14106 (define_expand "asin<mode>2"
14107 [(use (match_operand:MODEF 0 "register_operand" ""))
14108 (use (match_operand:MODEF 1 "general_operand" ""))]
14109 "TARGET_USE_FANCY_MATH_387
14110 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14111 || TARGET_MIX_SSE_I387)
14112 && flag_unsafe_math_optimizations"
14114 rtx op0 = gen_reg_rtx (XFmode);
14115 rtx op1 = gen_reg_rtx (XFmode);
14117 if (optimize_insn_for_size_p ())
14120 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14121 emit_insn (gen_asinxf2 (op0, op1));
14122 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14126 (define_expand "acosxf2"
14127 [(set (match_dup 2)
14128 (mult:XF (match_operand:XF 1 "register_operand" "")
14130 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14131 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14132 (parallel [(set (match_operand:XF 0 "register_operand" "")
14133 (unspec:XF [(match_dup 1) (match_dup 5)]
14135 (clobber (match_scratch:XF 6 ""))])]
14136 "TARGET_USE_FANCY_MATH_387
14137 && flag_unsafe_math_optimizations"
14141 if (optimize_insn_for_size_p ())
14144 for (i = 2; i < 6; i++)
14145 operands[i] = gen_reg_rtx (XFmode);
14147 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14150 (define_expand "acos<mode>2"
14151 [(use (match_operand:MODEF 0 "register_operand" ""))
14152 (use (match_operand:MODEF 1 "general_operand" ""))]
14153 "TARGET_USE_FANCY_MATH_387
14154 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14155 || TARGET_MIX_SSE_I387)
14156 && flag_unsafe_math_optimizations"
14158 rtx op0 = gen_reg_rtx (XFmode);
14159 rtx op1 = gen_reg_rtx (XFmode);
14161 if (optimize_insn_for_size_p ())
14164 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14165 emit_insn (gen_acosxf2 (op0, op1));
14166 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14170 (define_insn "fyl2xxf3_i387"
14171 [(set (match_operand:XF 0 "register_operand" "=f")
14172 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14173 (match_operand:XF 2 "register_operand" "u")]
14175 (clobber (match_scratch:XF 3 "=2"))]
14176 "TARGET_USE_FANCY_MATH_387
14177 && flag_unsafe_math_optimizations"
14179 [(set_attr "type" "fpspc")
14180 (set_attr "mode" "XF")])
14182 (define_insn "fyl2x_extend<mode>xf3_i387"
14183 [(set (match_operand:XF 0 "register_operand" "=f")
14184 (unspec:XF [(float_extend:XF
14185 (match_operand:MODEF 1 "register_operand" "0"))
14186 (match_operand:XF 2 "register_operand" "u")]
14188 (clobber (match_scratch:XF 3 "=2"))]
14189 "TARGET_USE_FANCY_MATH_387
14190 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14191 || TARGET_MIX_SSE_I387)
14192 && flag_unsafe_math_optimizations"
14194 [(set_attr "type" "fpspc")
14195 (set_attr "mode" "XF")])
14197 (define_expand "logxf2"
14198 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14199 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14200 (match_dup 2)] UNSPEC_FYL2X))
14201 (clobber (match_scratch:XF 3 ""))])]
14202 "TARGET_USE_FANCY_MATH_387
14203 && flag_unsafe_math_optimizations"
14205 operands[2] = gen_reg_rtx (XFmode);
14206 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14209 (define_expand "log<mode>2"
14210 [(use (match_operand:MODEF 0 "register_operand" ""))
14211 (use (match_operand:MODEF 1 "register_operand" ""))]
14212 "TARGET_USE_FANCY_MATH_387
14213 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14214 || TARGET_MIX_SSE_I387)
14215 && flag_unsafe_math_optimizations"
14217 rtx op0 = gen_reg_rtx (XFmode);
14219 rtx op2 = gen_reg_rtx (XFmode);
14220 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14222 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14223 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14227 (define_expand "log10xf2"
14228 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14229 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14230 (match_dup 2)] UNSPEC_FYL2X))
14231 (clobber (match_scratch:XF 3 ""))])]
14232 "TARGET_USE_FANCY_MATH_387
14233 && flag_unsafe_math_optimizations"
14235 operands[2] = gen_reg_rtx (XFmode);
14236 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14239 (define_expand "log10<mode>2"
14240 [(use (match_operand:MODEF 0 "register_operand" ""))
14241 (use (match_operand:MODEF 1 "register_operand" ""))]
14242 "TARGET_USE_FANCY_MATH_387
14243 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14244 || TARGET_MIX_SSE_I387)
14245 && flag_unsafe_math_optimizations"
14247 rtx op0 = gen_reg_rtx (XFmode);
14249 rtx op2 = gen_reg_rtx (XFmode);
14250 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14252 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14253 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14257 (define_expand "log2xf2"
14258 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14259 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14260 (match_dup 2)] UNSPEC_FYL2X))
14261 (clobber (match_scratch:XF 3 ""))])]
14262 "TARGET_USE_FANCY_MATH_387
14263 && flag_unsafe_math_optimizations"
14265 operands[2] = gen_reg_rtx (XFmode);
14266 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14269 (define_expand "log2<mode>2"
14270 [(use (match_operand:MODEF 0 "register_operand" ""))
14271 (use (match_operand:MODEF 1 "register_operand" ""))]
14272 "TARGET_USE_FANCY_MATH_387
14273 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14274 || TARGET_MIX_SSE_I387)
14275 && flag_unsafe_math_optimizations"
14277 rtx op0 = gen_reg_rtx (XFmode);
14279 rtx op2 = gen_reg_rtx (XFmode);
14280 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14282 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14283 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14287 (define_insn "fyl2xp1xf3_i387"
14288 [(set (match_operand:XF 0 "register_operand" "=f")
14289 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14290 (match_operand:XF 2 "register_operand" "u")]
14292 (clobber (match_scratch:XF 3 "=2"))]
14293 "TARGET_USE_FANCY_MATH_387
14294 && flag_unsafe_math_optimizations"
14296 [(set_attr "type" "fpspc")
14297 (set_attr "mode" "XF")])
14299 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14300 [(set (match_operand:XF 0 "register_operand" "=f")
14301 (unspec:XF [(float_extend:XF
14302 (match_operand:MODEF 1 "register_operand" "0"))
14303 (match_operand:XF 2 "register_operand" "u")]
14305 (clobber (match_scratch:XF 3 "=2"))]
14306 "TARGET_USE_FANCY_MATH_387
14307 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14308 || TARGET_MIX_SSE_I387)
14309 && flag_unsafe_math_optimizations"
14311 [(set_attr "type" "fpspc")
14312 (set_attr "mode" "XF")])
14314 (define_expand "log1pxf2"
14315 [(use (match_operand:XF 0 "register_operand" ""))
14316 (use (match_operand:XF 1 "register_operand" ""))]
14317 "TARGET_USE_FANCY_MATH_387
14318 && flag_unsafe_math_optimizations"
14320 if (optimize_insn_for_size_p ())
14323 ix86_emit_i387_log1p (operands[0], operands[1]);
14327 (define_expand "log1p<mode>2"
14328 [(use (match_operand:MODEF 0 "register_operand" ""))
14329 (use (match_operand:MODEF 1 "register_operand" ""))]
14330 "TARGET_USE_FANCY_MATH_387
14331 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14332 || TARGET_MIX_SSE_I387)
14333 && flag_unsafe_math_optimizations"
14337 if (optimize_insn_for_size_p ())
14340 op0 = gen_reg_rtx (XFmode);
14342 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14344 ix86_emit_i387_log1p (op0, operands[1]);
14345 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14349 (define_insn "fxtractxf3_i387"
14350 [(set (match_operand:XF 0 "register_operand" "=f")
14351 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14352 UNSPEC_XTRACT_FRACT))
14353 (set (match_operand:XF 1 "register_operand" "=u")
14354 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14355 "TARGET_USE_FANCY_MATH_387
14356 && flag_unsafe_math_optimizations"
14358 [(set_attr "type" "fpspc")
14359 (set_attr "mode" "XF")])
14361 (define_insn "fxtract_extend<mode>xf3_i387"
14362 [(set (match_operand:XF 0 "register_operand" "=f")
14363 (unspec:XF [(float_extend:XF
14364 (match_operand:MODEF 2 "register_operand" "0"))]
14365 UNSPEC_XTRACT_FRACT))
14366 (set (match_operand:XF 1 "register_operand" "=u")
14367 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14368 "TARGET_USE_FANCY_MATH_387
14369 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14370 || TARGET_MIX_SSE_I387)
14371 && flag_unsafe_math_optimizations"
14373 [(set_attr "type" "fpspc")
14374 (set_attr "mode" "XF")])
14376 (define_expand "logbxf2"
14377 [(parallel [(set (match_dup 2)
14378 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14379 UNSPEC_XTRACT_FRACT))
14380 (set (match_operand:XF 0 "register_operand" "")
14381 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14382 "TARGET_USE_FANCY_MATH_387
14383 && flag_unsafe_math_optimizations"
14385 operands[2] = gen_reg_rtx (XFmode);
14388 (define_expand "logb<mode>2"
14389 [(use (match_operand:MODEF 0 "register_operand" ""))
14390 (use (match_operand:MODEF 1 "register_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"
14396 rtx op0 = gen_reg_rtx (XFmode);
14397 rtx op1 = gen_reg_rtx (XFmode);
14399 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14400 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14404 (define_expand "ilogbxf2"
14405 [(use (match_operand:SI 0 "register_operand" ""))
14406 (use (match_operand:XF 1 "register_operand" ""))]
14407 "TARGET_USE_FANCY_MATH_387
14408 && flag_unsafe_math_optimizations"
14412 if (optimize_insn_for_size_p ())
14415 op0 = gen_reg_rtx (XFmode);
14416 op1 = gen_reg_rtx (XFmode);
14418 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14419 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14423 (define_expand "ilogb<mode>2"
14424 [(use (match_operand:SI 0 "register_operand" ""))
14425 (use (match_operand:MODEF 1 "register_operand" ""))]
14426 "TARGET_USE_FANCY_MATH_387
14427 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14428 || TARGET_MIX_SSE_I387)
14429 && flag_unsafe_math_optimizations"
14433 if (optimize_insn_for_size_p ())
14436 op0 = gen_reg_rtx (XFmode);
14437 op1 = gen_reg_rtx (XFmode);
14439 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14440 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14444 (define_insn "*f2xm1xf2_i387"
14445 [(set (match_operand:XF 0 "register_operand" "=f")
14446 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14448 "TARGET_USE_FANCY_MATH_387
14449 && flag_unsafe_math_optimizations"
14451 [(set_attr "type" "fpspc")
14452 (set_attr "mode" "XF")])
14454 (define_insn "*fscalexf4_i387"
14455 [(set (match_operand:XF 0 "register_operand" "=f")
14456 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14457 (match_operand:XF 3 "register_operand" "1")]
14458 UNSPEC_FSCALE_FRACT))
14459 (set (match_operand:XF 1 "register_operand" "=u")
14460 (unspec:XF [(match_dup 2) (match_dup 3)]
14461 UNSPEC_FSCALE_EXP))]
14462 "TARGET_USE_FANCY_MATH_387
14463 && flag_unsafe_math_optimizations"
14465 [(set_attr "type" "fpspc")
14466 (set_attr "mode" "XF")])
14468 (define_expand "expNcorexf3"
14469 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14470 (match_operand:XF 2 "register_operand" "")))
14471 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14472 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14473 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14474 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14475 (parallel [(set (match_operand:XF 0 "register_operand" "")
14476 (unspec:XF [(match_dup 8) (match_dup 4)]
14477 UNSPEC_FSCALE_FRACT))
14479 (unspec:XF [(match_dup 8) (match_dup 4)]
14480 UNSPEC_FSCALE_EXP))])]
14481 "TARGET_USE_FANCY_MATH_387
14482 && flag_unsafe_math_optimizations"
14486 if (optimize_insn_for_size_p ())
14489 for (i = 3; i < 10; i++)
14490 operands[i] = gen_reg_rtx (XFmode);
14492 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14495 (define_expand "expxf2"
14496 [(use (match_operand:XF 0 "register_operand" ""))
14497 (use (match_operand:XF 1 "register_operand" ""))]
14498 "TARGET_USE_FANCY_MATH_387
14499 && flag_unsafe_math_optimizations"
14503 if (optimize_insn_for_size_p ())
14506 op2 = gen_reg_rtx (XFmode);
14507 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14509 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14513 (define_expand "exp<mode>2"
14514 [(use (match_operand:MODEF 0 "register_operand" ""))
14515 (use (match_operand:MODEF 1 "general_operand" ""))]
14516 "TARGET_USE_FANCY_MATH_387
14517 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14518 || TARGET_MIX_SSE_I387)
14519 && flag_unsafe_math_optimizations"
14523 if (optimize_insn_for_size_p ())
14526 op0 = gen_reg_rtx (XFmode);
14527 op1 = gen_reg_rtx (XFmode);
14529 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14530 emit_insn (gen_expxf2 (op0, op1));
14531 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14535 (define_expand "exp10xf2"
14536 [(use (match_operand:XF 0 "register_operand" ""))
14537 (use (match_operand:XF 1 "register_operand" ""))]
14538 "TARGET_USE_FANCY_MATH_387
14539 && flag_unsafe_math_optimizations"
14543 if (optimize_insn_for_size_p ())
14546 op2 = gen_reg_rtx (XFmode);
14547 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14549 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14553 (define_expand "exp10<mode>2"
14554 [(use (match_operand:MODEF 0 "register_operand" ""))
14555 (use (match_operand:MODEF 1 "general_operand" ""))]
14556 "TARGET_USE_FANCY_MATH_387
14557 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14558 || TARGET_MIX_SSE_I387)
14559 && flag_unsafe_math_optimizations"
14563 if (optimize_insn_for_size_p ())
14566 op0 = gen_reg_rtx (XFmode);
14567 op1 = gen_reg_rtx (XFmode);
14569 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14570 emit_insn (gen_exp10xf2 (op0, op1));
14571 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14575 (define_expand "exp2xf2"
14576 [(use (match_operand:XF 0 "register_operand" ""))
14577 (use (match_operand:XF 1 "register_operand" ""))]
14578 "TARGET_USE_FANCY_MATH_387
14579 && flag_unsafe_math_optimizations"
14583 if (optimize_insn_for_size_p ())
14586 op2 = gen_reg_rtx (XFmode);
14587 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14589 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14593 (define_expand "exp2<mode>2"
14594 [(use (match_operand:MODEF 0 "register_operand" ""))
14595 (use (match_operand:MODEF 1 "general_operand" ""))]
14596 "TARGET_USE_FANCY_MATH_387
14597 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14598 || TARGET_MIX_SSE_I387)
14599 && flag_unsafe_math_optimizations"
14603 if (optimize_insn_for_size_p ())
14606 op0 = gen_reg_rtx (XFmode);
14607 op1 = gen_reg_rtx (XFmode);
14609 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14610 emit_insn (gen_exp2xf2 (op0, op1));
14611 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14615 (define_expand "expm1xf2"
14616 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14618 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14619 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14620 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14621 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14622 (parallel [(set (match_dup 7)
14623 (unspec:XF [(match_dup 6) (match_dup 4)]
14624 UNSPEC_FSCALE_FRACT))
14626 (unspec:XF [(match_dup 6) (match_dup 4)]
14627 UNSPEC_FSCALE_EXP))])
14628 (parallel [(set (match_dup 10)
14629 (unspec:XF [(match_dup 9) (match_dup 8)]
14630 UNSPEC_FSCALE_FRACT))
14631 (set (match_dup 11)
14632 (unspec:XF [(match_dup 9) (match_dup 8)]
14633 UNSPEC_FSCALE_EXP))])
14634 (set (match_dup 12) (minus:XF (match_dup 10)
14635 (float_extend:XF (match_dup 13))))
14636 (set (match_operand:XF 0 "register_operand" "")
14637 (plus:XF (match_dup 12) (match_dup 7)))]
14638 "TARGET_USE_FANCY_MATH_387
14639 && flag_unsafe_math_optimizations"
14643 if (optimize_insn_for_size_p ())
14646 for (i = 2; i < 13; i++)
14647 operands[i] = gen_reg_rtx (XFmode);
14650 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14652 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14655 (define_expand "expm1<mode>2"
14656 [(use (match_operand:MODEF 0 "register_operand" ""))
14657 (use (match_operand:MODEF 1 "general_operand" ""))]
14658 "TARGET_USE_FANCY_MATH_387
14659 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14660 || TARGET_MIX_SSE_I387)
14661 && flag_unsafe_math_optimizations"
14665 if (optimize_insn_for_size_p ())
14668 op0 = gen_reg_rtx (XFmode);
14669 op1 = gen_reg_rtx (XFmode);
14671 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14672 emit_insn (gen_expm1xf2 (op0, op1));
14673 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14677 (define_expand "ldexpxf3"
14678 [(set (match_dup 3)
14679 (float:XF (match_operand:SI 2 "register_operand" "")))
14680 (parallel [(set (match_operand:XF 0 " register_operand" "")
14681 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14683 UNSPEC_FSCALE_FRACT))
14685 (unspec:XF [(match_dup 1) (match_dup 3)]
14686 UNSPEC_FSCALE_EXP))])]
14687 "TARGET_USE_FANCY_MATH_387
14688 && flag_unsafe_math_optimizations"
14690 if (optimize_insn_for_size_p ())
14693 operands[3] = gen_reg_rtx (XFmode);
14694 operands[4] = gen_reg_rtx (XFmode);
14697 (define_expand "ldexp<mode>3"
14698 [(use (match_operand:MODEF 0 "register_operand" ""))
14699 (use (match_operand:MODEF 1 "general_operand" ""))
14700 (use (match_operand:SI 2 "register_operand" ""))]
14701 "TARGET_USE_FANCY_MATH_387
14702 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14703 || TARGET_MIX_SSE_I387)
14704 && flag_unsafe_math_optimizations"
14708 if (optimize_insn_for_size_p ())
14711 op0 = gen_reg_rtx (XFmode);
14712 op1 = gen_reg_rtx (XFmode);
14714 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14715 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14716 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14720 (define_expand "scalbxf3"
14721 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14722 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14723 (match_operand:XF 2 "register_operand" "")]
14724 UNSPEC_FSCALE_FRACT))
14726 (unspec:XF [(match_dup 1) (match_dup 2)]
14727 UNSPEC_FSCALE_EXP))])]
14728 "TARGET_USE_FANCY_MATH_387
14729 && flag_unsafe_math_optimizations"
14731 if (optimize_insn_for_size_p ())
14734 operands[3] = gen_reg_rtx (XFmode);
14737 (define_expand "scalb<mode>3"
14738 [(use (match_operand:MODEF 0 "register_operand" ""))
14739 (use (match_operand:MODEF 1 "general_operand" ""))
14740 (use (match_operand:MODEF 2 "general_operand" ""))]
14741 "TARGET_USE_FANCY_MATH_387
14742 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14743 || TARGET_MIX_SSE_I387)
14744 && flag_unsafe_math_optimizations"
14748 if (optimize_insn_for_size_p ())
14751 op0 = gen_reg_rtx (XFmode);
14752 op1 = gen_reg_rtx (XFmode);
14753 op2 = gen_reg_rtx (XFmode);
14755 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14756 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14757 emit_insn (gen_scalbxf3 (op0, op1, op2));
14758 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14762 (define_expand "significandxf2"
14763 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14764 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14765 UNSPEC_XTRACT_FRACT))
14767 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14768 "TARGET_USE_FANCY_MATH_387
14769 && flag_unsafe_math_optimizations"
14771 operands[2] = gen_reg_rtx (XFmode);
14774 (define_expand "significand<mode>2"
14775 [(use (match_operand:MODEF 0 "register_operand" ""))
14776 (use (match_operand:MODEF 1 "register_operand" ""))]
14777 "TARGET_USE_FANCY_MATH_387
14778 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14779 || TARGET_MIX_SSE_I387)
14780 && flag_unsafe_math_optimizations"
14782 rtx op0 = gen_reg_rtx (XFmode);
14783 rtx op1 = gen_reg_rtx (XFmode);
14785 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14786 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14791 (define_insn "sse4_1_round<mode>2"
14792 [(set (match_operand:MODEF 0 "register_operand" "=x")
14793 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14794 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14797 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14798 [(set_attr "type" "ssecvt")
14799 (set_attr "prefix_extra" "1")
14800 (set_attr "prefix" "maybe_vex")
14801 (set_attr "mode" "<MODE>")])
14803 (define_insn "rintxf2"
14804 [(set (match_operand:XF 0 "register_operand" "=f")
14805 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14807 "TARGET_USE_FANCY_MATH_387
14808 && flag_unsafe_math_optimizations"
14810 [(set_attr "type" "fpspc")
14811 (set_attr "mode" "XF")])
14813 (define_expand "rint<mode>2"
14814 [(use (match_operand:MODEF 0 "register_operand" ""))
14815 (use (match_operand:MODEF 1 "register_operand" ""))]
14816 "(TARGET_USE_FANCY_MATH_387
14817 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14818 || TARGET_MIX_SSE_I387)
14819 && flag_unsafe_math_optimizations)
14820 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14821 && !flag_trapping_math)"
14823 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14824 && !flag_trapping_math)
14826 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14829 emit_insn (gen_sse4_1_round<mode>2
14830 (operands[0], operands[1], GEN_INT (0x04)));
14832 ix86_expand_rint (operand0, operand1);
14836 rtx op0 = gen_reg_rtx (XFmode);
14837 rtx op1 = gen_reg_rtx (XFmode);
14839 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14840 emit_insn (gen_rintxf2 (op0, op1));
14842 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14847 (define_expand "round<mode>2"
14848 [(match_operand:MODEF 0 "register_operand" "")
14849 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14850 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14851 && !flag_trapping_math && !flag_rounding_math"
14853 if (optimize_insn_for_size_p ())
14855 if (TARGET_64BIT || (<MODE>mode != DFmode))
14856 ix86_expand_round (operand0, operand1);
14858 ix86_expand_rounddf_32 (operand0, operand1);
14862 (define_insn_and_split "*fistdi2_1"
14863 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14864 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14866 "TARGET_USE_FANCY_MATH_387
14867 && can_create_pseudo_p ()"
14872 if (memory_operand (operands[0], VOIDmode))
14873 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14876 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14877 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14882 [(set_attr "type" "fpspc")
14883 (set_attr "mode" "DI")])
14885 (define_insn "fistdi2"
14886 [(set (match_operand:DI 0 "memory_operand" "=m")
14887 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14889 (clobber (match_scratch:XF 2 "=&1f"))]
14890 "TARGET_USE_FANCY_MATH_387"
14891 "* return output_fix_trunc (insn, operands, 0);"
14892 [(set_attr "type" "fpspc")
14893 (set_attr "mode" "DI")])
14895 (define_insn "fistdi2_with_temp"
14896 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14897 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14899 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14900 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14901 "TARGET_USE_FANCY_MATH_387"
14903 [(set_attr "type" "fpspc")
14904 (set_attr "mode" "DI")])
14907 [(set (match_operand:DI 0 "register_operand" "")
14908 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14910 (clobber (match_operand:DI 2 "memory_operand" ""))
14911 (clobber (match_scratch 3 ""))]
14913 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14914 (clobber (match_dup 3))])
14915 (set (match_dup 0) (match_dup 2))]
14919 [(set (match_operand:DI 0 "memory_operand" "")
14920 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14922 (clobber (match_operand:DI 2 "memory_operand" ""))
14923 (clobber (match_scratch 3 ""))]
14925 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14926 (clobber (match_dup 3))])]
14929 (define_insn_and_split "*fist<mode>2_1"
14930 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14931 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14933 "TARGET_USE_FANCY_MATH_387
14934 && can_create_pseudo_p ()"
14939 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14940 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14944 [(set_attr "type" "fpspc")
14945 (set_attr "mode" "<MODE>")])
14947 (define_insn "fist<mode>2"
14948 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14949 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14951 "TARGET_USE_FANCY_MATH_387"
14952 "* return output_fix_trunc (insn, operands, 0);"
14953 [(set_attr "type" "fpspc")
14954 (set_attr "mode" "<MODE>")])
14956 (define_insn "fist<mode>2_with_temp"
14957 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14958 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14960 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14961 "TARGET_USE_FANCY_MATH_387"
14963 [(set_attr "type" "fpspc")
14964 (set_attr "mode" "<MODE>")])
14967 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14968 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14970 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14972 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14973 (set (match_dup 0) (match_dup 2))]
14977 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14978 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14980 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14982 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14985 (define_expand "lrintxf<mode>2"
14986 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14987 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14989 "TARGET_USE_FANCY_MATH_387"
14992 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14993 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14994 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14995 UNSPEC_FIX_NOTRUNC))]
14996 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14997 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
15000 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
15001 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
15002 (match_operand:MODEF 1 "register_operand" "")]
15003 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15004 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
15005 && !flag_trapping_math && !flag_rounding_math"
15007 if (optimize_insn_for_size_p ())
15009 ix86_expand_lround (operand0, operand1);
15013 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15014 (define_insn_and_split "frndintxf2_floor"
15015 [(set (match_operand:XF 0 "register_operand" "")
15016 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15017 UNSPEC_FRNDINT_FLOOR))
15018 (clobber (reg:CC FLAGS_REG))]
15019 "TARGET_USE_FANCY_MATH_387
15020 && flag_unsafe_math_optimizations
15021 && can_create_pseudo_p ()"
15026 ix86_optimize_mode_switching[I387_FLOOR] = 1;
15028 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15029 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
15031 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
15032 operands[2], operands[3]));
15035 [(set_attr "type" "frndint")
15036 (set_attr "i387_cw" "floor")
15037 (set_attr "mode" "XF")])
15039 (define_insn "frndintxf2_floor_i387"
15040 [(set (match_operand:XF 0 "register_operand" "=f")
15041 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15042 UNSPEC_FRNDINT_FLOOR))
15043 (use (match_operand:HI 2 "memory_operand" "m"))
15044 (use (match_operand:HI 3 "memory_operand" "m"))]
15045 "TARGET_USE_FANCY_MATH_387
15046 && flag_unsafe_math_optimizations"
15047 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15048 [(set_attr "type" "frndint")
15049 (set_attr "i387_cw" "floor")
15050 (set_attr "mode" "XF")])
15052 (define_expand "floorxf2"
15053 [(use (match_operand:XF 0 "register_operand" ""))
15054 (use (match_operand:XF 1 "register_operand" ""))]
15055 "TARGET_USE_FANCY_MATH_387
15056 && flag_unsafe_math_optimizations"
15058 if (optimize_insn_for_size_p ())
15060 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
15064 (define_expand "floor<mode>2"
15065 [(use (match_operand:MODEF 0 "register_operand" ""))
15066 (use (match_operand:MODEF 1 "register_operand" ""))]
15067 "(TARGET_USE_FANCY_MATH_387
15068 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15069 || TARGET_MIX_SSE_I387)
15070 && flag_unsafe_math_optimizations)
15071 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15072 && !flag_trapping_math)"
15074 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15075 && !flag_trapping_math
15076 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15078 if (!TARGET_ROUND && optimize_insn_for_size_p ())
15081 emit_insn (gen_sse4_1_round<mode>2
15082 (operands[0], operands[1], GEN_INT (0x01)));
15083 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15084 ix86_expand_floorceil (operand0, operand1, true);
15086 ix86_expand_floorceildf_32 (operand0, operand1, true);
15092 if (optimize_insn_for_size_p ())
15095 op0 = gen_reg_rtx (XFmode);
15096 op1 = gen_reg_rtx (XFmode);
15097 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15098 emit_insn (gen_frndintxf2_floor (op0, op1));
15100 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15105 (define_insn_and_split "*fist<mode>2_floor_1"
15106 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15107 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15108 UNSPEC_FIST_FLOOR))
15109 (clobber (reg:CC FLAGS_REG))]
15110 "TARGET_USE_FANCY_MATH_387
15111 && flag_unsafe_math_optimizations
15112 && can_create_pseudo_p ()"
15117 ix86_optimize_mode_switching[I387_FLOOR] = 1;
15119 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15120 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
15121 if (memory_operand (operands[0], VOIDmode))
15122 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
15123 operands[2], operands[3]));
15126 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15127 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
15128 operands[2], operands[3],
15133 [(set_attr "type" "fistp")
15134 (set_attr "i387_cw" "floor")
15135 (set_attr "mode" "<MODE>")])
15137 (define_insn "fistdi2_floor"
15138 [(set (match_operand:DI 0 "memory_operand" "=m")
15139 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15140 UNSPEC_FIST_FLOOR))
15141 (use (match_operand:HI 2 "memory_operand" "m"))
15142 (use (match_operand:HI 3 "memory_operand" "m"))
15143 (clobber (match_scratch:XF 4 "=&1f"))]
15144 "TARGET_USE_FANCY_MATH_387
15145 && flag_unsafe_math_optimizations"
15146 "* return output_fix_trunc (insn, operands, 0);"
15147 [(set_attr "type" "fistp")
15148 (set_attr "i387_cw" "floor")
15149 (set_attr "mode" "DI")])
15151 (define_insn "fistdi2_floor_with_temp"
15152 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15153 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15154 UNSPEC_FIST_FLOOR))
15155 (use (match_operand:HI 2 "memory_operand" "m,m"))
15156 (use (match_operand:HI 3 "memory_operand" "m,m"))
15157 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15158 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15159 "TARGET_USE_FANCY_MATH_387
15160 && flag_unsafe_math_optimizations"
15162 [(set_attr "type" "fistp")
15163 (set_attr "i387_cw" "floor")
15164 (set_attr "mode" "DI")])
15167 [(set (match_operand:DI 0 "register_operand" "")
15168 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15169 UNSPEC_FIST_FLOOR))
15170 (use (match_operand:HI 2 "memory_operand" ""))
15171 (use (match_operand:HI 3 "memory_operand" ""))
15172 (clobber (match_operand:DI 4 "memory_operand" ""))
15173 (clobber (match_scratch 5 ""))]
15175 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15176 (use (match_dup 2))
15177 (use (match_dup 3))
15178 (clobber (match_dup 5))])
15179 (set (match_dup 0) (match_dup 4))]
15183 [(set (match_operand:DI 0 "memory_operand" "")
15184 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15185 UNSPEC_FIST_FLOOR))
15186 (use (match_operand:HI 2 "memory_operand" ""))
15187 (use (match_operand:HI 3 "memory_operand" ""))
15188 (clobber (match_operand:DI 4 "memory_operand" ""))
15189 (clobber (match_scratch 5 ""))]
15191 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15192 (use (match_dup 2))
15193 (use (match_dup 3))
15194 (clobber (match_dup 5))])]
15197 (define_insn "fist<mode>2_floor"
15198 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15199 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15200 UNSPEC_FIST_FLOOR))
15201 (use (match_operand:HI 2 "memory_operand" "m"))
15202 (use (match_operand:HI 3 "memory_operand" "m"))]
15203 "TARGET_USE_FANCY_MATH_387
15204 && flag_unsafe_math_optimizations"
15205 "* return output_fix_trunc (insn, operands, 0);"
15206 [(set_attr "type" "fistp")
15207 (set_attr "i387_cw" "floor")
15208 (set_attr "mode" "<MODE>")])
15210 (define_insn "fist<mode>2_floor_with_temp"
15211 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15212 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15213 UNSPEC_FIST_FLOOR))
15214 (use (match_operand:HI 2 "memory_operand" "m,m"))
15215 (use (match_operand:HI 3 "memory_operand" "m,m"))
15216 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15217 "TARGET_USE_FANCY_MATH_387
15218 && flag_unsafe_math_optimizations"
15220 [(set_attr "type" "fistp")
15221 (set_attr "i387_cw" "floor")
15222 (set_attr "mode" "<MODE>")])
15225 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15226 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15227 UNSPEC_FIST_FLOOR))
15228 (use (match_operand:HI 2 "memory_operand" ""))
15229 (use (match_operand:HI 3 "memory_operand" ""))
15230 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15232 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15233 UNSPEC_FIST_FLOOR))
15234 (use (match_dup 2))
15235 (use (match_dup 3))])
15236 (set (match_dup 0) (match_dup 4))]
15240 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15241 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15242 UNSPEC_FIST_FLOOR))
15243 (use (match_operand:HI 2 "memory_operand" ""))
15244 (use (match_operand:HI 3 "memory_operand" ""))
15245 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15247 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15248 UNSPEC_FIST_FLOOR))
15249 (use (match_dup 2))
15250 (use (match_dup 3))])]
15253 (define_expand "lfloorxf<mode>2"
15254 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15255 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15256 UNSPEC_FIST_FLOOR))
15257 (clobber (reg:CC FLAGS_REG))])]
15258 "TARGET_USE_FANCY_MATH_387
15259 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15260 && flag_unsafe_math_optimizations"
15263 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15264 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15265 (match_operand:MODEF 1 "register_operand" "")]
15266 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15267 && !flag_trapping_math"
15269 if (TARGET_64BIT && optimize_insn_for_size_p ())
15271 ix86_expand_lfloorceil (operand0, operand1, true);
15275 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15276 (define_insn_and_split "frndintxf2_ceil"
15277 [(set (match_operand:XF 0 "register_operand" "")
15278 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15279 UNSPEC_FRNDINT_CEIL))
15280 (clobber (reg:CC FLAGS_REG))]
15281 "TARGET_USE_FANCY_MATH_387
15282 && flag_unsafe_math_optimizations
15283 && can_create_pseudo_p ()"
15288 ix86_optimize_mode_switching[I387_CEIL] = 1;
15290 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15291 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15293 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15294 operands[2], operands[3]));
15297 [(set_attr "type" "frndint")
15298 (set_attr "i387_cw" "ceil")
15299 (set_attr "mode" "XF")])
15301 (define_insn "frndintxf2_ceil_i387"
15302 [(set (match_operand:XF 0 "register_operand" "=f")
15303 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15304 UNSPEC_FRNDINT_CEIL))
15305 (use (match_operand:HI 2 "memory_operand" "m"))
15306 (use (match_operand:HI 3 "memory_operand" "m"))]
15307 "TARGET_USE_FANCY_MATH_387
15308 && flag_unsafe_math_optimizations"
15309 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15310 [(set_attr "type" "frndint")
15311 (set_attr "i387_cw" "ceil")
15312 (set_attr "mode" "XF")])
15314 (define_expand "ceilxf2"
15315 [(use (match_operand:XF 0 "register_operand" ""))
15316 (use (match_operand:XF 1 "register_operand" ""))]
15317 "TARGET_USE_FANCY_MATH_387
15318 && flag_unsafe_math_optimizations"
15320 if (optimize_insn_for_size_p ())
15322 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15326 (define_expand "ceil<mode>2"
15327 [(use (match_operand:MODEF 0 "register_operand" ""))
15328 (use (match_operand:MODEF 1 "register_operand" ""))]
15329 "(TARGET_USE_FANCY_MATH_387
15330 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15331 || TARGET_MIX_SSE_I387)
15332 && flag_unsafe_math_optimizations)
15333 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15334 && !flag_trapping_math)"
15336 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15337 && !flag_trapping_math
15338 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15341 emit_insn (gen_sse4_1_round<mode>2
15342 (operands[0], operands[1], GEN_INT (0x02)));
15343 else if (optimize_insn_for_size_p ())
15345 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15346 ix86_expand_floorceil (operand0, operand1, false);
15348 ix86_expand_floorceildf_32 (operand0, operand1, false);
15354 if (optimize_insn_for_size_p ())
15357 op0 = gen_reg_rtx (XFmode);
15358 op1 = gen_reg_rtx (XFmode);
15359 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15360 emit_insn (gen_frndintxf2_ceil (op0, op1));
15362 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15367 (define_insn_and_split "*fist<mode>2_ceil_1"
15368 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15369 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15371 (clobber (reg:CC FLAGS_REG))]
15372 "TARGET_USE_FANCY_MATH_387
15373 && flag_unsafe_math_optimizations
15374 && can_create_pseudo_p ()"
15379 ix86_optimize_mode_switching[I387_CEIL] = 1;
15381 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15382 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15383 if (memory_operand (operands[0], VOIDmode))
15384 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15385 operands[2], operands[3]));
15388 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15389 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15390 operands[2], operands[3],
15395 [(set_attr "type" "fistp")
15396 (set_attr "i387_cw" "ceil")
15397 (set_attr "mode" "<MODE>")])
15399 (define_insn "fistdi2_ceil"
15400 [(set (match_operand:DI 0 "memory_operand" "=m")
15401 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15403 (use (match_operand:HI 2 "memory_operand" "m"))
15404 (use (match_operand:HI 3 "memory_operand" "m"))
15405 (clobber (match_scratch:XF 4 "=&1f"))]
15406 "TARGET_USE_FANCY_MATH_387
15407 && flag_unsafe_math_optimizations"
15408 "* return output_fix_trunc (insn, operands, 0);"
15409 [(set_attr "type" "fistp")
15410 (set_attr "i387_cw" "ceil")
15411 (set_attr "mode" "DI")])
15413 (define_insn "fistdi2_ceil_with_temp"
15414 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15415 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15417 (use (match_operand:HI 2 "memory_operand" "m,m"))
15418 (use (match_operand:HI 3 "memory_operand" "m,m"))
15419 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15420 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15421 "TARGET_USE_FANCY_MATH_387
15422 && flag_unsafe_math_optimizations"
15424 [(set_attr "type" "fistp")
15425 (set_attr "i387_cw" "ceil")
15426 (set_attr "mode" "DI")])
15429 [(set (match_operand:DI 0 "register_operand" "")
15430 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15432 (use (match_operand:HI 2 "memory_operand" ""))
15433 (use (match_operand:HI 3 "memory_operand" ""))
15434 (clobber (match_operand:DI 4 "memory_operand" ""))
15435 (clobber (match_scratch 5 ""))]
15437 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15438 (use (match_dup 2))
15439 (use (match_dup 3))
15440 (clobber (match_dup 5))])
15441 (set (match_dup 0) (match_dup 4))]
15445 [(set (match_operand:DI 0 "memory_operand" "")
15446 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15448 (use (match_operand:HI 2 "memory_operand" ""))
15449 (use (match_operand:HI 3 "memory_operand" ""))
15450 (clobber (match_operand:DI 4 "memory_operand" ""))
15451 (clobber (match_scratch 5 ""))]
15453 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15454 (use (match_dup 2))
15455 (use (match_dup 3))
15456 (clobber (match_dup 5))])]
15459 (define_insn "fist<mode>2_ceil"
15460 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15461 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15463 (use (match_operand:HI 2 "memory_operand" "m"))
15464 (use (match_operand:HI 3 "memory_operand" "m"))]
15465 "TARGET_USE_FANCY_MATH_387
15466 && flag_unsafe_math_optimizations"
15467 "* return output_fix_trunc (insn, operands, 0);"
15468 [(set_attr "type" "fistp")
15469 (set_attr "i387_cw" "ceil")
15470 (set_attr "mode" "<MODE>")])
15472 (define_insn "fist<mode>2_ceil_with_temp"
15473 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15474 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15476 (use (match_operand:HI 2 "memory_operand" "m,m"))
15477 (use (match_operand:HI 3 "memory_operand" "m,m"))
15478 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15479 "TARGET_USE_FANCY_MATH_387
15480 && flag_unsafe_math_optimizations"
15482 [(set_attr "type" "fistp")
15483 (set_attr "i387_cw" "ceil")
15484 (set_attr "mode" "<MODE>")])
15487 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15488 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15490 (use (match_operand:HI 2 "memory_operand" ""))
15491 (use (match_operand:HI 3 "memory_operand" ""))
15492 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15494 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15496 (use (match_dup 2))
15497 (use (match_dup 3))])
15498 (set (match_dup 0) (match_dup 4))]
15502 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15503 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15505 (use (match_operand:HI 2 "memory_operand" ""))
15506 (use (match_operand:HI 3 "memory_operand" ""))
15507 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15509 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15511 (use (match_dup 2))
15512 (use (match_dup 3))])]
15515 (define_expand "lceilxf<mode>2"
15516 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15517 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15519 (clobber (reg:CC FLAGS_REG))])]
15520 "TARGET_USE_FANCY_MATH_387
15521 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15522 && flag_unsafe_math_optimizations"
15525 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15526 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15527 (match_operand:MODEF 1 "register_operand" "")]
15528 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15529 && !flag_trapping_math"
15531 ix86_expand_lfloorceil (operand0, operand1, false);
15535 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15536 (define_insn_and_split "frndintxf2_trunc"
15537 [(set (match_operand:XF 0 "register_operand" "")
15538 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15539 UNSPEC_FRNDINT_TRUNC))
15540 (clobber (reg:CC FLAGS_REG))]
15541 "TARGET_USE_FANCY_MATH_387
15542 && flag_unsafe_math_optimizations
15543 && can_create_pseudo_p ()"
15548 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15550 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15551 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15553 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15554 operands[2], operands[3]));
15557 [(set_attr "type" "frndint")
15558 (set_attr "i387_cw" "trunc")
15559 (set_attr "mode" "XF")])
15561 (define_insn "frndintxf2_trunc_i387"
15562 [(set (match_operand:XF 0 "register_operand" "=f")
15563 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15564 UNSPEC_FRNDINT_TRUNC))
15565 (use (match_operand:HI 2 "memory_operand" "m"))
15566 (use (match_operand:HI 3 "memory_operand" "m"))]
15567 "TARGET_USE_FANCY_MATH_387
15568 && flag_unsafe_math_optimizations"
15569 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15570 [(set_attr "type" "frndint")
15571 (set_attr "i387_cw" "trunc")
15572 (set_attr "mode" "XF")])
15574 (define_expand "btruncxf2"
15575 [(use (match_operand:XF 0 "register_operand" ""))
15576 (use (match_operand:XF 1 "register_operand" ""))]
15577 "TARGET_USE_FANCY_MATH_387
15578 && flag_unsafe_math_optimizations"
15580 if (optimize_insn_for_size_p ())
15582 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15586 (define_expand "btrunc<mode>2"
15587 [(use (match_operand:MODEF 0 "register_operand" ""))
15588 (use (match_operand:MODEF 1 "register_operand" ""))]
15589 "(TARGET_USE_FANCY_MATH_387
15590 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15591 || TARGET_MIX_SSE_I387)
15592 && flag_unsafe_math_optimizations)
15593 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15594 && !flag_trapping_math)"
15596 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15597 && !flag_trapping_math
15598 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15601 emit_insn (gen_sse4_1_round<mode>2
15602 (operands[0], operands[1], GEN_INT (0x03)));
15603 else if (optimize_insn_for_size_p ())
15605 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15606 ix86_expand_trunc (operand0, operand1);
15608 ix86_expand_truncdf_32 (operand0, operand1);
15614 if (optimize_insn_for_size_p ())
15617 op0 = gen_reg_rtx (XFmode);
15618 op1 = gen_reg_rtx (XFmode);
15619 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15620 emit_insn (gen_frndintxf2_trunc (op0, op1));
15622 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15627 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15628 (define_insn_and_split "frndintxf2_mask_pm"
15629 [(set (match_operand:XF 0 "register_operand" "")
15630 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15631 UNSPEC_FRNDINT_MASK_PM))
15632 (clobber (reg:CC FLAGS_REG))]
15633 "TARGET_USE_FANCY_MATH_387
15634 && flag_unsafe_math_optimizations
15635 && can_create_pseudo_p ()"
15640 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15642 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15643 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15645 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15646 operands[2], operands[3]));
15649 [(set_attr "type" "frndint")
15650 (set_attr "i387_cw" "mask_pm")
15651 (set_attr "mode" "XF")])
15653 (define_insn "frndintxf2_mask_pm_i387"
15654 [(set (match_operand:XF 0 "register_operand" "=f")
15655 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15656 UNSPEC_FRNDINT_MASK_PM))
15657 (use (match_operand:HI 2 "memory_operand" "m"))
15658 (use (match_operand:HI 3 "memory_operand" "m"))]
15659 "TARGET_USE_FANCY_MATH_387
15660 && flag_unsafe_math_optimizations"
15661 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15662 [(set_attr "type" "frndint")
15663 (set_attr "i387_cw" "mask_pm")
15664 (set_attr "mode" "XF")])
15666 (define_expand "nearbyintxf2"
15667 [(use (match_operand:XF 0 "register_operand" ""))
15668 (use (match_operand:XF 1 "register_operand" ""))]
15669 "TARGET_USE_FANCY_MATH_387
15670 && flag_unsafe_math_optimizations"
15672 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15677 (define_expand "nearbyint<mode>2"
15678 [(use (match_operand:MODEF 0 "register_operand" ""))
15679 (use (match_operand:MODEF 1 "register_operand" ""))]
15680 "TARGET_USE_FANCY_MATH_387
15681 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15682 || TARGET_MIX_SSE_I387)
15683 && flag_unsafe_math_optimizations"
15685 rtx op0 = gen_reg_rtx (XFmode);
15686 rtx op1 = gen_reg_rtx (XFmode);
15688 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15689 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15691 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15695 (define_insn "fxam<mode>2_i387"
15696 [(set (match_operand:HI 0 "register_operand" "=a")
15698 [(match_operand:X87MODEF 1 "register_operand" "f")]
15700 "TARGET_USE_FANCY_MATH_387"
15701 "fxam\n\tfnstsw\t%0"
15702 [(set_attr "type" "multi")
15703 (set_attr "length" "4")
15704 (set_attr "unit" "i387")
15705 (set_attr "mode" "<MODE>")])
15707 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15708 [(set (match_operand:HI 0 "register_operand" "")
15710 [(match_operand:MODEF 1 "memory_operand" "")]
15712 "TARGET_USE_FANCY_MATH_387
15713 && can_create_pseudo_p ()"
15716 [(set (match_dup 2)(match_dup 1))
15718 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15720 operands[2] = gen_reg_rtx (<MODE>mode);
15722 MEM_VOLATILE_P (operands[1]) = 1;
15724 [(set_attr "type" "multi")
15725 (set_attr "unit" "i387")
15726 (set_attr "mode" "<MODE>")])
15728 (define_expand "isinfxf2"
15729 [(use (match_operand:SI 0 "register_operand" ""))
15730 (use (match_operand:XF 1 "register_operand" ""))]
15731 "TARGET_USE_FANCY_MATH_387
15732 && TARGET_C99_FUNCTIONS"
15734 rtx mask = GEN_INT (0x45);
15735 rtx val = GEN_INT (0x05);
15739 rtx scratch = gen_reg_rtx (HImode);
15740 rtx res = gen_reg_rtx (QImode);
15742 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15744 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15745 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15746 cond = gen_rtx_fmt_ee (EQ, QImode,
15747 gen_rtx_REG (CCmode, FLAGS_REG),
15749 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15750 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15754 (define_expand "isinf<mode>2"
15755 [(use (match_operand:SI 0 "register_operand" ""))
15756 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15757 "TARGET_USE_FANCY_MATH_387
15758 && TARGET_C99_FUNCTIONS
15759 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15761 rtx mask = GEN_INT (0x45);
15762 rtx val = GEN_INT (0x05);
15766 rtx scratch = gen_reg_rtx (HImode);
15767 rtx res = gen_reg_rtx (QImode);
15769 /* Remove excess precision by forcing value through memory. */
15770 if (memory_operand (operands[1], VOIDmode))
15771 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15774 enum ix86_stack_slot slot = (virtuals_instantiated
15777 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15779 emit_move_insn (temp, operands[1]);
15780 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15783 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15784 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15785 cond = gen_rtx_fmt_ee (EQ, QImode,
15786 gen_rtx_REG (CCmode, FLAGS_REG),
15788 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15789 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15793 (define_expand "signbit<mode>2"
15794 [(use (match_operand:SI 0 "register_operand" ""))
15795 (use (match_operand:X87MODEF 1 "register_operand" ""))]
15796 "TARGET_USE_FANCY_MATH_387
15797 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15799 rtx mask = GEN_INT (0x0200);
15801 rtx scratch = gen_reg_rtx (HImode);
15803 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15804 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15808 ;; Block operation instructions
15811 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15814 [(set_attr "length" "1")
15815 (set_attr "length_immediate" "0")
15816 (set_attr "modrm" "0")])
15818 (define_expand "movmemsi"
15819 [(use (match_operand:BLK 0 "memory_operand" ""))
15820 (use (match_operand:BLK 1 "memory_operand" ""))
15821 (use (match_operand:SI 2 "nonmemory_operand" ""))
15822 (use (match_operand:SI 3 "const_int_operand" ""))
15823 (use (match_operand:SI 4 "const_int_operand" ""))
15824 (use (match_operand:SI 5 "const_int_operand" ""))]
15827 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15828 operands[4], operands[5]))
15834 (define_expand "movmemdi"
15835 [(use (match_operand:BLK 0 "memory_operand" ""))
15836 (use (match_operand:BLK 1 "memory_operand" ""))
15837 (use (match_operand:DI 2 "nonmemory_operand" ""))
15838 (use (match_operand:DI 3 "const_int_operand" ""))
15839 (use (match_operand:SI 4 "const_int_operand" ""))
15840 (use (match_operand:SI 5 "const_int_operand" ""))]
15843 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15844 operands[4], operands[5]))
15850 ;; Most CPUs don't like single string operations
15851 ;; Handle this case here to simplify previous expander.
15853 (define_expand "strmov"
15854 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15855 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15856 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15857 (clobber (reg:CC FLAGS_REG))])
15858 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15859 (clobber (reg:CC FLAGS_REG))])]
15862 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15864 /* If .md ever supports :P for Pmode, these can be directly
15865 in the pattern above. */
15866 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15867 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15869 /* Can't use this if the user has appropriated esi or edi. */
15870 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15871 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15873 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15874 operands[2], operands[3],
15875 operands[5], operands[6]));
15879 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15882 (define_expand "strmov_singleop"
15883 [(parallel [(set (match_operand 1 "memory_operand" "")
15884 (match_operand 3 "memory_operand" ""))
15885 (set (match_operand 0 "register_operand" "")
15886 (match_operand 4 "" ""))
15887 (set (match_operand 2 "register_operand" "")
15888 (match_operand 5 "" ""))])]
15890 "ix86_current_function_needs_cld = 1;")
15892 (define_insn "*strmovdi_rex_1"
15893 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15894 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15895 (set (match_operand:DI 0 "register_operand" "=D")
15896 (plus:DI (match_dup 2)
15898 (set (match_operand:DI 1 "register_operand" "=S")
15899 (plus:DI (match_dup 3)
15903 [(set_attr "type" "str")
15904 (set_attr "mode" "DI")
15905 (set_attr "memory" "both")])
15907 (define_insn "*strmovsi_1"
15908 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15909 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15910 (set (match_operand:SI 0 "register_operand" "=D")
15911 (plus:SI (match_dup 2)
15913 (set (match_operand:SI 1 "register_operand" "=S")
15914 (plus:SI (match_dup 3)
15918 [(set_attr "type" "str")
15919 (set_attr "mode" "SI")
15920 (set_attr "memory" "both")])
15922 (define_insn "*strmovsi_rex_1"
15923 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15924 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15925 (set (match_operand:DI 0 "register_operand" "=D")
15926 (plus:DI (match_dup 2)
15928 (set (match_operand:DI 1 "register_operand" "=S")
15929 (plus:DI (match_dup 3)
15933 [(set_attr "type" "str")
15934 (set_attr "mode" "SI")
15935 (set_attr "memory" "both")])
15937 (define_insn "*strmovhi_1"
15938 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15939 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15940 (set (match_operand:SI 0 "register_operand" "=D")
15941 (plus:SI (match_dup 2)
15943 (set (match_operand:SI 1 "register_operand" "=S")
15944 (plus:SI (match_dup 3)
15948 [(set_attr "type" "str")
15949 (set_attr "memory" "both")
15950 (set_attr "mode" "HI")])
15952 (define_insn "*strmovhi_rex_1"
15953 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15954 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15955 (set (match_operand:DI 0 "register_operand" "=D")
15956 (plus:DI (match_dup 2)
15958 (set (match_operand:DI 1 "register_operand" "=S")
15959 (plus:DI (match_dup 3)
15963 [(set_attr "type" "str")
15964 (set_attr "memory" "both")
15965 (set_attr "mode" "HI")])
15967 (define_insn "*strmovqi_1"
15968 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15969 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15970 (set (match_operand:SI 0 "register_operand" "=D")
15971 (plus:SI (match_dup 2)
15973 (set (match_operand:SI 1 "register_operand" "=S")
15974 (plus:SI (match_dup 3)
15978 [(set_attr "type" "str")
15979 (set_attr "memory" "both")
15980 (set_attr "mode" "QI")])
15982 (define_insn "*strmovqi_rex_1"
15983 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15984 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15985 (set (match_operand:DI 0 "register_operand" "=D")
15986 (plus:DI (match_dup 2)
15988 (set (match_operand:DI 1 "register_operand" "=S")
15989 (plus:DI (match_dup 3)
15993 [(set_attr "type" "str")
15994 (set_attr "memory" "both")
15995 (set_attr "prefix_rex" "0")
15996 (set_attr "mode" "QI")])
15998 (define_expand "rep_mov"
15999 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16000 (set (match_operand 0 "register_operand" "")
16001 (match_operand 5 "" ""))
16002 (set (match_operand 2 "register_operand" "")
16003 (match_operand 6 "" ""))
16004 (set (match_operand 1 "memory_operand" "")
16005 (match_operand 3 "memory_operand" ""))
16006 (use (match_dup 4))])]
16008 "ix86_current_function_needs_cld = 1;")
16010 (define_insn "*rep_movdi_rex64"
16011 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16012 (set (match_operand:DI 0 "register_operand" "=D")
16013 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16015 (match_operand:DI 3 "register_operand" "0")))
16016 (set (match_operand:DI 1 "register_operand" "=S")
16017 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16018 (match_operand:DI 4 "register_operand" "1")))
16019 (set (mem:BLK (match_dup 3))
16020 (mem:BLK (match_dup 4)))
16021 (use (match_dup 5))]
16024 [(set_attr "type" "str")
16025 (set_attr "prefix_rep" "1")
16026 (set_attr "memory" "both")
16027 (set_attr "mode" "DI")])
16029 (define_insn "*rep_movsi"
16030 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16031 (set (match_operand:SI 0 "register_operand" "=D")
16032 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16034 (match_operand:SI 3 "register_operand" "0")))
16035 (set (match_operand:SI 1 "register_operand" "=S")
16036 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16037 (match_operand:SI 4 "register_operand" "1")))
16038 (set (mem:BLK (match_dup 3))
16039 (mem:BLK (match_dup 4)))
16040 (use (match_dup 5))]
16043 [(set_attr "type" "str")
16044 (set_attr "prefix_rep" "1")
16045 (set_attr "memory" "both")
16046 (set_attr "mode" "SI")])
16048 (define_insn "*rep_movsi_rex64"
16049 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16050 (set (match_operand:DI 0 "register_operand" "=D")
16051 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16053 (match_operand:DI 3 "register_operand" "0")))
16054 (set (match_operand:DI 1 "register_operand" "=S")
16055 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16056 (match_operand:DI 4 "register_operand" "1")))
16057 (set (mem:BLK (match_dup 3))
16058 (mem:BLK (match_dup 4)))
16059 (use (match_dup 5))]
16062 [(set_attr "type" "str")
16063 (set_attr "prefix_rep" "1")
16064 (set_attr "memory" "both")
16065 (set_attr "mode" "SI")])
16067 (define_insn "*rep_movqi"
16068 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16069 (set (match_operand:SI 0 "register_operand" "=D")
16070 (plus:SI (match_operand:SI 3 "register_operand" "0")
16071 (match_operand:SI 5 "register_operand" "2")))
16072 (set (match_operand:SI 1 "register_operand" "=S")
16073 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16074 (set (mem:BLK (match_dup 3))
16075 (mem:BLK (match_dup 4)))
16076 (use (match_dup 5))]
16079 [(set_attr "type" "str")
16080 (set_attr "prefix_rep" "1")
16081 (set_attr "memory" "both")
16082 (set_attr "mode" "SI")])
16084 (define_insn "*rep_movqi_rex64"
16085 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16086 (set (match_operand:DI 0 "register_operand" "=D")
16087 (plus:DI (match_operand:DI 3 "register_operand" "0")
16088 (match_operand:DI 5 "register_operand" "2")))
16089 (set (match_operand:DI 1 "register_operand" "=S")
16090 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16091 (set (mem:BLK (match_dup 3))
16092 (mem:BLK (match_dup 4)))
16093 (use (match_dup 5))]
16096 [(set_attr "type" "str")
16097 (set_attr "prefix_rep" "1")
16098 (set_attr "memory" "both")
16099 (set_attr "mode" "SI")])
16101 (define_expand "setmemsi"
16102 [(use (match_operand:BLK 0 "memory_operand" ""))
16103 (use (match_operand:SI 1 "nonmemory_operand" ""))
16104 (use (match_operand 2 "const_int_operand" ""))
16105 (use (match_operand 3 "const_int_operand" ""))
16106 (use (match_operand:SI 4 "const_int_operand" ""))
16107 (use (match_operand:SI 5 "const_int_operand" ""))]
16110 if (ix86_expand_setmem (operands[0], operands[1],
16111 operands[2], operands[3],
16112 operands[4], operands[5]))
16118 (define_expand "setmemdi"
16119 [(use (match_operand:BLK 0 "memory_operand" ""))
16120 (use (match_operand:DI 1 "nonmemory_operand" ""))
16121 (use (match_operand 2 "const_int_operand" ""))
16122 (use (match_operand 3 "const_int_operand" ""))
16123 (use (match_operand 4 "const_int_operand" ""))
16124 (use (match_operand 5 "const_int_operand" ""))]
16127 if (ix86_expand_setmem (operands[0], operands[1],
16128 operands[2], operands[3],
16129 operands[4], operands[5]))
16135 ;; Most CPUs don't like single string operations
16136 ;; Handle this case here to simplify previous expander.
16138 (define_expand "strset"
16139 [(set (match_operand 1 "memory_operand" "")
16140 (match_operand 2 "register_operand" ""))
16141 (parallel [(set (match_operand 0 "register_operand" "")
16143 (clobber (reg:CC FLAGS_REG))])]
16146 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16147 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16149 /* If .md ever supports :P for Pmode, this can be directly
16150 in the pattern above. */
16151 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16152 GEN_INT (GET_MODE_SIZE (GET_MODE
16154 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16156 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16162 (define_expand "strset_singleop"
16163 [(parallel [(set (match_operand 1 "memory_operand" "")
16164 (match_operand 2 "register_operand" ""))
16165 (set (match_operand 0 "register_operand" "")
16166 (match_operand 3 "" ""))])]
16168 "ix86_current_function_needs_cld = 1;")
16170 (define_insn "*strsetdi_rex_1"
16171 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16172 (match_operand:DI 2 "register_operand" "a"))
16173 (set (match_operand:DI 0 "register_operand" "=D")
16174 (plus:DI (match_dup 1)
16178 [(set_attr "type" "str")
16179 (set_attr "memory" "store")
16180 (set_attr "mode" "DI")])
16182 (define_insn "*strsetsi_1"
16183 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16184 (match_operand:SI 2 "register_operand" "a"))
16185 (set (match_operand:SI 0 "register_operand" "=D")
16186 (plus:SI (match_dup 1)
16190 [(set_attr "type" "str")
16191 (set_attr "memory" "store")
16192 (set_attr "mode" "SI")])
16194 (define_insn "*strsetsi_rex_1"
16195 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16196 (match_operand:SI 2 "register_operand" "a"))
16197 (set (match_operand:DI 0 "register_operand" "=D")
16198 (plus:DI (match_dup 1)
16202 [(set_attr "type" "str")
16203 (set_attr "memory" "store")
16204 (set_attr "mode" "SI")])
16206 (define_insn "*strsethi_1"
16207 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16208 (match_operand:HI 2 "register_operand" "a"))
16209 (set (match_operand:SI 0 "register_operand" "=D")
16210 (plus:SI (match_dup 1)
16214 [(set_attr "type" "str")
16215 (set_attr "memory" "store")
16216 (set_attr "mode" "HI")])
16218 (define_insn "*strsethi_rex_1"
16219 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16220 (match_operand:HI 2 "register_operand" "a"))
16221 (set (match_operand:DI 0 "register_operand" "=D")
16222 (plus:DI (match_dup 1)
16226 [(set_attr "type" "str")
16227 (set_attr "memory" "store")
16228 (set_attr "mode" "HI")])
16230 (define_insn "*strsetqi_1"
16231 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16232 (match_operand:QI 2 "register_operand" "a"))
16233 (set (match_operand:SI 0 "register_operand" "=D")
16234 (plus:SI (match_dup 1)
16238 [(set_attr "type" "str")
16239 (set_attr "memory" "store")
16240 (set_attr "mode" "QI")])
16242 (define_insn "*strsetqi_rex_1"
16243 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16244 (match_operand:QI 2 "register_operand" "a"))
16245 (set (match_operand:DI 0 "register_operand" "=D")
16246 (plus:DI (match_dup 1)
16250 [(set_attr "type" "str")
16251 (set_attr "memory" "store")
16252 (set_attr "prefix_rex" "0")
16253 (set_attr "mode" "QI")])
16255 (define_expand "rep_stos"
16256 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16257 (set (match_operand 0 "register_operand" "")
16258 (match_operand 4 "" ""))
16259 (set (match_operand 2 "memory_operand" "") (const_int 0))
16260 (use (match_operand 3 "register_operand" ""))
16261 (use (match_dup 1))])]
16263 "ix86_current_function_needs_cld = 1;")
16265 (define_insn "*rep_stosdi_rex64"
16266 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16267 (set (match_operand:DI 0 "register_operand" "=D")
16268 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16270 (match_operand:DI 3 "register_operand" "0")))
16271 (set (mem:BLK (match_dup 3))
16273 (use (match_operand:DI 2 "register_operand" "a"))
16274 (use (match_dup 4))]
16277 [(set_attr "type" "str")
16278 (set_attr "prefix_rep" "1")
16279 (set_attr "memory" "store")
16280 (set_attr "mode" "DI")])
16282 (define_insn "*rep_stossi"
16283 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16284 (set (match_operand:SI 0 "register_operand" "=D")
16285 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16287 (match_operand:SI 3 "register_operand" "0")))
16288 (set (mem:BLK (match_dup 3))
16290 (use (match_operand:SI 2 "register_operand" "a"))
16291 (use (match_dup 4))]
16294 [(set_attr "type" "str")
16295 (set_attr "prefix_rep" "1")
16296 (set_attr "memory" "store")
16297 (set_attr "mode" "SI")])
16299 (define_insn "*rep_stossi_rex64"
16300 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16301 (set (match_operand:DI 0 "register_operand" "=D")
16302 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16304 (match_operand:DI 3 "register_operand" "0")))
16305 (set (mem:BLK (match_dup 3))
16307 (use (match_operand:SI 2 "register_operand" "a"))
16308 (use (match_dup 4))]
16311 [(set_attr "type" "str")
16312 (set_attr "prefix_rep" "1")
16313 (set_attr "memory" "store")
16314 (set_attr "mode" "SI")])
16316 (define_insn "*rep_stosqi"
16317 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16318 (set (match_operand:SI 0 "register_operand" "=D")
16319 (plus:SI (match_operand:SI 3 "register_operand" "0")
16320 (match_operand:SI 4 "register_operand" "1")))
16321 (set (mem:BLK (match_dup 3))
16323 (use (match_operand:QI 2 "register_operand" "a"))
16324 (use (match_dup 4))]
16327 [(set_attr "type" "str")
16328 (set_attr "prefix_rep" "1")
16329 (set_attr "memory" "store")
16330 (set_attr "mode" "QI")])
16332 (define_insn "*rep_stosqi_rex64"
16333 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16334 (set (match_operand:DI 0 "register_operand" "=D")
16335 (plus:DI (match_operand:DI 3 "register_operand" "0")
16336 (match_operand:DI 4 "register_operand" "1")))
16337 (set (mem:BLK (match_dup 3))
16339 (use (match_operand:QI 2 "register_operand" "a"))
16340 (use (match_dup 4))]
16343 [(set_attr "type" "str")
16344 (set_attr "prefix_rep" "1")
16345 (set_attr "memory" "store")
16346 (set_attr "prefix_rex" "0")
16347 (set_attr "mode" "QI")])
16349 (define_expand "cmpstrnsi"
16350 [(set (match_operand:SI 0 "register_operand" "")
16351 (compare:SI (match_operand:BLK 1 "general_operand" "")
16352 (match_operand:BLK 2 "general_operand" "")))
16353 (use (match_operand 3 "general_operand" ""))
16354 (use (match_operand 4 "immediate_operand" ""))]
16357 rtx addr1, addr2, out, outlow, count, countreg, align;
16359 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16362 /* Can't use this if the user has appropriated esi or edi. */
16363 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
16368 out = gen_reg_rtx (SImode);
16370 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16371 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16372 if (addr1 != XEXP (operands[1], 0))
16373 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16374 if (addr2 != XEXP (operands[2], 0))
16375 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16377 count = operands[3];
16378 countreg = ix86_zero_extend_to_Pmode (count);
16380 /* %%% Iff we are testing strict equality, we can use known alignment
16381 to good advantage. This may be possible with combine, particularly
16382 once cc0 is dead. */
16383 align = operands[4];
16385 if (CONST_INT_P (count))
16387 if (INTVAL (count) == 0)
16389 emit_move_insn (operands[0], const0_rtx);
16392 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16393 operands[1], operands[2]));
16397 rtx (*cmp_insn)(rtx, rtx);
16400 cmp_insn = gen_cmpdi_1;
16402 cmp_insn = gen_cmpsi_1;
16403 emit_insn (cmp_insn (countreg, countreg));
16404 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16405 operands[1], operands[2]));
16408 outlow = gen_lowpart (QImode, out);
16409 emit_insn (gen_cmpintqi (outlow));
16410 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16412 if (operands[0] != out)
16413 emit_move_insn (operands[0], out);
16418 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16420 (define_expand "cmpintqi"
16421 [(set (match_dup 1)
16422 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16424 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16425 (parallel [(set (match_operand:QI 0 "register_operand" "")
16426 (minus:QI (match_dup 1)
16428 (clobber (reg:CC FLAGS_REG))])]
16430 "operands[1] = gen_reg_rtx (QImode);
16431 operands[2] = gen_reg_rtx (QImode);")
16433 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16434 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16436 (define_expand "cmpstrnqi_nz_1"
16437 [(parallel [(set (reg:CC FLAGS_REG)
16438 (compare:CC (match_operand 4 "memory_operand" "")
16439 (match_operand 5 "memory_operand" "")))
16440 (use (match_operand 2 "register_operand" ""))
16441 (use (match_operand:SI 3 "immediate_operand" ""))
16442 (clobber (match_operand 0 "register_operand" ""))
16443 (clobber (match_operand 1 "register_operand" ""))
16444 (clobber (match_dup 2))])]
16446 "ix86_current_function_needs_cld = 1;")
16448 (define_insn "*cmpstrnqi_nz_1"
16449 [(set (reg:CC FLAGS_REG)
16450 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16451 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16452 (use (match_operand:SI 6 "register_operand" "2"))
16453 (use (match_operand:SI 3 "immediate_operand" "i"))
16454 (clobber (match_operand:SI 0 "register_operand" "=S"))
16455 (clobber (match_operand:SI 1 "register_operand" "=D"))
16456 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16459 [(set_attr "type" "str")
16460 (set_attr "mode" "QI")
16461 (set_attr "prefix_rep" "1")])
16463 (define_insn "*cmpstrnqi_nz_rex_1"
16464 [(set (reg:CC FLAGS_REG)
16465 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16466 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16467 (use (match_operand:DI 6 "register_operand" "2"))
16468 (use (match_operand:SI 3 "immediate_operand" "i"))
16469 (clobber (match_operand:DI 0 "register_operand" "=S"))
16470 (clobber (match_operand:DI 1 "register_operand" "=D"))
16471 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16474 [(set_attr "type" "str")
16475 (set_attr "mode" "QI")
16476 (set_attr "prefix_rex" "0")
16477 (set_attr "prefix_rep" "1")])
16479 ;; The same, but the count is not known to not be zero.
16481 (define_expand "cmpstrnqi_1"
16482 [(parallel [(set (reg:CC FLAGS_REG)
16483 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16485 (compare:CC (match_operand 4 "memory_operand" "")
16486 (match_operand 5 "memory_operand" ""))
16488 (use (match_operand:SI 3 "immediate_operand" ""))
16489 (use (reg:CC FLAGS_REG))
16490 (clobber (match_operand 0 "register_operand" ""))
16491 (clobber (match_operand 1 "register_operand" ""))
16492 (clobber (match_dup 2))])]
16494 "ix86_current_function_needs_cld = 1;")
16496 (define_insn "*cmpstrnqi_1"
16497 [(set (reg:CC FLAGS_REG)
16498 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16500 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16501 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16503 (use (match_operand:SI 3 "immediate_operand" "i"))
16504 (use (reg:CC FLAGS_REG))
16505 (clobber (match_operand:SI 0 "register_operand" "=S"))
16506 (clobber (match_operand:SI 1 "register_operand" "=D"))
16507 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16510 [(set_attr "type" "str")
16511 (set_attr "mode" "QI")
16512 (set_attr "prefix_rep" "1")])
16514 (define_insn "*cmpstrnqi_rex_1"
16515 [(set (reg:CC FLAGS_REG)
16516 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16518 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16519 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16521 (use (match_operand:SI 3 "immediate_operand" "i"))
16522 (use (reg:CC FLAGS_REG))
16523 (clobber (match_operand:DI 0 "register_operand" "=S"))
16524 (clobber (match_operand:DI 1 "register_operand" "=D"))
16525 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16528 [(set_attr "type" "str")
16529 (set_attr "mode" "QI")
16530 (set_attr "prefix_rex" "0")
16531 (set_attr "prefix_rep" "1")])
16533 (define_expand "strlensi"
16534 [(set (match_operand:SI 0 "register_operand" "")
16535 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16536 (match_operand:QI 2 "immediate_operand" "")
16537 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16540 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16546 (define_expand "strlendi"
16547 [(set (match_operand:DI 0 "register_operand" "")
16548 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16549 (match_operand:QI 2 "immediate_operand" "")
16550 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16553 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16559 (define_expand "strlenqi_1"
16560 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16561 (clobber (match_operand 1 "register_operand" ""))
16562 (clobber (reg:CC FLAGS_REG))])]
16564 "ix86_current_function_needs_cld = 1;")
16566 (define_insn "*strlenqi_1"
16567 [(set (match_operand:SI 0 "register_operand" "=&c")
16568 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16569 (match_operand:QI 2 "register_operand" "a")
16570 (match_operand:SI 3 "immediate_operand" "i")
16571 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16572 (clobber (match_operand:SI 1 "register_operand" "=D"))
16573 (clobber (reg:CC FLAGS_REG))]
16576 [(set_attr "type" "str")
16577 (set_attr "mode" "QI")
16578 (set_attr "prefix_rep" "1")])
16580 (define_insn "*strlenqi_rex_1"
16581 [(set (match_operand:DI 0 "register_operand" "=&c")
16582 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16583 (match_operand:QI 2 "register_operand" "a")
16584 (match_operand:DI 3 "immediate_operand" "i")
16585 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16586 (clobber (match_operand:DI 1 "register_operand" "=D"))
16587 (clobber (reg:CC FLAGS_REG))]
16590 [(set_attr "type" "str")
16591 (set_attr "mode" "QI")
16592 (set_attr "prefix_rex" "0")
16593 (set_attr "prefix_rep" "1")])
16595 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16596 ;; handled in combine, but it is not currently up to the task.
16597 ;; When used for their truth value, the cmpstrn* expanders generate
16606 ;; The intermediate three instructions are unnecessary.
16608 ;; This one handles cmpstrn*_nz_1...
16611 (set (reg:CC FLAGS_REG)
16612 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16613 (mem:BLK (match_operand 5 "register_operand" ""))))
16614 (use (match_operand 6 "register_operand" ""))
16615 (use (match_operand:SI 3 "immediate_operand" ""))
16616 (clobber (match_operand 0 "register_operand" ""))
16617 (clobber (match_operand 1 "register_operand" ""))
16618 (clobber (match_operand 2 "register_operand" ""))])
16619 (set (match_operand:QI 7 "register_operand" "")
16620 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16621 (set (match_operand:QI 8 "register_operand" "")
16622 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16623 (set (reg FLAGS_REG)
16624 (compare (match_dup 7) (match_dup 8)))
16626 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16628 (set (reg:CC FLAGS_REG)
16629 (compare:CC (mem:BLK (match_dup 4))
16630 (mem:BLK (match_dup 5))))
16631 (use (match_dup 6))
16632 (use (match_dup 3))
16633 (clobber (match_dup 0))
16634 (clobber (match_dup 1))
16635 (clobber (match_dup 2))])]
16638 ;; ...and this one handles cmpstrn*_1.
16641 (set (reg:CC FLAGS_REG)
16642 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16644 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16645 (mem:BLK (match_operand 5 "register_operand" "")))
16647 (use (match_operand:SI 3 "immediate_operand" ""))
16648 (use (reg:CC FLAGS_REG))
16649 (clobber (match_operand 0 "register_operand" ""))
16650 (clobber (match_operand 1 "register_operand" ""))
16651 (clobber (match_operand 2 "register_operand" ""))])
16652 (set (match_operand:QI 7 "register_operand" "")
16653 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16654 (set (match_operand:QI 8 "register_operand" "")
16655 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16656 (set (reg FLAGS_REG)
16657 (compare (match_dup 7) (match_dup 8)))
16659 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16661 (set (reg:CC FLAGS_REG)
16662 (if_then_else:CC (ne (match_dup 6)
16664 (compare:CC (mem:BLK (match_dup 4))
16665 (mem:BLK (match_dup 5)))
16667 (use (match_dup 3))
16668 (use (reg:CC FLAGS_REG))
16669 (clobber (match_dup 0))
16670 (clobber (match_dup 1))
16671 (clobber (match_dup 2))])]
16676 ;; Conditional move instructions.
16678 (define_expand "mov<mode>cc"
16679 [(set (match_operand:SWIM 0 "register_operand" "")
16680 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16681 (match_operand:SWIM 2 "general_operand" "")
16682 (match_operand:SWIM 3 "general_operand" "")))]
16684 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16686 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16687 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16688 ;; So just document what we're doing explicitly.
16690 (define_expand "x86_mov<mode>cc_0_m1"
16692 [(set (match_operand:SWI48 0 "register_operand" "")
16693 (if_then_else:SWI48
16694 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16695 [(match_operand 1 "flags_reg_operand" "")
16699 (clobber (reg:CC FLAGS_REG))])]
16703 (define_insn "*x86_mov<mode>cc_0_m1"
16704 [(set (match_operand:SWI48 0 "register_operand" "=r")
16705 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16706 [(reg FLAGS_REG) (const_int 0)])
16709 (clobber (reg:CC FLAGS_REG))]
16711 "sbb{<imodesuffix>}\t%0, %0"
16712 ; Since we don't have the proper number of operands for an alu insn,
16713 ; fill in all the blanks.
16714 [(set_attr "type" "alu")
16715 (set_attr "use_carry" "1")
16716 (set_attr "pent_pair" "pu")
16717 (set_attr "memory" "none")
16718 (set_attr "imm_disp" "false")
16719 (set_attr "mode" "<MODE>")
16720 (set_attr "length_immediate" "0")])
16722 (define_insn "*x86_mov<mode>cc_0_m1_se"
16723 [(set (match_operand:SWI48 0 "register_operand" "=r")
16724 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16725 [(reg FLAGS_REG) (const_int 0)])
16728 (clobber (reg:CC FLAGS_REG))]
16730 "sbb{<imodesuffix>}\t%0, %0"
16731 [(set_attr "type" "alu")
16732 (set_attr "use_carry" "1")
16733 (set_attr "pent_pair" "pu")
16734 (set_attr "memory" "none")
16735 (set_attr "imm_disp" "false")
16736 (set_attr "mode" "<MODE>")
16737 (set_attr "length_immediate" "0")])
16739 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16740 [(set (match_operand:SWI48 0 "register_operand" "=r")
16741 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16742 [(reg FLAGS_REG) (const_int 0)])))]
16744 "sbb{<imodesuffix>}\t%0, %0"
16745 [(set_attr "type" "alu")
16746 (set_attr "use_carry" "1")
16747 (set_attr "pent_pair" "pu")
16748 (set_attr "memory" "none")
16749 (set_attr "imm_disp" "false")
16750 (set_attr "mode" "<MODE>")
16751 (set_attr "length_immediate" "0")])
16753 (define_insn "*mov<mode>cc_noc"
16754 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16755 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16756 [(reg FLAGS_REG) (const_int 0)])
16757 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16758 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16759 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16761 cmov%O2%C1\t{%2, %0|%0, %2}
16762 cmov%O2%c1\t{%3, %0|%0, %3}"
16763 [(set_attr "type" "icmov")
16764 (set_attr "mode" "<MODE>")])
16766 (define_insn_and_split "*movqicc_noc"
16767 [(set (match_operand:QI 0 "register_operand" "=r,r")
16768 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16769 [(match_operand 4 "flags_reg_operand" "")
16771 (match_operand:QI 2 "register_operand" "r,0")
16772 (match_operand:QI 3 "register_operand" "0,r")))]
16773 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16775 "&& reload_completed"
16776 [(set (match_dup 0)
16777 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16780 "operands[0] = gen_lowpart (SImode, operands[0]);
16781 operands[2] = gen_lowpart (SImode, operands[2]);
16782 operands[3] = gen_lowpart (SImode, operands[3]);"
16783 [(set_attr "type" "icmov")
16784 (set_attr "mode" "SI")])
16786 (define_expand "mov<mode>cc"
16787 [(set (match_operand:X87MODEF 0 "register_operand" "")
16788 (if_then_else:X87MODEF
16789 (match_operand 1 "ix86_fp_comparison_operator" "")
16790 (match_operand:X87MODEF 2 "register_operand" "")
16791 (match_operand:X87MODEF 3 "register_operand" "")))]
16792 "(TARGET_80387 && TARGET_CMOVE)
16793 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16794 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16796 (define_insn "*movsfcc_1_387"
16797 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16798 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16799 [(reg FLAGS_REG) (const_int 0)])
16800 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16801 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16802 "TARGET_80387 && TARGET_CMOVE
16803 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16805 fcmov%F1\t{%2, %0|%0, %2}
16806 fcmov%f1\t{%3, %0|%0, %3}
16807 cmov%O2%C1\t{%2, %0|%0, %2}
16808 cmov%O2%c1\t{%3, %0|%0, %3}"
16809 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16810 (set_attr "mode" "SF,SF,SI,SI")])
16812 (define_insn "*movdfcc_1"
16813 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16814 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16815 [(reg FLAGS_REG) (const_int 0)])
16816 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16817 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16818 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16819 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16821 fcmov%F1\t{%2, %0|%0, %2}
16822 fcmov%f1\t{%3, %0|%0, %3}
16825 [(set_attr "type" "fcmov,fcmov,multi,multi")
16826 (set_attr "mode" "DF")])
16828 (define_insn "*movdfcc_1_rex64"
16829 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16830 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16831 [(reg FLAGS_REG) (const_int 0)])
16832 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16833 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16834 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16835 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16837 fcmov%F1\t{%2, %0|%0, %2}
16838 fcmov%f1\t{%3, %0|%0, %3}
16839 cmov%O2%C1\t{%2, %0|%0, %2}
16840 cmov%O2%c1\t{%3, %0|%0, %3}"
16841 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16842 (set_attr "mode" "DF")])
16845 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16846 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16847 [(match_operand 4 "flags_reg_operand" "")
16849 (match_operand:DF 2 "nonimmediate_operand" "")
16850 (match_operand:DF 3 "nonimmediate_operand" "")))]
16851 "!TARGET_64BIT && reload_completed"
16852 [(set (match_dup 2)
16853 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16857 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16860 "split_di (&operands[2], 2, &operands[5], &operands[7]);
16861 split_di (&operands[0], 1, &operands[2], &operands[3]);")
16863 (define_insn "*movxfcc_1"
16864 [(set (match_operand:XF 0 "register_operand" "=f,f")
16865 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16866 [(reg FLAGS_REG) (const_int 0)])
16867 (match_operand:XF 2 "register_operand" "f,0")
16868 (match_operand:XF 3 "register_operand" "0,f")))]
16869 "TARGET_80387 && TARGET_CMOVE"
16871 fcmov%F1\t{%2, %0|%0, %2}
16872 fcmov%f1\t{%3, %0|%0, %3}"
16873 [(set_attr "type" "fcmov")
16874 (set_attr "mode" "XF")])
16876 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16877 ;; the scalar versions to have only XMM registers as operands.
16879 ;; XOP conditional move
16880 (define_insn "*xop_pcmov_<mode>"
16881 [(set (match_operand:MODEF 0 "register_operand" "=x")
16882 (if_then_else:MODEF
16883 (match_operand:MODEF 1 "register_operand" "x")
16884 (match_operand:MODEF 2 "register_operand" "x")
16885 (match_operand:MODEF 3 "register_operand" "x")))]
16887 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16888 [(set_attr "type" "sse4arg")])
16890 ;; These versions of the min/max patterns are intentionally ignorant of
16891 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16892 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16893 ;; are undefined in this condition, we're certain this is correct.
16895 (define_insn "*avx_<code><mode>3"
16896 [(set (match_operand:MODEF 0 "register_operand" "=x")
16898 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16899 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16900 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16901 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16902 [(set_attr "type" "sseadd")
16903 (set_attr "prefix" "vex")
16904 (set_attr "mode" "<MODE>")])
16906 (define_insn "<code><mode>3"
16907 [(set (match_operand:MODEF 0 "register_operand" "=x")
16909 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16910 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16911 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16912 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16913 [(set_attr "type" "sseadd")
16914 (set_attr "mode" "<MODE>")])
16916 ;; These versions of the min/max patterns implement exactly the operations
16917 ;; min = (op1 < op2 ? op1 : op2)
16918 ;; max = (!(op1 < op2) ? op1 : op2)
16919 ;; Their operands are not commutative, and thus they may be used in the
16920 ;; presence of -0.0 and NaN.
16922 (define_insn "*avx_ieee_smin<mode>3"
16923 [(set (match_operand:MODEF 0 "register_operand" "=x")
16925 [(match_operand:MODEF 1 "register_operand" "x")
16926 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16928 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16929 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16930 [(set_attr "type" "sseadd")
16931 (set_attr "prefix" "vex")
16932 (set_attr "mode" "<MODE>")])
16934 (define_insn "*ieee_smin<mode>3"
16935 [(set (match_operand:MODEF 0 "register_operand" "=x")
16937 [(match_operand:MODEF 1 "register_operand" "0")
16938 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16940 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16941 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16942 [(set_attr "type" "sseadd")
16943 (set_attr "mode" "<MODE>")])
16945 (define_insn "*avx_ieee_smax<mode>3"
16946 [(set (match_operand:MODEF 0 "register_operand" "=x")
16948 [(match_operand:MODEF 1 "register_operand" "0")
16949 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16951 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16952 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16953 [(set_attr "type" "sseadd")
16954 (set_attr "prefix" "vex")
16955 (set_attr "mode" "<MODE>")])
16957 (define_insn "*ieee_smax<mode>3"
16958 [(set (match_operand:MODEF 0 "register_operand" "=x")
16960 [(match_operand:MODEF 1 "register_operand" "0")
16961 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16963 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16964 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16965 [(set_attr "type" "sseadd")
16966 (set_attr "mode" "<MODE>")])
16968 ;; Make two stack loads independent:
16970 ;; fld %st(0) -> fld bb
16971 ;; fmul bb fmul %st(1), %st
16973 ;; Actually we only match the last two instructions for simplicity.
16975 [(set (match_operand 0 "fp_register_operand" "")
16976 (match_operand 1 "fp_register_operand" ""))
16978 (match_operator 2 "binary_fp_operator"
16980 (match_operand 3 "memory_operand" "")]))]
16981 "REGNO (operands[0]) != REGNO (operands[1])"
16982 [(set (match_dup 0) (match_dup 3))
16983 (set (match_dup 0) (match_dup 4))]
16985 ;; The % modifier is not operational anymore in peephole2's, so we have to
16986 ;; swap the operands manually in the case of addition and multiplication.
16987 "if (COMMUTATIVE_ARITH_P (operands[2]))
16988 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16989 operands[0], operands[1]);
16991 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16992 operands[1], operands[0]);")
16994 ;; Conditional addition patterns
16995 (define_expand "add<mode>cc"
16996 [(match_operand:SWI 0 "register_operand" "")
16997 (match_operand 1 "comparison_operator" "")
16998 (match_operand:SWI 2 "register_operand" "")
16999 (match_operand:SWI 3 "const_int_operand" "")]
17001 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17004 ;; Misc patterns (?)
17006 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17007 ;; Otherwise there will be nothing to keep
17009 ;; [(set (reg ebp) (reg esp))]
17010 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17011 ;; (clobber (eflags)]
17012 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17014 ;; in proper program order.
17015 (define_insn "pro_epilogue_adjust_stack_1"
17016 [(set (match_operand:SI 0 "register_operand" "=r,r")
17017 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17018 (match_operand:SI 2 "immediate_operand" "i,i")))
17019 (clobber (reg:CC FLAGS_REG))
17020 (clobber (mem:BLK (scratch)))]
17023 switch (get_attr_type (insn))
17026 return "mov{l}\t{%1, %0|%0, %1}";
17029 if (CONST_INT_P (operands[2])
17030 && (INTVAL (operands[2]) == 128
17031 || (INTVAL (operands[2]) < 0
17032 && INTVAL (operands[2]) != -128)))
17034 operands[2] = GEN_INT (-INTVAL (operands[2]));
17035 return "sub{l}\t{%2, %0|%0, %2}";
17037 return "add{l}\t{%2, %0|%0, %2}";
17040 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17041 return "lea{l}\t{%a2, %0|%0, %a2}";
17044 gcc_unreachable ();
17047 [(set (attr "type")
17048 (cond [(and (eq_attr "alternative" "0")
17049 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
17050 (const_string "alu")
17051 (match_operand:SI 2 "const0_operand" "")
17052 (const_string "imov")
17054 (const_string "lea")))
17055 (set (attr "length_immediate")
17056 (cond [(eq_attr "type" "imov")
17058 (and (eq_attr "type" "alu")
17059 (match_operand 2 "const128_operand" ""))
17062 (const_string "*")))
17063 (set_attr "mode" "SI")])
17065 (define_insn "pro_epilogue_adjust_stack_rex64"
17066 [(set (match_operand:DI 0 "register_operand" "=r,r")
17067 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17068 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17069 (clobber (reg:CC FLAGS_REG))
17070 (clobber (mem:BLK (scratch)))]
17073 switch (get_attr_type (insn))
17076 return "mov{q}\t{%1, %0|%0, %1}";
17079 if (CONST_INT_P (operands[2])
17080 /* Avoid overflows. */
17081 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17082 && (INTVAL (operands[2]) == 128
17083 || (INTVAL (operands[2]) < 0
17084 && INTVAL (operands[2]) != -128)))
17086 operands[2] = GEN_INT (-INTVAL (operands[2]));
17087 return "sub{q}\t{%2, %0|%0, %2}";
17089 return "add{q}\t{%2, %0|%0, %2}";
17092 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17093 return "lea{q}\t{%a2, %0|%0, %a2}";
17096 gcc_unreachable ();
17099 [(set (attr "type")
17100 (cond [(and (eq_attr "alternative" "0")
17101 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
17102 (const_string "alu")
17103 (match_operand:DI 2 "const0_operand" "")
17104 (const_string "imov")
17106 (const_string "lea")))
17107 (set (attr "length_immediate")
17108 (cond [(eq_attr "type" "imov")
17110 (and (eq_attr "type" "alu")
17111 (match_operand 2 "const128_operand" ""))
17114 (const_string "*")))
17115 (set_attr "mode" "DI")])
17117 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17118 [(set (match_operand:DI 0 "register_operand" "=r,r")
17119 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17120 (match_operand:DI 3 "immediate_operand" "i,i")))
17121 (use (match_operand:DI 2 "register_operand" "r,r"))
17122 (clobber (reg:CC FLAGS_REG))
17123 (clobber (mem:BLK (scratch)))]
17126 switch (get_attr_type (insn))
17129 return "add{q}\t{%2, %0|%0, %2}";
17132 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17133 return "lea{q}\t{%a2, %0|%0, %a2}";
17136 gcc_unreachable ();
17139 [(set_attr "type" "alu,lea")
17140 (set_attr "mode" "DI")])
17142 (define_insn "allocate_stack_worker_32"
17143 [(set (match_operand:SI 0 "register_operand" "=a")
17144 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
17145 UNSPECV_STACK_PROBE))
17146 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
17147 (clobber (reg:CC FLAGS_REG))]
17148 "!TARGET_64BIT && TARGET_STACK_PROBE"
17150 [(set_attr "type" "multi")
17151 (set_attr "length" "5")])
17153 (define_insn "allocate_stack_worker_64"
17154 [(set (match_operand:DI 0 "register_operand" "=a")
17155 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
17156 UNSPECV_STACK_PROBE))
17157 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
17158 (clobber (reg:DI R10_REG))
17159 (clobber (reg:DI R11_REG))
17160 (clobber (reg:CC FLAGS_REG))]
17161 "TARGET_64BIT && TARGET_STACK_PROBE"
17163 [(set_attr "type" "multi")
17164 (set_attr "length" "5")])
17166 (define_expand "allocate_stack"
17167 [(match_operand 0 "register_operand" "")
17168 (match_operand 1 "general_operand" "")]
17169 "TARGET_STACK_PROBE"
17173 #ifndef CHECK_STACK_LIMIT
17174 #define CHECK_STACK_LIMIT 0
17177 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17178 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17180 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
17181 stack_pointer_rtx, 0, OPTAB_DIRECT);
17182 if (x != stack_pointer_rtx)
17183 emit_move_insn (stack_pointer_rtx, x);
17187 x = copy_to_mode_reg (Pmode, operands[1]);
17189 x = gen_allocate_stack_worker_64 (x, x);
17191 x = gen_allocate_stack_worker_32 (x, x);
17195 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17199 ;; Use IOR for stack probes, this is shorter.
17200 (define_expand "probe_stack"
17201 [(match_operand 0 "memory_operand" "")]
17204 if (GET_MODE (operands[0]) == DImode)
17205 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
17207 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
17211 (define_expand "builtin_setjmp_receiver"
17212 [(label_ref (match_operand 0 "" ""))]
17213 "!TARGET_64BIT && flag_pic"
17219 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
17220 rtx label_rtx = gen_label_rtx ();
17221 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17222 xops[0] = xops[1] = picreg;
17223 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17224 ix86_expand_binary_operator (MINUS, SImode, xops);
17228 emit_insn (gen_set_got (pic_offset_table_rtx));
17232 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17235 [(set (match_operand 0 "register_operand" "")
17236 (match_operator 3 "promotable_binary_operator"
17237 [(match_operand 1 "register_operand" "")
17238 (match_operand 2 "aligned_operand" "")]))
17239 (clobber (reg:CC FLAGS_REG))]
17240 "! TARGET_PARTIAL_REG_STALL && reload_completed
17241 && ((GET_MODE (operands[0]) == HImode
17242 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17243 /* ??? next two lines just !satisfies_constraint_K (...) */
17244 || !CONST_INT_P (operands[2])
17245 || satisfies_constraint_K (operands[2])))
17246 || (GET_MODE (operands[0]) == QImode
17247 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17248 [(parallel [(set (match_dup 0)
17249 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17250 (clobber (reg:CC FLAGS_REG))])]
17251 "operands[0] = gen_lowpart (SImode, operands[0]);
17252 operands[1] = gen_lowpart (SImode, operands[1]);
17253 if (GET_CODE (operands[3]) != ASHIFT)
17254 operands[2] = gen_lowpart (SImode, operands[2]);
17255 PUT_MODE (operands[3], SImode);")
17257 ; Promote the QImode tests, as i386 has encoding of the AND
17258 ; instruction with 32-bit sign-extended immediate and thus the
17259 ; instruction size is unchanged, except in the %eax case for
17260 ; which it is increased by one byte, hence the ! optimize_size.
17262 [(set (match_operand 0 "flags_reg_operand" "")
17263 (match_operator 2 "compare_operator"
17264 [(and (match_operand 3 "aligned_operand" "")
17265 (match_operand 4 "const_int_operand" ""))
17267 (set (match_operand 1 "register_operand" "")
17268 (and (match_dup 3) (match_dup 4)))]
17269 "! TARGET_PARTIAL_REG_STALL && reload_completed
17270 && optimize_insn_for_speed_p ()
17271 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17272 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17273 /* Ensure that the operand will remain sign-extended immediate. */
17274 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17275 [(parallel [(set (match_dup 0)
17276 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17279 (and:SI (match_dup 3) (match_dup 4)))])]
17282 = gen_int_mode (INTVAL (operands[4])
17283 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17284 operands[1] = gen_lowpart (SImode, operands[1]);
17285 operands[3] = gen_lowpart (SImode, operands[3]);
17288 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17289 ; the TEST instruction with 32-bit sign-extended immediate and thus
17290 ; the instruction size would at least double, which is not what we
17291 ; want even with ! optimize_size.
17293 [(set (match_operand 0 "flags_reg_operand" "")
17294 (match_operator 1 "compare_operator"
17295 [(and (match_operand:HI 2 "aligned_operand" "")
17296 (match_operand:HI 3 "const_int_operand" ""))
17298 "! TARGET_PARTIAL_REG_STALL && reload_completed
17299 && ! TARGET_FAST_PREFIX
17300 && optimize_insn_for_speed_p ()
17301 /* Ensure that the operand will remain sign-extended immediate. */
17302 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17303 [(set (match_dup 0)
17304 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17308 = gen_int_mode (INTVAL (operands[3])
17309 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17310 operands[2] = gen_lowpart (SImode, operands[2]);
17314 [(set (match_operand 0 "register_operand" "")
17315 (neg (match_operand 1 "register_operand" "")))
17316 (clobber (reg:CC FLAGS_REG))]
17317 "! TARGET_PARTIAL_REG_STALL && reload_completed
17318 && (GET_MODE (operands[0]) == HImode
17319 || (GET_MODE (operands[0]) == QImode
17320 && (TARGET_PROMOTE_QImode
17321 || optimize_insn_for_size_p ())))"
17322 [(parallel [(set (match_dup 0)
17323 (neg:SI (match_dup 1)))
17324 (clobber (reg:CC FLAGS_REG))])]
17325 "operands[0] = gen_lowpart (SImode, operands[0]);
17326 operands[1] = gen_lowpart (SImode, operands[1]);")
17329 [(set (match_operand 0 "register_operand" "")
17330 (not (match_operand 1 "register_operand" "")))]
17331 "! TARGET_PARTIAL_REG_STALL && reload_completed
17332 && (GET_MODE (operands[0]) == HImode
17333 || (GET_MODE (operands[0]) == QImode
17334 && (TARGET_PROMOTE_QImode
17335 || optimize_insn_for_size_p ())))"
17336 [(set (match_dup 0)
17337 (not:SI (match_dup 1)))]
17338 "operands[0] = gen_lowpart (SImode, operands[0]);
17339 operands[1] = gen_lowpart (SImode, operands[1]);")
17342 [(set (match_operand 0 "register_operand" "")
17343 (if_then_else (match_operator 1 "comparison_operator"
17344 [(reg FLAGS_REG) (const_int 0)])
17345 (match_operand 2 "register_operand" "")
17346 (match_operand 3 "register_operand" "")))]
17347 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17348 && (GET_MODE (operands[0]) == HImode
17349 || (GET_MODE (operands[0]) == QImode
17350 && (TARGET_PROMOTE_QImode
17351 || optimize_insn_for_size_p ())))"
17352 [(set (match_dup 0)
17353 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17354 "operands[0] = gen_lowpart (SImode, operands[0]);
17355 operands[2] = gen_lowpart (SImode, operands[2]);
17356 operands[3] = gen_lowpart (SImode, operands[3]);")
17359 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17360 ;; transform a complex memory operation into two memory to register operations.
17362 ;; Don't push memory operands
17364 [(set (match_operand:SI 0 "push_operand" "")
17365 (match_operand:SI 1 "memory_operand" ""))
17366 (match_scratch:SI 2 "r")]
17367 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17368 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17369 [(set (match_dup 2) (match_dup 1))
17370 (set (match_dup 0) (match_dup 2))]
17374 [(set (match_operand:DI 0 "push_operand" "")
17375 (match_operand:DI 1 "memory_operand" ""))
17376 (match_scratch:DI 2 "r")]
17377 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17378 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17379 [(set (match_dup 2) (match_dup 1))
17380 (set (match_dup 0) (match_dup 2))]
17383 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17386 [(set (match_operand:SF 0 "push_operand" "")
17387 (match_operand:SF 1 "memory_operand" ""))
17388 (match_scratch:SF 2 "r")]
17389 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17390 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17391 [(set (match_dup 2) (match_dup 1))
17392 (set (match_dup 0) (match_dup 2))]
17396 [(set (match_operand:HI 0 "push_operand" "")
17397 (match_operand:HI 1 "memory_operand" ""))
17398 (match_scratch:HI 2 "r")]
17399 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17400 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17401 [(set (match_dup 2) (match_dup 1))
17402 (set (match_dup 0) (match_dup 2))]
17406 [(set (match_operand:QI 0 "push_operand" "")
17407 (match_operand:QI 1 "memory_operand" ""))
17408 (match_scratch:QI 2 "q")]
17409 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17410 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17411 [(set (match_dup 2) (match_dup 1))
17412 (set (match_dup 0) (match_dup 2))]
17415 ;; Don't move an immediate directly to memory when the instruction
17418 [(match_scratch:SI 1 "r")
17419 (set (match_operand:SI 0 "memory_operand" "")
17421 "optimize_insn_for_speed_p ()
17422 && ! TARGET_USE_MOV0
17423 && TARGET_SPLIT_LONG_MOVES
17424 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17425 && peep2_regno_dead_p (0, FLAGS_REG)"
17426 [(parallel [(set (match_dup 1) (const_int 0))
17427 (clobber (reg:CC FLAGS_REG))])
17428 (set (match_dup 0) (match_dup 1))]
17432 [(match_scratch:HI 1 "r")
17433 (set (match_operand:HI 0 "memory_operand" "")
17435 "optimize_insn_for_speed_p ()
17436 && ! TARGET_USE_MOV0
17437 && TARGET_SPLIT_LONG_MOVES
17438 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17439 && peep2_regno_dead_p (0, FLAGS_REG)"
17440 [(parallel [(set (match_dup 2) (const_int 0))
17441 (clobber (reg:CC FLAGS_REG))])
17442 (set (match_dup 0) (match_dup 1))]
17443 "operands[2] = gen_lowpart (SImode, operands[1]);")
17446 [(match_scratch:QI 1 "q")
17447 (set (match_operand:QI 0 "memory_operand" "")
17449 "optimize_insn_for_speed_p ()
17450 && ! TARGET_USE_MOV0
17451 && TARGET_SPLIT_LONG_MOVES
17452 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17453 && peep2_regno_dead_p (0, FLAGS_REG)"
17454 [(parallel [(set (match_dup 2) (const_int 0))
17455 (clobber (reg:CC FLAGS_REG))])
17456 (set (match_dup 0) (match_dup 1))]
17457 "operands[2] = gen_lowpart (SImode, operands[1]);")
17460 [(match_scratch:SI 2 "r")
17461 (set (match_operand:SI 0 "memory_operand" "")
17462 (match_operand:SI 1 "immediate_operand" ""))]
17463 "optimize_insn_for_speed_p ()
17464 && TARGET_SPLIT_LONG_MOVES
17465 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17466 [(set (match_dup 2) (match_dup 1))
17467 (set (match_dup 0) (match_dup 2))]
17471 [(match_scratch:HI 2 "r")
17472 (set (match_operand:HI 0 "memory_operand" "")
17473 (match_operand:HI 1 "immediate_operand" ""))]
17474 "optimize_insn_for_speed_p ()
17475 && TARGET_SPLIT_LONG_MOVES
17476 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17477 [(set (match_dup 2) (match_dup 1))
17478 (set (match_dup 0) (match_dup 2))]
17482 [(match_scratch:QI 2 "q")
17483 (set (match_operand:QI 0 "memory_operand" "")
17484 (match_operand:QI 1 "immediate_operand" ""))]
17485 "optimize_insn_for_speed_p ()
17486 && TARGET_SPLIT_LONG_MOVES
17487 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17488 [(set (match_dup 2) (match_dup 1))
17489 (set (match_dup 0) (match_dup 2))]
17492 ;; Don't compare memory with zero, load and use a test instead.
17494 [(set (match_operand 0 "flags_reg_operand" "")
17495 (match_operator 1 "compare_operator"
17496 [(match_operand:SI 2 "memory_operand" "")
17498 (match_scratch:SI 3 "r")]
17499 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17500 [(set (match_dup 3) (match_dup 2))
17501 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17504 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17505 ;; Don't split NOTs with a displacement operand, because resulting XOR
17506 ;; will not be pairable anyway.
17508 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17509 ;; represented using a modRM byte. The XOR replacement is long decoded,
17510 ;; so this split helps here as well.
17512 ;; Note: Can't do this as a regular split because we can't get proper
17513 ;; lifetime information then.
17516 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17517 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17518 "optimize_insn_for_speed_p ()
17519 && ((TARGET_NOT_UNPAIRABLE
17520 && (!MEM_P (operands[0])
17521 || !memory_displacement_operand (operands[0], SImode)))
17522 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
17523 && peep2_regno_dead_p (0, FLAGS_REG)"
17524 [(parallel [(set (match_dup 0)
17525 (xor:SI (match_dup 1) (const_int -1)))
17526 (clobber (reg:CC FLAGS_REG))])]
17530 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17531 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17532 "optimize_insn_for_speed_p ()
17533 && ((TARGET_NOT_UNPAIRABLE
17534 && (!MEM_P (operands[0])
17535 || !memory_displacement_operand (operands[0], HImode)))
17536 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
17537 && peep2_regno_dead_p (0, FLAGS_REG)"
17538 [(parallel [(set (match_dup 0)
17539 (xor:HI (match_dup 1) (const_int -1)))
17540 (clobber (reg:CC FLAGS_REG))])]
17544 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17545 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17546 "optimize_insn_for_speed_p ()
17547 && ((TARGET_NOT_UNPAIRABLE
17548 && (!MEM_P (operands[0])
17549 || !memory_displacement_operand (operands[0], QImode)))
17550 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
17551 && peep2_regno_dead_p (0, FLAGS_REG)"
17552 [(parallel [(set (match_dup 0)
17553 (xor:QI (match_dup 1) (const_int -1)))
17554 (clobber (reg:CC FLAGS_REG))])]
17557 ;; Non pairable "test imm, reg" instructions can be translated to
17558 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17559 ;; byte opcode instead of two, have a short form for byte operands),
17560 ;; so do it for other CPUs as well. Given that the value was dead,
17561 ;; this should not create any new dependencies. Pass on the sub-word
17562 ;; versions if we're concerned about partial register stalls.
17565 [(set (match_operand 0 "flags_reg_operand" "")
17566 (match_operator 1 "compare_operator"
17567 [(and:SI (match_operand:SI 2 "register_operand" "")
17568 (match_operand:SI 3 "immediate_operand" ""))
17570 "ix86_match_ccmode (insn, CCNOmode)
17571 && (true_regnum (operands[2]) != AX_REG
17572 || satisfies_constraint_K (operands[3]))
17573 && peep2_reg_dead_p (1, operands[2])"
17575 [(set (match_dup 0)
17576 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17579 (and:SI (match_dup 2) (match_dup 3)))])]
17582 ;; We don't need to handle HImode case, because it will be promoted to SImode
17583 ;; on ! TARGET_PARTIAL_REG_STALL
17586 [(set (match_operand 0 "flags_reg_operand" "")
17587 (match_operator 1 "compare_operator"
17588 [(and:QI (match_operand:QI 2 "register_operand" "")
17589 (match_operand:QI 3 "immediate_operand" ""))
17591 "! TARGET_PARTIAL_REG_STALL
17592 && ix86_match_ccmode (insn, CCNOmode)
17593 && true_regnum (operands[2]) != AX_REG
17594 && peep2_reg_dead_p (1, operands[2])"
17596 [(set (match_dup 0)
17597 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17600 (and:QI (match_dup 2) (match_dup 3)))])]
17604 [(set (match_operand 0 "flags_reg_operand" "")
17605 (match_operator 1 "compare_operator"
17608 (match_operand 2 "ext_register_operand" "")
17611 (match_operand 3 "const_int_operand" ""))
17613 "! TARGET_PARTIAL_REG_STALL
17614 && ix86_match_ccmode (insn, CCNOmode)
17615 && true_regnum (operands[2]) != AX_REG
17616 && peep2_reg_dead_p (1, operands[2])"
17617 [(parallel [(set (match_dup 0)
17626 (set (zero_extract:SI (match_dup 2)
17637 ;; Don't do logical operations with memory inputs.
17639 [(match_scratch:SI 2 "r")
17640 (parallel [(set (match_operand:SI 0 "register_operand" "")
17641 (match_operator:SI 3 "arith_or_logical_operator"
17643 (match_operand:SI 1 "memory_operand" "")]))
17644 (clobber (reg:CC FLAGS_REG))])]
17645 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17646 [(set (match_dup 2) (match_dup 1))
17647 (parallel [(set (match_dup 0)
17648 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17649 (clobber (reg:CC FLAGS_REG))])]
17653 [(match_scratch:SI 2 "r")
17654 (parallel [(set (match_operand:SI 0 "register_operand" "")
17655 (match_operator:SI 3 "arith_or_logical_operator"
17656 [(match_operand:SI 1 "memory_operand" "")
17658 (clobber (reg:CC FLAGS_REG))])]
17659 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17660 [(set (match_dup 2) (match_dup 1))
17661 (parallel [(set (match_dup 0)
17662 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17663 (clobber (reg:CC FLAGS_REG))])]
17666 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17667 ;; refers to the destination of the load!
17670 [(set (match_operand:SI 0 "register_operand" "")
17671 (match_operand:SI 1 "register_operand" ""))
17672 (parallel [(set (match_dup 0)
17673 (match_operator:SI 3 "commutative_operator"
17675 (match_operand:SI 2 "memory_operand" "")]))
17676 (clobber (reg:CC FLAGS_REG))])]
17677 "REGNO (operands[0]) != REGNO (operands[1])
17678 && GENERAL_REGNO_P (REGNO (operands[0]))
17679 && GENERAL_REGNO_P (REGNO (operands[1]))"
17680 [(set (match_dup 0) (match_dup 4))
17681 (parallel [(set (match_dup 0)
17682 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17683 (clobber (reg:CC FLAGS_REG))])]
17684 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17687 [(set (match_operand 0 "register_operand" "")
17688 (match_operand 1 "register_operand" ""))
17690 (match_operator 3 "commutative_operator"
17692 (match_operand 2 "memory_operand" "")]))]
17693 "REGNO (operands[0]) != REGNO (operands[1])
17694 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17695 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17696 [(set (match_dup 0) (match_dup 2))
17698 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17701 ; Don't do logical operations with memory outputs
17703 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17704 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17705 ; the same decoder scheduling characteristics as the original.
17708 [(match_scratch:SI 2 "r")
17709 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17710 (match_operator:SI 3 "arith_or_logical_operator"
17712 (match_operand:SI 1 "nonmemory_operand" "")]))
17713 (clobber (reg:CC FLAGS_REG))])]
17714 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17715 /* Do not split stack checking probes. */
17716 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17717 [(set (match_dup 2) (match_dup 0))
17718 (parallel [(set (match_dup 2)
17719 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17720 (clobber (reg:CC FLAGS_REG))])
17721 (set (match_dup 0) (match_dup 2))]
17725 [(match_scratch:SI 2 "r")
17726 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17727 (match_operator:SI 3 "arith_or_logical_operator"
17728 [(match_operand:SI 1 "nonmemory_operand" "")
17730 (clobber (reg:CC FLAGS_REG))])]
17731 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17732 /* Do not split stack checking probes. */
17733 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17734 [(set (match_dup 2) (match_dup 0))
17735 (parallel [(set (match_dup 2)
17736 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17737 (clobber (reg:CC FLAGS_REG))])
17738 (set (match_dup 0) (match_dup 2))]
17741 ;; Attempt to always use XOR for zeroing registers.
17743 [(set (match_operand 0 "register_operand" "")
17744 (match_operand 1 "const0_operand" ""))]
17745 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17746 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17747 && GENERAL_REG_P (operands[0])
17748 && peep2_regno_dead_p (0, FLAGS_REG)"
17749 [(parallel [(set (match_dup 0) (const_int 0))
17750 (clobber (reg:CC FLAGS_REG))])]
17752 operands[0] = gen_lowpart (word_mode, operands[0]);
17756 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17758 "(GET_MODE (operands[0]) == QImode
17759 || GET_MODE (operands[0]) == HImode)
17760 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17761 && peep2_regno_dead_p (0, FLAGS_REG)"
17762 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17763 (clobber (reg:CC FLAGS_REG))])])
17765 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17767 [(set (match_operand 0 "register_operand" "")
17769 "(GET_MODE (operands[0]) == HImode
17770 || GET_MODE (operands[0]) == SImode
17771 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17772 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17773 && peep2_regno_dead_p (0, FLAGS_REG)"
17774 [(parallel [(set (match_dup 0) (const_int -1))
17775 (clobber (reg:CC FLAGS_REG))])]
17776 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17779 ;; Attempt to convert simple leas to adds. These can be created by
17782 [(set (match_operand:SI 0 "register_operand" "")
17783 (plus:SI (match_dup 0)
17784 (match_operand:SI 1 "nonmemory_operand" "")))]
17785 "peep2_regno_dead_p (0, FLAGS_REG)"
17786 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17787 (clobber (reg:CC FLAGS_REG))])]
17791 [(set (match_operand:SI 0 "register_operand" "")
17792 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17793 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17794 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17795 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17796 (clobber (reg:CC FLAGS_REG))])]
17797 "operands[2] = gen_lowpart (SImode, operands[2]);")
17800 [(set (match_operand:DI 0 "register_operand" "")
17801 (plus:DI (match_dup 0)
17802 (match_operand:DI 1 "x86_64_general_operand" "")))]
17803 "peep2_regno_dead_p (0, FLAGS_REG)"
17804 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17805 (clobber (reg:CC FLAGS_REG))])]
17809 [(set (match_operand:SI 0 "register_operand" "")
17810 (mult:SI (match_dup 0)
17811 (match_operand:SI 1 "const_int_operand" "")))]
17812 "exact_log2 (INTVAL (operands[1])) >= 0
17813 && peep2_regno_dead_p (0, FLAGS_REG)"
17814 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17815 (clobber (reg:CC FLAGS_REG))])]
17816 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17819 [(set (match_operand:DI 0 "register_operand" "")
17820 (mult:DI (match_dup 0)
17821 (match_operand:DI 1 "const_int_operand" "")))]
17822 "exact_log2 (INTVAL (operands[1])) >= 0
17823 && peep2_regno_dead_p (0, FLAGS_REG)"
17824 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17825 (clobber (reg:CC FLAGS_REG))])]
17826 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17829 [(set (match_operand:SI 0 "register_operand" "")
17830 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17831 (match_operand:DI 2 "const_int_operand" "")) 0))]
17832 "exact_log2 (INTVAL (operands[2])) >= 0
17833 && REGNO (operands[0]) == REGNO (operands[1])
17834 && peep2_regno_dead_p (0, FLAGS_REG)"
17835 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17836 (clobber (reg:CC FLAGS_REG))])]
17837 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17839 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17840 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17841 ;; many CPUs it is also faster, since special hardware to avoid esp
17842 ;; dependencies is present.
17844 ;; While some of these conversions may be done using splitters, we use peepholes
17845 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17847 ;; Convert prologue esp subtractions to push.
17848 ;; We need register to push. In order to keep verify_flow_info happy we have
17850 ;; - use scratch and clobber it in order to avoid dependencies
17851 ;; - use already live register
17852 ;; We can't use the second way right now, since there is no reliable way how to
17853 ;; verify that given register is live. First choice will also most likely in
17854 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17855 ;; call clobbered registers are dead. We may want to use base pointer as an
17856 ;; alternative when no register is available later.
17859 [(match_scratch:SI 0 "r")
17860 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17861 (clobber (reg:CC FLAGS_REG))
17862 (clobber (mem:BLK (scratch)))])]
17863 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17864 [(clobber (match_dup 0))
17865 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17866 (clobber (mem:BLK (scratch)))])])
17869 [(match_scratch:SI 0 "r")
17870 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17871 (clobber (reg:CC FLAGS_REG))
17872 (clobber (mem:BLK (scratch)))])]
17873 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17874 [(clobber (match_dup 0))
17875 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17876 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17877 (clobber (mem:BLK (scratch)))])])
17879 ;; Convert esp subtractions to push.
17881 [(match_scratch:SI 0 "r")
17882 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17883 (clobber (reg:CC FLAGS_REG))])]
17884 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17885 [(clobber (match_dup 0))
17886 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17889 [(match_scratch:SI 0 "r")
17890 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17891 (clobber (reg:CC FLAGS_REG))])]
17892 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17893 [(clobber (match_dup 0))
17894 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17895 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17897 ;; Convert epilogue deallocator to pop.
17899 [(match_scratch:SI 0 "r")
17900 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17901 (clobber (reg:CC FLAGS_REG))
17902 (clobber (mem:BLK (scratch)))])]
17903 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17904 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17905 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17906 (clobber (mem:BLK (scratch)))])]
17909 ;; Two pops case is tricky, since pop causes dependency on destination register.
17910 ;; We use two registers if available.
17912 [(match_scratch:SI 0 "r")
17913 (match_scratch:SI 1 "r")
17914 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17915 (clobber (reg:CC FLAGS_REG))
17916 (clobber (mem:BLK (scratch)))])]
17917 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17918 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17919 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17920 (clobber (mem:BLK (scratch)))])
17921 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17922 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17926 [(match_scratch:SI 0 "r")
17927 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17928 (clobber (reg:CC FLAGS_REG))
17929 (clobber (mem:BLK (scratch)))])]
17930 "optimize_insn_for_size_p ()"
17931 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17932 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17933 (clobber (mem:BLK (scratch)))])
17934 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17935 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17938 ;; Convert esp additions to pop.
17940 [(match_scratch:SI 0 "r")
17941 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17942 (clobber (reg:CC FLAGS_REG))])]
17944 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17945 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17948 ;; Two pops case is tricky, since pop causes dependency on destination register.
17949 ;; We use two registers if available.
17951 [(match_scratch:SI 0 "r")
17952 (match_scratch:SI 1 "r")
17953 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17954 (clobber (reg:CC FLAGS_REG))])]
17956 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17957 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17958 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17959 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17963 [(match_scratch:SI 0 "r")
17964 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17965 (clobber (reg:CC FLAGS_REG))])]
17966 "optimize_insn_for_size_p ()"
17967 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17968 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17969 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17970 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17973 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17974 ;; required and register dies. Similarly for 128 to -128.
17976 [(set (match_operand 0 "flags_reg_operand" "")
17977 (match_operator 1 "compare_operator"
17978 [(match_operand 2 "register_operand" "")
17979 (match_operand 3 "const_int_operand" "")]))]
17980 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17981 && incdec_operand (operands[3], GET_MODE (operands[3])))
17982 || (!TARGET_FUSE_CMP_AND_BRANCH
17983 && INTVAL (operands[3]) == 128))
17984 && ix86_match_ccmode (insn, CCGCmode)
17985 && peep2_reg_dead_p (1, operands[2])"
17986 [(parallel [(set (match_dup 0)
17987 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17988 (clobber (match_dup 2))])]
17992 [(match_scratch:DI 0 "r")
17993 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17994 (clobber (reg:CC FLAGS_REG))
17995 (clobber (mem:BLK (scratch)))])]
17996 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17997 [(clobber (match_dup 0))
17998 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17999 (clobber (mem:BLK (scratch)))])])
18002 [(match_scratch:DI 0 "r")
18003 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18004 (clobber (reg:CC FLAGS_REG))
18005 (clobber (mem:BLK (scratch)))])]
18006 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
18007 [(clobber (match_dup 0))
18008 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18009 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18010 (clobber (mem:BLK (scratch)))])])
18012 ;; Convert esp subtractions to push.
18014 [(match_scratch:DI 0 "r")
18015 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18016 (clobber (reg:CC FLAGS_REG))])]
18017 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
18018 [(clobber (match_dup 0))
18019 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18022 [(match_scratch:DI 0 "r")
18023 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18024 (clobber (reg:CC FLAGS_REG))])]
18025 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
18026 [(clobber (match_dup 0))
18027 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18028 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18030 ;; Convert epilogue deallocator to pop.
18032 [(match_scratch:DI 0 "r")
18033 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18034 (clobber (reg:CC FLAGS_REG))
18035 (clobber (mem:BLK (scratch)))])]
18036 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
18037 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18038 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18039 (clobber (mem:BLK (scratch)))])]
18042 ;; Two pops case is tricky, since pop causes dependency on destination register.
18043 ;; We use two registers if available.
18045 [(match_scratch:DI 0 "r")
18046 (match_scratch:DI 1 "r")
18047 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18048 (clobber (reg:CC FLAGS_REG))
18049 (clobber (mem:BLK (scratch)))])]
18050 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
18051 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18052 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18053 (clobber (mem:BLK (scratch)))])
18054 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18055 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18059 [(match_scratch:DI 0 "r")
18060 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18061 (clobber (reg:CC FLAGS_REG))
18062 (clobber (mem:BLK (scratch)))])]
18063 "optimize_insn_for_size_p ()"
18064 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18065 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18066 (clobber (mem:BLK (scratch)))])
18067 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18068 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18071 ;; Convert esp additions to pop.
18073 [(match_scratch:DI 0 "r")
18074 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18075 (clobber (reg:CC FLAGS_REG))])]
18077 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18078 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18081 ;; Two pops case is tricky, since pop causes dependency on destination register.
18082 ;; We use two registers if available.
18084 [(match_scratch:DI 0 "r")
18085 (match_scratch:DI 1 "r")
18086 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18087 (clobber (reg:CC FLAGS_REG))])]
18089 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18090 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18091 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18092 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18096 [(match_scratch:DI 0 "r")
18097 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18098 (clobber (reg:CC FLAGS_REG))])]
18099 "optimize_insn_for_size_p ()"
18100 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18101 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18102 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18103 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18106 ;; Convert imul by three, five and nine into lea
18109 [(set (match_operand:SI 0 "register_operand" "")
18110 (mult:SI (match_operand:SI 1 "register_operand" "")
18111 (match_operand:SI 2 "const_int_operand" "")))
18112 (clobber (reg:CC FLAGS_REG))])]
18113 "INTVAL (operands[2]) == 3
18114 || INTVAL (operands[2]) == 5
18115 || INTVAL (operands[2]) == 9"
18116 [(set (match_dup 0)
18117 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
18119 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18123 [(set (match_operand:SI 0 "register_operand" "")
18124 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18125 (match_operand:SI 2 "const_int_operand" "")))
18126 (clobber (reg:CC FLAGS_REG))])]
18127 "optimize_insn_for_speed_p ()
18128 && (INTVAL (operands[2]) == 3
18129 || INTVAL (operands[2]) == 5
18130 || INTVAL (operands[2]) == 9)"
18131 [(set (match_dup 0) (match_dup 1))
18133 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
18135 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18139 [(set (match_operand:DI 0 "register_operand" "")
18140 (mult:DI (match_operand:DI 1 "register_operand" "")
18141 (match_operand:DI 2 "const_int_operand" "")))
18142 (clobber (reg:CC FLAGS_REG))])]
18144 && (INTVAL (operands[2]) == 3
18145 || INTVAL (operands[2]) == 5
18146 || INTVAL (operands[2]) == 9)"
18147 [(set (match_dup 0)
18148 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
18150 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18154 [(set (match_operand:DI 0 "register_operand" "")
18155 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18156 (match_operand:DI 2 "const_int_operand" "")))
18157 (clobber (reg:CC FLAGS_REG))])]
18159 && optimize_insn_for_speed_p ()
18160 && (INTVAL (operands[2]) == 3
18161 || INTVAL (operands[2]) == 5
18162 || INTVAL (operands[2]) == 9)"
18163 [(set (match_dup 0) (match_dup 1))
18165 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18167 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18169 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18170 ;; imul $32bit_imm, reg, reg is direct decoded.
18172 [(match_scratch:DI 3 "r")
18173 (parallel [(set (match_operand:DI 0 "register_operand" "")
18174 (mult:DI (match_operand:DI 1 "memory_operand" "")
18175 (match_operand:DI 2 "immediate_operand" "")))
18176 (clobber (reg:CC FLAGS_REG))])]
18177 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18178 && !satisfies_constraint_K (operands[2])"
18179 [(set (match_dup 3) (match_dup 1))
18180 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18181 (clobber (reg:CC FLAGS_REG))])]
18185 [(match_scratch:SI 3 "r")
18186 (parallel [(set (match_operand:SI 0 "register_operand" "")
18187 (mult:SI (match_operand:SI 1 "memory_operand" "")
18188 (match_operand:SI 2 "immediate_operand" "")))
18189 (clobber (reg:CC FLAGS_REG))])]
18190 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18191 && !satisfies_constraint_K (operands[2])"
18192 [(set (match_dup 3) (match_dup 1))
18193 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18194 (clobber (reg:CC FLAGS_REG))])]
18198 [(match_scratch:SI 3 "r")
18199 (parallel [(set (match_operand:DI 0 "register_operand" "")
18201 (mult:SI (match_operand:SI 1 "memory_operand" "")
18202 (match_operand:SI 2 "immediate_operand" ""))))
18203 (clobber (reg:CC FLAGS_REG))])]
18204 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18205 && !satisfies_constraint_K (operands[2])"
18206 [(set (match_dup 3) (match_dup 1))
18207 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18208 (clobber (reg:CC FLAGS_REG))])]
18211 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18212 ;; Convert it into imul reg, reg
18213 ;; It would be better to force assembler to encode instruction using long
18214 ;; immediate, but there is apparently no way to do so.
18216 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18217 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18218 (match_operand:DI 2 "const_int_operand" "")))
18219 (clobber (reg:CC FLAGS_REG))])
18220 (match_scratch:DI 3 "r")]
18221 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18222 && satisfies_constraint_K (operands[2])"
18223 [(set (match_dup 3) (match_dup 2))
18224 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18225 (clobber (reg:CC FLAGS_REG))])]
18227 if (!rtx_equal_p (operands[0], operands[1]))
18228 emit_move_insn (operands[0], operands[1]);
18232 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18233 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18234 (match_operand:SI 2 "const_int_operand" "")))
18235 (clobber (reg:CC FLAGS_REG))])
18236 (match_scratch:SI 3 "r")]
18237 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18238 && satisfies_constraint_K (operands[2])"
18239 [(set (match_dup 3) (match_dup 2))
18240 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18241 (clobber (reg:CC FLAGS_REG))])]
18243 if (!rtx_equal_p (operands[0], operands[1]))
18244 emit_move_insn (operands[0], operands[1]);
18248 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18249 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18250 (match_operand:HI 2 "immediate_operand" "")))
18251 (clobber (reg:CC FLAGS_REG))])
18252 (match_scratch:HI 3 "r")]
18253 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
18254 [(set (match_dup 3) (match_dup 2))
18255 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18256 (clobber (reg:CC FLAGS_REG))])]
18258 if (!rtx_equal_p (operands[0], operands[1]))
18259 emit_move_insn (operands[0], operands[1]);
18262 ;; After splitting up read-modify operations, array accesses with memory
18263 ;; operands might end up in form:
18265 ;; movl 4(%esp), %edx
18267 ;; instead of pre-splitting:
18269 ;; addl 4(%esp), %eax
18271 ;; movl 4(%esp), %edx
18272 ;; leal (%edx,%eax,4), %eax
18275 [(parallel [(set (match_operand 0 "register_operand" "")
18276 (ashift (match_operand 1 "register_operand" "")
18277 (match_operand 2 "const_int_operand" "")))
18278 (clobber (reg:CC FLAGS_REG))])
18279 (set (match_operand 3 "register_operand")
18280 (match_operand 4 "x86_64_general_operand" ""))
18281 (parallel [(set (match_operand 5 "register_operand" "")
18282 (plus (match_operand 6 "register_operand" "")
18283 (match_operand 7 "register_operand" "")))
18284 (clobber (reg:CC FLAGS_REG))])]
18285 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
18286 /* Validate MODE for lea. */
18287 && ((!TARGET_PARTIAL_REG_STALL
18288 && (GET_MODE (operands[0]) == QImode
18289 || GET_MODE (operands[0]) == HImode))
18290 || GET_MODE (operands[0]) == SImode
18291 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18292 /* We reorder load and the shift. */
18293 && !rtx_equal_p (operands[1], operands[3])
18294 && !reg_overlap_mentioned_p (operands[0], operands[4])
18295 /* Last PLUS must consist of operand 0 and 3. */
18296 && !rtx_equal_p (operands[0], operands[3])
18297 && (rtx_equal_p (operands[3], operands[6])
18298 || rtx_equal_p (operands[3], operands[7]))
18299 && (rtx_equal_p (operands[0], operands[6])
18300 || rtx_equal_p (operands[0], operands[7]))
18301 /* The intermediate operand 0 must die or be same as output. */
18302 && (rtx_equal_p (operands[0], operands[5])
18303 || peep2_reg_dead_p (3, operands[0]))"
18304 [(set (match_dup 3) (match_dup 4))
18305 (set (match_dup 0) (match_dup 1))]
18307 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
18308 int scale = 1 << INTVAL (operands[2]);
18309 rtx index = gen_lowpart (Pmode, operands[1]);
18310 rtx base = gen_lowpart (Pmode, operands[3]);
18311 rtx dest = gen_lowpart (mode, operands[5]);
18313 operands[1] = gen_rtx_PLUS (Pmode, base,
18314 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
18316 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18317 operands[0] = dest;
18320 ;; Call-value patterns last so that the wildcard operand does not
18321 ;; disrupt insn-recog's switch tables.
18323 (define_insn "*call_value_pop_0"
18324 [(set (match_operand 0 "" "")
18325 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18326 (match_operand:SI 2 "" "")))
18327 (set (reg:SI SP_REG)
18328 (plus:SI (reg:SI SP_REG)
18329 (match_operand:SI 3 "immediate_operand" "")))]
18332 if (SIBLING_CALL_P (insn))
18335 return "call\t%P1";
18337 [(set_attr "type" "callv")])
18339 (define_insn "*call_value_pop_1"
18340 [(set (match_operand 0 "" "")
18341 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18342 (match_operand:SI 2 "" "")))
18343 (set (reg:SI SP_REG)
18344 (plus:SI (reg:SI SP_REG)
18345 (match_operand:SI 3 "immediate_operand" "i")))]
18346 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18348 if (constant_call_address_operand (operands[1], Pmode))
18349 return "call\t%P1";
18350 return "call\t%A1";
18352 [(set_attr "type" "callv")])
18354 (define_insn "*sibcall_value_pop_1"
18355 [(set (match_operand 0 "" "")
18356 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18357 (match_operand:SI 2 "" "")))
18358 (set (reg:SI SP_REG)
18359 (plus:SI (reg:SI SP_REG)
18360 (match_operand:SI 3 "immediate_operand" "i,i")))]
18361 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18365 [(set_attr "type" "callv")])
18367 (define_insn "*call_value_0"
18368 [(set (match_operand 0 "" "")
18369 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18370 (match_operand:SI 2 "" "")))]
18373 if (SIBLING_CALL_P (insn))
18376 return "call\t%P1";
18378 [(set_attr "type" "callv")])
18380 (define_insn "*call_value_0_rex64"
18381 [(set (match_operand 0 "" "")
18382 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18383 (match_operand:DI 2 "const_int_operand" "")))]
18386 if (SIBLING_CALL_P (insn))
18389 return "call\t%P1";
18391 [(set_attr "type" "callv")])
18393 (define_insn "*call_value_0_rex64_ms_sysv"
18394 [(set (match_operand 0 "" "")
18395 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18396 (match_operand:DI 2 "const_int_operand" "")))
18397 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18398 (clobber (reg:TI XMM6_REG))
18399 (clobber (reg:TI XMM7_REG))
18400 (clobber (reg:TI XMM8_REG))
18401 (clobber (reg:TI XMM9_REG))
18402 (clobber (reg:TI XMM10_REG))
18403 (clobber (reg:TI XMM11_REG))
18404 (clobber (reg:TI XMM12_REG))
18405 (clobber (reg:TI XMM13_REG))
18406 (clobber (reg:TI XMM14_REG))
18407 (clobber (reg:TI XMM15_REG))
18408 (clobber (reg:DI SI_REG))
18409 (clobber (reg:DI DI_REG))]
18410 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18412 if (SIBLING_CALL_P (insn))
18415 return "call\t%P1";
18417 [(set_attr "type" "callv")])
18419 (define_insn "*call_value_1"
18420 [(set (match_operand 0 "" "")
18421 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18422 (match_operand:SI 2 "" "")))]
18423 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18425 if (constant_call_address_operand (operands[1], Pmode))
18426 return "call\t%P1";
18427 return "call\t%A1";
18429 [(set_attr "type" "callv")])
18431 (define_insn "*sibcall_value_1"
18432 [(set (match_operand 0 "" "")
18433 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18434 (match_operand:SI 2 "" "")))]
18435 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18439 [(set_attr "type" "callv")])
18441 (define_insn "*call_value_1_rex64"
18442 [(set (match_operand 0 "" "")
18443 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18444 (match_operand:DI 2 "" "")))]
18445 "TARGET_64BIT && !SIBLING_CALL_P (insn)
18446 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
18448 if (constant_call_address_operand (operands[1], Pmode))
18449 return "call\t%P1";
18450 return "call\t%A1";
18452 [(set_attr "type" "callv")])
18454 (define_insn "*call_value_1_rex64_ms_sysv"
18455 [(set (match_operand 0 "" "")
18456 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18457 (match_operand:DI 2 "" "")))
18458 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18459 (clobber (reg:TI XMM6_REG))
18460 (clobber (reg:TI XMM7_REG))
18461 (clobber (reg:TI XMM8_REG))
18462 (clobber (reg:TI XMM9_REG))
18463 (clobber (reg:TI XMM10_REG))
18464 (clobber (reg:TI XMM11_REG))
18465 (clobber (reg:TI XMM12_REG))
18466 (clobber (reg:TI XMM13_REG))
18467 (clobber (reg:TI XMM14_REG))
18468 (clobber (reg:TI XMM15_REG))
18469 (clobber (reg:DI SI_REG))
18470 (clobber (reg:DI DI_REG))]
18471 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18473 if (constant_call_address_operand (operands[1], Pmode))
18474 return "call\t%P1";
18475 return "call\t%A1";
18477 [(set_attr "type" "callv")])
18479 (define_insn "*call_value_1_rex64_large"
18480 [(set (match_operand 0 "" "")
18481 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
18482 (match_operand:DI 2 "" "")))]
18483 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18485 [(set_attr "type" "callv")])
18487 (define_insn "*sibcall_value_1_rex64"
18488 [(set (match_operand 0 "" "")
18489 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
18490 (match_operand:DI 2 "" "")))]
18491 "TARGET_64BIT && SIBLING_CALL_P (insn)"
18495 [(set_attr "type" "callv")])
18497 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18498 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18499 ;; caught for use by garbage collectors and the like. Using an insn that
18500 ;; maps to SIGILL makes it more likely the program will rightfully die.
18501 ;; Keeping with tradition, "6" is in honor of #UD.
18502 (define_insn "trap"
18503 [(trap_if (const_int 1) (const_int 6))]
18505 { return ASM_SHORT "0x0b0f"; }
18506 [(set_attr "length" "2")])
18508 (define_expand "sse_prologue_save"
18509 [(parallel [(set (match_operand:BLK 0 "" "")
18510 (unspec:BLK [(reg:DI XMM0_REG)
18517 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18518 (use (match_operand:DI 1 "register_operand" ""))
18519 (use (match_operand:DI 2 "immediate_operand" ""))
18520 (use (label_ref:DI (match_operand 3 "" "")))])]
18524 (define_insn "*sse_prologue_save_insn"
18525 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18526 (match_operand:DI 4 "const_int_operand" "n")))
18527 (unspec:BLK [(reg:DI XMM0_REG)
18534 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18535 (use (match_operand:DI 1 "register_operand" "r"))
18536 (use (match_operand:DI 2 "const_int_operand" "i"))
18537 (use (label_ref:DI (match_operand 3 "" "X")))]
18539 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18540 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
18543 operands[0] = gen_rtx_MEM (Pmode,
18544 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
18545 /* VEX instruction with a REX prefix will #UD. */
18546 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
18547 gcc_unreachable ();
18549 output_asm_insn ("jmp\t%A1", operands);
18550 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
18552 operands[4] = adjust_address (operands[0], DImode, i*16);
18553 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
18554 PUT_MODE (operands[4], TImode);
18555 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
18556 output_asm_insn ("rex", operands);
18557 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
18559 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18560 CODE_LABEL_NUMBER (operands[3]));
18563 [(set_attr "type" "other")
18564 (set_attr "length_immediate" "0")
18565 (set_attr "length_address" "0")
18566 (set (attr "length")
18568 (eq (symbol_ref "TARGET_AVX") (const_int 0))
18569 (const_string "34")
18570 (const_string "42")))
18571 (set_attr "memory" "store")
18572 (set_attr "modrm" "0")
18573 (set_attr "prefix" "maybe_vex")
18574 (set_attr "mode" "DI")])
18576 (define_expand "prefetch"
18577 [(prefetch (match_operand 0 "address_operand" "")
18578 (match_operand:SI 1 "const_int_operand" "")
18579 (match_operand:SI 2 "const_int_operand" ""))]
18580 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
18582 int rw = INTVAL (operands[1]);
18583 int locality = INTVAL (operands[2]);
18585 gcc_assert (rw == 0 || rw == 1);
18586 gcc_assert (locality >= 0 && locality <= 3);
18587 gcc_assert (GET_MODE (operands[0]) == Pmode
18588 || GET_MODE (operands[0]) == VOIDmode);
18590 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18591 supported by SSE counterpart or the SSE prefetch is not available
18592 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18594 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
18595 operands[2] = GEN_INT (3);
18597 operands[1] = const0_rtx;
18600 (define_insn "*prefetch_sse"
18601 [(prefetch (match_operand:SI 0 "address_operand" "p")
18603 (match_operand:SI 1 "const_int_operand" ""))]
18604 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
18606 static const char * const patterns[4] = {
18607 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18610 int locality = INTVAL (operands[1]);
18611 gcc_assert (locality >= 0 && locality <= 3);
18613 return patterns[locality];
18615 [(set_attr "type" "sse")
18616 (set_attr "atom_sse_attr" "prefetch")
18617 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18618 (set_attr "memory" "none")])
18620 (define_insn "*prefetch_sse_rex"
18621 [(prefetch (match_operand:DI 0 "address_operand" "p")
18623 (match_operand:SI 1 "const_int_operand" ""))]
18624 "TARGET_PREFETCH_SSE && TARGET_64BIT"
18626 static const char * const patterns[4] = {
18627 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18630 int locality = INTVAL (operands[1]);
18631 gcc_assert (locality >= 0 && locality <= 3);
18633 return patterns[locality];
18635 [(set_attr "type" "sse")
18636 (set_attr "atom_sse_attr" "prefetch")
18637 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18638 (set_attr "memory" "none")])
18640 (define_insn "*prefetch_3dnow"
18641 [(prefetch (match_operand:SI 0 "address_operand" "p")
18642 (match_operand:SI 1 "const_int_operand" "n")
18644 "TARGET_3DNOW && !TARGET_64BIT"
18646 if (INTVAL (operands[1]) == 0)
18647 return "prefetch\t%a0";
18649 return "prefetchw\t%a0";
18651 [(set_attr "type" "mmx")
18652 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18653 (set_attr "memory" "none")])
18655 (define_insn "*prefetch_3dnow_rex"
18656 [(prefetch (match_operand:DI 0 "address_operand" "p")
18657 (match_operand:SI 1 "const_int_operand" "n")
18659 "TARGET_3DNOW && TARGET_64BIT"
18661 if (INTVAL (operands[1]) == 0)
18662 return "prefetch\t%a0";
18664 return "prefetchw\t%a0";
18666 [(set_attr "type" "mmx")
18667 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18668 (set_attr "memory" "none")])
18670 (define_expand "stack_protect_set"
18671 [(match_operand 0 "memory_operand" "")
18672 (match_operand 1 "memory_operand" "")]
18675 #ifdef TARGET_THREAD_SSP_OFFSET
18677 emit_insn (gen_stack_tls_protect_set_di (operands[0],
18678 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18680 emit_insn (gen_stack_tls_protect_set_si (operands[0],
18681 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18684 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18686 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18691 (define_insn "stack_protect_set_si"
18692 [(set (match_operand:SI 0 "memory_operand" "=m")
18693 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18694 (set (match_scratch:SI 2 "=&r") (const_int 0))
18695 (clobber (reg:CC FLAGS_REG))]
18697 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18698 [(set_attr "type" "multi")])
18700 (define_insn "stack_protect_set_di"
18701 [(set (match_operand:DI 0 "memory_operand" "=m")
18702 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18703 (set (match_scratch:DI 2 "=&r") (const_int 0))
18704 (clobber (reg:CC FLAGS_REG))]
18706 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18707 [(set_attr "type" "multi")])
18709 (define_insn "stack_tls_protect_set_si"
18710 [(set (match_operand:SI 0 "memory_operand" "=m")
18711 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18712 (set (match_scratch:SI 2 "=&r") (const_int 0))
18713 (clobber (reg:CC FLAGS_REG))]
18715 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18716 [(set_attr "type" "multi")])
18718 (define_insn "stack_tls_protect_set_di"
18719 [(set (match_operand:DI 0 "memory_operand" "=m")
18720 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18721 (set (match_scratch:DI 2 "=&r") (const_int 0))
18722 (clobber (reg:CC FLAGS_REG))]
18725 /* The kernel uses a different segment register for performance reasons; a
18726 system call would not have to trash the userspace segment register,
18727 which would be expensive */
18728 if (ix86_cmodel != CM_KERNEL)
18729 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18731 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18733 [(set_attr "type" "multi")])
18735 (define_expand "stack_protect_test"
18736 [(match_operand 0 "memory_operand" "")
18737 (match_operand 1 "memory_operand" "")
18738 (match_operand 2 "" "")]
18741 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18743 #ifdef TARGET_THREAD_SSP_OFFSET
18745 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18746 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18748 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18749 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18752 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18754 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18757 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18758 flags, const0_rtx, operands[2]));
18762 (define_insn "stack_protect_test_si"
18763 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18764 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18765 (match_operand:SI 2 "memory_operand" "m")]
18767 (clobber (match_scratch:SI 3 "=&r"))]
18769 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18770 [(set_attr "type" "multi")])
18772 (define_insn "stack_protect_test_di"
18773 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18774 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18775 (match_operand:DI 2 "memory_operand" "m")]
18777 (clobber (match_scratch:DI 3 "=&r"))]
18779 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18780 [(set_attr "type" "multi")])
18782 (define_insn "stack_tls_protect_test_si"
18783 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18784 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18785 (match_operand:SI 2 "const_int_operand" "i")]
18786 UNSPEC_SP_TLS_TEST))
18787 (clobber (match_scratch:SI 3 "=r"))]
18789 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18790 [(set_attr "type" "multi")])
18792 (define_insn "stack_tls_protect_test_di"
18793 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18794 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18795 (match_operand:DI 2 "const_int_operand" "i")]
18796 UNSPEC_SP_TLS_TEST))
18797 (clobber (match_scratch:DI 3 "=r"))]
18800 /* The kernel uses a different segment register for performance reasons; a
18801 system call would not have to trash the userspace segment register,
18802 which would be expensive */
18803 if (ix86_cmodel != CM_KERNEL)
18804 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18806 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18808 [(set_attr "type" "multi")])
18810 (define_insn "sse4_2_crc32<mode>"
18811 [(set (match_operand:SI 0 "register_operand" "=r")
18813 [(match_operand:SI 1 "register_operand" "0")
18814 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18816 "TARGET_SSE4_2 || TARGET_CRC32"
18817 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18818 [(set_attr "type" "sselog1")
18819 (set_attr "prefix_rep" "1")
18820 (set_attr "prefix_extra" "1")
18821 (set (attr "prefix_data16")
18822 (if_then_else (match_operand:HI 2 "" "")
18824 (const_string "*")))
18825 (set (attr "prefix_rex")
18826 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18828 (const_string "*")))
18829 (set_attr "mode" "SI")])
18831 (define_insn "sse4_2_crc32di"
18832 [(set (match_operand:DI 0 "register_operand" "=r")
18834 [(match_operand:DI 1 "register_operand" "0")
18835 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18837 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18838 "crc32{q}\t{%2, %0|%0, %2}"
18839 [(set_attr "type" "sselog1")
18840 (set_attr "prefix_rep" "1")
18841 (set_attr "prefix_extra" "1")
18842 (set_attr "mode" "DI")])
18844 (define_expand "rdpmc"
18845 [(match_operand:DI 0 "register_operand" "")
18846 (match_operand:SI 1 "register_operand" "")]
18849 rtx reg = gen_reg_rtx (DImode);
18852 /* Force operand 1 into ECX. */
18853 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18854 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18855 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18860 rtvec vec = rtvec_alloc (2);
18861 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18862 rtx upper = gen_reg_rtx (DImode);
18863 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18864 gen_rtvec (1, const0_rtx),
18866 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18867 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18869 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18870 NULL, 1, OPTAB_DIRECT);
18871 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18875 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18876 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18880 (define_insn "*rdpmc"
18881 [(set (match_operand:DI 0 "register_operand" "=A")
18882 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18886 [(set_attr "type" "other")
18887 (set_attr "length" "2")])
18889 (define_insn "*rdpmc_rex64"
18890 [(set (match_operand:DI 0 "register_operand" "=a")
18891 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18893 (set (match_operand:DI 1 "register_operand" "=d")
18894 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18897 [(set_attr "type" "other")
18898 (set_attr "length" "2")])
18900 (define_expand "rdtsc"
18901 [(set (match_operand:DI 0 "register_operand" "")
18902 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18907 rtvec vec = rtvec_alloc (2);
18908 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18909 rtx upper = gen_reg_rtx (DImode);
18910 rtx lower = gen_reg_rtx (DImode);
18911 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18912 gen_rtvec (1, const0_rtx),
18914 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18915 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18917 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18918 NULL, 1, OPTAB_DIRECT);
18919 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18921 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18926 (define_insn "*rdtsc"
18927 [(set (match_operand:DI 0 "register_operand" "=A")
18928 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18931 [(set_attr "type" "other")
18932 (set_attr "length" "2")])
18934 (define_insn "*rdtsc_rex64"
18935 [(set (match_operand:DI 0 "register_operand" "=a")
18936 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18937 (set (match_operand:DI 1 "register_operand" "=d")
18938 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18941 [(set_attr "type" "other")
18942 (set_attr "length" "2")])
18944 (define_expand "rdtscp"
18945 [(match_operand:DI 0 "register_operand" "")
18946 (match_operand:SI 1 "memory_operand" "")]
18949 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18950 gen_rtvec (1, const0_rtx),
18952 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18953 gen_rtvec (1, const0_rtx),
18955 rtx reg = gen_reg_rtx (DImode);
18956 rtx tmp = gen_reg_rtx (SImode);
18960 rtvec vec = rtvec_alloc (3);
18961 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18962 rtx upper = gen_reg_rtx (DImode);
18963 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18964 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18965 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18967 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18968 NULL, 1, OPTAB_DIRECT);
18969 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18974 rtvec vec = rtvec_alloc (2);
18975 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18976 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18977 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18980 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18981 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18985 (define_insn "*rdtscp"
18986 [(set (match_operand:DI 0 "register_operand" "=A")
18987 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18988 (set (match_operand:SI 1 "register_operand" "=c")
18989 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18992 [(set_attr "type" "other")
18993 (set_attr "length" "3")])
18995 (define_insn "*rdtscp_rex64"
18996 [(set (match_operand:DI 0 "register_operand" "=a")
18997 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18998 (set (match_operand:DI 1 "register_operand" "=d")
18999 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19000 (set (match_operand:SI 2 "register_operand" "=c")
19001 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19004 [(set_attr "type" "other")
19005 (set_attr "length" "3")])
19007 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19009 ;; LWP instructions
19011 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19013 (define_expand "lwp_llwpcb"
19014 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
19015 UNSPECV_LLWP_INTRINSIC)]
19019 (define_insn "*lwp_llwpcb<mode>1"
19020 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19021 UNSPECV_LLWP_INTRINSIC)]
19024 [(set_attr "type" "lwp")
19025 (set_attr "mode" "<MODE>")
19026 (set_attr "length" "5")])
19028 (define_expand "lwp_slwpcb"
19029 [(set (match_operand 0 "register_operand" "=r")
19030 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19034 emit_insn (gen_lwp_slwpcbdi (operands[0]));
19036 emit_insn (gen_lwp_slwpcbsi (operands[0]));
19040 (define_insn "lwp_slwpcb<mode>"
19041 [(set (match_operand:P 0 "register_operand" "=r")
19042 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19045 [(set_attr "type" "lwp")
19046 (set_attr "mode" "<MODE>")
19047 (set_attr "length" "5")])
19049 (define_expand "lwp_lwpval<mode>3"
19050 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
19051 (match_operand:SI 2 "nonimmediate_operand" "rm")
19052 (match_operand:SI 3 "const_int_operand" "i")]
19053 UNSPECV_LWPVAL_INTRINSIC)]
19055 "/* Avoid unused variable warning. */
19058 (define_insn "*lwp_lwpval<mode>3_1"
19059 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19060 (match_operand:SI 1 "nonimmediate_operand" "rm")
19061 (match_operand:SI 2 "const_int_operand" "i")]
19062 UNSPECV_LWPVAL_INTRINSIC)]
19064 "lwpval\t{%2, %1, %0|%0, %1, %2}"
19065 [(set_attr "type" "lwp")
19066 (set_attr "mode" "<MODE>")
19067 (set (attr "length")
19068 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19070 (define_expand "lwp_lwpins<mode>3"
19071 [(set (reg:CCC FLAGS_REG)
19072 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
19073 (match_operand:SI 2 "nonimmediate_operand" "rm")
19074 (match_operand:SI 3 "const_int_operand" "i")]
19075 UNSPECV_LWPINS_INTRINSIC))
19076 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
19077 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19081 (define_insn "*lwp_lwpins<mode>3_1"
19082 [(set (reg:CCC FLAGS_REG)
19083 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19084 (match_operand:SI 1 "nonimmediate_operand" "rm")
19085 (match_operand:SI 2 "const_int_operand" "i")]
19086 UNSPECV_LWPINS_INTRINSIC))]
19088 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19089 [(set_attr "type" "lwp")
19090 (set_attr "mode" "<MODE>")
19091 (set (attr "length")
19092 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19096 (include "sync.md")