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))]
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))]
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 "*bt<mode>"
10969 [(set (reg:CCC FLAGS_REG)
10971 (zero_extract:SWI48
10972 (match_operand:SWI48 0 "register_operand" "r")
10974 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10976 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10977 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10978 [(set_attr "type" "alu1")
10979 (set_attr "prefix_0f" "1")
10980 (set_attr "mode" "<MODE>")])
10982 ;; Store-flag instructions.
10984 ;; For all sCOND expanders, also expand the compare or test insn that
10985 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10987 (define_insn_and_split "*setcc_di_1"
10988 [(set (match_operand:DI 0 "register_operand" "=q")
10989 (match_operator:DI 1 "ix86_comparison_operator"
10990 [(reg FLAGS_REG) (const_int 0)]))]
10991 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10993 "&& reload_completed"
10994 [(set (match_dup 2) (match_dup 1))
10995 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10997 PUT_MODE (operands[1], QImode);
10998 operands[2] = gen_lowpart (QImode, operands[0]);
11001 (define_insn_and_split "*setcc_si_1_and"
11002 [(set (match_operand:SI 0 "register_operand" "=q")
11003 (match_operator:SI 1 "ix86_comparison_operator"
11004 [(reg FLAGS_REG) (const_int 0)]))
11005 (clobber (reg:CC FLAGS_REG))]
11006 "!TARGET_PARTIAL_REG_STALL
11007 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11009 "&& reload_completed"
11010 [(set (match_dup 2) (match_dup 1))
11011 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11012 (clobber (reg:CC FLAGS_REG))])]
11014 PUT_MODE (operands[1], QImode);
11015 operands[2] = gen_lowpart (QImode, operands[0]);
11018 (define_insn_and_split "*setcc_si_1_movzbl"
11019 [(set (match_operand:SI 0 "register_operand" "=q")
11020 (match_operator:SI 1 "ix86_comparison_operator"
11021 [(reg FLAGS_REG) (const_int 0)]))]
11022 "!TARGET_PARTIAL_REG_STALL
11023 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11025 "&& reload_completed"
11026 [(set (match_dup 2) (match_dup 1))
11027 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11029 PUT_MODE (operands[1], QImode);
11030 operands[2] = gen_lowpart (QImode, operands[0]);
11033 (define_insn "*setcc_qi"
11034 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11035 (match_operator:QI 1 "ix86_comparison_operator"
11036 [(reg FLAGS_REG) (const_int 0)]))]
11039 [(set_attr "type" "setcc")
11040 (set_attr "mode" "QI")])
11042 (define_insn "*setcc_qi_slp"
11043 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11044 (match_operator:QI 1 "ix86_comparison_operator"
11045 [(reg FLAGS_REG) (const_int 0)]))]
11048 [(set_attr "type" "setcc")
11049 (set_attr "mode" "QI")])
11051 ;; In general it is not safe to assume too much about CCmode registers,
11052 ;; so simplify-rtx stops when it sees a second one. Under certain
11053 ;; conditions this is safe on x86, so help combine not create
11060 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11061 (ne:QI (match_operator 1 "ix86_comparison_operator"
11062 [(reg FLAGS_REG) (const_int 0)])
11065 [(set (match_dup 0) (match_dup 1))]
11067 PUT_MODE (operands[1], QImode);
11071 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11072 (ne:QI (match_operator 1 "ix86_comparison_operator"
11073 [(reg FLAGS_REG) (const_int 0)])
11076 [(set (match_dup 0) (match_dup 1))]
11078 PUT_MODE (operands[1], QImode);
11082 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11083 (eq:QI (match_operator 1 "ix86_comparison_operator"
11084 [(reg FLAGS_REG) (const_int 0)])
11087 [(set (match_dup 0) (match_dup 1))]
11089 rtx new_op1 = copy_rtx (operands[1]);
11090 operands[1] = new_op1;
11091 PUT_MODE (new_op1, QImode);
11092 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11093 GET_MODE (XEXP (new_op1, 0))));
11095 /* Make sure that (a) the CCmode we have for the flags is strong
11096 enough for the reversed compare or (b) we have a valid FP compare. */
11097 if (! ix86_comparison_operator (new_op1, VOIDmode))
11102 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11103 (eq:QI (match_operator 1 "ix86_comparison_operator"
11104 [(reg FLAGS_REG) (const_int 0)])
11107 [(set (match_dup 0) (match_dup 1))]
11109 rtx new_op1 = copy_rtx (operands[1]);
11110 operands[1] = new_op1;
11111 PUT_MODE (new_op1, QImode);
11112 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11113 GET_MODE (XEXP (new_op1, 0))));
11115 /* Make sure that (a) the CCmode we have for the flags is strong
11116 enough for the reversed compare or (b) we have a valid FP compare. */
11117 if (! ix86_comparison_operator (new_op1, VOIDmode))
11121 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11122 ;; subsequent logical operations are used to imitate conditional moves.
11123 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11126 (define_insn "*avx_setcc<mode>"
11127 [(set (match_operand:MODEF 0 "register_operand" "=x")
11128 (match_operator:MODEF 1 "avx_comparison_float_operator"
11129 [(match_operand:MODEF 2 "register_operand" "x")
11130 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11132 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
11133 [(set_attr "type" "ssecmp")
11134 (set_attr "prefix" "vex")
11135 (set_attr "length_immediate" "1")
11136 (set_attr "mode" "<MODE>")])
11138 (define_insn "*sse_setcc<mode>"
11139 [(set (match_operand:MODEF 0 "register_operand" "=x")
11140 (match_operator:MODEF 1 "sse_comparison_operator"
11141 [(match_operand:MODEF 2 "register_operand" "0")
11142 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11143 "SSE_FLOAT_MODE_P (<MODE>mode)"
11144 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
11145 [(set_attr "type" "ssecmp")
11146 (set_attr "length_immediate" "1")
11147 (set_attr "mode" "<MODE>")])
11149 ;; Basic conditional jump instructions.
11150 ;; We ignore the overflow flag for signed branch instructions.
11152 (define_insn "*jcc_1"
11154 (if_then_else (match_operator 1 "ix86_comparison_operator"
11155 [(reg FLAGS_REG) (const_int 0)])
11156 (label_ref (match_operand 0 "" ""))
11160 [(set_attr "type" "ibr")
11161 (set_attr "modrm" "0")
11162 (set (attr "length")
11163 (if_then_else (and (ge (minus (match_dup 0) (pc))
11165 (lt (minus (match_dup 0) (pc))
11170 (define_insn "*jcc_2"
11172 (if_then_else (match_operator 1 "ix86_comparison_operator"
11173 [(reg FLAGS_REG) (const_int 0)])
11175 (label_ref (match_operand 0 "" ""))))]
11178 [(set_attr "type" "ibr")
11179 (set_attr "modrm" "0")
11180 (set (attr "length")
11181 (if_then_else (and (ge (minus (match_dup 0) (pc))
11183 (lt (minus (match_dup 0) (pc))
11188 ;; In general it is not safe to assume too much about CCmode registers,
11189 ;; so simplify-rtx stops when it sees a second one. Under certain
11190 ;; conditions this is safe on x86, so help combine not create
11198 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11199 [(reg FLAGS_REG) (const_int 0)])
11201 (label_ref (match_operand 1 "" ""))
11205 (if_then_else (match_dup 0)
11206 (label_ref (match_dup 1))
11209 PUT_MODE (operands[0], VOIDmode);
11214 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11215 [(reg FLAGS_REG) (const_int 0)])
11217 (label_ref (match_operand 1 "" ""))
11221 (if_then_else (match_dup 0)
11222 (label_ref (match_dup 1))
11225 rtx new_op0 = copy_rtx (operands[0]);
11226 operands[0] = new_op0;
11227 PUT_MODE (new_op0, VOIDmode);
11228 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11229 GET_MODE (XEXP (new_op0, 0))));
11231 /* Make sure that (a) the CCmode we have for the flags is strong
11232 enough for the reversed compare or (b) we have a valid FP compare. */
11233 if (! ix86_comparison_operator (new_op0, VOIDmode))
11237 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11238 ;; pass generates from shift insn with QImode operand. Actually, the mode
11239 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11240 ;; appropriate modulo of the bit offset value.
11242 (define_insn_and_split "*jcc_bt<mode>"
11244 (if_then_else (match_operator 0 "bt_comparison_operator"
11245 [(zero_extract:SWI48
11246 (match_operand:SWI48 1 "register_operand" "r")
11249 (match_operand:QI 2 "register_operand" "r")))
11251 (label_ref (match_operand 3 "" ""))
11253 (clobber (reg:CC FLAGS_REG))]
11254 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11257 [(set (reg:CCC FLAGS_REG)
11259 (zero_extract:SWI48
11265 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11266 (label_ref (match_dup 3))
11269 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11271 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11274 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11275 ;; also for DImode, this is what combine produces.
11276 (define_insn_and_split "*jcc_bt<mode>_mask"
11278 (if_then_else (match_operator 0 "bt_comparison_operator"
11279 [(zero_extract:SWI48
11280 (match_operand:SWI48 1 "register_operand" "r")
11283 (match_operand:SI 2 "register_operand" "r")
11284 (match_operand:SI 3 "const_int_operand" "n")))])
11285 (label_ref (match_operand 4 "" ""))
11287 (clobber (reg:CC FLAGS_REG))]
11288 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11289 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11290 == GET_MODE_BITSIZE (<MODE>mode)-1"
11293 [(set (reg:CCC FLAGS_REG)
11295 (zero_extract:SWI48
11301 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11302 (label_ref (match_dup 4))
11305 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11307 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11310 (define_insn_and_split "*jcc_btsi_1"
11312 (if_then_else (match_operator 0 "bt_comparison_operator"
11315 (match_operand:SI 1 "register_operand" "r")
11316 (match_operand:QI 2 "register_operand" "r"))
11319 (label_ref (match_operand 3 "" ""))
11321 (clobber (reg:CC FLAGS_REG))]
11322 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11325 [(set (reg:CCC FLAGS_REG)
11333 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11334 (label_ref (match_dup 3))
11337 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11339 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11342 ;; avoid useless masking of bit offset operand
11343 (define_insn_and_split "*jcc_btsi_mask_1"
11346 (match_operator 0 "bt_comparison_operator"
11349 (match_operand:SI 1 "register_operand" "r")
11352 (match_operand:SI 2 "register_operand" "r")
11353 (match_operand:SI 3 "const_int_operand" "n")) 0))
11356 (label_ref (match_operand 4 "" ""))
11358 (clobber (reg:CC FLAGS_REG))]
11359 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11360 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11363 [(set (reg:CCC FLAGS_REG)
11371 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11372 (label_ref (match_dup 4))
11374 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11376 ;; Define combination compare-and-branch fp compare instructions to help
11379 (define_insn "*fp_jcc_3_387"
11381 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11382 [(match_operand 1 "register_operand" "f")
11383 (match_operand 2 "nonimmediate_operand" "fm")])
11384 (label_ref (match_operand 3 "" ""))
11386 (clobber (reg:CCFP FPSR_REG))
11387 (clobber (reg:CCFP FLAGS_REG))
11388 (clobber (match_scratch:HI 4 "=a"))]
11390 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11391 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11392 && SELECT_CC_MODE (GET_CODE (operands[0]),
11393 operands[1], operands[2]) == CCFPmode
11397 (define_insn "*fp_jcc_4_387"
11399 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11400 [(match_operand 1 "register_operand" "f")
11401 (match_operand 2 "nonimmediate_operand" "fm")])
11403 (label_ref (match_operand 3 "" ""))))
11404 (clobber (reg:CCFP FPSR_REG))
11405 (clobber (reg:CCFP FLAGS_REG))
11406 (clobber (match_scratch:HI 4 "=a"))]
11408 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11409 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11410 && SELECT_CC_MODE (GET_CODE (operands[0]),
11411 operands[1], operands[2]) == CCFPmode
11415 (define_insn "*fp_jcc_5_387"
11417 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11418 [(match_operand 1 "register_operand" "f")
11419 (match_operand 2 "register_operand" "f")])
11420 (label_ref (match_operand 3 "" ""))
11422 (clobber (reg:CCFP FPSR_REG))
11423 (clobber (reg:CCFP FLAGS_REG))
11424 (clobber (match_scratch:HI 4 "=a"))]
11425 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11426 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11430 (define_insn "*fp_jcc_6_387"
11432 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11433 [(match_operand 1 "register_operand" "f")
11434 (match_operand 2 "register_operand" "f")])
11436 (label_ref (match_operand 3 "" ""))))
11437 (clobber (reg:CCFP FPSR_REG))
11438 (clobber (reg:CCFP FLAGS_REG))
11439 (clobber (match_scratch:HI 4 "=a"))]
11440 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11441 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11445 (define_insn "*fp_jcc_7_387"
11447 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11448 [(match_operand 1 "register_operand" "f")
11449 (match_operand 2 "const0_operand" "")])
11450 (label_ref (match_operand 3 "" ""))
11452 (clobber (reg:CCFP FPSR_REG))
11453 (clobber (reg:CCFP FLAGS_REG))
11454 (clobber (match_scratch:HI 4 "=a"))]
11455 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11456 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11457 && SELECT_CC_MODE (GET_CODE (operands[0]),
11458 operands[1], operands[2]) == CCFPmode
11462 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
11463 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11464 ;; with a precedence over other operators and is always put in the first
11465 ;; place. Swap condition and operands to match ficom instruction.
11467 (define_insn "*fp_jcc_8<mode>_387"
11469 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11470 [(match_operator 1 "float_operator"
11471 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11472 (match_operand 3 "register_operand" "f,f")])
11473 (label_ref (match_operand 4 "" ""))
11475 (clobber (reg:CCFP FPSR_REG))
11476 (clobber (reg:CCFP FLAGS_REG))
11477 (clobber (match_scratch:HI 5 "=a,a"))]
11478 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11479 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11480 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11481 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11487 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11488 [(match_operand 1 "register_operand" "")
11489 (match_operand 2 "nonimmediate_operand" "")])
11490 (match_operand 3 "" "")
11491 (match_operand 4 "" "")))
11492 (clobber (reg:CCFP FPSR_REG))
11493 (clobber (reg:CCFP FLAGS_REG))]
11497 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11498 operands[3], operands[4], NULL_RTX, NULL_RTX);
11504 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11505 [(match_operand 1 "register_operand" "")
11506 (match_operand 2 "general_operand" "")])
11507 (match_operand 3 "" "")
11508 (match_operand 4 "" "")))
11509 (clobber (reg:CCFP FPSR_REG))
11510 (clobber (reg:CCFP FLAGS_REG))
11511 (clobber (match_scratch:HI 5 "=a"))]
11515 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11516 operands[3], operands[4], operands[5], NULL_RTX);
11522 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11523 [(match_operator 1 "float_operator"
11524 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11525 (match_operand 3 "register_operand" "")])
11526 (match_operand 4 "" "")
11527 (match_operand 5 "" "")))
11528 (clobber (reg:CCFP FPSR_REG))
11529 (clobber (reg:CCFP FLAGS_REG))
11530 (clobber (match_scratch:HI 6 "=a"))]
11534 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11535 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11536 operands[3], operands[7],
11537 operands[4], operands[5], operands[6], NULL_RTX);
11541 ;; %%% Kill this when reload knows how to do it.
11544 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11545 [(match_operator 1 "float_operator"
11546 [(match_operand:X87MODEI12 2 "register_operand" "")])
11547 (match_operand 3 "register_operand" "")])
11548 (match_operand 4 "" "")
11549 (match_operand 5 "" "")))
11550 (clobber (reg:CCFP FPSR_REG))
11551 (clobber (reg:CCFP FLAGS_REG))
11552 (clobber (match_scratch:HI 6 "=a"))]
11556 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11557 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11558 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11559 operands[3], operands[7],
11560 operands[4], operands[5], operands[6], operands[2]);
11564 ;; Unconditional and other jump instructions
11566 (define_insn "jump"
11568 (label_ref (match_operand 0 "" "")))]
11571 [(set_attr "type" "ibr")
11572 (set (attr "length")
11573 (if_then_else (and (ge (minus (match_dup 0) (pc))
11575 (lt (minus (match_dup 0) (pc))
11579 (set_attr "modrm" "0")])
11581 (define_expand "indirect_jump"
11582 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11586 (define_insn "*indirect_jump"
11587 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11590 [(set_attr "type" "ibr")
11591 (set_attr "length_immediate" "0")])
11593 (define_expand "tablejump"
11594 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11595 (use (label_ref (match_operand 1 "" "")))])]
11598 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11599 relative. Convert the relative address to an absolute address. */
11603 enum rtx_code code;
11605 /* We can't use @GOTOFF for text labels on VxWorks;
11606 see gotoff_operand. */
11607 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11611 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11613 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11617 op1 = pic_offset_table_rtx;
11622 op0 = pic_offset_table_rtx;
11626 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11631 (define_insn "*tablejump_1"
11632 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11633 (use (label_ref (match_operand 1 "" "")))]
11636 [(set_attr "type" "ibr")
11637 (set_attr "length_immediate" "0")])
11639 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11642 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11643 (set (match_operand:QI 1 "register_operand" "")
11644 (match_operator:QI 2 "ix86_comparison_operator"
11645 [(reg FLAGS_REG) (const_int 0)]))
11646 (set (match_operand 3 "q_regs_operand" "")
11647 (zero_extend (match_dup 1)))]
11648 "(peep2_reg_dead_p (3, operands[1])
11649 || operands_match_p (operands[1], operands[3]))
11650 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11651 [(set (match_dup 4) (match_dup 0))
11652 (set (strict_low_part (match_dup 5))
11655 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11656 operands[5] = gen_lowpart (QImode, operands[3]);
11657 ix86_expand_clear (operands[3]);
11660 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11663 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11664 (set (match_operand:QI 1 "register_operand" "")
11665 (match_operator:QI 2 "ix86_comparison_operator"
11666 [(reg FLAGS_REG) (const_int 0)]))
11667 (parallel [(set (match_operand 3 "q_regs_operand" "")
11668 (zero_extend (match_dup 1)))
11669 (clobber (reg:CC FLAGS_REG))])]
11670 "(peep2_reg_dead_p (3, operands[1])
11671 || operands_match_p (operands[1], operands[3]))
11672 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11673 [(set (match_dup 4) (match_dup 0))
11674 (set (strict_low_part (match_dup 5))
11677 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11678 operands[5] = gen_lowpart (QImode, operands[3]);
11679 ix86_expand_clear (operands[3]);
11682 ;; Call instructions.
11684 ;; The predicates normally associated with named expanders are not properly
11685 ;; checked for calls. This is a bug in the generic code, but it isn't that
11686 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11688 ;; P6 processors will jump to the address after the decrement when %esp
11689 ;; is used as a call operand, so they will execute return address as a code.
11690 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11692 ;; Call subroutine returning no value.
11694 (define_expand "call_pop"
11695 [(parallel [(call (match_operand:QI 0 "" "")
11696 (match_operand:SI 1 "" ""))
11697 (set (reg:SI SP_REG)
11698 (plus:SI (reg:SI SP_REG)
11699 (match_operand:SI 3 "" "")))])]
11702 ix86_expand_call (NULL, operands[0], operands[1],
11703 operands[2], operands[3], 0);
11707 (define_insn "*call_pop_0"
11708 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11709 (match_operand:SI 1 "" ""))
11710 (set (reg:SI SP_REG)
11711 (plus:SI (reg:SI SP_REG)
11712 (match_operand:SI 2 "immediate_operand" "")))]
11715 if (SIBLING_CALL_P (insn))
11718 return "call\t%P0";
11720 [(set_attr "type" "call")])
11722 (define_insn "*call_pop_1"
11723 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11724 (match_operand:SI 1 "" ""))
11725 (set (reg:SI SP_REG)
11726 (plus:SI (reg:SI SP_REG)
11727 (match_operand:SI 2 "immediate_operand" "i")))]
11728 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11730 if (constant_call_address_operand (operands[0], Pmode))
11731 return "call\t%P0";
11732 return "call\t%A0";
11734 [(set_attr "type" "call")])
11736 (define_insn "*sibcall_pop_1"
11737 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11738 (match_operand:SI 1 "" ""))
11739 (set (reg:SI SP_REG)
11740 (plus:SI (reg:SI SP_REG)
11741 (match_operand:SI 2 "immediate_operand" "i,i")))]
11742 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11746 [(set_attr "type" "call")])
11748 (define_expand "call"
11749 [(call (match_operand:QI 0 "" "")
11750 (match_operand 1 "" ""))
11751 (use (match_operand 2 "" ""))]
11754 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11758 (define_expand "sibcall"
11759 [(call (match_operand:QI 0 "" "")
11760 (match_operand 1 "" ""))
11761 (use (match_operand 2 "" ""))]
11764 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11768 (define_insn "*call_0"
11769 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11770 (match_operand 1 "" ""))]
11773 if (SIBLING_CALL_P (insn))
11776 return "call\t%P0";
11778 [(set_attr "type" "call")])
11780 (define_insn "*call_1"
11781 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11782 (match_operand 1 "" ""))]
11783 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11785 if (constant_call_address_operand (operands[0], Pmode))
11786 return "call\t%P0";
11787 return "call\t%A0";
11789 [(set_attr "type" "call")])
11791 (define_insn "*sibcall_1"
11792 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11793 (match_operand 1 "" ""))]
11794 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11798 [(set_attr "type" "call")])
11800 (define_insn "*call_1_rex64"
11801 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11802 (match_operand 1 "" ""))]
11803 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11804 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11806 if (constant_call_address_operand (operands[0], Pmode))
11807 return "call\t%P0";
11808 return "call\t%A0";
11810 [(set_attr "type" "call")])
11812 (define_insn "*call_1_rex64_ms_sysv"
11813 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11814 (match_operand 1 "" ""))
11815 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11816 (clobber (reg:TI XMM6_REG))
11817 (clobber (reg:TI XMM7_REG))
11818 (clobber (reg:TI XMM8_REG))
11819 (clobber (reg:TI XMM9_REG))
11820 (clobber (reg:TI XMM10_REG))
11821 (clobber (reg:TI XMM11_REG))
11822 (clobber (reg:TI XMM12_REG))
11823 (clobber (reg:TI XMM13_REG))
11824 (clobber (reg:TI XMM14_REG))
11825 (clobber (reg:TI XMM15_REG))
11826 (clobber (reg:DI SI_REG))
11827 (clobber (reg:DI DI_REG))]
11828 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11830 if (constant_call_address_operand (operands[0], Pmode))
11831 return "call\t%P0";
11832 return "call\t%A0";
11834 [(set_attr "type" "call")])
11836 (define_insn "*call_1_rex64_large"
11837 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11838 (match_operand 1 "" ""))]
11839 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11841 [(set_attr "type" "call")])
11843 (define_insn "*sibcall_1_rex64"
11844 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11845 (match_operand 1 "" ""))]
11846 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11850 [(set_attr "type" "call")])
11852 ;; Call subroutine, returning value in operand 0
11853 (define_expand "call_value_pop"
11854 [(parallel [(set (match_operand 0 "" "")
11855 (call (match_operand:QI 1 "" "")
11856 (match_operand:SI 2 "" "")))
11857 (set (reg:SI SP_REG)
11858 (plus:SI (reg:SI SP_REG)
11859 (match_operand:SI 4 "" "")))])]
11862 ix86_expand_call (operands[0], operands[1], operands[2],
11863 operands[3], operands[4], 0);
11867 (define_expand "call_value"
11868 [(set (match_operand 0 "" "")
11869 (call (match_operand:QI 1 "" "")
11870 (match_operand:SI 2 "" "")))
11871 (use (match_operand:SI 3 "" ""))]
11872 ;; Operand 3 is not used on the i386.
11875 ix86_expand_call (operands[0], operands[1], operands[2],
11876 operands[3], NULL, 0);
11880 (define_expand "sibcall_value"
11881 [(set (match_operand 0 "" "")
11882 (call (match_operand:QI 1 "" "")
11883 (match_operand:SI 2 "" "")))
11884 (use (match_operand:SI 3 "" ""))]
11885 ;; Operand 3 is not used on the i386.
11888 ix86_expand_call (operands[0], operands[1], operands[2],
11889 operands[3], NULL, 1);
11893 ;; Call subroutine returning any type.
11895 (define_expand "untyped_call"
11896 [(parallel [(call (match_operand 0 "" "")
11898 (match_operand 1 "" "")
11899 (match_operand 2 "" "")])]
11904 /* In order to give reg-stack an easier job in validating two
11905 coprocessor registers as containing a possible return value,
11906 simply pretend the untyped call returns a complex long double
11909 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11910 and should have the default ABI. */
11912 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11913 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11914 operands[0], const0_rtx,
11915 GEN_INT ((TARGET_64BIT
11916 ? (ix86_abi == SYSV_ABI
11917 ? X86_64_SSE_REGPARM_MAX
11918 : X86_64_MS_SSE_REGPARM_MAX)
11919 : X86_32_SSE_REGPARM_MAX)
11923 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11925 rtx set = XVECEXP (operands[2], 0, i);
11926 emit_move_insn (SET_DEST (set), SET_SRC (set));
11929 /* The optimizer does not know that the call sets the function value
11930 registers we stored in the result block. We avoid problems by
11931 claiming that all hard registers are used and clobbered at this
11933 emit_insn (gen_blockage ());
11938 ;; Prologue and epilogue instructions
11940 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11941 ;; all of memory. This blocks insns from being moved across this point.
11943 (define_insn "blockage"
11944 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11947 [(set_attr "length" "0")])
11949 ;; Do not schedule instructions accessing memory across this point.
11951 (define_expand "memory_blockage"
11952 [(set (match_dup 0)
11953 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11956 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11957 MEM_VOLATILE_P (operands[0]) = 1;
11960 (define_insn "*memory_blockage"
11961 [(set (match_operand:BLK 0 "" "")
11962 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11965 [(set_attr "length" "0")])
11967 ;; As USE insns aren't meaningful after reload, this is used instead
11968 ;; to prevent deleting instructions setting registers for PIC code
11969 (define_insn "prologue_use"
11970 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11973 [(set_attr "length" "0")])
11975 ;; Insn emitted into the body of a function to return from a function.
11976 ;; This is only done if the function's epilogue is known to be simple.
11977 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11979 (define_expand "return"
11981 "ix86_can_use_return_insn_p ()"
11983 if (crtl->args.pops_args)
11985 rtx popc = GEN_INT (crtl->args.pops_args);
11986 emit_jump_insn (gen_return_pop_internal (popc));
11991 (define_insn "return_internal"
11995 [(set_attr "length" "1")
11996 (set_attr "atom_unit" "jeu")
11997 (set_attr "length_immediate" "0")
11998 (set_attr "modrm" "0")])
12000 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12001 ;; instruction Athlon and K8 have.
12003 (define_insn "return_internal_long"
12005 (unspec [(const_int 0)] UNSPEC_REP)]
12008 [(set_attr "length" "2")
12009 (set_attr "atom_unit" "jeu")
12010 (set_attr "length_immediate" "0")
12011 (set_attr "prefix_rep" "1")
12012 (set_attr "modrm" "0")])
12014 (define_insn "return_pop_internal"
12016 (use (match_operand:SI 0 "const_int_operand" ""))]
12019 [(set_attr "length" "3")
12020 (set_attr "atom_unit" "jeu")
12021 (set_attr "length_immediate" "2")
12022 (set_attr "modrm" "0")])
12024 (define_insn "return_indirect_internal"
12026 (use (match_operand:SI 0 "register_operand" "r"))]
12029 [(set_attr "type" "ibr")
12030 (set_attr "length_immediate" "0")])
12036 [(set_attr "length" "1")
12037 (set_attr "length_immediate" "0")
12038 (set_attr "modrm" "0")])
12040 (define_insn "vswapmov"
12041 [(set (match_operand:SI 0 "register_operand" "=r")
12042 (match_operand:SI 1 "register_operand" "r"))
12043 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
12045 "movl.s\t{%1, %0|%0, %1}"
12046 [(set_attr "length" "2")
12047 (set_attr "length_immediate" "0")
12048 (set_attr "modrm" "0")])
12050 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12051 ;; branch prediction penalty for the third jump in a 16-byte
12055 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
12058 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12059 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12061 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12062 The align insn is used to avoid 3 jump instructions in the row to improve
12063 branch prediction and the benefits hardly outweigh the cost of extra 8
12064 nops on the average inserted by full alignment pseudo operation. */
12068 [(set_attr "length" "16")])
12070 (define_expand "prologue"
12073 "ix86_expand_prologue (); DONE;")
12075 (define_insn "set_got"
12076 [(set (match_operand:SI 0 "register_operand" "=r")
12077 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12078 (clobber (reg:CC FLAGS_REG))]
12080 { return output_set_got (operands[0], NULL_RTX); }
12081 [(set_attr "type" "multi")
12082 (set_attr "length" "12")])
12084 (define_insn "set_got_labelled"
12085 [(set (match_operand:SI 0 "register_operand" "=r")
12086 (unspec:SI [(label_ref (match_operand 1 "" ""))]
12088 (clobber (reg:CC FLAGS_REG))]
12090 { return output_set_got (operands[0], operands[1]); }
12091 [(set_attr "type" "multi")
12092 (set_attr "length" "12")])
12094 (define_insn "set_got_rex64"
12095 [(set (match_operand:DI 0 "register_operand" "=r")
12096 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12098 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12099 [(set_attr "type" "lea")
12100 (set_attr "length_address" "4")
12101 (set_attr "mode" "DI")])
12103 (define_insn "set_rip_rex64"
12104 [(set (match_operand:DI 0 "register_operand" "=r")
12105 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
12107 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12108 [(set_attr "type" "lea")
12109 (set_attr "length_address" "4")
12110 (set_attr "mode" "DI")])
12112 (define_insn "set_got_offset_rex64"
12113 [(set (match_operand:DI 0 "register_operand" "=r")
12115 [(label_ref (match_operand 1 "" ""))]
12116 UNSPEC_SET_GOT_OFFSET))]
12118 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12119 [(set_attr "type" "imov")
12120 (set_attr "length_immediate" "0")
12121 (set_attr "length_address" "8")
12122 (set_attr "mode" "DI")])
12124 (define_expand "epilogue"
12127 "ix86_expand_epilogue (1); DONE;")
12129 (define_expand "sibcall_epilogue"
12132 "ix86_expand_epilogue (0); DONE;")
12134 (define_expand "eh_return"
12135 [(use (match_operand 0 "register_operand" ""))]
12138 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12140 /* Tricky bit: we write the address of the handler to which we will
12141 be returning into someone else's stack frame, one word below the
12142 stack address we wish to restore. */
12143 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12144 tmp = plus_constant (tmp, -UNITS_PER_WORD);
12145 tmp = gen_rtx_MEM (Pmode, tmp);
12146 emit_move_insn (tmp, ra);
12148 emit_jump_insn (gen_eh_return_internal ());
12153 (define_insn_and_split "eh_return_internal"
12157 "epilogue_completed"
12159 "ix86_expand_epilogue (2); DONE;")
12161 (define_insn "leave"
12162 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12163 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12164 (clobber (mem:BLK (scratch)))]
12167 [(set_attr "type" "leave")])
12169 (define_insn "leave_rex64"
12170 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12171 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12172 (clobber (mem:BLK (scratch)))]
12175 [(set_attr "type" "leave")])
12177 (define_expand "ffssi2"
12179 [(set (match_operand:SI 0 "register_operand" "")
12180 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
12181 (clobber (match_scratch:SI 2 ""))
12182 (clobber (reg:CC FLAGS_REG))])]
12187 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
12192 (define_expand "ffs_cmove"
12193 [(set (match_dup 2) (const_int -1))
12194 (parallel [(set (reg:CCZ FLAGS_REG)
12195 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
12197 (set (match_operand:SI 0 "register_operand" "")
12198 (ctz:SI (match_dup 1)))])
12199 (set (match_dup 0) (if_then_else:SI
12200 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12203 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12204 (clobber (reg:CC FLAGS_REG))])]
12206 "operands[2] = gen_reg_rtx (SImode);")
12208 (define_insn_and_split "*ffs_no_cmove"
12209 [(set (match_operand:SI 0 "register_operand" "=r")
12210 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12211 (clobber (match_scratch:SI 2 "=&q"))
12212 (clobber (reg:CC FLAGS_REG))]
12215 "&& reload_completed"
12216 [(parallel [(set (reg:CCZ FLAGS_REG)
12217 (compare:CCZ (match_dup 1) (const_int 0)))
12218 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12219 (set (strict_low_part (match_dup 3))
12220 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12221 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12222 (clobber (reg:CC FLAGS_REG))])
12223 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12224 (clobber (reg:CC FLAGS_REG))])
12225 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12226 (clobber (reg:CC FLAGS_REG))])]
12228 operands[3] = gen_lowpart (QImode, operands[2]);
12229 ix86_expand_clear (operands[2]);
12232 (define_insn "*ffssi_1"
12233 [(set (reg:CCZ FLAGS_REG)
12234 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
12236 (set (match_operand:SI 0 "register_operand" "=r")
12237 (ctz:SI (match_dup 1)))]
12239 "bsf{l}\t{%1, %0|%0, %1}"
12240 [(set_attr "type" "alu1")
12241 (set_attr "prefix_0f" "1")
12242 (set_attr "mode" "SI")])
12244 (define_expand "ffsdi2"
12245 [(set (match_dup 2) (const_int -1))
12246 (parallel [(set (reg:CCZ FLAGS_REG)
12247 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
12249 (set (match_operand:DI 0 "register_operand" "")
12250 (ctz:DI (match_dup 1)))])
12251 (set (match_dup 0) (if_then_else:DI
12252 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12255 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
12256 (clobber (reg:CC FLAGS_REG))])]
12258 "operands[2] = gen_reg_rtx (DImode);")
12260 (define_insn "*ffsdi_1"
12261 [(set (reg:CCZ FLAGS_REG)
12262 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
12264 (set (match_operand:DI 0 "register_operand" "=r")
12265 (ctz:DI (match_dup 1)))]
12267 "bsf{q}\t{%1, %0|%0, %1}"
12268 [(set_attr "type" "alu1")
12269 (set_attr "prefix_0f" "1")
12270 (set_attr "mode" "DI")])
12272 (define_insn "ctzsi2"
12273 [(set (match_operand:SI 0 "register_operand" "=r")
12274 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12275 (clobber (reg:CC FLAGS_REG))]
12277 "bsf{l}\t{%1, %0|%0, %1}"
12278 [(set_attr "type" "alu1")
12279 (set_attr "prefix_0f" "1")
12280 (set_attr "mode" "SI")])
12282 (define_insn "ctzdi2"
12283 [(set (match_operand:DI 0 "register_operand" "=r")
12284 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
12285 (clobber (reg:CC FLAGS_REG))]
12287 "bsf{q}\t{%1, %0|%0, %1}"
12288 [(set_attr "type" "alu1")
12289 (set_attr "prefix_0f" "1")
12290 (set_attr "mode" "DI")])
12292 (define_expand "clzsi2"
12294 [(set (match_operand:SI 0 "register_operand" "")
12295 (minus:SI (const_int 31)
12296 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
12297 (clobber (reg:CC FLAGS_REG))])
12299 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
12300 (clobber (reg:CC FLAGS_REG))])]
12305 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
12310 (define_insn "clzsi2_abm"
12311 [(set (match_operand:SI 0 "register_operand" "=r")
12312 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12313 (clobber (reg:CC FLAGS_REG))]
12315 "lzcnt{l}\t{%1, %0|%0, %1}"
12316 [(set_attr "prefix_rep" "1")
12317 (set_attr "type" "bitmanip")
12318 (set_attr "mode" "SI")])
12321 [(set (match_operand:SI 0 "register_operand" "=r")
12322 (minus:SI (const_int 31)
12323 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12324 (clobber (reg:CC FLAGS_REG))]
12326 "bsr{l}\t{%1, %0|%0, %1}"
12327 [(set_attr "type" "alu1")
12328 (set_attr "prefix_0f" "1")
12329 (set_attr "mode" "SI")])
12331 (define_insn "popcount<mode>2"
12332 [(set (match_operand:SWI248 0 "register_operand" "=r")
12334 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12335 (clobber (reg:CC FLAGS_REG))]
12339 return "popcnt\t{%1, %0|%0, %1}";
12341 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12344 [(set_attr "prefix_rep" "1")
12345 (set_attr "type" "bitmanip")
12346 (set_attr "mode" "<MODE>")])
12348 (define_insn "*popcount<mode>2_cmp"
12349 [(set (reg FLAGS_REG)
12352 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12354 (set (match_operand:SWI248 0 "register_operand" "=r")
12355 (popcount:SWI248 (match_dup 1)))]
12356 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12359 return "popcnt\t{%1, %0|%0, %1}";
12361 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12364 [(set_attr "prefix_rep" "1")
12365 (set_attr "type" "bitmanip")
12366 (set_attr "mode" "<MODE>")])
12368 (define_insn "*popcountsi2_cmp_zext"
12369 [(set (reg FLAGS_REG)
12371 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12373 (set (match_operand:DI 0 "register_operand" "=r")
12374 (zero_extend:DI(popcount:SI (match_dup 1))))]
12375 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12378 return "popcnt\t{%1, %0|%0, %1}";
12380 return "popcnt{l}\t{%1, %0|%0, %1}";
12383 [(set_attr "prefix_rep" "1")
12384 (set_attr "type" "bitmanip")
12385 (set_attr "mode" "SI")])
12387 (define_expand "bswapsi2"
12388 [(set (match_operand:SI 0 "register_operand" "")
12389 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
12392 if (!(TARGET_BSWAP || TARGET_MOVBE))
12394 rtx x = operands[0];
12396 emit_move_insn (x, operands[1]);
12397 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12398 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12399 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12404 (define_insn "*bswapsi_movbe"
12405 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
12406 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
12407 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12410 movbe\t{%1, %0|%0, %1}
12411 movbe\t{%1, %0|%0, %1}"
12412 [(set_attr "type" "*,imov,imov")
12413 (set_attr "modrm" "*,1,1")
12414 (set_attr "prefix_0f" "1")
12415 (set_attr "prefix_extra" "*,1,1")
12416 (set_attr "length" "2,*,*")
12417 (set_attr "mode" "SI")])
12419 (define_insn "*bswapsi_1"
12420 [(set (match_operand:SI 0 "register_operand" "=r")
12421 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
12424 [(set_attr "prefix_0f" "1")
12425 (set_attr "length" "2")])
12427 (define_insn "*bswaphi_lowpart_1"
12428 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12429 (bswap:HI (match_dup 0)))
12430 (clobber (reg:CC FLAGS_REG))]
12431 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12433 xchg{b}\t{%h0, %b0|%b0, %h0}
12434 rol{w}\t{$8, %0|%0, 8}"
12435 [(set_attr "length" "2,4")
12436 (set_attr "mode" "QI,HI")])
12438 (define_insn "bswaphi_lowpart"
12439 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12440 (bswap:HI (match_dup 0)))
12441 (clobber (reg:CC FLAGS_REG))]
12443 "rol{w}\t{$8, %0|%0, 8}"
12444 [(set_attr "length" "4")
12445 (set_attr "mode" "HI")])
12447 (define_expand "bswapdi2"
12448 [(set (match_operand:DI 0 "register_operand" "")
12449 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
12453 (define_insn "*bswapdi_movbe"
12454 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12455 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12456 "TARGET_64BIT && TARGET_MOVBE
12457 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12460 movbe\t{%1, %0|%0, %1}
12461 movbe\t{%1, %0|%0, %1}"
12462 [(set_attr "type" "*,imov,imov")
12463 (set_attr "modrm" "*,1,1")
12464 (set_attr "prefix_0f" "1")
12465 (set_attr "prefix_extra" "*,1,1")
12466 (set_attr "length" "3,*,*")
12467 (set_attr "mode" "DI")])
12469 (define_insn "*bswapdi_1"
12470 [(set (match_operand:DI 0 "register_operand" "=r")
12471 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
12474 [(set_attr "prefix_0f" "1")
12475 (set_attr "length" "3")])
12477 (define_expand "clzdi2"
12479 [(set (match_operand:DI 0 "register_operand" "")
12480 (minus:DI (const_int 63)
12481 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
12482 (clobber (reg:CC FLAGS_REG))])
12484 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
12485 (clobber (reg:CC FLAGS_REG))])]
12490 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
12495 (define_insn "clzdi2_abm"
12496 [(set (match_operand:DI 0 "register_operand" "=r")
12497 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
12498 (clobber (reg:CC FLAGS_REG))]
12499 "TARGET_64BIT && TARGET_ABM"
12500 "lzcnt{q}\t{%1, %0|%0, %1}"
12501 [(set_attr "prefix_rep" "1")
12502 (set_attr "type" "bitmanip")
12503 (set_attr "mode" "DI")])
12505 (define_insn "bsr_rex64"
12506 [(set (match_operand:DI 0 "register_operand" "=r")
12507 (minus:DI (const_int 63)
12508 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12509 (clobber (reg:CC FLAGS_REG))]
12511 "bsr{q}\t{%1, %0|%0, %1}"
12512 [(set_attr "type" "alu1")
12513 (set_attr "prefix_0f" "1")
12514 (set_attr "mode" "DI")])
12516 (define_expand "clzhi2"
12518 [(set (match_operand:HI 0 "register_operand" "")
12519 (minus:HI (const_int 15)
12520 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
12521 (clobber (reg:CC FLAGS_REG))])
12523 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
12524 (clobber (reg:CC FLAGS_REG))])]
12529 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
12534 (define_insn "clzhi2_abm"
12535 [(set (match_operand:HI 0 "register_operand" "=r")
12536 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
12537 (clobber (reg:CC FLAGS_REG))]
12539 "lzcnt{w}\t{%1, %0|%0, %1}"
12540 [(set_attr "prefix_rep" "1")
12541 (set_attr "type" "bitmanip")
12542 (set_attr "mode" "HI")])
12544 (define_insn "*bsrhi"
12545 [(set (match_operand:HI 0 "register_operand" "=r")
12546 (minus:HI (const_int 15)
12547 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12548 (clobber (reg:CC FLAGS_REG))]
12550 "bsr{w}\t{%1, %0|%0, %1}"
12551 [(set_attr "type" "alu1")
12552 (set_attr "prefix_0f" "1")
12553 (set_attr "mode" "HI")])
12555 (define_expand "paritydi2"
12556 [(set (match_operand:DI 0 "register_operand" "")
12557 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12560 rtx scratch = gen_reg_rtx (QImode);
12563 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12564 NULL_RTX, operands[1]));
12566 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12567 gen_rtx_REG (CCmode, FLAGS_REG),
12569 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12572 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12575 rtx tmp = gen_reg_rtx (SImode);
12577 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12578 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12583 (define_insn_and_split "paritydi2_cmp"
12584 [(set (reg:CC FLAGS_REG)
12585 (parity:CC (match_operand:DI 3 "register_operand" "0")))
12586 (clobber (match_scratch:DI 0 "=r"))
12587 (clobber (match_scratch:SI 1 "=&r"))
12588 (clobber (match_scratch:HI 2 "=Q"))]
12591 "&& reload_completed"
12593 [(set (match_dup 1)
12594 (xor:SI (match_dup 1) (match_dup 4)))
12595 (clobber (reg:CC FLAGS_REG))])
12597 [(set (reg:CC FLAGS_REG)
12598 (parity:CC (match_dup 1)))
12599 (clobber (match_dup 1))
12600 (clobber (match_dup 2))])]
12602 operands[4] = gen_lowpart (SImode, operands[3]);
12606 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12607 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12610 operands[1] = gen_highpart (SImode, operands[3]);
12613 (define_expand "paritysi2"
12614 [(set (match_operand:SI 0 "register_operand" "")
12615 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12618 rtx scratch = gen_reg_rtx (QImode);
12621 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12623 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12624 gen_rtx_REG (CCmode, FLAGS_REG),
12626 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12628 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12632 (define_insn_and_split "paritysi2_cmp"
12633 [(set (reg:CC FLAGS_REG)
12634 (parity:CC (match_operand:SI 2 "register_operand" "0")))
12635 (clobber (match_scratch:SI 0 "=r"))
12636 (clobber (match_scratch:HI 1 "=&Q"))]
12639 "&& reload_completed"
12641 [(set (match_dup 1)
12642 (xor:HI (match_dup 1) (match_dup 3)))
12643 (clobber (reg:CC FLAGS_REG))])
12645 [(set (reg:CC FLAGS_REG)
12646 (parity:CC (match_dup 1)))
12647 (clobber (match_dup 1))])]
12649 operands[3] = gen_lowpart (HImode, operands[2]);
12651 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12652 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12655 (define_insn "*parityhi2_cmp"
12656 [(set (reg:CC FLAGS_REG)
12657 (parity:CC (match_operand:HI 1 "register_operand" "0")))
12658 (clobber (match_scratch:HI 0 "=Q"))]
12660 "xor{b}\t{%h0, %b0|%b0, %h0}"
12661 [(set_attr "length" "2")
12662 (set_attr "mode" "HI")])
12664 (define_insn "*parityqi2_cmp"
12665 [(set (reg:CC FLAGS_REG)
12666 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
12669 [(set_attr "length" "2")
12670 (set_attr "mode" "QI")])
12672 ;; Thread-local storage patterns for ELF.
12674 ;; Note that these code sequences must appear exactly as shown
12675 ;; in order to allow linker relaxation.
12677 (define_insn "*tls_global_dynamic_32_gnu"
12678 [(set (match_operand:SI 0 "register_operand" "=a")
12679 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12680 (match_operand:SI 2 "tls_symbolic_operand" "")
12681 (match_operand:SI 3 "call_insn_operand" "")]
12683 (clobber (match_scratch:SI 4 "=d"))
12684 (clobber (match_scratch:SI 5 "=c"))
12685 (clobber (reg:CC FLAGS_REG))]
12686 "!TARGET_64BIT && TARGET_GNU_TLS"
12687 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12688 [(set_attr "type" "multi")
12689 (set_attr "length" "12")])
12691 (define_expand "tls_global_dynamic_32"
12692 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12695 (match_operand:SI 1 "tls_symbolic_operand" "")
12698 (clobber (match_scratch:SI 4 ""))
12699 (clobber (match_scratch:SI 5 ""))
12700 (clobber (reg:CC FLAGS_REG))])]
12704 operands[2] = pic_offset_table_rtx;
12707 operands[2] = gen_reg_rtx (Pmode);
12708 emit_insn (gen_set_got (operands[2]));
12710 if (TARGET_GNU2_TLS)
12712 emit_insn (gen_tls_dynamic_gnu2_32
12713 (operands[0], operands[1], operands[2]));
12716 operands[3] = ix86_tls_get_addr ();
12719 (define_insn "*tls_global_dynamic_64"
12720 [(set (match_operand:DI 0 "register_operand" "=a")
12721 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12722 (match_operand:DI 3 "" "")))
12723 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12726 { 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"; }
12727 [(set_attr "type" "multi")
12728 (set_attr "length" "16")])
12730 (define_expand "tls_global_dynamic_64"
12731 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12732 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12733 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12737 if (TARGET_GNU2_TLS)
12739 emit_insn (gen_tls_dynamic_gnu2_64
12740 (operands[0], operands[1]));
12743 operands[2] = ix86_tls_get_addr ();
12746 (define_insn "*tls_local_dynamic_base_32_gnu"
12747 [(set (match_operand:SI 0 "register_operand" "=a")
12748 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12749 (match_operand:SI 2 "call_insn_operand" "")]
12750 UNSPEC_TLS_LD_BASE))
12751 (clobber (match_scratch:SI 3 "=d"))
12752 (clobber (match_scratch:SI 4 "=c"))
12753 (clobber (reg:CC FLAGS_REG))]
12754 "!TARGET_64BIT && TARGET_GNU_TLS"
12755 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12756 [(set_attr "type" "multi")
12757 (set_attr "length" "11")])
12759 (define_expand "tls_local_dynamic_base_32"
12760 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12761 (unspec:SI [(match_dup 1) (match_dup 2)]
12762 UNSPEC_TLS_LD_BASE))
12763 (clobber (match_scratch:SI 3 ""))
12764 (clobber (match_scratch:SI 4 ""))
12765 (clobber (reg:CC FLAGS_REG))])]
12769 operands[1] = pic_offset_table_rtx;
12772 operands[1] = gen_reg_rtx (Pmode);
12773 emit_insn (gen_set_got (operands[1]));
12775 if (TARGET_GNU2_TLS)
12777 emit_insn (gen_tls_dynamic_gnu2_32
12778 (operands[0], ix86_tls_module_base (), operands[1]));
12781 operands[2] = ix86_tls_get_addr ();
12784 (define_insn "*tls_local_dynamic_base_64"
12785 [(set (match_operand:DI 0 "register_operand" "=a")
12786 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12787 (match_operand:DI 2 "" "")))
12788 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12790 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12791 [(set_attr "type" "multi")
12792 (set_attr "length" "12")])
12794 (define_expand "tls_local_dynamic_base_64"
12795 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12796 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12797 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12800 if (TARGET_GNU2_TLS)
12802 emit_insn (gen_tls_dynamic_gnu2_64
12803 (operands[0], ix86_tls_module_base ()));
12806 operands[1] = ix86_tls_get_addr ();
12809 ;; Local dynamic of a single variable is a lose. Show combine how
12810 ;; to convert that back to global dynamic.
12812 (define_insn_and_split "*tls_local_dynamic_32_once"
12813 [(set (match_operand:SI 0 "register_operand" "=a")
12814 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12815 (match_operand:SI 2 "call_insn_operand" "")]
12816 UNSPEC_TLS_LD_BASE)
12817 (const:SI (unspec:SI
12818 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12820 (clobber (match_scratch:SI 4 "=d"))
12821 (clobber (match_scratch:SI 5 "=c"))
12822 (clobber (reg:CC FLAGS_REG))]
12826 [(parallel [(set (match_dup 0)
12827 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12829 (clobber (match_dup 4))
12830 (clobber (match_dup 5))
12831 (clobber (reg:CC FLAGS_REG))])]
12834 ;; Load and add the thread base pointer from %gs:0.
12836 (define_insn "*load_tp_si"
12837 [(set (match_operand:SI 0 "register_operand" "=r")
12838 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12840 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12841 [(set_attr "type" "imov")
12842 (set_attr "modrm" "0")
12843 (set_attr "length" "7")
12844 (set_attr "memory" "load")
12845 (set_attr "imm_disp" "false")])
12847 (define_insn "*add_tp_si"
12848 [(set (match_operand:SI 0 "register_operand" "=r")
12849 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12850 (match_operand:SI 1 "register_operand" "0")))
12851 (clobber (reg:CC FLAGS_REG))]
12853 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12854 [(set_attr "type" "alu")
12855 (set_attr "modrm" "0")
12856 (set_attr "length" "7")
12857 (set_attr "memory" "load")
12858 (set_attr "imm_disp" "false")])
12860 (define_insn "*load_tp_di"
12861 [(set (match_operand:DI 0 "register_operand" "=r")
12862 (unspec:DI [(const_int 0)] UNSPEC_TP))]
12864 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12865 [(set_attr "type" "imov")
12866 (set_attr "modrm" "0")
12867 (set_attr "length" "7")
12868 (set_attr "memory" "load")
12869 (set_attr "imm_disp" "false")])
12871 (define_insn "*add_tp_di"
12872 [(set (match_operand:DI 0 "register_operand" "=r")
12873 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12874 (match_operand:DI 1 "register_operand" "0")))
12875 (clobber (reg:CC FLAGS_REG))]
12877 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12878 [(set_attr "type" "alu")
12879 (set_attr "modrm" "0")
12880 (set_attr "length" "7")
12881 (set_attr "memory" "load")
12882 (set_attr "imm_disp" "false")])
12884 ;; GNU2 TLS patterns can be split.
12886 (define_expand "tls_dynamic_gnu2_32"
12887 [(set (match_dup 3)
12888 (plus:SI (match_operand:SI 2 "register_operand" "")
12890 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12893 [(set (match_operand:SI 0 "register_operand" "")
12894 (unspec:SI [(match_dup 1) (match_dup 3)
12895 (match_dup 2) (reg:SI SP_REG)]
12897 (clobber (reg:CC FLAGS_REG))])]
12898 "!TARGET_64BIT && TARGET_GNU2_TLS"
12900 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12901 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12904 (define_insn "*tls_dynamic_lea_32"
12905 [(set (match_operand:SI 0 "register_operand" "=r")
12906 (plus:SI (match_operand:SI 1 "register_operand" "b")
12908 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12909 UNSPEC_TLSDESC))))]
12910 "!TARGET_64BIT && TARGET_GNU2_TLS"
12911 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12912 [(set_attr "type" "lea")
12913 (set_attr "mode" "SI")
12914 (set_attr "length" "6")
12915 (set_attr "length_address" "4")])
12917 (define_insn "*tls_dynamic_call_32"
12918 [(set (match_operand:SI 0 "register_operand" "=a")
12919 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12920 (match_operand:SI 2 "register_operand" "0")
12921 ;; we have to make sure %ebx still points to the GOT
12922 (match_operand:SI 3 "register_operand" "b")
12925 (clobber (reg:CC FLAGS_REG))]
12926 "!TARGET_64BIT && TARGET_GNU2_TLS"
12927 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12928 [(set_attr "type" "call")
12929 (set_attr "length" "2")
12930 (set_attr "length_address" "0")])
12932 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12933 [(set (match_operand:SI 0 "register_operand" "=&a")
12935 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12936 (match_operand:SI 4 "" "")
12937 (match_operand:SI 2 "register_operand" "b")
12940 (const:SI (unspec:SI
12941 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12943 (clobber (reg:CC FLAGS_REG))]
12944 "!TARGET_64BIT && TARGET_GNU2_TLS"
12947 [(set (match_dup 0) (match_dup 5))]
12949 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12950 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12953 (define_expand "tls_dynamic_gnu2_64"
12954 [(set (match_dup 2)
12955 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12958 [(set (match_operand:DI 0 "register_operand" "")
12959 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12961 (clobber (reg:CC FLAGS_REG))])]
12962 "TARGET_64BIT && TARGET_GNU2_TLS"
12964 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12965 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12968 (define_insn "*tls_dynamic_lea_64"
12969 [(set (match_operand:DI 0 "register_operand" "=r")
12970 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12972 "TARGET_64BIT && TARGET_GNU2_TLS"
12973 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12974 [(set_attr "type" "lea")
12975 (set_attr "mode" "DI")
12976 (set_attr "length" "7")
12977 (set_attr "length_address" "4")])
12979 (define_insn "*tls_dynamic_call_64"
12980 [(set (match_operand:DI 0 "register_operand" "=a")
12981 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12982 (match_operand:DI 2 "register_operand" "0")
12985 (clobber (reg:CC FLAGS_REG))]
12986 "TARGET_64BIT && TARGET_GNU2_TLS"
12987 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12988 [(set_attr "type" "call")
12989 (set_attr "length" "2")
12990 (set_attr "length_address" "0")])
12992 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12993 [(set (match_operand:DI 0 "register_operand" "=&a")
12995 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12996 (match_operand:DI 3 "" "")
12999 (const:DI (unspec:DI
13000 [(match_operand:DI 1 "tls_symbolic_operand" "")]
13002 (clobber (reg:CC FLAGS_REG))]
13003 "TARGET_64BIT && TARGET_GNU2_TLS"
13006 [(set (match_dup 0) (match_dup 4))]
13008 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13009 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13014 ;; These patterns match the binary 387 instructions for addM3, subM3,
13015 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13016 ;; SFmode. The first is the normal insn, the second the same insn but
13017 ;; with one operand a conversion, and the third the same insn but with
13018 ;; the other operand a conversion. The conversion may be SFmode or
13019 ;; SImode if the target mode DFmode, but only SImode if the target mode
13022 ;; Gcc is slightly more smart about handling normal two address instructions
13023 ;; so use special patterns for add and mull.
13025 (define_insn "*fop_<mode>_comm_mixed_avx"
13026 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
13027 (match_operator:MODEF 3 "binary_fp_operator"
13028 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13029 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
13030 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13031 && COMMUTATIVE_ARITH_P (operands[3])
13032 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13033 "* return output_387_binary_op (insn, operands);"
13034 [(set (attr "type")
13035 (if_then_else (eq_attr "alternative" "1")
13036 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13037 (const_string "ssemul")
13038 (const_string "sseadd"))
13039 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13040 (const_string "fmul")
13041 (const_string "fop"))))
13042 (set_attr "prefix" "orig,maybe_vex")
13043 (set_attr "mode" "<MODE>")])
13045 (define_insn "*fop_<mode>_comm_mixed"
13046 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
13047 (match_operator:MODEF 3 "binary_fp_operator"
13048 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
13049 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
13050 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13051 && COMMUTATIVE_ARITH_P (operands[3])
13052 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13053 "* return output_387_binary_op (insn, operands);"
13054 [(set (attr "type")
13055 (if_then_else (eq_attr "alternative" "1")
13056 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13057 (const_string "ssemul")
13058 (const_string "sseadd"))
13059 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13060 (const_string "fmul")
13061 (const_string "fop"))))
13062 (set_attr "mode" "<MODE>")])
13064 (define_insn "*fop_<mode>_comm_avx"
13065 [(set (match_operand:MODEF 0 "register_operand" "=x")
13066 (match_operator:MODEF 3 "binary_fp_operator"
13067 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
13068 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13069 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13070 && COMMUTATIVE_ARITH_P (operands[3])
13071 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13072 "* return output_387_binary_op (insn, operands);"
13073 [(set (attr "type")
13074 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13075 (const_string "ssemul")
13076 (const_string "sseadd")))
13077 (set_attr "prefix" "vex")
13078 (set_attr "mode" "<MODE>")])
13080 (define_insn "*fop_<mode>_comm_sse"
13081 [(set (match_operand:MODEF 0 "register_operand" "=x")
13082 (match_operator:MODEF 3 "binary_fp_operator"
13083 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13084 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13085 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13086 && COMMUTATIVE_ARITH_P (operands[3])
13087 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13088 "* return output_387_binary_op (insn, operands);"
13089 [(set (attr "type")
13090 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13091 (const_string "ssemul")
13092 (const_string "sseadd")))
13093 (set_attr "mode" "<MODE>")])
13095 (define_insn "*fop_<mode>_comm_i387"
13096 [(set (match_operand:MODEF 0 "register_operand" "=f")
13097 (match_operator:MODEF 3 "binary_fp_operator"
13098 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13099 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13100 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13101 && COMMUTATIVE_ARITH_P (operands[3])
13102 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13103 "* return output_387_binary_op (insn, operands);"
13104 [(set (attr "type")
13105 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13106 (const_string "fmul")
13107 (const_string "fop")))
13108 (set_attr "mode" "<MODE>")])
13110 (define_insn "*fop_<mode>_1_mixed_avx"
13111 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13112 (match_operator:MODEF 3 "binary_fp_operator"
13113 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
13114 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13115 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13116 && !COMMUTATIVE_ARITH_P (operands[3])
13117 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13118 "* return output_387_binary_op (insn, operands);"
13119 [(set (attr "type")
13120 (cond [(and (eq_attr "alternative" "2")
13121 (match_operand:MODEF 3 "mult_operator" ""))
13122 (const_string "ssemul")
13123 (and (eq_attr "alternative" "2")
13124 (match_operand:MODEF 3 "div_operator" ""))
13125 (const_string "ssediv")
13126 (eq_attr "alternative" "2")
13127 (const_string "sseadd")
13128 (match_operand:MODEF 3 "mult_operator" "")
13129 (const_string "fmul")
13130 (match_operand:MODEF 3 "div_operator" "")
13131 (const_string "fdiv")
13133 (const_string "fop")))
13134 (set_attr "prefix" "orig,orig,maybe_vex")
13135 (set_attr "mode" "<MODE>")])
13137 (define_insn "*fop_<mode>_1_mixed"
13138 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13139 (match_operator:MODEF 3 "binary_fp_operator"
13140 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
13141 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13142 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13143 && !COMMUTATIVE_ARITH_P (operands[3])
13144 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13145 "* return output_387_binary_op (insn, operands);"
13146 [(set (attr "type")
13147 (cond [(and (eq_attr "alternative" "2")
13148 (match_operand:MODEF 3 "mult_operator" ""))
13149 (const_string "ssemul")
13150 (and (eq_attr "alternative" "2")
13151 (match_operand:MODEF 3 "div_operator" ""))
13152 (const_string "ssediv")
13153 (eq_attr "alternative" "2")
13154 (const_string "sseadd")
13155 (match_operand:MODEF 3 "mult_operator" "")
13156 (const_string "fmul")
13157 (match_operand:MODEF 3 "div_operator" "")
13158 (const_string "fdiv")
13160 (const_string "fop")))
13161 (set_attr "mode" "<MODE>")])
13163 (define_insn "*rcpsf2_sse"
13164 [(set (match_operand:SF 0 "register_operand" "=x")
13165 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13168 "%vrcpss\t{%1, %d0|%d0, %1}"
13169 [(set_attr "type" "sse")
13170 (set_attr "atom_sse_attr" "rcp")
13171 (set_attr "prefix" "maybe_vex")
13172 (set_attr "mode" "SF")])
13174 (define_insn "*fop_<mode>_1_avx"
13175 [(set (match_operand:MODEF 0 "register_operand" "=x")
13176 (match_operator:MODEF 3 "binary_fp_operator"
13177 [(match_operand:MODEF 1 "register_operand" "x")
13178 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13179 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13180 && !COMMUTATIVE_ARITH_P (operands[3])"
13181 "* return output_387_binary_op (insn, operands);"
13182 [(set (attr "type")
13183 (cond [(match_operand:MODEF 3 "mult_operator" "")
13184 (const_string "ssemul")
13185 (match_operand:MODEF 3 "div_operator" "")
13186 (const_string "ssediv")
13188 (const_string "sseadd")))
13189 (set_attr "prefix" "vex")
13190 (set_attr "mode" "<MODE>")])
13192 (define_insn "*fop_<mode>_1_sse"
13193 [(set (match_operand:MODEF 0 "register_operand" "=x")
13194 (match_operator:MODEF 3 "binary_fp_operator"
13195 [(match_operand:MODEF 1 "register_operand" "0")
13196 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13197 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13198 && !COMMUTATIVE_ARITH_P (operands[3])"
13199 "* return output_387_binary_op (insn, operands);"
13200 [(set (attr "type")
13201 (cond [(match_operand:MODEF 3 "mult_operator" "")
13202 (const_string "ssemul")
13203 (match_operand:MODEF 3 "div_operator" "")
13204 (const_string "ssediv")
13206 (const_string "sseadd")))
13207 (set_attr "mode" "<MODE>")])
13209 ;; This pattern is not fully shadowed by the pattern above.
13210 (define_insn "*fop_<mode>_1_i387"
13211 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13212 (match_operator:MODEF 3 "binary_fp_operator"
13213 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13214 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13215 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13216 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
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 [(match_operand:MODEF 3 "mult_operator" "")
13222 (const_string "fmul")
13223 (match_operand:MODEF 3 "div_operator" "")
13224 (const_string "fdiv")
13226 (const_string "fop")))
13227 (set_attr "mode" "<MODE>")])
13229 ;; ??? Add SSE splitters for these!
13230 (define_insn "*fop_<MODEF:mode>_2_i387"
13231 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13232 (match_operator:MODEF 3 "binary_fp_operator"
13234 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13235 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13236 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13237 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13238 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13239 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13240 [(set (attr "type")
13241 (cond [(match_operand:MODEF 3 "mult_operator" "")
13242 (const_string "fmul")
13243 (match_operand:MODEF 3 "div_operator" "")
13244 (const_string "fdiv")
13246 (const_string "fop")))
13247 (set_attr "fp_int_src" "true")
13248 (set_attr "mode" "<X87MODEI12:MODE>")])
13250 (define_insn "*fop_<MODEF:mode>_3_i387"
13251 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13252 (match_operator:MODEF 3 "binary_fp_operator"
13253 [(match_operand:MODEF 1 "register_operand" "0,0")
13255 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13256 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13257 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13258 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13259 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13260 [(set (attr "type")
13261 (cond [(match_operand:MODEF 3 "mult_operator" "")
13262 (const_string "fmul")
13263 (match_operand:MODEF 3 "div_operator" "")
13264 (const_string "fdiv")
13266 (const_string "fop")))
13267 (set_attr "fp_int_src" "true")
13268 (set_attr "mode" "<MODE>")])
13270 (define_insn "*fop_df_4_i387"
13271 [(set (match_operand:DF 0 "register_operand" "=f,f")
13272 (match_operator:DF 3 "binary_fp_operator"
13274 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13275 (match_operand:DF 2 "register_operand" "0,f")]))]
13276 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13277 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13278 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13279 "* return output_387_binary_op (insn, operands);"
13280 [(set (attr "type")
13281 (cond [(match_operand:DF 3 "mult_operator" "")
13282 (const_string "fmul")
13283 (match_operand:DF 3 "div_operator" "")
13284 (const_string "fdiv")
13286 (const_string "fop")))
13287 (set_attr "mode" "SF")])
13289 (define_insn "*fop_df_5_i387"
13290 [(set (match_operand:DF 0 "register_operand" "=f,f")
13291 (match_operator:DF 3 "binary_fp_operator"
13292 [(match_operand:DF 1 "register_operand" "0,f")
13294 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13295 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13296 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13297 "* return output_387_binary_op (insn, operands);"
13298 [(set (attr "type")
13299 (cond [(match_operand:DF 3 "mult_operator" "")
13300 (const_string "fmul")
13301 (match_operand:DF 3 "div_operator" "")
13302 (const_string "fdiv")
13304 (const_string "fop")))
13305 (set_attr "mode" "SF")])
13307 (define_insn "*fop_df_6_i387"
13308 [(set (match_operand:DF 0 "register_operand" "=f,f")
13309 (match_operator:DF 3 "binary_fp_operator"
13311 (match_operand:SF 1 "register_operand" "0,f"))
13313 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13314 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13315 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13316 "* return output_387_binary_op (insn, operands);"
13317 [(set (attr "type")
13318 (cond [(match_operand:DF 3 "mult_operator" "")
13319 (const_string "fmul")
13320 (match_operand:DF 3 "div_operator" "")
13321 (const_string "fdiv")
13323 (const_string "fop")))
13324 (set_attr "mode" "SF")])
13326 (define_insn "*fop_xf_comm_i387"
13327 [(set (match_operand:XF 0 "register_operand" "=f")
13328 (match_operator:XF 3 "binary_fp_operator"
13329 [(match_operand:XF 1 "register_operand" "%0")
13330 (match_operand:XF 2 "register_operand" "f")]))]
13332 && COMMUTATIVE_ARITH_P (operands[3])"
13333 "* return output_387_binary_op (insn, operands);"
13334 [(set (attr "type")
13335 (if_then_else (match_operand:XF 3 "mult_operator" "")
13336 (const_string "fmul")
13337 (const_string "fop")))
13338 (set_attr "mode" "XF")])
13340 (define_insn "*fop_xf_1_i387"
13341 [(set (match_operand:XF 0 "register_operand" "=f,f")
13342 (match_operator:XF 3 "binary_fp_operator"
13343 [(match_operand:XF 1 "register_operand" "0,f")
13344 (match_operand:XF 2 "register_operand" "f,0")]))]
13346 && !COMMUTATIVE_ARITH_P (operands[3])"
13347 "* return output_387_binary_op (insn, operands);"
13348 [(set (attr "type")
13349 (cond [(match_operand:XF 3 "mult_operator" "")
13350 (const_string "fmul")
13351 (match_operand:XF 3 "div_operator" "")
13352 (const_string "fdiv")
13354 (const_string "fop")))
13355 (set_attr "mode" "XF")])
13357 (define_insn "*fop_xf_2_i387"
13358 [(set (match_operand:XF 0 "register_operand" "=f,f")
13359 (match_operator:XF 3 "binary_fp_operator"
13361 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13362 (match_operand:XF 2 "register_operand" "0,0")]))]
13363 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13364 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13365 [(set (attr "type")
13366 (cond [(match_operand:XF 3 "mult_operator" "")
13367 (const_string "fmul")
13368 (match_operand:XF 3 "div_operator" "")
13369 (const_string "fdiv")
13371 (const_string "fop")))
13372 (set_attr "fp_int_src" "true")
13373 (set_attr "mode" "<MODE>")])
13375 (define_insn "*fop_xf_3_i387"
13376 [(set (match_operand:XF 0 "register_operand" "=f,f")
13377 (match_operator:XF 3 "binary_fp_operator"
13378 [(match_operand:XF 1 "register_operand" "0,0")
13380 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13381 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13382 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13383 [(set (attr "type")
13384 (cond [(match_operand:XF 3 "mult_operator" "")
13385 (const_string "fmul")
13386 (match_operand:XF 3 "div_operator" "")
13387 (const_string "fdiv")
13389 (const_string "fop")))
13390 (set_attr "fp_int_src" "true")
13391 (set_attr "mode" "<MODE>")])
13393 (define_insn "*fop_xf_4_i387"
13394 [(set (match_operand:XF 0 "register_operand" "=f,f")
13395 (match_operator:XF 3 "binary_fp_operator"
13397 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13398 (match_operand:XF 2 "register_operand" "0,f")]))]
13400 "* return output_387_binary_op (insn, operands);"
13401 [(set (attr "type")
13402 (cond [(match_operand:XF 3 "mult_operator" "")
13403 (const_string "fmul")
13404 (match_operand:XF 3 "div_operator" "")
13405 (const_string "fdiv")
13407 (const_string "fop")))
13408 (set_attr "mode" "<MODE>")])
13410 (define_insn "*fop_xf_5_i387"
13411 [(set (match_operand:XF 0 "register_operand" "=f,f")
13412 (match_operator:XF 3 "binary_fp_operator"
13413 [(match_operand:XF 1 "register_operand" "0,f")
13415 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13417 "* return output_387_binary_op (insn, operands);"
13418 [(set (attr "type")
13419 (cond [(match_operand:XF 3 "mult_operator" "")
13420 (const_string "fmul")
13421 (match_operand:XF 3 "div_operator" "")
13422 (const_string "fdiv")
13424 (const_string "fop")))
13425 (set_attr "mode" "<MODE>")])
13427 (define_insn "*fop_xf_6_i387"
13428 [(set (match_operand:XF 0 "register_operand" "=f,f")
13429 (match_operator:XF 3 "binary_fp_operator"
13431 (match_operand:MODEF 1 "register_operand" "0,f"))
13433 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13435 "* return output_387_binary_op (insn, operands);"
13436 [(set (attr "type")
13437 (cond [(match_operand:XF 3 "mult_operator" "")
13438 (const_string "fmul")
13439 (match_operand:XF 3 "div_operator" "")
13440 (const_string "fdiv")
13442 (const_string "fop")))
13443 (set_attr "mode" "<MODE>")])
13446 [(set (match_operand 0 "register_operand" "")
13447 (match_operator 3 "binary_fp_operator"
13448 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13449 (match_operand 2 "register_operand" "")]))]
13451 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13452 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13455 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13456 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13457 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13458 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13459 GET_MODE (operands[3]),
13462 ix86_free_from_memory (GET_MODE (operands[1]));
13467 [(set (match_operand 0 "register_operand" "")
13468 (match_operator 3 "binary_fp_operator"
13469 [(match_operand 1 "register_operand" "")
13470 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13472 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13473 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13476 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13477 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13478 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13479 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13480 GET_MODE (operands[3]),
13483 ix86_free_from_memory (GET_MODE (operands[2]));
13487 ;; FPU special functions.
13489 ;; This pattern implements a no-op XFmode truncation for
13490 ;; all fancy i386 XFmode math functions.
13492 (define_insn "truncxf<mode>2_i387_noop_unspec"
13493 [(set (match_operand:MODEF 0 "register_operand" "=f")
13494 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13495 UNSPEC_TRUNC_NOOP))]
13496 "TARGET_USE_FANCY_MATH_387"
13497 "* return output_387_reg_move (insn, operands);"
13498 [(set_attr "type" "fmov")
13499 (set_attr "mode" "<MODE>")])
13501 (define_insn "sqrtxf2"
13502 [(set (match_operand:XF 0 "register_operand" "=f")
13503 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13504 "TARGET_USE_FANCY_MATH_387"
13506 [(set_attr "type" "fpspc")
13507 (set_attr "mode" "XF")
13508 (set_attr "athlon_decode" "direct")
13509 (set_attr "amdfam10_decode" "direct")])
13511 (define_insn "sqrt_extend<mode>xf2_i387"
13512 [(set (match_operand:XF 0 "register_operand" "=f")
13515 (match_operand:MODEF 1 "register_operand" "0"))))]
13516 "TARGET_USE_FANCY_MATH_387"
13518 [(set_attr "type" "fpspc")
13519 (set_attr "mode" "XF")
13520 (set_attr "athlon_decode" "direct")
13521 (set_attr "amdfam10_decode" "direct")])
13523 (define_insn "*rsqrtsf2_sse"
13524 [(set (match_operand:SF 0 "register_operand" "=x")
13525 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13528 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13529 [(set_attr "type" "sse")
13530 (set_attr "atom_sse_attr" "rcp")
13531 (set_attr "prefix" "maybe_vex")
13532 (set_attr "mode" "SF")])
13534 (define_expand "rsqrtsf2"
13535 [(set (match_operand:SF 0 "register_operand" "")
13536 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13540 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13544 (define_insn "*sqrt<mode>2_sse"
13545 [(set (match_operand:MODEF 0 "register_operand" "=x")
13547 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13548 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13549 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13550 [(set_attr "type" "sse")
13551 (set_attr "atom_sse_attr" "sqrt")
13552 (set_attr "prefix" "maybe_vex")
13553 (set_attr "mode" "<MODE>")
13554 (set_attr "athlon_decode" "*")
13555 (set_attr "amdfam10_decode" "*")])
13557 (define_expand "sqrt<mode>2"
13558 [(set (match_operand:MODEF 0 "register_operand" "")
13560 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13561 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13562 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13564 if (<MODE>mode == SFmode
13565 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13566 && flag_finite_math_only && !flag_trapping_math
13567 && flag_unsafe_math_optimizations)
13569 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13573 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13575 rtx op0 = gen_reg_rtx (XFmode);
13576 rtx op1 = force_reg (<MODE>mode, operands[1]);
13578 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13579 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13584 (define_insn "fpremxf4_i387"
13585 [(set (match_operand:XF 0 "register_operand" "=f")
13586 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13587 (match_operand:XF 3 "register_operand" "1")]
13589 (set (match_operand:XF 1 "register_operand" "=u")
13590 (unspec:XF [(match_dup 2) (match_dup 3)]
13592 (set (reg:CCFP FPSR_REG)
13593 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13595 "TARGET_USE_FANCY_MATH_387"
13597 [(set_attr "type" "fpspc")
13598 (set_attr "mode" "XF")])
13600 (define_expand "fmodxf3"
13601 [(use (match_operand:XF 0 "register_operand" ""))
13602 (use (match_operand:XF 1 "general_operand" ""))
13603 (use (match_operand:XF 2 "general_operand" ""))]
13604 "TARGET_USE_FANCY_MATH_387"
13606 rtx label = gen_label_rtx ();
13608 rtx op1 = gen_reg_rtx (XFmode);
13609 rtx op2 = gen_reg_rtx (XFmode);
13611 emit_move_insn (op2, operands[2]);
13612 emit_move_insn (op1, operands[1]);
13614 emit_label (label);
13615 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13616 ix86_emit_fp_unordered_jump (label);
13617 LABEL_NUSES (label) = 1;
13619 emit_move_insn (operands[0], op1);
13623 (define_expand "fmod<mode>3"
13624 [(use (match_operand:MODEF 0 "register_operand" ""))
13625 (use (match_operand:MODEF 1 "general_operand" ""))
13626 (use (match_operand:MODEF 2 "general_operand" ""))]
13627 "TARGET_USE_FANCY_MATH_387"
13629 rtx label = gen_label_rtx ();
13631 rtx op1 = gen_reg_rtx (XFmode);
13632 rtx op2 = gen_reg_rtx (XFmode);
13634 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13635 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13637 emit_label (label);
13638 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13639 ix86_emit_fp_unordered_jump (label);
13640 LABEL_NUSES (label) = 1;
13642 /* Truncate the result properly for strict SSE math. */
13643 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13644 && !TARGET_MIX_SSE_I387)
13645 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13647 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13652 (define_insn "fprem1xf4_i387"
13653 [(set (match_operand:XF 0 "register_operand" "=f")
13654 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13655 (match_operand:XF 3 "register_operand" "1")]
13657 (set (match_operand:XF 1 "register_operand" "=u")
13658 (unspec:XF [(match_dup 2) (match_dup 3)]
13660 (set (reg:CCFP FPSR_REG)
13661 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13663 "TARGET_USE_FANCY_MATH_387"
13665 [(set_attr "type" "fpspc")
13666 (set_attr "mode" "XF")])
13668 (define_expand "remainderxf3"
13669 [(use (match_operand:XF 0 "register_operand" ""))
13670 (use (match_operand:XF 1 "general_operand" ""))
13671 (use (match_operand:XF 2 "general_operand" ""))]
13672 "TARGET_USE_FANCY_MATH_387"
13674 rtx label = gen_label_rtx ();
13676 rtx op1 = gen_reg_rtx (XFmode);
13677 rtx op2 = gen_reg_rtx (XFmode);
13679 emit_move_insn (op2, operands[2]);
13680 emit_move_insn (op1, operands[1]);
13682 emit_label (label);
13683 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13684 ix86_emit_fp_unordered_jump (label);
13685 LABEL_NUSES (label) = 1;
13687 emit_move_insn (operands[0], op1);
13691 (define_expand "remainder<mode>3"
13692 [(use (match_operand:MODEF 0 "register_operand" ""))
13693 (use (match_operand:MODEF 1 "general_operand" ""))
13694 (use (match_operand:MODEF 2 "general_operand" ""))]
13695 "TARGET_USE_FANCY_MATH_387"
13697 rtx label = gen_label_rtx ();
13699 rtx op1 = gen_reg_rtx (XFmode);
13700 rtx op2 = gen_reg_rtx (XFmode);
13702 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13703 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13705 emit_label (label);
13707 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13708 ix86_emit_fp_unordered_jump (label);
13709 LABEL_NUSES (label) = 1;
13711 /* Truncate the result properly for strict SSE math. */
13712 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13713 && !TARGET_MIX_SSE_I387)
13714 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13716 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13721 (define_insn "*sinxf2_i387"
13722 [(set (match_operand:XF 0 "register_operand" "=f")
13723 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13724 "TARGET_USE_FANCY_MATH_387
13725 && flag_unsafe_math_optimizations"
13727 [(set_attr "type" "fpspc")
13728 (set_attr "mode" "XF")])
13730 (define_insn "*sin_extend<mode>xf2_i387"
13731 [(set (match_operand:XF 0 "register_operand" "=f")
13732 (unspec:XF [(float_extend:XF
13733 (match_operand:MODEF 1 "register_operand" "0"))]
13735 "TARGET_USE_FANCY_MATH_387
13736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13737 || TARGET_MIX_SSE_I387)
13738 && flag_unsafe_math_optimizations"
13740 [(set_attr "type" "fpspc")
13741 (set_attr "mode" "XF")])
13743 (define_insn "*cosxf2_i387"
13744 [(set (match_operand:XF 0 "register_operand" "=f")
13745 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13746 "TARGET_USE_FANCY_MATH_387
13747 && flag_unsafe_math_optimizations"
13749 [(set_attr "type" "fpspc")
13750 (set_attr "mode" "XF")])
13752 (define_insn "*cos_extend<mode>xf2_i387"
13753 [(set (match_operand:XF 0 "register_operand" "=f")
13754 (unspec:XF [(float_extend:XF
13755 (match_operand:MODEF 1 "register_operand" "0"))]
13757 "TARGET_USE_FANCY_MATH_387
13758 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13759 || TARGET_MIX_SSE_I387)
13760 && flag_unsafe_math_optimizations"
13762 [(set_attr "type" "fpspc")
13763 (set_attr "mode" "XF")])
13765 ;; When sincos pattern is defined, sin and cos builtin functions will be
13766 ;; expanded to sincos pattern with one of its outputs left unused.
13767 ;; CSE pass will figure out if two sincos patterns can be combined,
13768 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13769 ;; depending on the unused output.
13771 (define_insn "sincosxf3"
13772 [(set (match_operand:XF 0 "register_operand" "=f")
13773 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13774 UNSPEC_SINCOS_COS))
13775 (set (match_operand:XF 1 "register_operand" "=u")
13776 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13777 "TARGET_USE_FANCY_MATH_387
13778 && flag_unsafe_math_optimizations"
13780 [(set_attr "type" "fpspc")
13781 (set_attr "mode" "XF")])
13784 [(set (match_operand:XF 0 "register_operand" "")
13785 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13786 UNSPEC_SINCOS_COS))
13787 (set (match_operand:XF 1 "register_operand" "")
13788 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13789 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13790 && !(reload_completed || reload_in_progress)"
13791 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13795 [(set (match_operand:XF 0 "register_operand" "")
13796 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13797 UNSPEC_SINCOS_COS))
13798 (set (match_operand:XF 1 "register_operand" "")
13799 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13800 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13801 && !(reload_completed || reload_in_progress)"
13802 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13805 (define_insn "sincos_extend<mode>xf3_i387"
13806 [(set (match_operand:XF 0 "register_operand" "=f")
13807 (unspec:XF [(float_extend:XF
13808 (match_operand:MODEF 2 "register_operand" "0"))]
13809 UNSPEC_SINCOS_COS))
13810 (set (match_operand:XF 1 "register_operand" "=u")
13811 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13812 "TARGET_USE_FANCY_MATH_387
13813 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13814 || TARGET_MIX_SSE_I387)
13815 && flag_unsafe_math_optimizations"
13817 [(set_attr "type" "fpspc")
13818 (set_attr "mode" "XF")])
13821 [(set (match_operand:XF 0 "register_operand" "")
13822 (unspec:XF [(float_extend:XF
13823 (match_operand:MODEF 2 "register_operand" ""))]
13824 UNSPEC_SINCOS_COS))
13825 (set (match_operand:XF 1 "register_operand" "")
13826 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13827 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13828 && !(reload_completed || reload_in_progress)"
13829 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13833 [(set (match_operand:XF 0 "register_operand" "")
13834 (unspec:XF [(float_extend:XF
13835 (match_operand:MODEF 2 "register_operand" ""))]
13836 UNSPEC_SINCOS_COS))
13837 (set (match_operand:XF 1 "register_operand" "")
13838 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13839 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13840 && !(reload_completed || reload_in_progress)"
13841 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13844 (define_expand "sincos<mode>3"
13845 [(use (match_operand:MODEF 0 "register_operand" ""))
13846 (use (match_operand:MODEF 1 "register_operand" ""))
13847 (use (match_operand:MODEF 2 "register_operand" ""))]
13848 "TARGET_USE_FANCY_MATH_387
13849 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13850 || TARGET_MIX_SSE_I387)
13851 && flag_unsafe_math_optimizations"
13853 rtx op0 = gen_reg_rtx (XFmode);
13854 rtx op1 = gen_reg_rtx (XFmode);
13856 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13857 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13858 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13862 (define_insn "fptanxf4_i387"
13863 [(set (match_operand:XF 0 "register_operand" "=f")
13864 (match_operand:XF 3 "const_double_operand" "F"))
13865 (set (match_operand:XF 1 "register_operand" "=u")
13866 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13868 "TARGET_USE_FANCY_MATH_387
13869 && flag_unsafe_math_optimizations
13870 && standard_80387_constant_p (operands[3]) == 2"
13872 [(set_attr "type" "fpspc")
13873 (set_attr "mode" "XF")])
13875 (define_insn "fptan_extend<mode>xf4_i387"
13876 [(set (match_operand:MODEF 0 "register_operand" "=f")
13877 (match_operand:MODEF 3 "const_double_operand" "F"))
13878 (set (match_operand:XF 1 "register_operand" "=u")
13879 (unspec:XF [(float_extend:XF
13880 (match_operand:MODEF 2 "register_operand" "0"))]
13882 "TARGET_USE_FANCY_MATH_387
13883 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13884 || TARGET_MIX_SSE_I387)
13885 && flag_unsafe_math_optimizations
13886 && standard_80387_constant_p (operands[3]) == 2"
13888 [(set_attr "type" "fpspc")
13889 (set_attr "mode" "XF")])
13891 (define_expand "tanxf2"
13892 [(use (match_operand:XF 0 "register_operand" ""))
13893 (use (match_operand:XF 1 "register_operand" ""))]
13894 "TARGET_USE_FANCY_MATH_387
13895 && flag_unsafe_math_optimizations"
13897 rtx one = gen_reg_rtx (XFmode);
13898 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13900 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13904 (define_expand "tan<mode>2"
13905 [(use (match_operand:MODEF 0 "register_operand" ""))
13906 (use (match_operand:MODEF 1 "register_operand" ""))]
13907 "TARGET_USE_FANCY_MATH_387
13908 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13909 || TARGET_MIX_SSE_I387)
13910 && flag_unsafe_math_optimizations"
13912 rtx op0 = gen_reg_rtx (XFmode);
13914 rtx one = gen_reg_rtx (<MODE>mode);
13915 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13917 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13918 operands[1], op2));
13919 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13923 (define_insn "*fpatanxf3_i387"
13924 [(set (match_operand:XF 0 "register_operand" "=f")
13925 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13926 (match_operand:XF 2 "register_operand" "u")]
13928 (clobber (match_scratch:XF 3 "=2"))]
13929 "TARGET_USE_FANCY_MATH_387
13930 && flag_unsafe_math_optimizations"
13932 [(set_attr "type" "fpspc")
13933 (set_attr "mode" "XF")])
13935 (define_insn "fpatan_extend<mode>xf3_i387"
13936 [(set (match_operand:XF 0 "register_operand" "=f")
13937 (unspec:XF [(float_extend:XF
13938 (match_operand:MODEF 1 "register_operand" "0"))
13940 (match_operand:MODEF 2 "register_operand" "u"))]
13942 (clobber (match_scratch:XF 3 "=2"))]
13943 "TARGET_USE_FANCY_MATH_387
13944 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13945 || TARGET_MIX_SSE_I387)
13946 && flag_unsafe_math_optimizations"
13948 [(set_attr "type" "fpspc")
13949 (set_attr "mode" "XF")])
13951 (define_expand "atan2xf3"
13952 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13953 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13954 (match_operand:XF 1 "register_operand" "")]
13956 (clobber (match_scratch:XF 3 ""))])]
13957 "TARGET_USE_FANCY_MATH_387
13958 && flag_unsafe_math_optimizations"
13961 (define_expand "atan2<mode>3"
13962 [(use (match_operand:MODEF 0 "register_operand" ""))
13963 (use (match_operand:MODEF 1 "register_operand" ""))
13964 (use (match_operand:MODEF 2 "register_operand" ""))]
13965 "TARGET_USE_FANCY_MATH_387
13966 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13967 || TARGET_MIX_SSE_I387)
13968 && flag_unsafe_math_optimizations"
13970 rtx op0 = gen_reg_rtx (XFmode);
13972 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13973 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13977 (define_expand "atanxf2"
13978 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13979 (unspec:XF [(match_dup 2)
13980 (match_operand:XF 1 "register_operand" "")]
13982 (clobber (match_scratch:XF 3 ""))])]
13983 "TARGET_USE_FANCY_MATH_387
13984 && flag_unsafe_math_optimizations"
13986 operands[2] = gen_reg_rtx (XFmode);
13987 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13990 (define_expand "atan<mode>2"
13991 [(use (match_operand:MODEF 0 "register_operand" ""))
13992 (use (match_operand:MODEF 1 "register_operand" ""))]
13993 "TARGET_USE_FANCY_MATH_387
13994 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13995 || TARGET_MIX_SSE_I387)
13996 && flag_unsafe_math_optimizations"
13998 rtx op0 = gen_reg_rtx (XFmode);
14000 rtx op2 = gen_reg_rtx (<MODE>mode);
14001 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14003 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14004 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14008 (define_expand "asinxf2"
14009 [(set (match_dup 2)
14010 (mult:XF (match_operand:XF 1 "register_operand" "")
14012 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14013 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14014 (parallel [(set (match_operand:XF 0 "register_operand" "")
14015 (unspec:XF [(match_dup 5) (match_dup 1)]
14017 (clobber (match_scratch:XF 6 ""))])]
14018 "TARGET_USE_FANCY_MATH_387
14019 && flag_unsafe_math_optimizations"
14023 if (optimize_insn_for_size_p ())
14026 for (i = 2; i < 6; i++)
14027 operands[i] = gen_reg_rtx (XFmode);
14029 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14032 (define_expand "asin<mode>2"
14033 [(use (match_operand:MODEF 0 "register_operand" ""))
14034 (use (match_operand:MODEF 1 "general_operand" ""))]
14035 "TARGET_USE_FANCY_MATH_387
14036 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14037 || TARGET_MIX_SSE_I387)
14038 && flag_unsafe_math_optimizations"
14040 rtx op0 = gen_reg_rtx (XFmode);
14041 rtx op1 = gen_reg_rtx (XFmode);
14043 if (optimize_insn_for_size_p ())
14046 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14047 emit_insn (gen_asinxf2 (op0, op1));
14048 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14052 (define_expand "acosxf2"
14053 [(set (match_dup 2)
14054 (mult:XF (match_operand:XF 1 "register_operand" "")
14056 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14057 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14058 (parallel [(set (match_operand:XF 0 "register_operand" "")
14059 (unspec:XF [(match_dup 1) (match_dup 5)]
14061 (clobber (match_scratch:XF 6 ""))])]
14062 "TARGET_USE_FANCY_MATH_387
14063 && flag_unsafe_math_optimizations"
14067 if (optimize_insn_for_size_p ())
14070 for (i = 2; i < 6; i++)
14071 operands[i] = gen_reg_rtx (XFmode);
14073 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14076 (define_expand "acos<mode>2"
14077 [(use (match_operand:MODEF 0 "register_operand" ""))
14078 (use (match_operand:MODEF 1 "general_operand" ""))]
14079 "TARGET_USE_FANCY_MATH_387
14080 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14081 || TARGET_MIX_SSE_I387)
14082 && flag_unsafe_math_optimizations"
14084 rtx op0 = gen_reg_rtx (XFmode);
14085 rtx op1 = gen_reg_rtx (XFmode);
14087 if (optimize_insn_for_size_p ())
14090 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14091 emit_insn (gen_acosxf2 (op0, op1));
14092 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14096 (define_insn "fyl2xxf3_i387"
14097 [(set (match_operand:XF 0 "register_operand" "=f")
14098 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14099 (match_operand:XF 2 "register_operand" "u")]
14101 (clobber (match_scratch:XF 3 "=2"))]
14102 "TARGET_USE_FANCY_MATH_387
14103 && flag_unsafe_math_optimizations"
14105 [(set_attr "type" "fpspc")
14106 (set_attr "mode" "XF")])
14108 (define_insn "fyl2x_extend<mode>xf3_i387"
14109 [(set (match_operand:XF 0 "register_operand" "=f")
14110 (unspec:XF [(float_extend:XF
14111 (match_operand:MODEF 1 "register_operand" "0"))
14112 (match_operand:XF 2 "register_operand" "u")]
14114 (clobber (match_scratch:XF 3 "=2"))]
14115 "TARGET_USE_FANCY_MATH_387
14116 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14117 || TARGET_MIX_SSE_I387)
14118 && flag_unsafe_math_optimizations"
14120 [(set_attr "type" "fpspc")
14121 (set_attr "mode" "XF")])
14123 (define_expand "logxf2"
14124 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14125 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14126 (match_dup 2)] UNSPEC_FYL2X))
14127 (clobber (match_scratch:XF 3 ""))])]
14128 "TARGET_USE_FANCY_MATH_387
14129 && flag_unsafe_math_optimizations"
14131 operands[2] = gen_reg_rtx (XFmode);
14132 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14135 (define_expand "log<mode>2"
14136 [(use (match_operand:MODEF 0 "register_operand" ""))
14137 (use (match_operand:MODEF 1 "register_operand" ""))]
14138 "TARGET_USE_FANCY_MATH_387
14139 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14140 || TARGET_MIX_SSE_I387)
14141 && flag_unsafe_math_optimizations"
14143 rtx op0 = gen_reg_rtx (XFmode);
14145 rtx op2 = gen_reg_rtx (XFmode);
14146 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14148 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14149 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14153 (define_expand "log10xf2"
14154 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14155 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14156 (match_dup 2)] UNSPEC_FYL2X))
14157 (clobber (match_scratch:XF 3 ""))])]
14158 "TARGET_USE_FANCY_MATH_387
14159 && flag_unsafe_math_optimizations"
14161 operands[2] = gen_reg_rtx (XFmode);
14162 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14165 (define_expand "log10<mode>2"
14166 [(use (match_operand:MODEF 0 "register_operand" ""))
14167 (use (match_operand:MODEF 1 "register_operand" ""))]
14168 "TARGET_USE_FANCY_MATH_387
14169 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14170 || TARGET_MIX_SSE_I387)
14171 && flag_unsafe_math_optimizations"
14173 rtx op0 = gen_reg_rtx (XFmode);
14175 rtx op2 = gen_reg_rtx (XFmode);
14176 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14178 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14179 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14183 (define_expand "log2xf2"
14184 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14185 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14186 (match_dup 2)] UNSPEC_FYL2X))
14187 (clobber (match_scratch:XF 3 ""))])]
14188 "TARGET_USE_FANCY_MATH_387
14189 && flag_unsafe_math_optimizations"
14191 operands[2] = gen_reg_rtx (XFmode);
14192 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14195 (define_expand "log2<mode>2"
14196 [(use (match_operand:MODEF 0 "register_operand" ""))
14197 (use (match_operand:MODEF 1 "register_operand" ""))]
14198 "TARGET_USE_FANCY_MATH_387
14199 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14200 || TARGET_MIX_SSE_I387)
14201 && flag_unsafe_math_optimizations"
14203 rtx op0 = gen_reg_rtx (XFmode);
14205 rtx op2 = gen_reg_rtx (XFmode);
14206 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14208 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14209 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14213 (define_insn "fyl2xp1xf3_i387"
14214 [(set (match_operand:XF 0 "register_operand" "=f")
14215 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14216 (match_operand:XF 2 "register_operand" "u")]
14218 (clobber (match_scratch:XF 3 "=2"))]
14219 "TARGET_USE_FANCY_MATH_387
14220 && flag_unsafe_math_optimizations"
14222 [(set_attr "type" "fpspc")
14223 (set_attr "mode" "XF")])
14225 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14226 [(set (match_operand:XF 0 "register_operand" "=f")
14227 (unspec:XF [(float_extend:XF
14228 (match_operand:MODEF 1 "register_operand" "0"))
14229 (match_operand:XF 2 "register_operand" "u")]
14231 (clobber (match_scratch:XF 3 "=2"))]
14232 "TARGET_USE_FANCY_MATH_387
14233 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14234 || TARGET_MIX_SSE_I387)
14235 && flag_unsafe_math_optimizations"
14237 [(set_attr "type" "fpspc")
14238 (set_attr "mode" "XF")])
14240 (define_expand "log1pxf2"
14241 [(use (match_operand:XF 0 "register_operand" ""))
14242 (use (match_operand:XF 1 "register_operand" ""))]
14243 "TARGET_USE_FANCY_MATH_387
14244 && flag_unsafe_math_optimizations"
14246 if (optimize_insn_for_size_p ())
14249 ix86_emit_i387_log1p (operands[0], operands[1]);
14253 (define_expand "log1p<mode>2"
14254 [(use (match_operand:MODEF 0 "register_operand" ""))
14255 (use (match_operand:MODEF 1 "register_operand" ""))]
14256 "TARGET_USE_FANCY_MATH_387
14257 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14258 || TARGET_MIX_SSE_I387)
14259 && flag_unsafe_math_optimizations"
14263 if (optimize_insn_for_size_p ())
14266 op0 = gen_reg_rtx (XFmode);
14268 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14270 ix86_emit_i387_log1p (op0, operands[1]);
14271 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14275 (define_insn "fxtractxf3_i387"
14276 [(set (match_operand:XF 0 "register_operand" "=f")
14277 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14278 UNSPEC_XTRACT_FRACT))
14279 (set (match_operand:XF 1 "register_operand" "=u")
14280 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14281 "TARGET_USE_FANCY_MATH_387
14282 && flag_unsafe_math_optimizations"
14284 [(set_attr "type" "fpspc")
14285 (set_attr "mode" "XF")])
14287 (define_insn "fxtract_extend<mode>xf3_i387"
14288 [(set (match_operand:XF 0 "register_operand" "=f")
14289 (unspec:XF [(float_extend:XF
14290 (match_operand:MODEF 2 "register_operand" "0"))]
14291 UNSPEC_XTRACT_FRACT))
14292 (set (match_operand:XF 1 "register_operand" "=u")
14293 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14294 "TARGET_USE_FANCY_MATH_387
14295 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14296 || TARGET_MIX_SSE_I387)
14297 && flag_unsafe_math_optimizations"
14299 [(set_attr "type" "fpspc")
14300 (set_attr "mode" "XF")])
14302 (define_expand "logbxf2"
14303 [(parallel [(set (match_dup 2)
14304 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14305 UNSPEC_XTRACT_FRACT))
14306 (set (match_operand:XF 0 "register_operand" "")
14307 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14308 "TARGET_USE_FANCY_MATH_387
14309 && flag_unsafe_math_optimizations"
14311 operands[2] = gen_reg_rtx (XFmode);
14314 (define_expand "logb<mode>2"
14315 [(use (match_operand:MODEF 0 "register_operand" ""))
14316 (use (match_operand:MODEF 1 "register_operand" ""))]
14317 "TARGET_USE_FANCY_MATH_387
14318 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14319 || TARGET_MIX_SSE_I387)
14320 && flag_unsafe_math_optimizations"
14322 rtx op0 = gen_reg_rtx (XFmode);
14323 rtx op1 = gen_reg_rtx (XFmode);
14325 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14326 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14330 (define_expand "ilogbxf2"
14331 [(use (match_operand:SI 0 "register_operand" ""))
14332 (use (match_operand:XF 1 "register_operand" ""))]
14333 "TARGET_USE_FANCY_MATH_387
14334 && flag_unsafe_math_optimizations"
14338 if (optimize_insn_for_size_p ())
14341 op0 = gen_reg_rtx (XFmode);
14342 op1 = gen_reg_rtx (XFmode);
14344 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14345 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14349 (define_expand "ilogb<mode>2"
14350 [(use (match_operand:SI 0 "register_operand" ""))
14351 (use (match_operand:MODEF 1 "register_operand" ""))]
14352 "TARGET_USE_FANCY_MATH_387
14353 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14354 || TARGET_MIX_SSE_I387)
14355 && flag_unsafe_math_optimizations"
14359 if (optimize_insn_for_size_p ())
14362 op0 = gen_reg_rtx (XFmode);
14363 op1 = gen_reg_rtx (XFmode);
14365 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14366 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14370 (define_insn "*f2xm1xf2_i387"
14371 [(set (match_operand:XF 0 "register_operand" "=f")
14372 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14374 "TARGET_USE_FANCY_MATH_387
14375 && flag_unsafe_math_optimizations"
14377 [(set_attr "type" "fpspc")
14378 (set_attr "mode" "XF")])
14380 (define_insn "*fscalexf4_i387"
14381 [(set (match_operand:XF 0 "register_operand" "=f")
14382 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14383 (match_operand:XF 3 "register_operand" "1")]
14384 UNSPEC_FSCALE_FRACT))
14385 (set (match_operand:XF 1 "register_operand" "=u")
14386 (unspec:XF [(match_dup 2) (match_dup 3)]
14387 UNSPEC_FSCALE_EXP))]
14388 "TARGET_USE_FANCY_MATH_387
14389 && flag_unsafe_math_optimizations"
14391 [(set_attr "type" "fpspc")
14392 (set_attr "mode" "XF")])
14394 (define_expand "expNcorexf3"
14395 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14396 (match_operand:XF 2 "register_operand" "")))
14397 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14398 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14399 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14400 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14401 (parallel [(set (match_operand:XF 0 "register_operand" "")
14402 (unspec:XF [(match_dup 8) (match_dup 4)]
14403 UNSPEC_FSCALE_FRACT))
14405 (unspec:XF [(match_dup 8) (match_dup 4)]
14406 UNSPEC_FSCALE_EXP))])]
14407 "TARGET_USE_FANCY_MATH_387
14408 && flag_unsafe_math_optimizations"
14412 if (optimize_insn_for_size_p ())
14415 for (i = 3; i < 10; i++)
14416 operands[i] = gen_reg_rtx (XFmode);
14418 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14421 (define_expand "expxf2"
14422 [(use (match_operand:XF 0 "register_operand" ""))
14423 (use (match_operand:XF 1 "register_operand" ""))]
14424 "TARGET_USE_FANCY_MATH_387
14425 && flag_unsafe_math_optimizations"
14429 if (optimize_insn_for_size_p ())
14432 op2 = gen_reg_rtx (XFmode);
14433 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14435 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14439 (define_expand "exp<mode>2"
14440 [(use (match_operand:MODEF 0 "register_operand" ""))
14441 (use (match_operand:MODEF 1 "general_operand" ""))]
14442 "TARGET_USE_FANCY_MATH_387
14443 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14444 || TARGET_MIX_SSE_I387)
14445 && flag_unsafe_math_optimizations"
14449 if (optimize_insn_for_size_p ())
14452 op0 = gen_reg_rtx (XFmode);
14453 op1 = gen_reg_rtx (XFmode);
14455 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14456 emit_insn (gen_expxf2 (op0, op1));
14457 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14461 (define_expand "exp10xf2"
14462 [(use (match_operand:XF 0 "register_operand" ""))
14463 (use (match_operand:XF 1 "register_operand" ""))]
14464 "TARGET_USE_FANCY_MATH_387
14465 && flag_unsafe_math_optimizations"
14469 if (optimize_insn_for_size_p ())
14472 op2 = gen_reg_rtx (XFmode);
14473 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14475 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14479 (define_expand "exp10<mode>2"
14480 [(use (match_operand:MODEF 0 "register_operand" ""))
14481 (use (match_operand:MODEF 1 "general_operand" ""))]
14482 "TARGET_USE_FANCY_MATH_387
14483 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14484 || TARGET_MIX_SSE_I387)
14485 && flag_unsafe_math_optimizations"
14489 if (optimize_insn_for_size_p ())
14492 op0 = gen_reg_rtx (XFmode);
14493 op1 = gen_reg_rtx (XFmode);
14495 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14496 emit_insn (gen_exp10xf2 (op0, op1));
14497 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14501 (define_expand "exp2xf2"
14502 [(use (match_operand:XF 0 "register_operand" ""))
14503 (use (match_operand:XF 1 "register_operand" ""))]
14504 "TARGET_USE_FANCY_MATH_387
14505 && flag_unsafe_math_optimizations"
14509 if (optimize_insn_for_size_p ())
14512 op2 = gen_reg_rtx (XFmode);
14513 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14515 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14519 (define_expand "exp2<mode>2"
14520 [(use (match_operand:MODEF 0 "register_operand" ""))
14521 (use (match_operand:MODEF 1 "general_operand" ""))]
14522 "TARGET_USE_FANCY_MATH_387
14523 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14524 || TARGET_MIX_SSE_I387)
14525 && flag_unsafe_math_optimizations"
14529 if (optimize_insn_for_size_p ())
14532 op0 = gen_reg_rtx (XFmode);
14533 op1 = gen_reg_rtx (XFmode);
14535 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14536 emit_insn (gen_exp2xf2 (op0, op1));
14537 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14541 (define_expand "expm1xf2"
14542 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14544 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14545 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14546 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14547 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14548 (parallel [(set (match_dup 7)
14549 (unspec:XF [(match_dup 6) (match_dup 4)]
14550 UNSPEC_FSCALE_FRACT))
14552 (unspec:XF [(match_dup 6) (match_dup 4)]
14553 UNSPEC_FSCALE_EXP))])
14554 (parallel [(set (match_dup 10)
14555 (unspec:XF [(match_dup 9) (match_dup 8)]
14556 UNSPEC_FSCALE_FRACT))
14557 (set (match_dup 11)
14558 (unspec:XF [(match_dup 9) (match_dup 8)]
14559 UNSPEC_FSCALE_EXP))])
14560 (set (match_dup 12) (minus:XF (match_dup 10)
14561 (float_extend:XF (match_dup 13))))
14562 (set (match_operand:XF 0 "register_operand" "")
14563 (plus:XF (match_dup 12) (match_dup 7)))]
14564 "TARGET_USE_FANCY_MATH_387
14565 && flag_unsafe_math_optimizations"
14569 if (optimize_insn_for_size_p ())
14572 for (i = 2; i < 13; i++)
14573 operands[i] = gen_reg_rtx (XFmode);
14576 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14578 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14581 (define_expand "expm1<mode>2"
14582 [(use (match_operand:MODEF 0 "register_operand" ""))
14583 (use (match_operand:MODEF 1 "general_operand" ""))]
14584 "TARGET_USE_FANCY_MATH_387
14585 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14586 || TARGET_MIX_SSE_I387)
14587 && flag_unsafe_math_optimizations"
14591 if (optimize_insn_for_size_p ())
14594 op0 = gen_reg_rtx (XFmode);
14595 op1 = gen_reg_rtx (XFmode);
14597 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14598 emit_insn (gen_expm1xf2 (op0, op1));
14599 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14603 (define_expand "ldexpxf3"
14604 [(set (match_dup 3)
14605 (float:XF (match_operand:SI 2 "register_operand" "")))
14606 (parallel [(set (match_operand:XF 0 " register_operand" "")
14607 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14609 UNSPEC_FSCALE_FRACT))
14611 (unspec:XF [(match_dup 1) (match_dup 3)]
14612 UNSPEC_FSCALE_EXP))])]
14613 "TARGET_USE_FANCY_MATH_387
14614 && flag_unsafe_math_optimizations"
14616 if (optimize_insn_for_size_p ())
14619 operands[3] = gen_reg_rtx (XFmode);
14620 operands[4] = gen_reg_rtx (XFmode);
14623 (define_expand "ldexp<mode>3"
14624 [(use (match_operand:MODEF 0 "register_operand" ""))
14625 (use (match_operand:MODEF 1 "general_operand" ""))
14626 (use (match_operand:SI 2 "register_operand" ""))]
14627 "TARGET_USE_FANCY_MATH_387
14628 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14629 || TARGET_MIX_SSE_I387)
14630 && flag_unsafe_math_optimizations"
14634 if (optimize_insn_for_size_p ())
14637 op0 = gen_reg_rtx (XFmode);
14638 op1 = gen_reg_rtx (XFmode);
14640 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14641 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14642 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14646 (define_expand "scalbxf3"
14647 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14648 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14649 (match_operand:XF 2 "register_operand" "")]
14650 UNSPEC_FSCALE_FRACT))
14652 (unspec:XF [(match_dup 1) (match_dup 2)]
14653 UNSPEC_FSCALE_EXP))])]
14654 "TARGET_USE_FANCY_MATH_387
14655 && flag_unsafe_math_optimizations"
14657 if (optimize_insn_for_size_p ())
14660 operands[3] = gen_reg_rtx (XFmode);
14663 (define_expand "scalb<mode>3"
14664 [(use (match_operand:MODEF 0 "register_operand" ""))
14665 (use (match_operand:MODEF 1 "general_operand" ""))
14666 (use (match_operand:MODEF 2 "general_operand" ""))]
14667 "TARGET_USE_FANCY_MATH_387
14668 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14669 || TARGET_MIX_SSE_I387)
14670 && flag_unsafe_math_optimizations"
14674 if (optimize_insn_for_size_p ())
14677 op0 = gen_reg_rtx (XFmode);
14678 op1 = gen_reg_rtx (XFmode);
14679 op2 = gen_reg_rtx (XFmode);
14681 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14682 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14683 emit_insn (gen_scalbxf3 (op0, op1, op2));
14684 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14688 (define_expand "significandxf2"
14689 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14690 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14691 UNSPEC_XTRACT_FRACT))
14693 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14694 "TARGET_USE_FANCY_MATH_387
14695 && flag_unsafe_math_optimizations"
14697 operands[2] = gen_reg_rtx (XFmode);
14700 (define_expand "significand<mode>2"
14701 [(use (match_operand:MODEF 0 "register_operand" ""))
14702 (use (match_operand:MODEF 1 "register_operand" ""))]
14703 "TARGET_USE_FANCY_MATH_387
14704 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14705 || TARGET_MIX_SSE_I387)
14706 && flag_unsafe_math_optimizations"
14708 rtx op0 = gen_reg_rtx (XFmode);
14709 rtx op1 = gen_reg_rtx (XFmode);
14711 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14712 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14717 (define_insn "sse4_1_round<mode>2"
14718 [(set (match_operand:MODEF 0 "register_operand" "=x")
14719 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14720 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14723 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14724 [(set_attr "type" "ssecvt")
14725 (set_attr "prefix_extra" "1")
14726 (set_attr "prefix" "maybe_vex")
14727 (set_attr "mode" "<MODE>")])
14729 (define_insn "rintxf2"
14730 [(set (match_operand:XF 0 "register_operand" "=f")
14731 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14733 "TARGET_USE_FANCY_MATH_387
14734 && flag_unsafe_math_optimizations"
14736 [(set_attr "type" "fpspc")
14737 (set_attr "mode" "XF")])
14739 (define_expand "rint<mode>2"
14740 [(use (match_operand:MODEF 0 "register_operand" ""))
14741 (use (match_operand:MODEF 1 "register_operand" ""))]
14742 "(TARGET_USE_FANCY_MATH_387
14743 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14744 || TARGET_MIX_SSE_I387)
14745 && flag_unsafe_math_optimizations)
14746 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14747 && !flag_trapping_math)"
14749 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14750 && !flag_trapping_math)
14752 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14755 emit_insn (gen_sse4_1_round<mode>2
14756 (operands[0], operands[1], GEN_INT (0x04)));
14758 ix86_expand_rint (operand0, operand1);
14762 rtx op0 = gen_reg_rtx (XFmode);
14763 rtx op1 = gen_reg_rtx (XFmode);
14765 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14766 emit_insn (gen_rintxf2 (op0, op1));
14768 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14773 (define_expand "round<mode>2"
14774 [(match_operand:MODEF 0 "register_operand" "")
14775 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14776 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14777 && !flag_trapping_math && !flag_rounding_math"
14779 if (optimize_insn_for_size_p ())
14781 if (TARGET_64BIT || (<MODE>mode != DFmode))
14782 ix86_expand_round (operand0, operand1);
14784 ix86_expand_rounddf_32 (operand0, operand1);
14788 (define_insn_and_split "*fistdi2_1"
14789 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14790 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14792 "TARGET_USE_FANCY_MATH_387
14793 && can_create_pseudo_p ()"
14798 if (memory_operand (operands[0], VOIDmode))
14799 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14802 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14803 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14808 [(set_attr "type" "fpspc")
14809 (set_attr "mode" "DI")])
14811 (define_insn "fistdi2"
14812 [(set (match_operand:DI 0 "memory_operand" "=m")
14813 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14815 (clobber (match_scratch:XF 2 "=&1f"))]
14816 "TARGET_USE_FANCY_MATH_387"
14817 "* return output_fix_trunc (insn, operands, 0);"
14818 [(set_attr "type" "fpspc")
14819 (set_attr "mode" "DI")])
14821 (define_insn "fistdi2_with_temp"
14822 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14823 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14825 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14826 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14827 "TARGET_USE_FANCY_MATH_387"
14829 [(set_attr "type" "fpspc")
14830 (set_attr "mode" "DI")])
14833 [(set (match_operand:DI 0 "register_operand" "")
14834 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14836 (clobber (match_operand:DI 2 "memory_operand" ""))
14837 (clobber (match_scratch 3 ""))]
14839 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14840 (clobber (match_dup 3))])
14841 (set (match_dup 0) (match_dup 2))]
14845 [(set (match_operand:DI 0 "memory_operand" "")
14846 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14848 (clobber (match_operand:DI 2 "memory_operand" ""))
14849 (clobber (match_scratch 3 ""))]
14851 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14852 (clobber (match_dup 3))])]
14855 (define_insn_and_split "*fist<mode>2_1"
14856 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14857 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14859 "TARGET_USE_FANCY_MATH_387
14860 && can_create_pseudo_p ()"
14865 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14866 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14870 [(set_attr "type" "fpspc")
14871 (set_attr "mode" "<MODE>")])
14873 (define_insn "fist<mode>2"
14874 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14875 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14877 "TARGET_USE_FANCY_MATH_387"
14878 "* return output_fix_trunc (insn, operands, 0);"
14879 [(set_attr "type" "fpspc")
14880 (set_attr "mode" "<MODE>")])
14882 (define_insn "fist<mode>2_with_temp"
14883 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14884 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14886 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14887 "TARGET_USE_FANCY_MATH_387"
14889 [(set_attr "type" "fpspc")
14890 (set_attr "mode" "<MODE>")])
14893 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14894 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14896 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14898 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14899 (set (match_dup 0) (match_dup 2))]
14903 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14904 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14906 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14908 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14911 (define_expand "lrintxf<mode>2"
14912 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14913 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14915 "TARGET_USE_FANCY_MATH_387"
14918 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14919 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14920 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14921 UNSPEC_FIX_NOTRUNC))]
14922 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14923 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14926 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14927 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14928 (match_operand:MODEF 1 "register_operand" "")]
14929 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14930 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14931 && !flag_trapping_math && !flag_rounding_math"
14933 if (optimize_insn_for_size_p ())
14935 ix86_expand_lround (operand0, operand1);
14939 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14940 (define_insn_and_split "frndintxf2_floor"
14941 [(set (match_operand:XF 0 "register_operand" "")
14942 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14943 UNSPEC_FRNDINT_FLOOR))
14944 (clobber (reg:CC FLAGS_REG))]
14945 "TARGET_USE_FANCY_MATH_387
14946 && flag_unsafe_math_optimizations
14947 && can_create_pseudo_p ()"
14952 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14954 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14955 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14957 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14958 operands[2], operands[3]));
14961 [(set_attr "type" "frndint")
14962 (set_attr "i387_cw" "floor")
14963 (set_attr "mode" "XF")])
14965 (define_insn "frndintxf2_floor_i387"
14966 [(set (match_operand:XF 0 "register_operand" "=f")
14967 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14968 UNSPEC_FRNDINT_FLOOR))
14969 (use (match_operand:HI 2 "memory_operand" "m"))
14970 (use (match_operand:HI 3 "memory_operand" "m"))]
14971 "TARGET_USE_FANCY_MATH_387
14972 && flag_unsafe_math_optimizations"
14973 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14974 [(set_attr "type" "frndint")
14975 (set_attr "i387_cw" "floor")
14976 (set_attr "mode" "XF")])
14978 (define_expand "floorxf2"
14979 [(use (match_operand:XF 0 "register_operand" ""))
14980 (use (match_operand:XF 1 "register_operand" ""))]
14981 "TARGET_USE_FANCY_MATH_387
14982 && flag_unsafe_math_optimizations"
14984 if (optimize_insn_for_size_p ())
14986 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14990 (define_expand "floor<mode>2"
14991 [(use (match_operand:MODEF 0 "register_operand" ""))
14992 (use (match_operand:MODEF 1 "register_operand" ""))]
14993 "(TARGET_USE_FANCY_MATH_387
14994 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14995 || TARGET_MIX_SSE_I387)
14996 && flag_unsafe_math_optimizations)
14997 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14998 && !flag_trapping_math)"
15000 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15001 && !flag_trapping_math
15002 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15004 if (!TARGET_ROUND && optimize_insn_for_size_p ())
15007 emit_insn (gen_sse4_1_round<mode>2
15008 (operands[0], operands[1], GEN_INT (0x01)));
15009 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15010 ix86_expand_floorceil (operand0, operand1, true);
15012 ix86_expand_floorceildf_32 (operand0, operand1, true);
15018 if (optimize_insn_for_size_p ())
15021 op0 = gen_reg_rtx (XFmode);
15022 op1 = gen_reg_rtx (XFmode);
15023 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15024 emit_insn (gen_frndintxf2_floor (op0, op1));
15026 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15031 (define_insn_and_split "*fist<mode>2_floor_1"
15032 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15033 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15034 UNSPEC_FIST_FLOOR))
15035 (clobber (reg:CC FLAGS_REG))]
15036 "TARGET_USE_FANCY_MATH_387
15037 && flag_unsafe_math_optimizations
15038 && can_create_pseudo_p ()"
15043 ix86_optimize_mode_switching[I387_FLOOR] = 1;
15045 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15046 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
15047 if (memory_operand (operands[0], VOIDmode))
15048 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
15049 operands[2], operands[3]));
15052 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15053 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
15054 operands[2], operands[3],
15059 [(set_attr "type" "fistp")
15060 (set_attr "i387_cw" "floor")
15061 (set_attr "mode" "<MODE>")])
15063 (define_insn "fistdi2_floor"
15064 [(set (match_operand:DI 0 "memory_operand" "=m")
15065 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15066 UNSPEC_FIST_FLOOR))
15067 (use (match_operand:HI 2 "memory_operand" "m"))
15068 (use (match_operand:HI 3 "memory_operand" "m"))
15069 (clobber (match_scratch:XF 4 "=&1f"))]
15070 "TARGET_USE_FANCY_MATH_387
15071 && flag_unsafe_math_optimizations"
15072 "* return output_fix_trunc (insn, operands, 0);"
15073 [(set_attr "type" "fistp")
15074 (set_attr "i387_cw" "floor")
15075 (set_attr "mode" "DI")])
15077 (define_insn "fistdi2_floor_with_temp"
15078 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15079 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15080 UNSPEC_FIST_FLOOR))
15081 (use (match_operand:HI 2 "memory_operand" "m,m"))
15082 (use (match_operand:HI 3 "memory_operand" "m,m"))
15083 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15084 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15085 "TARGET_USE_FANCY_MATH_387
15086 && flag_unsafe_math_optimizations"
15088 [(set_attr "type" "fistp")
15089 (set_attr "i387_cw" "floor")
15090 (set_attr "mode" "DI")])
15093 [(set (match_operand:DI 0 "register_operand" "")
15094 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15095 UNSPEC_FIST_FLOOR))
15096 (use (match_operand:HI 2 "memory_operand" ""))
15097 (use (match_operand:HI 3 "memory_operand" ""))
15098 (clobber (match_operand:DI 4 "memory_operand" ""))
15099 (clobber (match_scratch 5 ""))]
15101 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15102 (use (match_dup 2))
15103 (use (match_dup 3))
15104 (clobber (match_dup 5))])
15105 (set (match_dup 0) (match_dup 4))]
15109 [(set (match_operand:DI 0 "memory_operand" "")
15110 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15111 UNSPEC_FIST_FLOOR))
15112 (use (match_operand:HI 2 "memory_operand" ""))
15113 (use (match_operand:HI 3 "memory_operand" ""))
15114 (clobber (match_operand:DI 4 "memory_operand" ""))
15115 (clobber (match_scratch 5 ""))]
15117 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15118 (use (match_dup 2))
15119 (use (match_dup 3))
15120 (clobber (match_dup 5))])]
15123 (define_insn "fist<mode>2_floor"
15124 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15125 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15126 UNSPEC_FIST_FLOOR))
15127 (use (match_operand:HI 2 "memory_operand" "m"))
15128 (use (match_operand:HI 3 "memory_operand" "m"))]
15129 "TARGET_USE_FANCY_MATH_387
15130 && flag_unsafe_math_optimizations"
15131 "* return output_fix_trunc (insn, operands, 0);"
15132 [(set_attr "type" "fistp")
15133 (set_attr "i387_cw" "floor")
15134 (set_attr "mode" "<MODE>")])
15136 (define_insn "fist<mode>2_floor_with_temp"
15137 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15138 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15139 UNSPEC_FIST_FLOOR))
15140 (use (match_operand:HI 2 "memory_operand" "m,m"))
15141 (use (match_operand:HI 3 "memory_operand" "m,m"))
15142 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15143 "TARGET_USE_FANCY_MATH_387
15144 && flag_unsafe_math_optimizations"
15146 [(set_attr "type" "fistp")
15147 (set_attr "i387_cw" "floor")
15148 (set_attr "mode" "<MODE>")])
15151 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15152 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15153 UNSPEC_FIST_FLOOR))
15154 (use (match_operand:HI 2 "memory_operand" ""))
15155 (use (match_operand:HI 3 "memory_operand" ""))
15156 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15158 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15159 UNSPEC_FIST_FLOOR))
15160 (use (match_dup 2))
15161 (use (match_dup 3))])
15162 (set (match_dup 0) (match_dup 4))]
15166 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15167 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15168 UNSPEC_FIST_FLOOR))
15169 (use (match_operand:HI 2 "memory_operand" ""))
15170 (use (match_operand:HI 3 "memory_operand" ""))
15171 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15173 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15174 UNSPEC_FIST_FLOOR))
15175 (use (match_dup 2))
15176 (use (match_dup 3))])]
15179 (define_expand "lfloorxf<mode>2"
15180 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15181 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15182 UNSPEC_FIST_FLOOR))
15183 (clobber (reg:CC FLAGS_REG))])]
15184 "TARGET_USE_FANCY_MATH_387
15185 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15186 && flag_unsafe_math_optimizations"
15189 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15190 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15191 (match_operand:MODEF 1 "register_operand" "")]
15192 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15193 && !flag_trapping_math"
15195 if (TARGET_64BIT && optimize_insn_for_size_p ())
15197 ix86_expand_lfloorceil (operand0, operand1, true);
15201 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15202 (define_insn_and_split "frndintxf2_ceil"
15203 [(set (match_operand:XF 0 "register_operand" "")
15204 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15205 UNSPEC_FRNDINT_CEIL))
15206 (clobber (reg:CC FLAGS_REG))]
15207 "TARGET_USE_FANCY_MATH_387
15208 && flag_unsafe_math_optimizations
15209 && can_create_pseudo_p ()"
15214 ix86_optimize_mode_switching[I387_CEIL] = 1;
15216 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15217 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15219 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15220 operands[2], operands[3]));
15223 [(set_attr "type" "frndint")
15224 (set_attr "i387_cw" "ceil")
15225 (set_attr "mode" "XF")])
15227 (define_insn "frndintxf2_ceil_i387"
15228 [(set (match_operand:XF 0 "register_operand" "=f")
15229 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15230 UNSPEC_FRNDINT_CEIL))
15231 (use (match_operand:HI 2 "memory_operand" "m"))
15232 (use (match_operand:HI 3 "memory_operand" "m"))]
15233 "TARGET_USE_FANCY_MATH_387
15234 && flag_unsafe_math_optimizations"
15235 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15236 [(set_attr "type" "frndint")
15237 (set_attr "i387_cw" "ceil")
15238 (set_attr "mode" "XF")])
15240 (define_expand "ceilxf2"
15241 [(use (match_operand:XF 0 "register_operand" ""))
15242 (use (match_operand:XF 1 "register_operand" ""))]
15243 "TARGET_USE_FANCY_MATH_387
15244 && flag_unsafe_math_optimizations"
15246 if (optimize_insn_for_size_p ())
15248 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15252 (define_expand "ceil<mode>2"
15253 [(use (match_operand:MODEF 0 "register_operand" ""))
15254 (use (match_operand:MODEF 1 "register_operand" ""))]
15255 "(TARGET_USE_FANCY_MATH_387
15256 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15257 || TARGET_MIX_SSE_I387)
15258 && flag_unsafe_math_optimizations)
15259 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15260 && !flag_trapping_math)"
15262 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15263 && !flag_trapping_math
15264 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15267 emit_insn (gen_sse4_1_round<mode>2
15268 (operands[0], operands[1], GEN_INT (0x02)));
15269 else if (optimize_insn_for_size_p ())
15271 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15272 ix86_expand_floorceil (operand0, operand1, false);
15274 ix86_expand_floorceildf_32 (operand0, operand1, false);
15280 if (optimize_insn_for_size_p ())
15283 op0 = gen_reg_rtx (XFmode);
15284 op1 = gen_reg_rtx (XFmode);
15285 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15286 emit_insn (gen_frndintxf2_ceil (op0, op1));
15288 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15293 (define_insn_and_split "*fist<mode>2_ceil_1"
15294 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15295 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15297 (clobber (reg:CC FLAGS_REG))]
15298 "TARGET_USE_FANCY_MATH_387
15299 && flag_unsafe_math_optimizations
15300 && can_create_pseudo_p ()"
15305 ix86_optimize_mode_switching[I387_CEIL] = 1;
15307 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15308 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15309 if (memory_operand (operands[0], VOIDmode))
15310 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15311 operands[2], operands[3]));
15314 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15315 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15316 operands[2], operands[3],
15321 [(set_attr "type" "fistp")
15322 (set_attr "i387_cw" "ceil")
15323 (set_attr "mode" "<MODE>")])
15325 (define_insn "fistdi2_ceil"
15326 [(set (match_operand:DI 0 "memory_operand" "=m")
15327 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15329 (use (match_operand:HI 2 "memory_operand" "m"))
15330 (use (match_operand:HI 3 "memory_operand" "m"))
15331 (clobber (match_scratch:XF 4 "=&1f"))]
15332 "TARGET_USE_FANCY_MATH_387
15333 && flag_unsafe_math_optimizations"
15334 "* return output_fix_trunc (insn, operands, 0);"
15335 [(set_attr "type" "fistp")
15336 (set_attr "i387_cw" "ceil")
15337 (set_attr "mode" "DI")])
15339 (define_insn "fistdi2_ceil_with_temp"
15340 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15341 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15343 (use (match_operand:HI 2 "memory_operand" "m,m"))
15344 (use (match_operand:HI 3 "memory_operand" "m,m"))
15345 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15346 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15347 "TARGET_USE_FANCY_MATH_387
15348 && flag_unsafe_math_optimizations"
15350 [(set_attr "type" "fistp")
15351 (set_attr "i387_cw" "ceil")
15352 (set_attr "mode" "DI")])
15355 [(set (match_operand:DI 0 "register_operand" "")
15356 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15358 (use (match_operand:HI 2 "memory_operand" ""))
15359 (use (match_operand:HI 3 "memory_operand" ""))
15360 (clobber (match_operand:DI 4 "memory_operand" ""))
15361 (clobber (match_scratch 5 ""))]
15363 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15364 (use (match_dup 2))
15365 (use (match_dup 3))
15366 (clobber (match_dup 5))])
15367 (set (match_dup 0) (match_dup 4))]
15371 [(set (match_operand:DI 0 "memory_operand" "")
15372 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15374 (use (match_operand:HI 2 "memory_operand" ""))
15375 (use (match_operand:HI 3 "memory_operand" ""))
15376 (clobber (match_operand:DI 4 "memory_operand" ""))
15377 (clobber (match_scratch 5 ""))]
15379 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15380 (use (match_dup 2))
15381 (use (match_dup 3))
15382 (clobber (match_dup 5))])]
15385 (define_insn "fist<mode>2_ceil"
15386 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15387 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15389 (use (match_operand:HI 2 "memory_operand" "m"))
15390 (use (match_operand:HI 3 "memory_operand" "m"))]
15391 "TARGET_USE_FANCY_MATH_387
15392 && flag_unsafe_math_optimizations"
15393 "* return output_fix_trunc (insn, operands, 0);"
15394 [(set_attr "type" "fistp")
15395 (set_attr "i387_cw" "ceil")
15396 (set_attr "mode" "<MODE>")])
15398 (define_insn "fist<mode>2_ceil_with_temp"
15399 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15400 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15402 (use (match_operand:HI 2 "memory_operand" "m,m"))
15403 (use (match_operand:HI 3 "memory_operand" "m,m"))
15404 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15405 "TARGET_USE_FANCY_MATH_387
15406 && flag_unsafe_math_optimizations"
15408 [(set_attr "type" "fistp")
15409 (set_attr "i387_cw" "ceil")
15410 (set_attr "mode" "<MODE>")])
15413 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15414 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15416 (use (match_operand:HI 2 "memory_operand" ""))
15417 (use (match_operand:HI 3 "memory_operand" ""))
15418 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15420 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15422 (use (match_dup 2))
15423 (use (match_dup 3))])
15424 (set (match_dup 0) (match_dup 4))]
15428 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15429 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15431 (use (match_operand:HI 2 "memory_operand" ""))
15432 (use (match_operand:HI 3 "memory_operand" ""))
15433 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15435 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15437 (use (match_dup 2))
15438 (use (match_dup 3))])]
15441 (define_expand "lceilxf<mode>2"
15442 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15443 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15445 (clobber (reg:CC FLAGS_REG))])]
15446 "TARGET_USE_FANCY_MATH_387
15447 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15448 && flag_unsafe_math_optimizations"
15451 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15452 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15453 (match_operand:MODEF 1 "register_operand" "")]
15454 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15455 && !flag_trapping_math"
15457 ix86_expand_lfloorceil (operand0, operand1, false);
15461 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15462 (define_insn_and_split "frndintxf2_trunc"
15463 [(set (match_operand:XF 0 "register_operand" "")
15464 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15465 UNSPEC_FRNDINT_TRUNC))
15466 (clobber (reg:CC FLAGS_REG))]
15467 "TARGET_USE_FANCY_MATH_387
15468 && flag_unsafe_math_optimizations
15469 && can_create_pseudo_p ()"
15474 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15476 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15477 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15479 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15480 operands[2], operands[3]));
15483 [(set_attr "type" "frndint")
15484 (set_attr "i387_cw" "trunc")
15485 (set_attr "mode" "XF")])
15487 (define_insn "frndintxf2_trunc_i387"
15488 [(set (match_operand:XF 0 "register_operand" "=f")
15489 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15490 UNSPEC_FRNDINT_TRUNC))
15491 (use (match_operand:HI 2 "memory_operand" "m"))
15492 (use (match_operand:HI 3 "memory_operand" "m"))]
15493 "TARGET_USE_FANCY_MATH_387
15494 && flag_unsafe_math_optimizations"
15495 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15496 [(set_attr "type" "frndint")
15497 (set_attr "i387_cw" "trunc")
15498 (set_attr "mode" "XF")])
15500 (define_expand "btruncxf2"
15501 [(use (match_operand:XF 0 "register_operand" ""))
15502 (use (match_operand:XF 1 "register_operand" ""))]
15503 "TARGET_USE_FANCY_MATH_387
15504 && flag_unsafe_math_optimizations"
15506 if (optimize_insn_for_size_p ())
15508 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15512 (define_expand "btrunc<mode>2"
15513 [(use (match_operand:MODEF 0 "register_operand" ""))
15514 (use (match_operand:MODEF 1 "register_operand" ""))]
15515 "(TARGET_USE_FANCY_MATH_387
15516 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15517 || TARGET_MIX_SSE_I387)
15518 && flag_unsafe_math_optimizations)
15519 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15520 && !flag_trapping_math)"
15522 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15523 && !flag_trapping_math
15524 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15527 emit_insn (gen_sse4_1_round<mode>2
15528 (operands[0], operands[1], GEN_INT (0x03)));
15529 else if (optimize_insn_for_size_p ())
15531 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15532 ix86_expand_trunc (operand0, operand1);
15534 ix86_expand_truncdf_32 (operand0, operand1);
15540 if (optimize_insn_for_size_p ())
15543 op0 = gen_reg_rtx (XFmode);
15544 op1 = gen_reg_rtx (XFmode);
15545 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15546 emit_insn (gen_frndintxf2_trunc (op0, op1));
15548 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15553 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15554 (define_insn_and_split "frndintxf2_mask_pm"
15555 [(set (match_operand:XF 0 "register_operand" "")
15556 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15557 UNSPEC_FRNDINT_MASK_PM))
15558 (clobber (reg:CC FLAGS_REG))]
15559 "TARGET_USE_FANCY_MATH_387
15560 && flag_unsafe_math_optimizations
15561 && can_create_pseudo_p ()"
15566 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15568 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15569 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15571 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15572 operands[2], operands[3]));
15575 [(set_attr "type" "frndint")
15576 (set_attr "i387_cw" "mask_pm")
15577 (set_attr "mode" "XF")])
15579 (define_insn "frndintxf2_mask_pm_i387"
15580 [(set (match_operand:XF 0 "register_operand" "=f")
15581 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15582 UNSPEC_FRNDINT_MASK_PM))
15583 (use (match_operand:HI 2 "memory_operand" "m"))
15584 (use (match_operand:HI 3 "memory_operand" "m"))]
15585 "TARGET_USE_FANCY_MATH_387
15586 && flag_unsafe_math_optimizations"
15587 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15588 [(set_attr "type" "frndint")
15589 (set_attr "i387_cw" "mask_pm")
15590 (set_attr "mode" "XF")])
15592 (define_expand "nearbyintxf2"
15593 [(use (match_operand:XF 0 "register_operand" ""))
15594 (use (match_operand:XF 1 "register_operand" ""))]
15595 "TARGET_USE_FANCY_MATH_387
15596 && flag_unsafe_math_optimizations"
15598 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15603 (define_expand "nearbyint<mode>2"
15604 [(use (match_operand:MODEF 0 "register_operand" ""))
15605 (use (match_operand:MODEF 1 "register_operand" ""))]
15606 "TARGET_USE_FANCY_MATH_387
15607 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15608 || TARGET_MIX_SSE_I387)
15609 && flag_unsafe_math_optimizations"
15611 rtx op0 = gen_reg_rtx (XFmode);
15612 rtx op1 = gen_reg_rtx (XFmode);
15614 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15615 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15617 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15621 (define_insn "fxam<mode>2_i387"
15622 [(set (match_operand:HI 0 "register_operand" "=a")
15624 [(match_operand:X87MODEF 1 "register_operand" "f")]
15626 "TARGET_USE_FANCY_MATH_387"
15627 "fxam\n\tfnstsw\t%0"
15628 [(set_attr "type" "multi")
15629 (set_attr "length" "4")
15630 (set_attr "unit" "i387")
15631 (set_attr "mode" "<MODE>")])
15633 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15634 [(set (match_operand:HI 0 "register_operand" "")
15636 [(match_operand:MODEF 1 "memory_operand" "")]
15638 "TARGET_USE_FANCY_MATH_387
15639 && can_create_pseudo_p ()"
15642 [(set (match_dup 2)(match_dup 1))
15644 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15646 operands[2] = gen_reg_rtx (<MODE>mode);
15648 MEM_VOLATILE_P (operands[1]) = 1;
15650 [(set_attr "type" "multi")
15651 (set_attr "unit" "i387")
15652 (set_attr "mode" "<MODE>")])
15654 (define_expand "isinfxf2"
15655 [(use (match_operand:SI 0 "register_operand" ""))
15656 (use (match_operand:XF 1 "register_operand" ""))]
15657 "TARGET_USE_FANCY_MATH_387
15658 && TARGET_C99_FUNCTIONS"
15660 rtx mask = GEN_INT (0x45);
15661 rtx val = GEN_INT (0x05);
15665 rtx scratch = gen_reg_rtx (HImode);
15666 rtx res = gen_reg_rtx (QImode);
15668 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15670 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15671 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15672 cond = gen_rtx_fmt_ee (EQ, QImode,
15673 gen_rtx_REG (CCmode, FLAGS_REG),
15675 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15676 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15680 (define_expand "isinf<mode>2"
15681 [(use (match_operand:SI 0 "register_operand" ""))
15682 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15683 "TARGET_USE_FANCY_MATH_387
15684 && TARGET_C99_FUNCTIONS
15685 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15687 rtx mask = GEN_INT (0x45);
15688 rtx val = GEN_INT (0x05);
15692 rtx scratch = gen_reg_rtx (HImode);
15693 rtx res = gen_reg_rtx (QImode);
15695 /* Remove excess precision by forcing value through memory. */
15696 if (memory_operand (operands[1], VOIDmode))
15697 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15700 enum ix86_stack_slot slot = (virtuals_instantiated
15703 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15705 emit_move_insn (temp, operands[1]);
15706 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15709 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15710 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15711 cond = gen_rtx_fmt_ee (EQ, QImode,
15712 gen_rtx_REG (CCmode, FLAGS_REG),
15714 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15715 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15719 (define_expand "signbit<mode>2"
15720 [(use (match_operand:SI 0 "register_operand" ""))
15721 (use (match_operand:X87MODEF 1 "register_operand" ""))]
15722 "TARGET_USE_FANCY_MATH_387
15723 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15725 rtx mask = GEN_INT (0x0200);
15727 rtx scratch = gen_reg_rtx (HImode);
15729 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15730 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15734 ;; Block operation instructions
15737 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15740 [(set_attr "length" "1")
15741 (set_attr "length_immediate" "0")
15742 (set_attr "modrm" "0")])
15744 (define_expand "movmemsi"
15745 [(use (match_operand:BLK 0 "memory_operand" ""))
15746 (use (match_operand:BLK 1 "memory_operand" ""))
15747 (use (match_operand:SI 2 "nonmemory_operand" ""))
15748 (use (match_operand:SI 3 "const_int_operand" ""))
15749 (use (match_operand:SI 4 "const_int_operand" ""))
15750 (use (match_operand:SI 5 "const_int_operand" ""))]
15753 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15754 operands[4], operands[5]))
15760 (define_expand "movmemdi"
15761 [(use (match_operand:BLK 0 "memory_operand" ""))
15762 (use (match_operand:BLK 1 "memory_operand" ""))
15763 (use (match_operand:DI 2 "nonmemory_operand" ""))
15764 (use (match_operand:DI 3 "const_int_operand" ""))
15765 (use (match_operand:SI 4 "const_int_operand" ""))
15766 (use (match_operand:SI 5 "const_int_operand" ""))]
15769 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15770 operands[4], operands[5]))
15776 ;; Most CPUs don't like single string operations
15777 ;; Handle this case here to simplify previous expander.
15779 (define_expand "strmov"
15780 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15781 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15782 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15783 (clobber (reg:CC FLAGS_REG))])
15784 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15785 (clobber (reg:CC FLAGS_REG))])]
15788 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15790 /* If .md ever supports :P for Pmode, these can be directly
15791 in the pattern above. */
15792 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15793 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15795 /* Can't use this if the user has appropriated esi or edi. */
15796 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15797 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15799 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15800 operands[2], operands[3],
15801 operands[5], operands[6]));
15805 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15808 (define_expand "strmov_singleop"
15809 [(parallel [(set (match_operand 1 "memory_operand" "")
15810 (match_operand 3 "memory_operand" ""))
15811 (set (match_operand 0 "register_operand" "")
15812 (match_operand 4 "" ""))
15813 (set (match_operand 2 "register_operand" "")
15814 (match_operand 5 "" ""))])]
15816 "ix86_current_function_needs_cld = 1;")
15818 (define_insn "*strmovdi_rex_1"
15819 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15820 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15821 (set (match_operand:DI 0 "register_operand" "=D")
15822 (plus:DI (match_dup 2)
15824 (set (match_operand:DI 1 "register_operand" "=S")
15825 (plus:DI (match_dup 3)
15829 [(set_attr "type" "str")
15830 (set_attr "mode" "DI")
15831 (set_attr "memory" "both")])
15833 (define_insn "*strmovsi_1"
15834 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15835 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15836 (set (match_operand:SI 0 "register_operand" "=D")
15837 (plus:SI (match_dup 2)
15839 (set (match_operand:SI 1 "register_operand" "=S")
15840 (plus:SI (match_dup 3)
15844 [(set_attr "type" "str")
15845 (set_attr "mode" "SI")
15846 (set_attr "memory" "both")])
15848 (define_insn "*strmovsi_rex_1"
15849 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15850 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15851 (set (match_operand:DI 0 "register_operand" "=D")
15852 (plus:DI (match_dup 2)
15854 (set (match_operand:DI 1 "register_operand" "=S")
15855 (plus:DI (match_dup 3)
15859 [(set_attr "type" "str")
15860 (set_attr "mode" "SI")
15861 (set_attr "memory" "both")])
15863 (define_insn "*strmovhi_1"
15864 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15865 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15866 (set (match_operand:SI 0 "register_operand" "=D")
15867 (plus:SI (match_dup 2)
15869 (set (match_operand:SI 1 "register_operand" "=S")
15870 (plus:SI (match_dup 3)
15874 [(set_attr "type" "str")
15875 (set_attr "memory" "both")
15876 (set_attr "mode" "HI")])
15878 (define_insn "*strmovhi_rex_1"
15879 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15880 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15881 (set (match_operand:DI 0 "register_operand" "=D")
15882 (plus:DI (match_dup 2)
15884 (set (match_operand:DI 1 "register_operand" "=S")
15885 (plus:DI (match_dup 3)
15889 [(set_attr "type" "str")
15890 (set_attr "memory" "both")
15891 (set_attr "mode" "HI")])
15893 (define_insn "*strmovqi_1"
15894 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15895 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15896 (set (match_operand:SI 0 "register_operand" "=D")
15897 (plus:SI (match_dup 2)
15899 (set (match_operand:SI 1 "register_operand" "=S")
15900 (plus:SI (match_dup 3)
15904 [(set_attr "type" "str")
15905 (set_attr "memory" "both")
15906 (set_attr "mode" "QI")])
15908 (define_insn "*strmovqi_rex_1"
15909 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15910 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15911 (set (match_operand:DI 0 "register_operand" "=D")
15912 (plus:DI (match_dup 2)
15914 (set (match_operand:DI 1 "register_operand" "=S")
15915 (plus:DI (match_dup 3)
15919 [(set_attr "type" "str")
15920 (set_attr "memory" "both")
15921 (set_attr "prefix_rex" "0")
15922 (set_attr "mode" "QI")])
15924 (define_expand "rep_mov"
15925 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15926 (set (match_operand 0 "register_operand" "")
15927 (match_operand 5 "" ""))
15928 (set (match_operand 2 "register_operand" "")
15929 (match_operand 6 "" ""))
15930 (set (match_operand 1 "memory_operand" "")
15931 (match_operand 3 "memory_operand" ""))
15932 (use (match_dup 4))])]
15934 "ix86_current_function_needs_cld = 1;")
15936 (define_insn "*rep_movdi_rex64"
15937 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15938 (set (match_operand:DI 0 "register_operand" "=D")
15939 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15941 (match_operand:DI 3 "register_operand" "0")))
15942 (set (match_operand:DI 1 "register_operand" "=S")
15943 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15944 (match_operand:DI 4 "register_operand" "1")))
15945 (set (mem:BLK (match_dup 3))
15946 (mem:BLK (match_dup 4)))
15947 (use (match_dup 5))]
15950 [(set_attr "type" "str")
15951 (set_attr "prefix_rep" "1")
15952 (set_attr "memory" "both")
15953 (set_attr "mode" "DI")])
15955 (define_insn "*rep_movsi"
15956 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15957 (set (match_operand:SI 0 "register_operand" "=D")
15958 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15960 (match_operand:SI 3 "register_operand" "0")))
15961 (set (match_operand:SI 1 "register_operand" "=S")
15962 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15963 (match_operand:SI 4 "register_operand" "1")))
15964 (set (mem:BLK (match_dup 3))
15965 (mem:BLK (match_dup 4)))
15966 (use (match_dup 5))]
15969 [(set_attr "type" "str")
15970 (set_attr "prefix_rep" "1")
15971 (set_attr "memory" "both")
15972 (set_attr "mode" "SI")])
15974 (define_insn "*rep_movsi_rex64"
15975 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15976 (set (match_operand:DI 0 "register_operand" "=D")
15977 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15979 (match_operand:DI 3 "register_operand" "0")))
15980 (set (match_operand:DI 1 "register_operand" "=S")
15981 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15982 (match_operand:DI 4 "register_operand" "1")))
15983 (set (mem:BLK (match_dup 3))
15984 (mem:BLK (match_dup 4)))
15985 (use (match_dup 5))]
15988 [(set_attr "type" "str")
15989 (set_attr "prefix_rep" "1")
15990 (set_attr "memory" "both")
15991 (set_attr "mode" "SI")])
15993 (define_insn "*rep_movqi"
15994 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15995 (set (match_operand:SI 0 "register_operand" "=D")
15996 (plus:SI (match_operand:SI 3 "register_operand" "0")
15997 (match_operand:SI 5 "register_operand" "2")))
15998 (set (match_operand:SI 1 "register_operand" "=S")
15999 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16000 (set (mem:BLK (match_dup 3))
16001 (mem:BLK (match_dup 4)))
16002 (use (match_dup 5))]
16005 [(set_attr "type" "str")
16006 (set_attr "prefix_rep" "1")
16007 (set_attr "memory" "both")
16008 (set_attr "mode" "SI")])
16010 (define_insn "*rep_movqi_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 (match_operand:DI 3 "register_operand" "0")
16014 (match_operand:DI 5 "register_operand" "2")))
16015 (set (match_operand:DI 1 "register_operand" "=S")
16016 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16017 (set (mem:BLK (match_dup 3))
16018 (mem:BLK (match_dup 4)))
16019 (use (match_dup 5))]
16022 [(set_attr "type" "str")
16023 (set_attr "prefix_rep" "1")
16024 (set_attr "memory" "both")
16025 (set_attr "mode" "SI")])
16027 (define_expand "setmemsi"
16028 [(use (match_operand:BLK 0 "memory_operand" ""))
16029 (use (match_operand:SI 1 "nonmemory_operand" ""))
16030 (use (match_operand 2 "const_int_operand" ""))
16031 (use (match_operand 3 "const_int_operand" ""))
16032 (use (match_operand:SI 4 "const_int_operand" ""))
16033 (use (match_operand:SI 5 "const_int_operand" ""))]
16036 if (ix86_expand_setmem (operands[0], operands[1],
16037 operands[2], operands[3],
16038 operands[4], operands[5]))
16044 (define_expand "setmemdi"
16045 [(use (match_operand:BLK 0 "memory_operand" ""))
16046 (use (match_operand:DI 1 "nonmemory_operand" ""))
16047 (use (match_operand 2 "const_int_operand" ""))
16048 (use (match_operand 3 "const_int_operand" ""))
16049 (use (match_operand 4 "const_int_operand" ""))
16050 (use (match_operand 5 "const_int_operand" ""))]
16053 if (ix86_expand_setmem (operands[0], operands[1],
16054 operands[2], operands[3],
16055 operands[4], operands[5]))
16061 ;; Most CPUs don't like single string operations
16062 ;; Handle this case here to simplify previous expander.
16064 (define_expand "strset"
16065 [(set (match_operand 1 "memory_operand" "")
16066 (match_operand 2 "register_operand" ""))
16067 (parallel [(set (match_operand 0 "register_operand" "")
16069 (clobber (reg:CC FLAGS_REG))])]
16072 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16073 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16075 /* If .md ever supports :P for Pmode, this can be directly
16076 in the pattern above. */
16077 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16078 GEN_INT (GET_MODE_SIZE (GET_MODE
16080 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16082 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16088 (define_expand "strset_singleop"
16089 [(parallel [(set (match_operand 1 "memory_operand" "")
16090 (match_operand 2 "register_operand" ""))
16091 (set (match_operand 0 "register_operand" "")
16092 (match_operand 3 "" ""))])]
16094 "ix86_current_function_needs_cld = 1;")
16096 (define_insn "*strsetdi_rex_1"
16097 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16098 (match_operand:DI 2 "register_operand" "a"))
16099 (set (match_operand:DI 0 "register_operand" "=D")
16100 (plus:DI (match_dup 1)
16104 [(set_attr "type" "str")
16105 (set_attr "memory" "store")
16106 (set_attr "mode" "DI")])
16108 (define_insn "*strsetsi_1"
16109 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16110 (match_operand:SI 2 "register_operand" "a"))
16111 (set (match_operand:SI 0 "register_operand" "=D")
16112 (plus:SI (match_dup 1)
16116 [(set_attr "type" "str")
16117 (set_attr "memory" "store")
16118 (set_attr "mode" "SI")])
16120 (define_insn "*strsetsi_rex_1"
16121 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16122 (match_operand:SI 2 "register_operand" "a"))
16123 (set (match_operand:DI 0 "register_operand" "=D")
16124 (plus:DI (match_dup 1)
16128 [(set_attr "type" "str")
16129 (set_attr "memory" "store")
16130 (set_attr "mode" "SI")])
16132 (define_insn "*strsethi_1"
16133 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16134 (match_operand:HI 2 "register_operand" "a"))
16135 (set (match_operand:SI 0 "register_operand" "=D")
16136 (plus:SI (match_dup 1)
16140 [(set_attr "type" "str")
16141 (set_attr "memory" "store")
16142 (set_attr "mode" "HI")])
16144 (define_insn "*strsethi_rex_1"
16145 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16146 (match_operand:HI 2 "register_operand" "a"))
16147 (set (match_operand:DI 0 "register_operand" "=D")
16148 (plus:DI (match_dup 1)
16152 [(set_attr "type" "str")
16153 (set_attr "memory" "store")
16154 (set_attr "mode" "HI")])
16156 (define_insn "*strsetqi_1"
16157 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16158 (match_operand:QI 2 "register_operand" "a"))
16159 (set (match_operand:SI 0 "register_operand" "=D")
16160 (plus:SI (match_dup 1)
16164 [(set_attr "type" "str")
16165 (set_attr "memory" "store")
16166 (set_attr "mode" "QI")])
16168 (define_insn "*strsetqi_rex_1"
16169 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16170 (match_operand:QI 2 "register_operand" "a"))
16171 (set (match_operand:DI 0 "register_operand" "=D")
16172 (plus:DI (match_dup 1)
16176 [(set_attr "type" "str")
16177 (set_attr "memory" "store")
16178 (set_attr "prefix_rex" "0")
16179 (set_attr "mode" "QI")])
16181 (define_expand "rep_stos"
16182 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16183 (set (match_operand 0 "register_operand" "")
16184 (match_operand 4 "" ""))
16185 (set (match_operand 2 "memory_operand" "") (const_int 0))
16186 (use (match_operand 3 "register_operand" ""))
16187 (use (match_dup 1))])]
16189 "ix86_current_function_needs_cld = 1;")
16191 (define_insn "*rep_stosdi_rex64"
16192 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16193 (set (match_operand:DI 0 "register_operand" "=D")
16194 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16196 (match_operand:DI 3 "register_operand" "0")))
16197 (set (mem:BLK (match_dup 3))
16199 (use (match_operand:DI 2 "register_operand" "a"))
16200 (use (match_dup 4))]
16203 [(set_attr "type" "str")
16204 (set_attr "prefix_rep" "1")
16205 (set_attr "memory" "store")
16206 (set_attr "mode" "DI")])
16208 (define_insn "*rep_stossi"
16209 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16210 (set (match_operand:SI 0 "register_operand" "=D")
16211 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16213 (match_operand:SI 3 "register_operand" "0")))
16214 (set (mem:BLK (match_dup 3))
16216 (use (match_operand:SI 2 "register_operand" "a"))
16217 (use (match_dup 4))]
16220 [(set_attr "type" "str")
16221 (set_attr "prefix_rep" "1")
16222 (set_attr "memory" "store")
16223 (set_attr "mode" "SI")])
16225 (define_insn "*rep_stossi_rex64"
16226 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16227 (set (match_operand:DI 0 "register_operand" "=D")
16228 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16230 (match_operand:DI 3 "register_operand" "0")))
16231 (set (mem:BLK (match_dup 3))
16233 (use (match_operand:SI 2 "register_operand" "a"))
16234 (use (match_dup 4))]
16237 [(set_attr "type" "str")
16238 (set_attr "prefix_rep" "1")
16239 (set_attr "memory" "store")
16240 (set_attr "mode" "SI")])
16242 (define_insn "*rep_stosqi"
16243 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16244 (set (match_operand:SI 0 "register_operand" "=D")
16245 (plus:SI (match_operand:SI 3 "register_operand" "0")
16246 (match_operand:SI 4 "register_operand" "1")))
16247 (set (mem:BLK (match_dup 3))
16249 (use (match_operand:QI 2 "register_operand" "a"))
16250 (use (match_dup 4))]
16253 [(set_attr "type" "str")
16254 (set_attr "prefix_rep" "1")
16255 (set_attr "memory" "store")
16256 (set_attr "mode" "QI")])
16258 (define_insn "*rep_stosqi_rex64"
16259 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16260 (set (match_operand:DI 0 "register_operand" "=D")
16261 (plus:DI (match_operand:DI 3 "register_operand" "0")
16262 (match_operand:DI 4 "register_operand" "1")))
16263 (set (mem:BLK (match_dup 3))
16265 (use (match_operand:QI 2 "register_operand" "a"))
16266 (use (match_dup 4))]
16269 [(set_attr "type" "str")
16270 (set_attr "prefix_rep" "1")
16271 (set_attr "memory" "store")
16272 (set_attr "prefix_rex" "0")
16273 (set_attr "mode" "QI")])
16275 (define_expand "cmpstrnsi"
16276 [(set (match_operand:SI 0 "register_operand" "")
16277 (compare:SI (match_operand:BLK 1 "general_operand" "")
16278 (match_operand:BLK 2 "general_operand" "")))
16279 (use (match_operand 3 "general_operand" ""))
16280 (use (match_operand 4 "immediate_operand" ""))]
16283 rtx addr1, addr2, out, outlow, count, countreg, align;
16285 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16288 /* Can't use this if the user has appropriated esi or edi. */
16289 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
16294 out = gen_reg_rtx (SImode);
16296 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16297 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16298 if (addr1 != XEXP (operands[1], 0))
16299 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16300 if (addr2 != XEXP (operands[2], 0))
16301 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16303 count = operands[3];
16304 countreg = ix86_zero_extend_to_Pmode (count);
16306 /* %%% Iff we are testing strict equality, we can use known alignment
16307 to good advantage. This may be possible with combine, particularly
16308 once cc0 is dead. */
16309 align = operands[4];
16311 if (CONST_INT_P (count))
16313 if (INTVAL (count) == 0)
16315 emit_move_insn (operands[0], const0_rtx);
16318 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16319 operands[1], operands[2]));
16323 rtx (*cmp_insn)(rtx, rtx);
16326 cmp_insn = gen_cmpdi_1;
16328 cmp_insn = gen_cmpsi_1;
16329 emit_insn (cmp_insn (countreg, countreg));
16330 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16331 operands[1], operands[2]));
16334 outlow = gen_lowpart (QImode, out);
16335 emit_insn (gen_cmpintqi (outlow));
16336 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16338 if (operands[0] != out)
16339 emit_move_insn (operands[0], out);
16344 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16346 (define_expand "cmpintqi"
16347 [(set (match_dup 1)
16348 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16350 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16351 (parallel [(set (match_operand:QI 0 "register_operand" "")
16352 (minus:QI (match_dup 1)
16354 (clobber (reg:CC FLAGS_REG))])]
16356 "operands[1] = gen_reg_rtx (QImode);
16357 operands[2] = gen_reg_rtx (QImode);")
16359 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16360 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16362 (define_expand "cmpstrnqi_nz_1"
16363 [(parallel [(set (reg:CC FLAGS_REG)
16364 (compare:CC (match_operand 4 "memory_operand" "")
16365 (match_operand 5 "memory_operand" "")))
16366 (use (match_operand 2 "register_operand" ""))
16367 (use (match_operand:SI 3 "immediate_operand" ""))
16368 (clobber (match_operand 0 "register_operand" ""))
16369 (clobber (match_operand 1 "register_operand" ""))
16370 (clobber (match_dup 2))])]
16372 "ix86_current_function_needs_cld = 1;")
16374 (define_insn "*cmpstrnqi_nz_1"
16375 [(set (reg:CC FLAGS_REG)
16376 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16377 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16378 (use (match_operand:SI 6 "register_operand" "2"))
16379 (use (match_operand:SI 3 "immediate_operand" "i"))
16380 (clobber (match_operand:SI 0 "register_operand" "=S"))
16381 (clobber (match_operand:SI 1 "register_operand" "=D"))
16382 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16385 [(set_attr "type" "str")
16386 (set_attr "mode" "QI")
16387 (set_attr "prefix_rep" "1")])
16389 (define_insn "*cmpstrnqi_nz_rex_1"
16390 [(set (reg:CC FLAGS_REG)
16391 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16392 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16393 (use (match_operand:DI 6 "register_operand" "2"))
16394 (use (match_operand:SI 3 "immediate_operand" "i"))
16395 (clobber (match_operand:DI 0 "register_operand" "=S"))
16396 (clobber (match_operand:DI 1 "register_operand" "=D"))
16397 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16400 [(set_attr "type" "str")
16401 (set_attr "mode" "QI")
16402 (set_attr "prefix_rex" "0")
16403 (set_attr "prefix_rep" "1")])
16405 ;; The same, but the count is not known to not be zero.
16407 (define_expand "cmpstrnqi_1"
16408 [(parallel [(set (reg:CC FLAGS_REG)
16409 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16411 (compare:CC (match_operand 4 "memory_operand" "")
16412 (match_operand 5 "memory_operand" ""))
16414 (use (match_operand:SI 3 "immediate_operand" ""))
16415 (use (reg:CC FLAGS_REG))
16416 (clobber (match_operand 0 "register_operand" ""))
16417 (clobber (match_operand 1 "register_operand" ""))
16418 (clobber (match_dup 2))])]
16420 "ix86_current_function_needs_cld = 1;")
16422 (define_insn "*cmpstrnqi_1"
16423 [(set (reg:CC FLAGS_REG)
16424 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16426 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16427 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16429 (use (match_operand:SI 3 "immediate_operand" "i"))
16430 (use (reg:CC FLAGS_REG))
16431 (clobber (match_operand:SI 0 "register_operand" "=S"))
16432 (clobber (match_operand:SI 1 "register_operand" "=D"))
16433 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16436 [(set_attr "type" "str")
16437 (set_attr "mode" "QI")
16438 (set_attr "prefix_rep" "1")])
16440 (define_insn "*cmpstrnqi_rex_1"
16441 [(set (reg:CC FLAGS_REG)
16442 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16444 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16445 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16447 (use (match_operand:SI 3 "immediate_operand" "i"))
16448 (use (reg:CC FLAGS_REG))
16449 (clobber (match_operand:DI 0 "register_operand" "=S"))
16450 (clobber (match_operand:DI 1 "register_operand" "=D"))
16451 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16454 [(set_attr "type" "str")
16455 (set_attr "mode" "QI")
16456 (set_attr "prefix_rex" "0")
16457 (set_attr "prefix_rep" "1")])
16459 (define_expand "strlensi"
16460 [(set (match_operand:SI 0 "register_operand" "")
16461 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16462 (match_operand:QI 2 "immediate_operand" "")
16463 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16466 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16472 (define_expand "strlendi"
16473 [(set (match_operand:DI 0 "register_operand" "")
16474 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16475 (match_operand:QI 2 "immediate_operand" "")
16476 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16479 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16485 (define_expand "strlenqi_1"
16486 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16487 (clobber (match_operand 1 "register_operand" ""))
16488 (clobber (reg:CC FLAGS_REG))])]
16490 "ix86_current_function_needs_cld = 1;")
16492 (define_insn "*strlenqi_1"
16493 [(set (match_operand:SI 0 "register_operand" "=&c")
16494 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16495 (match_operand:QI 2 "register_operand" "a")
16496 (match_operand:SI 3 "immediate_operand" "i")
16497 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16498 (clobber (match_operand:SI 1 "register_operand" "=D"))
16499 (clobber (reg:CC FLAGS_REG))]
16502 [(set_attr "type" "str")
16503 (set_attr "mode" "QI")
16504 (set_attr "prefix_rep" "1")])
16506 (define_insn "*strlenqi_rex_1"
16507 [(set (match_operand:DI 0 "register_operand" "=&c")
16508 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16509 (match_operand:QI 2 "register_operand" "a")
16510 (match_operand:DI 3 "immediate_operand" "i")
16511 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16512 (clobber (match_operand:DI 1 "register_operand" "=D"))
16513 (clobber (reg:CC FLAGS_REG))]
16516 [(set_attr "type" "str")
16517 (set_attr "mode" "QI")
16518 (set_attr "prefix_rex" "0")
16519 (set_attr "prefix_rep" "1")])
16521 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16522 ;; handled in combine, but it is not currently up to the task.
16523 ;; When used for their truth value, the cmpstrn* expanders generate
16532 ;; The intermediate three instructions are unnecessary.
16534 ;; This one handles cmpstrn*_nz_1...
16537 (set (reg:CC FLAGS_REG)
16538 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16539 (mem:BLK (match_operand 5 "register_operand" ""))))
16540 (use (match_operand 6 "register_operand" ""))
16541 (use (match_operand:SI 3 "immediate_operand" ""))
16542 (clobber (match_operand 0 "register_operand" ""))
16543 (clobber (match_operand 1 "register_operand" ""))
16544 (clobber (match_operand 2 "register_operand" ""))])
16545 (set (match_operand:QI 7 "register_operand" "")
16546 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16547 (set (match_operand:QI 8 "register_operand" "")
16548 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16549 (set (reg FLAGS_REG)
16550 (compare (match_dup 7) (match_dup 8)))
16552 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16554 (set (reg:CC FLAGS_REG)
16555 (compare:CC (mem:BLK (match_dup 4))
16556 (mem:BLK (match_dup 5))))
16557 (use (match_dup 6))
16558 (use (match_dup 3))
16559 (clobber (match_dup 0))
16560 (clobber (match_dup 1))
16561 (clobber (match_dup 2))])]
16564 ;; ...and this one handles cmpstrn*_1.
16567 (set (reg:CC FLAGS_REG)
16568 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16570 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16571 (mem:BLK (match_operand 5 "register_operand" "")))
16573 (use (match_operand:SI 3 "immediate_operand" ""))
16574 (use (reg:CC FLAGS_REG))
16575 (clobber (match_operand 0 "register_operand" ""))
16576 (clobber (match_operand 1 "register_operand" ""))
16577 (clobber (match_operand 2 "register_operand" ""))])
16578 (set (match_operand:QI 7 "register_operand" "")
16579 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16580 (set (match_operand:QI 8 "register_operand" "")
16581 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16582 (set (reg FLAGS_REG)
16583 (compare (match_dup 7) (match_dup 8)))
16585 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16587 (set (reg:CC FLAGS_REG)
16588 (if_then_else:CC (ne (match_dup 6)
16590 (compare:CC (mem:BLK (match_dup 4))
16591 (mem:BLK (match_dup 5)))
16593 (use (match_dup 3))
16594 (use (reg:CC FLAGS_REG))
16595 (clobber (match_dup 0))
16596 (clobber (match_dup 1))
16597 (clobber (match_dup 2))])]
16602 ;; Conditional move instructions.
16604 (define_expand "mov<mode>cc"
16605 [(set (match_operand:SWIM 0 "register_operand" "")
16606 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16607 (match_operand:SWIM 2 "general_operand" "")
16608 (match_operand:SWIM 3 "general_operand" "")))]
16610 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16612 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16613 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16614 ;; So just document what we're doing explicitly.
16616 (define_expand "x86_mov<mode>cc_0_m1"
16618 [(set (match_operand:SWI48 0 "register_operand" "")
16619 (if_then_else:SWI48
16620 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16621 [(match_operand 1 "flags_reg_operand" "")
16625 (clobber (reg:CC FLAGS_REG))])]
16629 (define_insn "*x86_mov<mode>cc_0_m1"
16630 [(set (match_operand:SWI48 0 "register_operand" "=r")
16631 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16632 [(reg FLAGS_REG) (const_int 0)])
16635 (clobber (reg:CC FLAGS_REG))]
16637 "sbb{<imodesuffix>}\t%0, %0"
16638 ; Since we don't have the proper number of operands for an alu insn,
16639 ; fill in all the blanks.
16640 [(set_attr "type" "alu")
16641 (set_attr "use_carry" "1")
16642 (set_attr "pent_pair" "pu")
16643 (set_attr "memory" "none")
16644 (set_attr "imm_disp" "false")
16645 (set_attr "mode" "<MODE>")
16646 (set_attr "length_immediate" "0")])
16648 (define_insn "*x86_mov<mode>cc_0_m1_se"
16649 [(set (match_operand:SWI48 0 "register_operand" "=r")
16650 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16651 [(reg FLAGS_REG) (const_int 0)])
16654 (clobber (reg:CC FLAGS_REG))]
16656 "sbb{<imodesuffix>}\t%0, %0"
16657 [(set_attr "type" "alu")
16658 (set_attr "use_carry" "1")
16659 (set_attr "pent_pair" "pu")
16660 (set_attr "memory" "none")
16661 (set_attr "imm_disp" "false")
16662 (set_attr "mode" "<MODE>")
16663 (set_attr "length_immediate" "0")])
16665 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16666 [(set (match_operand:SWI48 0 "register_operand" "=r")
16667 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16668 [(reg FLAGS_REG) (const_int 0)])))]
16670 "sbb{<imodesuffix>}\t%0, %0"
16671 [(set_attr "type" "alu")
16672 (set_attr "use_carry" "1")
16673 (set_attr "pent_pair" "pu")
16674 (set_attr "memory" "none")
16675 (set_attr "imm_disp" "false")
16676 (set_attr "mode" "<MODE>")
16677 (set_attr "length_immediate" "0")])
16679 (define_insn "*mov<mode>cc_noc"
16680 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16681 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16682 [(reg FLAGS_REG) (const_int 0)])
16683 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16684 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16685 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16687 cmov%O2%C1\t{%2, %0|%0, %2}
16688 cmov%O2%c1\t{%3, %0|%0, %3}"
16689 [(set_attr "type" "icmov")
16690 (set_attr "mode" "<MODE>")])
16692 (define_insn_and_split "*movqicc_noc"
16693 [(set (match_operand:QI 0 "register_operand" "=r,r")
16694 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16695 [(match_operand 4 "flags_reg_operand" "")
16697 (match_operand:QI 2 "register_operand" "r,0")
16698 (match_operand:QI 3 "register_operand" "0,r")))]
16699 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16701 "&& reload_completed"
16702 [(set (match_dup 0)
16703 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16706 "operands[0] = gen_lowpart (SImode, operands[0]);
16707 operands[2] = gen_lowpart (SImode, operands[2]);
16708 operands[3] = gen_lowpart (SImode, operands[3]);"
16709 [(set_attr "type" "icmov")
16710 (set_attr "mode" "SI")])
16712 (define_expand "mov<mode>cc"
16713 [(set (match_operand:X87MODEF 0 "register_operand" "")
16714 (if_then_else:X87MODEF
16715 (match_operand 1 "ix86_fp_comparison_operator" "")
16716 (match_operand:X87MODEF 2 "register_operand" "")
16717 (match_operand:X87MODEF 3 "register_operand" "")))]
16718 "(TARGET_80387 && TARGET_CMOVE)
16719 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16720 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16722 (define_insn "*movsfcc_1_387"
16723 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16724 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16725 [(reg FLAGS_REG) (const_int 0)])
16726 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16727 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16728 "TARGET_80387 && TARGET_CMOVE
16729 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16731 fcmov%F1\t{%2, %0|%0, %2}
16732 fcmov%f1\t{%3, %0|%0, %3}
16733 cmov%O2%C1\t{%2, %0|%0, %2}
16734 cmov%O2%c1\t{%3, %0|%0, %3}"
16735 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16736 (set_attr "mode" "SF,SF,SI,SI")])
16738 (define_insn "*movdfcc_1"
16739 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16740 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16741 [(reg FLAGS_REG) (const_int 0)])
16742 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16743 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16744 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16745 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16747 fcmov%F1\t{%2, %0|%0, %2}
16748 fcmov%f1\t{%3, %0|%0, %3}
16751 [(set_attr "type" "fcmov,fcmov,multi,multi")
16752 (set_attr "mode" "DF")])
16754 (define_insn "*movdfcc_1_rex64"
16755 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16756 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16757 [(reg FLAGS_REG) (const_int 0)])
16758 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16759 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16760 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16761 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16763 fcmov%F1\t{%2, %0|%0, %2}
16764 fcmov%f1\t{%3, %0|%0, %3}
16765 cmov%O2%C1\t{%2, %0|%0, %2}
16766 cmov%O2%c1\t{%3, %0|%0, %3}"
16767 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16768 (set_attr "mode" "DF")])
16771 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16772 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16773 [(match_operand 4 "flags_reg_operand" "")
16775 (match_operand:DF 2 "nonimmediate_operand" "")
16776 (match_operand:DF 3 "nonimmediate_operand" "")))]
16777 "!TARGET_64BIT && reload_completed"
16778 [(set (match_dup 2)
16779 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16783 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16786 "split_di (&operands[2], 2, &operands[5], &operands[7]);
16787 split_di (&operands[0], 1, &operands[2], &operands[3]);")
16789 (define_insn "*movxfcc_1"
16790 [(set (match_operand:XF 0 "register_operand" "=f,f")
16791 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16792 [(reg FLAGS_REG) (const_int 0)])
16793 (match_operand:XF 2 "register_operand" "f,0")
16794 (match_operand:XF 3 "register_operand" "0,f")))]
16795 "TARGET_80387 && TARGET_CMOVE"
16797 fcmov%F1\t{%2, %0|%0, %2}
16798 fcmov%f1\t{%3, %0|%0, %3}"
16799 [(set_attr "type" "fcmov")
16800 (set_attr "mode" "XF")])
16802 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16803 ;; the scalar versions to have only XMM registers as operands.
16805 ;; XOP conditional move
16806 (define_insn "*xop_pcmov_<mode>"
16807 [(set (match_operand:MODEF 0 "register_operand" "=x")
16808 (if_then_else:MODEF
16809 (match_operand:MODEF 1 "register_operand" "x")
16810 (match_operand:MODEF 2 "register_operand" "x")
16811 (match_operand:MODEF 3 "register_operand" "x")))]
16813 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16814 [(set_attr "type" "sse4arg")])
16816 ;; These versions of the min/max patterns are intentionally ignorant of
16817 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16818 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16819 ;; are undefined in this condition, we're certain this is correct.
16821 (define_insn "*avx_<code><mode>3"
16822 [(set (match_operand:MODEF 0 "register_operand" "=x")
16824 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16825 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16826 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16827 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16828 [(set_attr "type" "sseadd")
16829 (set_attr "prefix" "vex")
16830 (set_attr "mode" "<MODE>")])
16832 (define_insn "<code><mode>3"
16833 [(set (match_operand:MODEF 0 "register_operand" "=x")
16835 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16836 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16837 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16838 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16839 [(set_attr "type" "sseadd")
16840 (set_attr "mode" "<MODE>")])
16842 ;; These versions of the min/max patterns implement exactly the operations
16843 ;; min = (op1 < op2 ? op1 : op2)
16844 ;; max = (!(op1 < op2) ? op1 : op2)
16845 ;; Their operands are not commutative, and thus they may be used in the
16846 ;; presence of -0.0 and NaN.
16848 (define_insn "*avx_ieee_smin<mode>3"
16849 [(set (match_operand:MODEF 0 "register_operand" "=x")
16851 [(match_operand:MODEF 1 "register_operand" "x")
16852 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16854 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16855 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16856 [(set_attr "type" "sseadd")
16857 (set_attr "prefix" "vex")
16858 (set_attr "mode" "<MODE>")])
16860 (define_insn "*ieee_smin<mode>3"
16861 [(set (match_operand:MODEF 0 "register_operand" "=x")
16863 [(match_operand:MODEF 1 "register_operand" "0")
16864 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16866 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16867 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16868 [(set_attr "type" "sseadd")
16869 (set_attr "mode" "<MODE>")])
16871 (define_insn "*avx_ieee_smax<mode>3"
16872 [(set (match_operand:MODEF 0 "register_operand" "=x")
16874 [(match_operand:MODEF 1 "register_operand" "0")
16875 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16877 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16878 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16879 [(set_attr "type" "sseadd")
16880 (set_attr "prefix" "vex")
16881 (set_attr "mode" "<MODE>")])
16883 (define_insn "*ieee_smax<mode>3"
16884 [(set (match_operand:MODEF 0 "register_operand" "=x")
16886 [(match_operand:MODEF 1 "register_operand" "0")
16887 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16889 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16890 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16891 [(set_attr "type" "sseadd")
16892 (set_attr "mode" "<MODE>")])
16894 ;; Make two stack loads independent:
16896 ;; fld %st(0) -> fld bb
16897 ;; fmul bb fmul %st(1), %st
16899 ;; Actually we only match the last two instructions for simplicity.
16901 [(set (match_operand 0 "fp_register_operand" "")
16902 (match_operand 1 "fp_register_operand" ""))
16904 (match_operator 2 "binary_fp_operator"
16906 (match_operand 3 "memory_operand" "")]))]
16907 "REGNO (operands[0]) != REGNO (operands[1])"
16908 [(set (match_dup 0) (match_dup 3))
16909 (set (match_dup 0) (match_dup 4))]
16911 ;; The % modifier is not operational anymore in peephole2's, so we have to
16912 ;; swap the operands manually in the case of addition and multiplication.
16913 "if (COMMUTATIVE_ARITH_P (operands[2]))
16914 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16915 operands[0], operands[1]);
16917 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16918 operands[1], operands[0]);")
16920 ;; Conditional addition patterns
16921 (define_expand "add<mode>cc"
16922 [(match_operand:SWI 0 "register_operand" "")
16923 (match_operand 1 "comparison_operator" "")
16924 (match_operand:SWI 2 "register_operand" "")
16925 (match_operand:SWI 3 "const_int_operand" "")]
16927 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16930 ;; Misc patterns (?)
16932 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16933 ;; Otherwise there will be nothing to keep
16935 ;; [(set (reg ebp) (reg esp))]
16936 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16937 ;; (clobber (eflags)]
16938 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16940 ;; in proper program order.
16941 (define_insn "pro_epilogue_adjust_stack_1"
16942 [(set (match_operand:SI 0 "register_operand" "=r,r")
16943 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16944 (match_operand:SI 2 "immediate_operand" "i,i")))
16945 (clobber (reg:CC FLAGS_REG))
16946 (clobber (mem:BLK (scratch)))]
16949 switch (get_attr_type (insn))
16952 return "mov{l}\t{%1, %0|%0, %1}";
16955 if (CONST_INT_P (operands[2])
16956 && (INTVAL (operands[2]) == 128
16957 || (INTVAL (operands[2]) < 0
16958 && INTVAL (operands[2]) != -128)))
16960 operands[2] = GEN_INT (-INTVAL (operands[2]));
16961 return "sub{l}\t{%2, %0|%0, %2}";
16963 return "add{l}\t{%2, %0|%0, %2}";
16966 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16967 return "lea{l}\t{%a2, %0|%0, %a2}";
16970 gcc_unreachable ();
16973 [(set (attr "type")
16974 (cond [(and (eq_attr "alternative" "0")
16975 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16976 (const_string "alu")
16977 (match_operand:SI 2 "const0_operand" "")
16978 (const_string "imov")
16980 (const_string "lea")))
16981 (set (attr "length_immediate")
16982 (cond [(eq_attr "type" "imov")
16984 (and (eq_attr "type" "alu")
16985 (match_operand 2 "const128_operand" ""))
16988 (const_string "*")))
16989 (set_attr "mode" "SI")])
16991 (define_insn "pro_epilogue_adjust_stack_rex64"
16992 [(set (match_operand:DI 0 "register_operand" "=r,r")
16993 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16994 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16995 (clobber (reg:CC FLAGS_REG))
16996 (clobber (mem:BLK (scratch)))]
16999 switch (get_attr_type (insn))
17002 return "mov{q}\t{%1, %0|%0, %1}";
17005 if (CONST_INT_P (operands[2])
17006 /* Avoid overflows. */
17007 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17008 && (INTVAL (operands[2]) == 128
17009 || (INTVAL (operands[2]) < 0
17010 && INTVAL (operands[2]) != -128)))
17012 operands[2] = GEN_INT (-INTVAL (operands[2]));
17013 return "sub{q}\t{%2, %0|%0, %2}";
17015 return "add{q}\t{%2, %0|%0, %2}";
17018 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17019 return "lea{q}\t{%a2, %0|%0, %a2}";
17022 gcc_unreachable ();
17025 [(set (attr "type")
17026 (cond [(and (eq_attr "alternative" "0")
17027 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
17028 (const_string "alu")
17029 (match_operand:DI 2 "const0_operand" "")
17030 (const_string "imov")
17032 (const_string "lea")))
17033 (set (attr "length_immediate")
17034 (cond [(eq_attr "type" "imov")
17036 (and (eq_attr "type" "alu")
17037 (match_operand 2 "const128_operand" ""))
17040 (const_string "*")))
17041 (set_attr "mode" "DI")])
17043 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17044 [(set (match_operand:DI 0 "register_operand" "=r,r")
17045 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17046 (match_operand:DI 3 "immediate_operand" "i,i")))
17047 (use (match_operand:DI 2 "register_operand" "r,r"))
17048 (clobber (reg:CC FLAGS_REG))
17049 (clobber (mem:BLK (scratch)))]
17052 switch (get_attr_type (insn))
17055 return "add{q}\t{%2, %0|%0, %2}";
17058 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17059 return "lea{q}\t{%a2, %0|%0, %a2}";
17062 gcc_unreachable ();
17065 [(set_attr "type" "alu,lea")
17066 (set_attr "mode" "DI")])
17068 (define_insn "allocate_stack_worker_32"
17069 [(set (match_operand:SI 0 "register_operand" "=a")
17070 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
17071 UNSPECV_STACK_PROBE))
17072 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
17073 (clobber (reg:CC FLAGS_REG))]
17074 "!TARGET_64BIT && TARGET_STACK_PROBE"
17076 [(set_attr "type" "multi")
17077 (set_attr "length" "5")])
17079 (define_insn "allocate_stack_worker_64"
17080 [(set (match_operand:DI 0 "register_operand" "=a")
17081 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
17082 UNSPECV_STACK_PROBE))
17083 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
17084 (clobber (reg:DI R10_REG))
17085 (clobber (reg:DI R11_REG))
17086 (clobber (reg:CC FLAGS_REG))]
17087 "TARGET_64BIT && TARGET_STACK_PROBE"
17089 [(set_attr "type" "multi")
17090 (set_attr "length" "5")])
17092 (define_expand "allocate_stack"
17093 [(match_operand 0 "register_operand" "")
17094 (match_operand 1 "general_operand" "")]
17095 "TARGET_STACK_PROBE"
17099 #ifndef CHECK_STACK_LIMIT
17100 #define CHECK_STACK_LIMIT 0
17103 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17104 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17106 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
17107 stack_pointer_rtx, 0, OPTAB_DIRECT);
17108 if (x != stack_pointer_rtx)
17109 emit_move_insn (stack_pointer_rtx, x);
17113 x = copy_to_mode_reg (Pmode, operands[1]);
17115 x = gen_allocate_stack_worker_64 (x, x);
17117 x = gen_allocate_stack_worker_32 (x, x);
17121 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17125 ;; Use IOR for stack probes, this is shorter.
17126 (define_expand "probe_stack"
17127 [(match_operand 0 "memory_operand" "")]
17130 if (GET_MODE (operands[0]) == DImode)
17131 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
17133 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
17137 (define_expand "builtin_setjmp_receiver"
17138 [(label_ref (match_operand 0 "" ""))]
17139 "!TARGET_64BIT && flag_pic"
17145 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
17146 rtx label_rtx = gen_label_rtx ();
17147 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17148 xops[0] = xops[1] = picreg;
17149 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17150 ix86_expand_binary_operator (MINUS, SImode, xops);
17154 emit_insn (gen_set_got (pic_offset_table_rtx));
17158 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17161 [(set (match_operand 0 "register_operand" "")
17162 (match_operator 3 "promotable_binary_operator"
17163 [(match_operand 1 "register_operand" "")
17164 (match_operand 2 "aligned_operand" "")]))
17165 (clobber (reg:CC FLAGS_REG))]
17166 "! TARGET_PARTIAL_REG_STALL && reload_completed
17167 && ((GET_MODE (operands[0]) == HImode
17168 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17169 /* ??? next two lines just !satisfies_constraint_K (...) */
17170 || !CONST_INT_P (operands[2])
17171 || satisfies_constraint_K (operands[2])))
17172 || (GET_MODE (operands[0]) == QImode
17173 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17174 [(parallel [(set (match_dup 0)
17175 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17176 (clobber (reg:CC FLAGS_REG))])]
17177 "operands[0] = gen_lowpart (SImode, operands[0]);
17178 operands[1] = gen_lowpart (SImode, operands[1]);
17179 if (GET_CODE (operands[3]) != ASHIFT)
17180 operands[2] = gen_lowpart (SImode, operands[2]);
17181 PUT_MODE (operands[3], SImode);")
17183 ; Promote the QImode tests, as i386 has encoding of the AND
17184 ; instruction with 32-bit sign-extended immediate and thus the
17185 ; instruction size is unchanged, except in the %eax case for
17186 ; which it is increased by one byte, hence the ! optimize_size.
17188 [(set (match_operand 0 "flags_reg_operand" "")
17189 (match_operator 2 "compare_operator"
17190 [(and (match_operand 3 "aligned_operand" "")
17191 (match_operand 4 "const_int_operand" ""))
17193 (set (match_operand 1 "register_operand" "")
17194 (and (match_dup 3) (match_dup 4)))]
17195 "! TARGET_PARTIAL_REG_STALL && reload_completed
17196 && optimize_insn_for_speed_p ()
17197 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17198 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17199 /* Ensure that the operand will remain sign-extended immediate. */
17200 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17201 [(parallel [(set (match_dup 0)
17202 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17205 (and:SI (match_dup 3) (match_dup 4)))])]
17208 = gen_int_mode (INTVAL (operands[4])
17209 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17210 operands[1] = gen_lowpart (SImode, operands[1]);
17211 operands[3] = gen_lowpart (SImode, operands[3]);
17214 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17215 ; the TEST instruction with 32-bit sign-extended immediate and thus
17216 ; the instruction size would at least double, which is not what we
17217 ; want even with ! optimize_size.
17219 [(set (match_operand 0 "flags_reg_operand" "")
17220 (match_operator 1 "compare_operator"
17221 [(and (match_operand:HI 2 "aligned_operand" "")
17222 (match_operand:HI 3 "const_int_operand" ""))
17224 "! TARGET_PARTIAL_REG_STALL && reload_completed
17225 && ! TARGET_FAST_PREFIX
17226 && optimize_insn_for_speed_p ()
17227 /* Ensure that the operand will remain sign-extended immediate. */
17228 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17229 [(set (match_dup 0)
17230 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17234 = gen_int_mode (INTVAL (operands[3])
17235 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17236 operands[2] = gen_lowpart (SImode, operands[2]);
17240 [(set (match_operand 0 "register_operand" "")
17241 (neg (match_operand 1 "register_operand" "")))
17242 (clobber (reg:CC FLAGS_REG))]
17243 "! TARGET_PARTIAL_REG_STALL && reload_completed
17244 && (GET_MODE (operands[0]) == HImode
17245 || (GET_MODE (operands[0]) == QImode
17246 && (TARGET_PROMOTE_QImode
17247 || optimize_insn_for_size_p ())))"
17248 [(parallel [(set (match_dup 0)
17249 (neg:SI (match_dup 1)))
17250 (clobber (reg:CC FLAGS_REG))])]
17251 "operands[0] = gen_lowpart (SImode, operands[0]);
17252 operands[1] = gen_lowpart (SImode, operands[1]);")
17255 [(set (match_operand 0 "register_operand" "")
17256 (not (match_operand 1 "register_operand" "")))]
17257 "! TARGET_PARTIAL_REG_STALL && reload_completed
17258 && (GET_MODE (operands[0]) == HImode
17259 || (GET_MODE (operands[0]) == QImode
17260 && (TARGET_PROMOTE_QImode
17261 || optimize_insn_for_size_p ())))"
17262 [(set (match_dup 0)
17263 (not:SI (match_dup 1)))]
17264 "operands[0] = gen_lowpart (SImode, operands[0]);
17265 operands[1] = gen_lowpart (SImode, operands[1]);")
17268 [(set (match_operand 0 "register_operand" "")
17269 (if_then_else (match_operator 1 "comparison_operator"
17270 [(reg FLAGS_REG) (const_int 0)])
17271 (match_operand 2 "register_operand" "")
17272 (match_operand 3 "register_operand" "")))]
17273 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17274 && (GET_MODE (operands[0]) == HImode
17275 || (GET_MODE (operands[0]) == QImode
17276 && (TARGET_PROMOTE_QImode
17277 || optimize_insn_for_size_p ())))"
17278 [(set (match_dup 0)
17279 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17280 "operands[0] = gen_lowpart (SImode, operands[0]);
17281 operands[2] = gen_lowpart (SImode, operands[2]);
17282 operands[3] = gen_lowpart (SImode, operands[3]);")
17285 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17286 ;; transform a complex memory operation into two memory to register operations.
17288 ;; Don't push memory operands
17290 [(set (match_operand:SI 0 "push_operand" "")
17291 (match_operand:SI 1 "memory_operand" ""))
17292 (match_scratch:SI 2 "r")]
17293 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17294 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17295 [(set (match_dup 2) (match_dup 1))
17296 (set (match_dup 0) (match_dup 2))]
17300 [(set (match_operand:DI 0 "push_operand" "")
17301 (match_operand:DI 1 "memory_operand" ""))
17302 (match_scratch:DI 2 "r")]
17303 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17304 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17305 [(set (match_dup 2) (match_dup 1))
17306 (set (match_dup 0) (match_dup 2))]
17309 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17312 [(set (match_operand:SF 0 "push_operand" "")
17313 (match_operand:SF 1 "memory_operand" ""))
17314 (match_scratch:SF 2 "r")]
17315 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17316 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17317 [(set (match_dup 2) (match_dup 1))
17318 (set (match_dup 0) (match_dup 2))]
17322 [(set (match_operand:HI 0 "push_operand" "")
17323 (match_operand:HI 1 "memory_operand" ""))
17324 (match_scratch:HI 2 "r")]
17325 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17326 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17327 [(set (match_dup 2) (match_dup 1))
17328 (set (match_dup 0) (match_dup 2))]
17332 [(set (match_operand:QI 0 "push_operand" "")
17333 (match_operand:QI 1 "memory_operand" ""))
17334 (match_scratch:QI 2 "q")]
17335 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17336 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17337 [(set (match_dup 2) (match_dup 1))
17338 (set (match_dup 0) (match_dup 2))]
17341 ;; Don't move an immediate directly to memory when the instruction
17344 [(match_scratch:SI 1 "r")
17345 (set (match_operand:SI 0 "memory_operand" "")
17347 "optimize_insn_for_speed_p ()
17348 && ! TARGET_USE_MOV0
17349 && TARGET_SPLIT_LONG_MOVES
17350 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17351 && peep2_regno_dead_p (0, FLAGS_REG)"
17352 [(parallel [(set (match_dup 1) (const_int 0))
17353 (clobber (reg:CC FLAGS_REG))])
17354 (set (match_dup 0) (match_dup 1))]
17358 [(match_scratch:HI 1 "r")
17359 (set (match_operand:HI 0 "memory_operand" "")
17361 "optimize_insn_for_speed_p ()
17362 && ! TARGET_USE_MOV0
17363 && TARGET_SPLIT_LONG_MOVES
17364 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17365 && peep2_regno_dead_p (0, FLAGS_REG)"
17366 [(parallel [(set (match_dup 2) (const_int 0))
17367 (clobber (reg:CC FLAGS_REG))])
17368 (set (match_dup 0) (match_dup 1))]
17369 "operands[2] = gen_lowpart (SImode, operands[1]);")
17372 [(match_scratch:QI 1 "q")
17373 (set (match_operand:QI 0 "memory_operand" "")
17375 "optimize_insn_for_speed_p ()
17376 && ! TARGET_USE_MOV0
17377 && TARGET_SPLIT_LONG_MOVES
17378 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17379 && peep2_regno_dead_p (0, FLAGS_REG)"
17380 [(parallel [(set (match_dup 2) (const_int 0))
17381 (clobber (reg:CC FLAGS_REG))])
17382 (set (match_dup 0) (match_dup 1))]
17383 "operands[2] = gen_lowpart (SImode, operands[1]);")
17386 [(match_scratch:SI 2 "r")
17387 (set (match_operand:SI 0 "memory_operand" "")
17388 (match_operand:SI 1 "immediate_operand" ""))]
17389 "optimize_insn_for_speed_p ()
17390 && TARGET_SPLIT_LONG_MOVES
17391 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17392 [(set (match_dup 2) (match_dup 1))
17393 (set (match_dup 0) (match_dup 2))]
17397 [(match_scratch:HI 2 "r")
17398 (set (match_operand:HI 0 "memory_operand" "")
17399 (match_operand:HI 1 "immediate_operand" ""))]
17400 "optimize_insn_for_speed_p ()
17401 && TARGET_SPLIT_LONG_MOVES
17402 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17403 [(set (match_dup 2) (match_dup 1))
17404 (set (match_dup 0) (match_dup 2))]
17408 [(match_scratch:QI 2 "q")
17409 (set (match_operand:QI 0 "memory_operand" "")
17410 (match_operand:QI 1 "immediate_operand" ""))]
17411 "optimize_insn_for_speed_p ()
17412 && TARGET_SPLIT_LONG_MOVES
17413 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17414 [(set (match_dup 2) (match_dup 1))
17415 (set (match_dup 0) (match_dup 2))]
17418 ;; Don't compare memory with zero, load and use a test instead.
17420 [(set (match_operand 0 "flags_reg_operand" "")
17421 (match_operator 1 "compare_operator"
17422 [(match_operand:SI 2 "memory_operand" "")
17424 (match_scratch:SI 3 "r")]
17425 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17426 [(set (match_dup 3) (match_dup 2))
17427 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17430 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17431 ;; Don't split NOTs with a displacement operand, because resulting XOR
17432 ;; will not be pairable anyway.
17434 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17435 ;; represented using a modRM byte. The XOR replacement is long decoded,
17436 ;; so this split helps here as well.
17438 ;; Note: Can't do this as a regular split because we can't get proper
17439 ;; lifetime information then.
17442 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17443 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17444 "optimize_insn_for_speed_p ()
17445 && ((TARGET_NOT_UNPAIRABLE
17446 && (!MEM_P (operands[0])
17447 || !memory_displacement_operand (operands[0], SImode)))
17448 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
17449 && peep2_regno_dead_p (0, FLAGS_REG)"
17450 [(parallel [(set (match_dup 0)
17451 (xor:SI (match_dup 1) (const_int -1)))
17452 (clobber (reg:CC FLAGS_REG))])]
17456 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17457 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17458 "optimize_insn_for_speed_p ()
17459 && ((TARGET_NOT_UNPAIRABLE
17460 && (!MEM_P (operands[0])
17461 || !memory_displacement_operand (operands[0], HImode)))
17462 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
17463 && peep2_regno_dead_p (0, FLAGS_REG)"
17464 [(parallel [(set (match_dup 0)
17465 (xor:HI (match_dup 1) (const_int -1)))
17466 (clobber (reg:CC FLAGS_REG))])]
17470 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17471 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17472 "optimize_insn_for_speed_p ()
17473 && ((TARGET_NOT_UNPAIRABLE
17474 && (!MEM_P (operands[0])
17475 || !memory_displacement_operand (operands[0], QImode)))
17476 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
17477 && peep2_regno_dead_p (0, FLAGS_REG)"
17478 [(parallel [(set (match_dup 0)
17479 (xor:QI (match_dup 1) (const_int -1)))
17480 (clobber (reg:CC FLAGS_REG))])]
17483 ;; Non pairable "test imm, reg" instructions can be translated to
17484 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17485 ;; byte opcode instead of two, have a short form for byte operands),
17486 ;; so do it for other CPUs as well. Given that the value was dead,
17487 ;; this should not create any new dependencies. Pass on the sub-word
17488 ;; versions if we're concerned about partial register stalls.
17491 [(set (match_operand 0 "flags_reg_operand" "")
17492 (match_operator 1 "compare_operator"
17493 [(and:SI (match_operand:SI 2 "register_operand" "")
17494 (match_operand:SI 3 "immediate_operand" ""))
17496 "ix86_match_ccmode (insn, CCNOmode)
17497 && (true_regnum (operands[2]) != AX_REG
17498 || satisfies_constraint_K (operands[3]))
17499 && peep2_reg_dead_p (1, operands[2])"
17501 [(set (match_dup 0)
17502 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17505 (and:SI (match_dup 2) (match_dup 3)))])]
17508 ;; We don't need to handle HImode case, because it will be promoted to SImode
17509 ;; on ! TARGET_PARTIAL_REG_STALL
17512 [(set (match_operand 0 "flags_reg_operand" "")
17513 (match_operator 1 "compare_operator"
17514 [(and:QI (match_operand:QI 2 "register_operand" "")
17515 (match_operand:QI 3 "immediate_operand" ""))
17517 "! TARGET_PARTIAL_REG_STALL
17518 && ix86_match_ccmode (insn, CCNOmode)
17519 && true_regnum (operands[2]) != AX_REG
17520 && peep2_reg_dead_p (1, operands[2])"
17522 [(set (match_dup 0)
17523 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17526 (and:QI (match_dup 2) (match_dup 3)))])]
17530 [(set (match_operand 0 "flags_reg_operand" "")
17531 (match_operator 1 "compare_operator"
17534 (match_operand 2 "ext_register_operand" "")
17537 (match_operand 3 "const_int_operand" ""))
17539 "! TARGET_PARTIAL_REG_STALL
17540 && ix86_match_ccmode (insn, CCNOmode)
17541 && true_regnum (operands[2]) != AX_REG
17542 && peep2_reg_dead_p (1, operands[2])"
17543 [(parallel [(set (match_dup 0)
17552 (set (zero_extract:SI (match_dup 2)
17563 ;; Don't do logical operations with memory inputs.
17565 [(match_scratch:SI 2 "r")
17566 (parallel [(set (match_operand:SI 0 "register_operand" "")
17567 (match_operator:SI 3 "arith_or_logical_operator"
17569 (match_operand:SI 1 "memory_operand" "")]))
17570 (clobber (reg:CC FLAGS_REG))])]
17571 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17572 [(set (match_dup 2) (match_dup 1))
17573 (parallel [(set (match_dup 0)
17574 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17575 (clobber (reg:CC FLAGS_REG))])]
17579 [(match_scratch:SI 2 "r")
17580 (parallel [(set (match_operand:SI 0 "register_operand" "")
17581 (match_operator:SI 3 "arith_or_logical_operator"
17582 [(match_operand:SI 1 "memory_operand" "")
17584 (clobber (reg:CC FLAGS_REG))])]
17585 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17586 [(set (match_dup 2) (match_dup 1))
17587 (parallel [(set (match_dup 0)
17588 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17589 (clobber (reg:CC FLAGS_REG))])]
17592 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17593 ;; refers to the destination of the load!
17596 [(set (match_operand:SI 0 "register_operand" "")
17597 (match_operand:SI 1 "register_operand" ""))
17598 (parallel [(set (match_dup 0)
17599 (match_operator:SI 3 "commutative_operator"
17601 (match_operand:SI 2 "memory_operand" "")]))
17602 (clobber (reg:CC FLAGS_REG))])]
17603 "REGNO (operands[0]) != REGNO (operands[1])
17604 && GENERAL_REGNO_P (REGNO (operands[0]))
17605 && GENERAL_REGNO_P (REGNO (operands[1]))"
17606 [(set (match_dup 0) (match_dup 4))
17607 (parallel [(set (match_dup 0)
17608 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17609 (clobber (reg:CC FLAGS_REG))])]
17610 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17613 [(set (match_operand 0 "register_operand" "")
17614 (match_operand 1 "register_operand" ""))
17616 (match_operator 3 "commutative_operator"
17618 (match_operand 2 "memory_operand" "")]))]
17619 "REGNO (operands[0]) != REGNO (operands[1])
17620 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17621 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17622 [(set (match_dup 0) (match_dup 2))
17624 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17627 ; Don't do logical operations with memory outputs
17629 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17630 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17631 ; the same decoder scheduling characteristics as the original.
17634 [(match_scratch:SI 2 "r")
17635 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17636 (match_operator:SI 3 "arith_or_logical_operator"
17638 (match_operand:SI 1 "nonmemory_operand" "")]))
17639 (clobber (reg:CC FLAGS_REG))])]
17640 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17641 /* Do not split stack checking probes. */
17642 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17643 [(set (match_dup 2) (match_dup 0))
17644 (parallel [(set (match_dup 2)
17645 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17646 (clobber (reg:CC FLAGS_REG))])
17647 (set (match_dup 0) (match_dup 2))]
17651 [(match_scratch:SI 2 "r")
17652 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17653 (match_operator:SI 3 "arith_or_logical_operator"
17654 [(match_operand:SI 1 "nonmemory_operand" "")
17656 (clobber (reg:CC FLAGS_REG))])]
17657 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17658 /* Do not split stack checking probes. */
17659 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17660 [(set (match_dup 2) (match_dup 0))
17661 (parallel [(set (match_dup 2)
17662 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17663 (clobber (reg:CC FLAGS_REG))])
17664 (set (match_dup 0) (match_dup 2))]
17667 ;; Attempt to always use XOR for zeroing registers.
17669 [(set (match_operand 0 "register_operand" "")
17670 (match_operand 1 "const0_operand" ""))]
17671 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17672 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17673 && GENERAL_REG_P (operands[0])
17674 && peep2_regno_dead_p (0, FLAGS_REG)"
17675 [(parallel [(set (match_dup 0) (const_int 0))
17676 (clobber (reg:CC FLAGS_REG))])]
17678 operands[0] = gen_lowpart (word_mode, operands[0]);
17682 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17684 "(GET_MODE (operands[0]) == QImode
17685 || GET_MODE (operands[0]) == HImode)
17686 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17687 && peep2_regno_dead_p (0, FLAGS_REG)"
17688 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17689 (clobber (reg:CC FLAGS_REG))])])
17691 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17693 [(set (match_operand 0 "register_operand" "")
17695 "(GET_MODE (operands[0]) == HImode
17696 || GET_MODE (operands[0]) == SImode
17697 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17698 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17699 && peep2_regno_dead_p (0, FLAGS_REG)"
17700 [(parallel [(set (match_dup 0) (const_int -1))
17701 (clobber (reg:CC FLAGS_REG))])]
17702 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17705 ;; Attempt to convert simple leas to adds. These can be created by
17708 [(set (match_operand:SI 0 "register_operand" "")
17709 (plus:SI (match_dup 0)
17710 (match_operand:SI 1 "nonmemory_operand" "")))]
17711 "peep2_regno_dead_p (0, FLAGS_REG)"
17712 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17713 (clobber (reg:CC FLAGS_REG))])]
17717 [(set (match_operand:SI 0 "register_operand" "")
17718 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17719 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17720 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17721 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17722 (clobber (reg:CC FLAGS_REG))])]
17723 "operands[2] = gen_lowpart (SImode, operands[2]);")
17726 [(set (match_operand:DI 0 "register_operand" "")
17727 (plus:DI (match_dup 0)
17728 (match_operand:DI 1 "x86_64_general_operand" "")))]
17729 "peep2_regno_dead_p (0, FLAGS_REG)"
17730 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17731 (clobber (reg:CC FLAGS_REG))])]
17735 [(set (match_operand:SI 0 "register_operand" "")
17736 (mult:SI (match_dup 0)
17737 (match_operand:SI 1 "const_int_operand" "")))]
17738 "exact_log2 (INTVAL (operands[1])) >= 0
17739 && peep2_regno_dead_p (0, FLAGS_REG)"
17740 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17741 (clobber (reg:CC FLAGS_REG))])]
17742 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17745 [(set (match_operand:DI 0 "register_operand" "")
17746 (mult:DI (match_dup 0)
17747 (match_operand:DI 1 "const_int_operand" "")))]
17748 "exact_log2 (INTVAL (operands[1])) >= 0
17749 && peep2_regno_dead_p (0, FLAGS_REG)"
17750 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17751 (clobber (reg:CC FLAGS_REG))])]
17752 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17755 [(set (match_operand:SI 0 "register_operand" "")
17756 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17757 (match_operand:DI 2 "const_int_operand" "")) 0))]
17758 "exact_log2 (INTVAL (operands[2])) >= 0
17759 && REGNO (operands[0]) == REGNO (operands[1])
17760 && peep2_regno_dead_p (0, FLAGS_REG)"
17761 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17762 (clobber (reg:CC FLAGS_REG))])]
17763 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17765 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17766 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17767 ;; many CPUs it is also faster, since special hardware to avoid esp
17768 ;; dependencies is present.
17770 ;; While some of these conversions may be done using splitters, we use peepholes
17771 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17773 ;; Convert prologue esp subtractions to push.
17774 ;; We need register to push. In order to keep verify_flow_info happy we have
17776 ;; - use scratch and clobber it in order to avoid dependencies
17777 ;; - use already live register
17778 ;; We can't use the second way right now, since there is no reliable way how to
17779 ;; verify that given register is live. First choice will also most likely in
17780 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17781 ;; call clobbered registers are dead. We may want to use base pointer as an
17782 ;; alternative when no register is available later.
17785 [(match_scratch:SI 0 "r")
17786 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17787 (clobber (reg:CC FLAGS_REG))
17788 (clobber (mem:BLK (scratch)))])]
17789 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17790 [(clobber (match_dup 0))
17791 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17792 (clobber (mem:BLK (scratch)))])])
17795 [(match_scratch:SI 0 "r")
17796 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17797 (clobber (reg:CC FLAGS_REG))
17798 (clobber (mem:BLK (scratch)))])]
17799 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17800 [(clobber (match_dup 0))
17801 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17802 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17803 (clobber (mem:BLK (scratch)))])])
17805 ;; Convert esp subtractions to push.
17807 [(match_scratch:SI 0 "r")
17808 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17809 (clobber (reg:CC FLAGS_REG))])]
17810 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17811 [(clobber (match_dup 0))
17812 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17815 [(match_scratch:SI 0 "r")
17816 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17817 (clobber (reg:CC FLAGS_REG))])]
17818 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17819 [(clobber (match_dup 0))
17820 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17821 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17823 ;; Convert epilogue deallocator to pop.
17825 [(match_scratch:SI 0 "r")
17826 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17827 (clobber (reg:CC FLAGS_REG))
17828 (clobber (mem:BLK (scratch)))])]
17829 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17830 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17831 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17832 (clobber (mem:BLK (scratch)))])]
17835 ;; Two pops case is tricky, since pop causes dependency on destination register.
17836 ;; We use two registers if available.
17838 [(match_scratch:SI 0 "r")
17839 (match_scratch:SI 1 "r")
17840 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17841 (clobber (reg:CC FLAGS_REG))
17842 (clobber (mem:BLK (scratch)))])]
17843 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17844 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17845 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17846 (clobber (mem:BLK (scratch)))])
17847 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17848 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17852 [(match_scratch:SI 0 "r")
17853 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17854 (clobber (reg:CC FLAGS_REG))
17855 (clobber (mem:BLK (scratch)))])]
17856 "optimize_insn_for_size_p ()"
17857 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17858 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17859 (clobber (mem:BLK (scratch)))])
17860 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17861 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17864 ;; Convert esp additions to pop.
17866 [(match_scratch:SI 0 "r")
17867 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17868 (clobber (reg:CC FLAGS_REG))])]
17870 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17871 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17874 ;; Two pops case is tricky, since pop causes dependency on destination register.
17875 ;; We use two registers if available.
17877 [(match_scratch:SI 0 "r")
17878 (match_scratch:SI 1 "r")
17879 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17880 (clobber (reg:CC FLAGS_REG))])]
17882 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17883 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17884 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17885 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
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 ()"
17893 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17894 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17895 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17896 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17899 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17900 ;; required and register dies. Similarly for 128 to -128.
17902 [(set (match_operand 0 "flags_reg_operand" "")
17903 (match_operator 1 "compare_operator"
17904 [(match_operand 2 "register_operand" "")
17905 (match_operand 3 "const_int_operand" "")]))]
17906 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17907 && incdec_operand (operands[3], GET_MODE (operands[3])))
17908 || (!TARGET_FUSE_CMP_AND_BRANCH
17909 && INTVAL (operands[3]) == 128))
17910 && ix86_match_ccmode (insn, CCGCmode)
17911 && peep2_reg_dead_p (1, operands[2])"
17912 [(parallel [(set (match_dup 0)
17913 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17914 (clobber (match_dup 2))])]
17918 [(match_scratch:DI 0 "r")
17919 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17920 (clobber (reg:CC FLAGS_REG))
17921 (clobber (mem:BLK (scratch)))])]
17922 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17923 [(clobber (match_dup 0))
17924 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17925 (clobber (mem:BLK (scratch)))])])
17928 [(match_scratch:DI 0 "r")
17929 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17930 (clobber (reg:CC FLAGS_REG))
17931 (clobber (mem:BLK (scratch)))])]
17932 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17933 [(clobber (match_dup 0))
17934 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17935 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17936 (clobber (mem:BLK (scratch)))])])
17938 ;; Convert esp subtractions to push.
17940 [(match_scratch:DI 0 "r")
17941 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17942 (clobber (reg:CC FLAGS_REG))])]
17943 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17944 [(clobber (match_dup 0))
17945 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17948 [(match_scratch:DI 0 "r")
17949 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17950 (clobber (reg:CC FLAGS_REG))])]
17951 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17952 [(clobber (match_dup 0))
17953 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17954 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17956 ;; Convert epilogue deallocator to pop.
17958 [(match_scratch:DI 0 "r")
17959 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17960 (clobber (reg:CC FLAGS_REG))
17961 (clobber (mem:BLK (scratch)))])]
17962 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17963 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17964 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17965 (clobber (mem:BLK (scratch)))])]
17968 ;; Two pops case is tricky, since pop causes dependency on destination register.
17969 ;; We use two registers if available.
17971 [(match_scratch:DI 0 "r")
17972 (match_scratch:DI 1 "r")
17973 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17974 (clobber (reg:CC FLAGS_REG))
17975 (clobber (mem:BLK (scratch)))])]
17976 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17977 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17978 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17979 (clobber (mem:BLK (scratch)))])
17980 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17981 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17985 [(match_scratch:DI 0 "r")
17986 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17987 (clobber (reg:CC FLAGS_REG))
17988 (clobber (mem:BLK (scratch)))])]
17989 "optimize_insn_for_size_p ()"
17990 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17991 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17992 (clobber (mem:BLK (scratch)))])
17993 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17994 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17997 ;; Convert esp additions to pop.
17999 [(match_scratch:DI 0 "r")
18000 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18001 (clobber (reg:CC FLAGS_REG))])]
18003 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18004 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18007 ;; Two pops case is tricky, since pop causes dependency on destination register.
18008 ;; We use two registers if available.
18010 [(match_scratch:DI 0 "r")
18011 (match_scratch:DI 1 "r")
18012 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18013 (clobber (reg:CC FLAGS_REG))])]
18015 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18016 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18017 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18018 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
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 ()"
18026 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18027 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18028 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18029 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18032 ;; Convert imul by three, five and nine into lea
18035 [(set (match_operand:SI 0 "register_operand" "")
18036 (mult:SI (match_operand:SI 1 "register_operand" "")
18037 (match_operand:SI 2 "const_int_operand" "")))
18038 (clobber (reg:CC FLAGS_REG))])]
18039 "INTVAL (operands[2]) == 3
18040 || INTVAL (operands[2]) == 5
18041 || INTVAL (operands[2]) == 9"
18042 [(set (match_dup 0)
18043 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
18045 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18049 [(set (match_operand:SI 0 "register_operand" "")
18050 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18051 (match_operand:SI 2 "const_int_operand" "")))
18052 (clobber (reg:CC FLAGS_REG))])]
18053 "optimize_insn_for_speed_p ()
18054 && (INTVAL (operands[2]) == 3
18055 || INTVAL (operands[2]) == 5
18056 || INTVAL (operands[2]) == 9)"
18057 [(set (match_dup 0) (match_dup 1))
18059 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
18061 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18065 [(set (match_operand:DI 0 "register_operand" "")
18066 (mult:DI (match_operand:DI 1 "register_operand" "")
18067 (match_operand:DI 2 "const_int_operand" "")))
18068 (clobber (reg:CC FLAGS_REG))])]
18070 && (INTVAL (operands[2]) == 3
18071 || INTVAL (operands[2]) == 5
18072 || INTVAL (operands[2]) == 9)"
18073 [(set (match_dup 0)
18074 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
18076 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18080 [(set (match_operand:DI 0 "register_operand" "")
18081 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18082 (match_operand:DI 2 "const_int_operand" "")))
18083 (clobber (reg:CC FLAGS_REG))])]
18085 && optimize_insn_for_speed_p ()
18086 && (INTVAL (operands[2]) == 3
18087 || INTVAL (operands[2]) == 5
18088 || INTVAL (operands[2]) == 9)"
18089 [(set (match_dup 0) (match_dup 1))
18091 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18093 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18095 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18096 ;; imul $32bit_imm, reg, reg is direct decoded.
18098 [(match_scratch:DI 3 "r")
18099 (parallel [(set (match_operand:DI 0 "register_operand" "")
18100 (mult:DI (match_operand:DI 1 "memory_operand" "")
18101 (match_operand:DI 2 "immediate_operand" "")))
18102 (clobber (reg:CC FLAGS_REG))])]
18103 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18104 && !satisfies_constraint_K (operands[2])"
18105 [(set (match_dup 3) (match_dup 1))
18106 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18107 (clobber (reg:CC FLAGS_REG))])]
18111 [(match_scratch:SI 3 "r")
18112 (parallel [(set (match_operand:SI 0 "register_operand" "")
18113 (mult:SI (match_operand:SI 1 "memory_operand" "")
18114 (match_operand:SI 2 "immediate_operand" "")))
18115 (clobber (reg:CC FLAGS_REG))])]
18116 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18117 && !satisfies_constraint_K (operands[2])"
18118 [(set (match_dup 3) (match_dup 1))
18119 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18120 (clobber (reg:CC FLAGS_REG))])]
18124 [(match_scratch:SI 3 "r")
18125 (parallel [(set (match_operand:DI 0 "register_operand" "")
18127 (mult:SI (match_operand:SI 1 "memory_operand" "")
18128 (match_operand:SI 2 "immediate_operand" ""))))
18129 (clobber (reg:CC FLAGS_REG))])]
18130 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18131 && !satisfies_constraint_K (operands[2])"
18132 [(set (match_dup 3) (match_dup 1))
18133 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18134 (clobber (reg:CC FLAGS_REG))])]
18137 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18138 ;; Convert it into imul reg, reg
18139 ;; It would be better to force assembler to encode instruction using long
18140 ;; immediate, but there is apparently no way to do so.
18142 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18143 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18144 (match_operand:DI 2 "const_int_operand" "")))
18145 (clobber (reg:CC FLAGS_REG))])
18146 (match_scratch:DI 3 "r")]
18147 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18148 && satisfies_constraint_K (operands[2])"
18149 [(set (match_dup 3) (match_dup 2))
18150 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18151 (clobber (reg:CC FLAGS_REG))])]
18153 if (!rtx_equal_p (operands[0], operands[1]))
18154 emit_move_insn (operands[0], operands[1]);
18158 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18159 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18160 (match_operand:SI 2 "const_int_operand" "")))
18161 (clobber (reg:CC FLAGS_REG))])
18162 (match_scratch:SI 3 "r")]
18163 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18164 && satisfies_constraint_K (operands[2])"
18165 [(set (match_dup 3) (match_dup 2))
18166 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18167 (clobber (reg:CC FLAGS_REG))])]
18169 if (!rtx_equal_p (operands[0], operands[1]))
18170 emit_move_insn (operands[0], operands[1]);
18174 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18175 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18176 (match_operand:HI 2 "immediate_operand" "")))
18177 (clobber (reg:CC FLAGS_REG))])
18178 (match_scratch:HI 3 "r")]
18179 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
18180 [(set (match_dup 3) (match_dup 2))
18181 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18182 (clobber (reg:CC FLAGS_REG))])]
18184 if (!rtx_equal_p (operands[0], operands[1]))
18185 emit_move_insn (operands[0], operands[1]);
18188 ;; After splitting up read-modify operations, array accesses with memory
18189 ;; operands might end up in form:
18191 ;; movl 4(%esp), %edx
18193 ;; instead of pre-splitting:
18195 ;; addl 4(%esp), %eax
18197 ;; movl 4(%esp), %edx
18198 ;; leal (%edx,%eax,4), %eax
18201 [(parallel [(set (match_operand 0 "register_operand" "")
18202 (ashift (match_operand 1 "register_operand" "")
18203 (match_operand 2 "const_int_operand" "")))
18204 (clobber (reg:CC FLAGS_REG))])
18205 (set (match_operand 3 "register_operand")
18206 (match_operand 4 "x86_64_general_operand" ""))
18207 (parallel [(set (match_operand 5 "register_operand" "")
18208 (plus (match_operand 6 "register_operand" "")
18209 (match_operand 7 "register_operand" "")))
18210 (clobber (reg:CC FLAGS_REG))])]
18211 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
18212 /* Validate MODE for lea. */
18213 && ((!TARGET_PARTIAL_REG_STALL
18214 && (GET_MODE (operands[0]) == QImode
18215 || GET_MODE (operands[0]) == HImode))
18216 || GET_MODE (operands[0]) == SImode
18217 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18218 /* We reorder load and the shift. */
18219 && !rtx_equal_p (operands[1], operands[3])
18220 && !reg_overlap_mentioned_p (operands[0], operands[4])
18221 /* Last PLUS must consist of operand 0 and 3. */
18222 && !rtx_equal_p (operands[0], operands[3])
18223 && (rtx_equal_p (operands[3], operands[6])
18224 || rtx_equal_p (operands[3], operands[7]))
18225 && (rtx_equal_p (operands[0], operands[6])
18226 || rtx_equal_p (operands[0], operands[7]))
18227 /* The intermediate operand 0 must die or be same as output. */
18228 && (rtx_equal_p (operands[0], operands[5])
18229 || peep2_reg_dead_p (3, operands[0]))"
18230 [(set (match_dup 3) (match_dup 4))
18231 (set (match_dup 0) (match_dup 1))]
18233 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
18234 int scale = 1 << INTVAL (operands[2]);
18235 rtx index = gen_lowpart (Pmode, operands[1]);
18236 rtx base = gen_lowpart (Pmode, operands[3]);
18237 rtx dest = gen_lowpart (mode, operands[5]);
18239 operands[1] = gen_rtx_PLUS (Pmode, base,
18240 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
18242 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18243 operands[0] = dest;
18246 ;; Call-value patterns last so that the wildcard operand does not
18247 ;; disrupt insn-recog's switch tables.
18249 (define_insn "*call_value_pop_0"
18250 [(set (match_operand 0 "" "")
18251 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18252 (match_operand:SI 2 "" "")))
18253 (set (reg:SI SP_REG)
18254 (plus:SI (reg:SI SP_REG)
18255 (match_operand:SI 3 "immediate_operand" "")))]
18258 if (SIBLING_CALL_P (insn))
18261 return "call\t%P1";
18263 [(set_attr "type" "callv")])
18265 (define_insn "*call_value_pop_1"
18266 [(set (match_operand 0 "" "")
18267 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18268 (match_operand:SI 2 "" "")))
18269 (set (reg:SI SP_REG)
18270 (plus:SI (reg:SI SP_REG)
18271 (match_operand:SI 3 "immediate_operand" "i")))]
18272 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18274 if (constant_call_address_operand (operands[1], Pmode))
18275 return "call\t%P1";
18276 return "call\t%A1";
18278 [(set_attr "type" "callv")])
18280 (define_insn "*sibcall_value_pop_1"
18281 [(set (match_operand 0 "" "")
18282 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18283 (match_operand:SI 2 "" "")))
18284 (set (reg:SI SP_REG)
18285 (plus:SI (reg:SI SP_REG)
18286 (match_operand:SI 3 "immediate_operand" "i,i")))]
18287 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18291 [(set_attr "type" "callv")])
18293 (define_insn "*call_value_0"
18294 [(set (match_operand 0 "" "")
18295 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18296 (match_operand:SI 2 "" "")))]
18299 if (SIBLING_CALL_P (insn))
18302 return "call\t%P1";
18304 [(set_attr "type" "callv")])
18306 (define_insn "*call_value_0_rex64"
18307 [(set (match_operand 0 "" "")
18308 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18309 (match_operand:DI 2 "const_int_operand" "")))]
18312 if (SIBLING_CALL_P (insn))
18315 return "call\t%P1";
18317 [(set_attr "type" "callv")])
18319 (define_insn "*call_value_0_rex64_ms_sysv"
18320 [(set (match_operand 0 "" "")
18321 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18322 (match_operand:DI 2 "const_int_operand" "")))
18323 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18324 (clobber (reg:TI XMM6_REG))
18325 (clobber (reg:TI XMM7_REG))
18326 (clobber (reg:TI XMM8_REG))
18327 (clobber (reg:TI XMM9_REG))
18328 (clobber (reg:TI XMM10_REG))
18329 (clobber (reg:TI XMM11_REG))
18330 (clobber (reg:TI XMM12_REG))
18331 (clobber (reg:TI XMM13_REG))
18332 (clobber (reg:TI XMM14_REG))
18333 (clobber (reg:TI XMM15_REG))
18334 (clobber (reg:DI SI_REG))
18335 (clobber (reg:DI DI_REG))]
18336 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18338 if (SIBLING_CALL_P (insn))
18341 return "call\t%P1";
18343 [(set_attr "type" "callv")])
18345 (define_insn "*call_value_1"
18346 [(set (match_operand 0 "" "")
18347 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18348 (match_operand:SI 2 "" "")))]
18349 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18351 if (constant_call_address_operand (operands[1], Pmode))
18352 return "call\t%P1";
18353 return "call\t%A1";
18355 [(set_attr "type" "callv")])
18357 (define_insn "*sibcall_value_1"
18358 [(set (match_operand 0 "" "")
18359 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18360 (match_operand:SI 2 "" "")))]
18361 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18365 [(set_attr "type" "callv")])
18367 (define_insn "*call_value_1_rex64"
18368 [(set (match_operand 0 "" "")
18369 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18370 (match_operand:DI 2 "" "")))]
18371 "TARGET_64BIT && !SIBLING_CALL_P (insn)
18372 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
18374 if (constant_call_address_operand (operands[1], Pmode))
18375 return "call\t%P1";
18376 return "call\t%A1";
18378 [(set_attr "type" "callv")])
18380 (define_insn "*call_value_1_rex64_ms_sysv"
18381 [(set (match_operand 0 "" "")
18382 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18383 (match_operand:DI 2 "" "")))
18384 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18385 (clobber (reg:TI XMM6_REG))
18386 (clobber (reg:TI XMM7_REG))
18387 (clobber (reg:TI XMM8_REG))
18388 (clobber (reg:TI XMM9_REG))
18389 (clobber (reg:TI XMM10_REG))
18390 (clobber (reg:TI XMM11_REG))
18391 (clobber (reg:TI XMM12_REG))
18392 (clobber (reg:TI XMM13_REG))
18393 (clobber (reg:TI XMM14_REG))
18394 (clobber (reg:TI XMM15_REG))
18395 (clobber (reg:DI SI_REG))
18396 (clobber (reg:DI DI_REG))]
18397 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18399 if (constant_call_address_operand (operands[1], Pmode))
18400 return "call\t%P1";
18401 return "call\t%A1";
18403 [(set_attr "type" "callv")])
18405 (define_insn "*call_value_1_rex64_large"
18406 [(set (match_operand 0 "" "")
18407 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
18408 (match_operand:DI 2 "" "")))]
18409 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18411 [(set_attr "type" "callv")])
18413 (define_insn "*sibcall_value_1_rex64"
18414 [(set (match_operand 0 "" "")
18415 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
18416 (match_operand:DI 2 "" "")))]
18417 "TARGET_64BIT && SIBLING_CALL_P (insn)"
18421 [(set_attr "type" "callv")])
18423 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18424 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18425 ;; caught for use by garbage collectors and the like. Using an insn that
18426 ;; maps to SIGILL makes it more likely the program will rightfully die.
18427 ;; Keeping with tradition, "6" is in honor of #UD.
18428 (define_insn "trap"
18429 [(trap_if (const_int 1) (const_int 6))]
18431 { return ASM_SHORT "0x0b0f"; }
18432 [(set_attr "length" "2")])
18434 (define_expand "sse_prologue_save"
18435 [(parallel [(set (match_operand:BLK 0 "" "")
18436 (unspec:BLK [(reg:DI XMM0_REG)
18443 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18444 (use (match_operand:DI 1 "register_operand" ""))
18445 (use (match_operand:DI 2 "immediate_operand" ""))
18446 (use (label_ref:DI (match_operand 3 "" "")))])]
18450 (define_insn "*sse_prologue_save_insn"
18451 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18452 (match_operand:DI 4 "const_int_operand" "n")))
18453 (unspec:BLK [(reg:DI XMM0_REG)
18460 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18461 (use (match_operand:DI 1 "register_operand" "r"))
18462 (use (match_operand:DI 2 "const_int_operand" "i"))
18463 (use (label_ref:DI (match_operand 3 "" "X")))]
18465 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18466 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
18469 operands[0] = gen_rtx_MEM (Pmode,
18470 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
18471 /* VEX instruction with a REX prefix will #UD. */
18472 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
18473 gcc_unreachable ();
18475 output_asm_insn ("jmp\t%A1", operands);
18476 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
18478 operands[4] = adjust_address (operands[0], DImode, i*16);
18479 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
18480 PUT_MODE (operands[4], TImode);
18481 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
18482 output_asm_insn ("rex", operands);
18483 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
18485 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18486 CODE_LABEL_NUMBER (operands[3]));
18489 [(set_attr "type" "other")
18490 (set_attr "length_immediate" "0")
18491 (set_attr "length_address" "0")
18492 (set (attr "length")
18494 (eq (symbol_ref "TARGET_AVX") (const_int 0))
18495 (const_string "34")
18496 (const_string "42")))
18497 (set_attr "memory" "store")
18498 (set_attr "modrm" "0")
18499 (set_attr "prefix" "maybe_vex")
18500 (set_attr "mode" "DI")])
18502 (define_expand "prefetch"
18503 [(prefetch (match_operand 0 "address_operand" "")
18504 (match_operand:SI 1 "const_int_operand" "")
18505 (match_operand:SI 2 "const_int_operand" ""))]
18506 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
18508 int rw = INTVAL (operands[1]);
18509 int locality = INTVAL (operands[2]);
18511 gcc_assert (rw == 0 || rw == 1);
18512 gcc_assert (locality >= 0 && locality <= 3);
18513 gcc_assert (GET_MODE (operands[0]) == Pmode
18514 || GET_MODE (operands[0]) == VOIDmode);
18516 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18517 supported by SSE counterpart or the SSE prefetch is not available
18518 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18520 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
18521 operands[2] = GEN_INT (3);
18523 operands[1] = const0_rtx;
18526 (define_insn "*prefetch_sse"
18527 [(prefetch (match_operand:SI 0 "address_operand" "p")
18529 (match_operand:SI 1 "const_int_operand" ""))]
18530 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
18532 static const char * const patterns[4] = {
18533 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18536 int locality = INTVAL (operands[1]);
18537 gcc_assert (locality >= 0 && locality <= 3);
18539 return patterns[locality];
18541 [(set_attr "type" "sse")
18542 (set_attr "atom_sse_attr" "prefetch")
18543 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18544 (set_attr "memory" "none")])
18546 (define_insn "*prefetch_sse_rex"
18547 [(prefetch (match_operand:DI 0 "address_operand" "p")
18549 (match_operand:SI 1 "const_int_operand" ""))]
18550 "TARGET_PREFETCH_SSE && TARGET_64BIT"
18552 static const char * const patterns[4] = {
18553 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18556 int locality = INTVAL (operands[1]);
18557 gcc_assert (locality >= 0 && locality <= 3);
18559 return patterns[locality];
18561 [(set_attr "type" "sse")
18562 (set_attr "atom_sse_attr" "prefetch")
18563 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18564 (set_attr "memory" "none")])
18566 (define_insn "*prefetch_3dnow"
18567 [(prefetch (match_operand:SI 0 "address_operand" "p")
18568 (match_operand:SI 1 "const_int_operand" "n")
18570 "TARGET_3DNOW && !TARGET_64BIT"
18572 if (INTVAL (operands[1]) == 0)
18573 return "prefetch\t%a0";
18575 return "prefetchw\t%a0";
18577 [(set_attr "type" "mmx")
18578 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18579 (set_attr "memory" "none")])
18581 (define_insn "*prefetch_3dnow_rex"
18582 [(prefetch (match_operand:DI 0 "address_operand" "p")
18583 (match_operand:SI 1 "const_int_operand" "n")
18585 "TARGET_3DNOW && TARGET_64BIT"
18587 if (INTVAL (operands[1]) == 0)
18588 return "prefetch\t%a0";
18590 return "prefetchw\t%a0";
18592 [(set_attr "type" "mmx")
18593 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18594 (set_attr "memory" "none")])
18596 (define_expand "stack_protect_set"
18597 [(match_operand 0 "memory_operand" "")
18598 (match_operand 1 "memory_operand" "")]
18601 #ifdef TARGET_THREAD_SSP_OFFSET
18603 emit_insn (gen_stack_tls_protect_set_di (operands[0],
18604 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18606 emit_insn (gen_stack_tls_protect_set_si (operands[0],
18607 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18610 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18612 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18617 (define_insn "stack_protect_set_si"
18618 [(set (match_operand:SI 0 "memory_operand" "=m")
18619 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18620 (set (match_scratch:SI 2 "=&r") (const_int 0))
18621 (clobber (reg:CC FLAGS_REG))]
18623 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18624 [(set_attr "type" "multi")])
18626 (define_insn "stack_protect_set_di"
18627 [(set (match_operand:DI 0 "memory_operand" "=m")
18628 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18629 (set (match_scratch:DI 2 "=&r") (const_int 0))
18630 (clobber (reg:CC FLAGS_REG))]
18632 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18633 [(set_attr "type" "multi")])
18635 (define_insn "stack_tls_protect_set_si"
18636 [(set (match_operand:SI 0 "memory_operand" "=m")
18637 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18638 (set (match_scratch:SI 2 "=&r") (const_int 0))
18639 (clobber (reg:CC FLAGS_REG))]
18641 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18642 [(set_attr "type" "multi")])
18644 (define_insn "stack_tls_protect_set_di"
18645 [(set (match_operand:DI 0 "memory_operand" "=m")
18646 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18647 (set (match_scratch:DI 2 "=&r") (const_int 0))
18648 (clobber (reg:CC FLAGS_REG))]
18651 /* The kernel uses a different segment register for performance reasons; a
18652 system call would not have to trash the userspace segment register,
18653 which would be expensive */
18654 if (ix86_cmodel != CM_KERNEL)
18655 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18657 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18659 [(set_attr "type" "multi")])
18661 (define_expand "stack_protect_test"
18662 [(match_operand 0 "memory_operand" "")
18663 (match_operand 1 "memory_operand" "")
18664 (match_operand 2 "" "")]
18667 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18669 #ifdef TARGET_THREAD_SSP_OFFSET
18671 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18672 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18674 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18675 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18678 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18680 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18683 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18684 flags, const0_rtx, operands[2]));
18688 (define_insn "stack_protect_test_si"
18689 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18690 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18691 (match_operand:SI 2 "memory_operand" "m")]
18693 (clobber (match_scratch:SI 3 "=&r"))]
18695 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18696 [(set_attr "type" "multi")])
18698 (define_insn "stack_protect_test_di"
18699 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18700 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18701 (match_operand:DI 2 "memory_operand" "m")]
18703 (clobber (match_scratch:DI 3 "=&r"))]
18705 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18706 [(set_attr "type" "multi")])
18708 (define_insn "stack_tls_protect_test_si"
18709 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18710 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18711 (match_operand:SI 2 "const_int_operand" "i")]
18712 UNSPEC_SP_TLS_TEST))
18713 (clobber (match_scratch:SI 3 "=r"))]
18715 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18716 [(set_attr "type" "multi")])
18718 (define_insn "stack_tls_protect_test_di"
18719 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18720 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18721 (match_operand:DI 2 "const_int_operand" "i")]
18722 UNSPEC_SP_TLS_TEST))
18723 (clobber (match_scratch:DI 3 "=r"))]
18726 /* The kernel uses a different segment register for performance reasons; a
18727 system call would not have to trash the userspace segment register,
18728 which would be expensive */
18729 if (ix86_cmodel != CM_KERNEL)
18730 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18732 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18734 [(set_attr "type" "multi")])
18736 (define_insn "sse4_2_crc32<mode>"
18737 [(set (match_operand:SI 0 "register_operand" "=r")
18739 [(match_operand:SI 1 "register_operand" "0")
18740 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18742 "TARGET_SSE4_2 || TARGET_CRC32"
18743 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18744 [(set_attr "type" "sselog1")
18745 (set_attr "prefix_rep" "1")
18746 (set_attr "prefix_extra" "1")
18747 (set (attr "prefix_data16")
18748 (if_then_else (match_operand:HI 2 "" "")
18750 (const_string "*")))
18751 (set (attr "prefix_rex")
18752 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18754 (const_string "*")))
18755 (set_attr "mode" "SI")])
18757 (define_insn "sse4_2_crc32di"
18758 [(set (match_operand:DI 0 "register_operand" "=r")
18760 [(match_operand:DI 1 "register_operand" "0")
18761 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18763 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18764 "crc32{q}\t{%2, %0|%0, %2}"
18765 [(set_attr "type" "sselog1")
18766 (set_attr "prefix_rep" "1")
18767 (set_attr "prefix_extra" "1")
18768 (set_attr "mode" "DI")])
18770 (define_expand "rdpmc"
18771 [(match_operand:DI 0 "register_operand" "")
18772 (match_operand:SI 1 "register_operand" "")]
18775 rtx reg = gen_reg_rtx (DImode);
18778 /* Force operand 1 into ECX. */
18779 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18780 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18781 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18786 rtvec vec = rtvec_alloc (2);
18787 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18788 rtx upper = gen_reg_rtx (DImode);
18789 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18790 gen_rtvec (1, const0_rtx),
18792 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18793 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18795 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18796 NULL, 1, OPTAB_DIRECT);
18797 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18801 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18802 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18806 (define_insn "*rdpmc"
18807 [(set (match_operand:DI 0 "register_operand" "=A")
18808 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18812 [(set_attr "type" "other")
18813 (set_attr "length" "2")])
18815 (define_insn "*rdpmc_rex64"
18816 [(set (match_operand:DI 0 "register_operand" "=a")
18817 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18819 (set (match_operand:DI 1 "register_operand" "=d")
18820 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18823 [(set_attr "type" "other")
18824 (set_attr "length" "2")])
18826 (define_expand "rdtsc"
18827 [(set (match_operand:DI 0 "register_operand" "")
18828 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18833 rtvec vec = rtvec_alloc (2);
18834 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18835 rtx upper = gen_reg_rtx (DImode);
18836 rtx lower = gen_reg_rtx (DImode);
18837 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18838 gen_rtvec (1, const0_rtx),
18840 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18841 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18843 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18844 NULL, 1, OPTAB_DIRECT);
18845 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18847 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18852 (define_insn "*rdtsc"
18853 [(set (match_operand:DI 0 "register_operand" "=A")
18854 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18857 [(set_attr "type" "other")
18858 (set_attr "length" "2")])
18860 (define_insn "*rdtsc_rex64"
18861 [(set (match_operand:DI 0 "register_operand" "=a")
18862 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18863 (set (match_operand:DI 1 "register_operand" "=d")
18864 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18867 [(set_attr "type" "other")
18868 (set_attr "length" "2")])
18870 (define_expand "rdtscp"
18871 [(match_operand:DI 0 "register_operand" "")
18872 (match_operand:SI 1 "memory_operand" "")]
18875 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18876 gen_rtvec (1, const0_rtx),
18878 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18879 gen_rtvec (1, const0_rtx),
18881 rtx reg = gen_reg_rtx (DImode);
18882 rtx tmp = gen_reg_rtx (SImode);
18886 rtvec vec = rtvec_alloc (3);
18887 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18888 rtx upper = gen_reg_rtx (DImode);
18889 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18890 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18891 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18893 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18894 NULL, 1, OPTAB_DIRECT);
18895 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18900 rtvec vec = rtvec_alloc (2);
18901 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18902 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18903 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18906 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18907 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18911 (define_insn "*rdtscp"
18912 [(set (match_operand:DI 0 "register_operand" "=A")
18913 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18914 (set (match_operand:SI 1 "register_operand" "=c")
18915 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18918 [(set_attr "type" "other")
18919 (set_attr "length" "3")])
18921 (define_insn "*rdtscp_rex64"
18922 [(set (match_operand:DI 0 "register_operand" "=a")
18923 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18924 (set (match_operand:DI 1 "register_operand" "=d")
18925 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18926 (set (match_operand:SI 2 "register_operand" "=c")
18927 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18930 [(set_attr "type" "other")
18931 (set_attr "length" "3")])
18933 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18935 ;; LWP instructions
18937 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18939 (define_expand "lwp_llwpcb"
18940 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18941 UNSPECV_LLWP_INTRINSIC)]
18945 (define_insn "*lwp_llwpcb<mode>1"
18946 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18947 UNSPECV_LLWP_INTRINSIC)]
18950 [(set_attr "type" "lwp")
18951 (set_attr "mode" "<MODE>")
18952 (set_attr "length" "5")])
18954 (define_expand "lwp_slwpcb"
18955 [(set (match_operand 0 "register_operand" "=r")
18956 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18960 emit_insn (gen_lwp_slwpcbdi (operands[0]));
18962 emit_insn (gen_lwp_slwpcbsi (operands[0]));
18966 (define_insn "lwp_slwpcb<mode>"
18967 [(set (match_operand:P 0 "register_operand" "=r")
18968 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18971 [(set_attr "type" "lwp")
18972 (set_attr "mode" "<MODE>")
18973 (set_attr "length" "5")])
18975 (define_expand "lwp_lwpval<mode>3"
18976 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18977 (match_operand:SI 2 "nonimmediate_operand" "rm")
18978 (match_operand:SI 3 "const_int_operand" "i")]
18979 UNSPECV_LWPVAL_INTRINSIC)]
18981 "/* Avoid unused variable warning. */
18984 (define_insn "*lwp_lwpval<mode>3_1"
18985 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18986 (match_operand:SI 1 "nonimmediate_operand" "rm")
18987 (match_operand:SI 2 "const_int_operand" "i")]
18988 UNSPECV_LWPVAL_INTRINSIC)]
18990 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18991 [(set_attr "type" "lwp")
18992 (set_attr "mode" "<MODE>")
18993 (set (attr "length")
18994 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18996 (define_expand "lwp_lwpins<mode>3"
18997 [(set (reg:CCC FLAGS_REG)
18998 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18999 (match_operand:SI 2 "nonimmediate_operand" "rm")
19000 (match_operand:SI 3 "const_int_operand" "i")]
19001 UNSPECV_LWPINS_INTRINSIC))
19002 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
19003 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19007 (define_insn "*lwp_lwpins<mode>3_1"
19008 [(set (reg:CCC FLAGS_REG)
19009 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19010 (match_operand:SI 1 "nonimmediate_operand" "rm")
19011 (match_operand:SI 2 "const_int_operand" "i")]
19012 UNSPECV_LWPINS_INTRINSIC))]
19014 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19015 [(set_attr "type" "lwp")
19016 (set_attr "mode" "<MODE>")
19017 (set (attr "length")
19018 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19022 (include "sync.md")