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 maxminiprefix [(smax "maxs") (smin "mins")
717 (umax "maxu") (umin "minu")])
718 (define_code_attr maxminfprefix [(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 logicprefix [(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 abs neg operators
737 (define_code_iterator absneg [abs neg])
739 ;; Base name for x87 insn mnemonic.
740 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
742 ;; Used in signed and unsigned widening multiplications.
743 (define_code_iterator any_extend [sign_extend zero_extend])
745 ;; Various insn prefixes for signed and unsigned operations.
746 (define_code_attr u [(sign_extend "") (zero_extend "u")
747 (div "") (udiv "u")])
748 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
750 ;; Used in signed and unsigned divisions.
751 (define_code_iterator any_div [div udiv])
753 ;; Instruction prefix for signed and unsigned operations.
754 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
755 (div "i") (udiv "")])
757 ;; All single word integer modes.
758 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
760 ;; Single word integer modes without DImode.
761 (define_mode_iterator SWI124 [QI HI SI])
763 ;; Single word integer modes without QImode.
764 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
766 ;; Single word integer modes without QImode and HImode.
767 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
769 ;; All math-dependant single and double word integer modes.
770 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
771 (HI "TARGET_HIMODE_MATH")
772 SI DI (TI "TARGET_64BIT")])
774 ;; Math-dependant single word integer modes.
775 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
776 (HI "TARGET_HIMODE_MATH")
777 SI (DI "TARGET_64BIT")])
779 ;; Math-dependant single word integer modes without QImode.
780 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
781 SI (DI "TARGET_64BIT")])
783 ;; Double word integer modes.
784 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
785 (TI "TARGET_64BIT")])
787 ;; Double word integer modes as mode attribute.
788 (define_mode_attr DWI [(SI "DI") (DI "TI")])
789 (define_mode_attr dwi [(SI "di") (DI "ti")])
791 ;; Half mode for double word integer modes.
792 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
793 (DI "TARGET_64BIT")])
795 ;; Instruction suffix for integer modes.
796 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
798 ;; Register class for integer modes.
799 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
801 ;; Immediate operand constraint for integer modes.
802 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
804 ;; General operand constraint for word modes.
805 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
807 ;; Immediate operand constraint for double integer modes.
808 (define_mode_attr di [(SI "iF") (DI "e")])
810 ;; Immediate operand constraint for shifts.
811 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
813 ;; General operand predicate for integer modes.
814 (define_mode_attr general_operand
815 [(QI "general_operand")
816 (HI "general_operand")
817 (SI "general_operand")
818 (DI "x86_64_general_operand")
819 (TI "x86_64_general_operand")])
821 ;; General sign/zero extend operand predicate for integer modes.
822 (define_mode_attr general_szext_operand
823 [(QI "general_operand")
824 (HI "general_operand")
825 (SI "general_operand")
826 (DI "x86_64_szext_general_operand")])
828 ;; Operand predicate for shifts.
829 (define_mode_attr shift_operand
830 [(QI "nonimmediate_operand")
831 (HI "nonimmediate_operand")
832 (SI "nonimmediate_operand")
833 (DI "shiftdi_operand")
834 (TI "register_operand")])
836 ;; Operand predicate for shift argument.
837 (define_mode_attr shift_immediate_operand
838 [(QI "const_1_to_31_operand")
839 (HI "const_1_to_31_operand")
840 (SI "const_1_to_31_operand")
841 (DI "const_1_to_63_operand")])
843 ;; Input operand predicate for arithmetic left shifts.
844 (define_mode_attr ashl_input_operand
845 [(QI "nonimmediate_operand")
846 (HI "nonimmediate_operand")
847 (SI "nonimmediate_operand")
848 (DI "ashldi_input_operand")
849 (TI "reg_or_pm1_operand")])
851 ;; SSE and x87 SFmode and DFmode floating point modes
852 (define_mode_iterator MODEF [SF DF])
854 ;; All x87 floating point modes
855 (define_mode_iterator X87MODEF [SF DF XF])
857 ;; All integer modes handled by x87 fisttp operator.
858 (define_mode_iterator X87MODEI [HI SI DI])
860 ;; All integer modes handled by integer x87 operators.
861 (define_mode_iterator X87MODEI12 [HI SI])
863 ;; All integer modes handled by SSE cvtts?2si* operators.
864 (define_mode_iterator SSEMODEI24 [SI DI])
866 ;; SSE asm suffix for floating point modes
867 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
869 ;; SSE vector mode corresponding to a scalar mode
870 (define_mode_attr ssevecmode
871 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
873 ;; Instruction suffix for REX 64bit operators.
874 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
876 ;; This mode iterator allows :P to be used for patterns that operate on
877 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
878 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
880 ;; Scheduling descriptions
882 (include "pentium.md")
885 (include "athlon.md")
890 ;; Operand and operator predicates and constraints
892 (include "predicates.md")
893 (include "constraints.md")
896 ;; Compare and branch/compare and store instructions.
898 (define_expand "cbranch<mode>4"
899 [(set (reg:CC FLAGS_REG)
900 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
901 (match_operand:SDWIM 2 "<general_operand>" "")))
902 (set (pc) (if_then_else
903 (match_operator 0 "comparison_operator"
904 [(reg:CC FLAGS_REG) (const_int 0)])
905 (label_ref (match_operand 3 "" ""))
909 if (MEM_P (operands[1]) && MEM_P (operands[2]))
910 operands[1] = force_reg (<MODE>mode, operands[1]);
911 ix86_compare_op0 = operands[1];
912 ix86_compare_op1 = operands[2];
913 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
917 (define_expand "cstore<mode>4"
918 [(set (reg:CC FLAGS_REG)
919 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
920 (match_operand:SWIM 3 "<general_operand>" "")))
921 (set (match_operand:QI 0 "register_operand" "")
922 (match_operator 1 "comparison_operator"
923 [(reg:CC FLAGS_REG) (const_int 0)]))]
926 if (MEM_P (operands[2]) && MEM_P (operands[3]))
927 operands[2] = force_reg (<MODE>mode, operands[2]);
928 ix86_compare_op0 = operands[2];
929 ix86_compare_op1 = operands[3];
930 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
934 (define_expand "cmp<mode>_1"
935 [(set (reg:CC FLAGS_REG)
936 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
937 (match_operand:SWI48 1 "<general_operand>" "")))]
941 (define_insn "*cmp<mode>_ccno_1"
942 [(set (reg FLAGS_REG)
943 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
944 (match_operand:SWI 1 "const0_operand" "")))]
945 "ix86_match_ccmode (insn, CCNOmode)"
947 test{<imodesuffix>}\t%0, %0
948 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
949 [(set_attr "type" "test,icmp")
950 (set_attr "length_immediate" "0,1")
951 (set_attr "mode" "<MODE>")])
953 (define_insn "*cmp<mode>_1"
954 [(set (reg FLAGS_REG)
955 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
956 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
957 "ix86_match_ccmode (insn, CCmode)"
958 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
959 [(set_attr "type" "icmp")
960 (set_attr "mode" "<MODE>")])
962 (define_insn "*cmp<mode>_minus_1"
963 [(set (reg FLAGS_REG)
965 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
966 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
968 "ix86_match_ccmode (insn, CCGOCmode)"
969 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
970 [(set_attr "type" "icmp")
971 (set_attr "mode" "<MODE>")])
973 (define_insn "*cmpqi_ext_1"
974 [(set (reg FLAGS_REG)
976 (match_operand:QI 0 "general_operand" "Qm")
979 (match_operand 1 "ext_register_operand" "Q")
982 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
983 "cmp{b}\t{%h1, %0|%0, %h1}"
984 [(set_attr "type" "icmp")
985 (set_attr "mode" "QI")])
987 (define_insn "*cmpqi_ext_1_rex64"
988 [(set (reg FLAGS_REG)
990 (match_operand:QI 0 "register_operand" "Q")
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_2"
1002 [(set (reg FLAGS_REG)
1006 (match_operand 0 "ext_register_operand" "Q")
1009 (match_operand:QI 1 "const0_operand" "")))]
1010 "ix86_match_ccmode (insn, CCNOmode)"
1012 [(set_attr "type" "test")
1013 (set_attr "length_immediate" "0")
1014 (set_attr "mode" "QI")])
1016 (define_expand "cmpqi_ext_3"
1017 [(set (reg:CC FLAGS_REG)
1021 (match_operand 0 "ext_register_operand" "")
1024 (match_operand:QI 1 "immediate_operand" "")))]
1028 (define_insn "*cmpqi_ext_3_insn"
1029 [(set (reg FLAGS_REG)
1033 (match_operand 0 "ext_register_operand" "Q")
1036 (match_operand:QI 1 "general_operand" "Qmn")))]
1037 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1038 "cmp{b}\t{%1, %h0|%h0, %1}"
1039 [(set_attr "type" "icmp")
1040 (set_attr "modrm" "1")
1041 (set_attr "mode" "QI")])
1043 (define_insn "*cmpqi_ext_3_insn_rex64"
1044 [(set (reg FLAGS_REG)
1048 (match_operand 0 "ext_register_operand" "Q")
1051 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1052 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1053 "cmp{b}\t{%1, %h0|%h0, %1}"
1054 [(set_attr "type" "icmp")
1055 (set_attr "modrm" "1")
1056 (set_attr "mode" "QI")])
1058 (define_insn "*cmpqi_ext_4"
1059 [(set (reg FLAGS_REG)
1063 (match_operand 0 "ext_register_operand" "Q")
1068 (match_operand 1 "ext_register_operand" "Q")
1070 (const_int 8)) 0)))]
1071 "ix86_match_ccmode (insn, CCmode)"
1072 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1073 [(set_attr "type" "icmp")
1074 (set_attr "mode" "QI")])
1076 ;; These implement float point compares.
1077 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1078 ;; which would allow mix and match FP modes on the compares. Which is what
1079 ;; the old patterns did, but with many more of them.
1081 (define_expand "cbranchxf4"
1082 [(set (reg:CC FLAGS_REG)
1083 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1084 (match_operand:XF 2 "nonmemory_operand" "")))
1085 (set (pc) (if_then_else
1086 (match_operator 0 "ix86_fp_comparison_operator"
1089 (label_ref (match_operand 3 "" ""))
1093 ix86_compare_op0 = operands[1];
1094 ix86_compare_op1 = operands[2];
1095 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1099 (define_expand "cstorexf4"
1100 [(set (reg:CC FLAGS_REG)
1101 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1102 (match_operand:XF 3 "nonmemory_operand" "")))
1103 (set (match_operand:QI 0 "register_operand" "")
1104 (match_operator 1 "ix86_fp_comparison_operator"
1109 ix86_compare_op0 = operands[2];
1110 ix86_compare_op1 = operands[3];
1111 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1115 (define_expand "cbranch<mode>4"
1116 [(set (reg:CC FLAGS_REG)
1117 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1118 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1119 (set (pc) (if_then_else
1120 (match_operator 0 "ix86_fp_comparison_operator"
1123 (label_ref (match_operand 3 "" ""))
1125 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1127 ix86_compare_op0 = operands[1];
1128 ix86_compare_op1 = operands[2];
1129 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1133 (define_expand "cstore<mode>4"
1134 [(set (reg:CC FLAGS_REG)
1135 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1136 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1137 (set (match_operand:QI 0 "register_operand" "")
1138 (match_operator 1 "ix86_fp_comparison_operator"
1141 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1143 ix86_compare_op0 = operands[2];
1144 ix86_compare_op1 = operands[3];
1145 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1149 (define_expand "cbranchcc4"
1150 [(set (pc) (if_then_else
1151 (match_operator 0 "comparison_operator"
1152 [(match_operand 1 "flags_reg_operand" "")
1153 (match_operand 2 "const0_operand" "")])
1154 (label_ref (match_operand 3 "" ""))
1158 ix86_compare_op0 = operands[1];
1159 ix86_compare_op1 = operands[2];
1160 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1164 (define_expand "cstorecc4"
1165 [(set (match_operand:QI 0 "register_operand" "")
1166 (match_operator 1 "comparison_operator"
1167 [(match_operand 2 "flags_reg_operand" "")
1168 (match_operand 3 "const0_operand" "")]))]
1171 ix86_compare_op0 = operands[2];
1172 ix86_compare_op1 = operands[3];
1173 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1178 ;; FP compares, step 1:
1179 ;; Set the FP condition codes.
1181 ;; CCFPmode compare with exceptions
1182 ;; CCFPUmode compare with no exceptions
1184 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1185 ;; used to manage the reg stack popping would not be preserved.
1187 (define_insn "*cmpfp_0"
1188 [(set (match_operand:HI 0 "register_operand" "=a")
1191 (match_operand 1 "register_operand" "f")
1192 (match_operand 2 "const0_operand" ""))]
1194 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1195 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1196 "* return output_fp_compare (insn, operands, 0, 0);"
1197 [(set_attr "type" "multi")
1198 (set_attr "unit" "i387")
1200 (cond [(match_operand:SF 1 "" "")
1202 (match_operand:DF 1 "" "")
1205 (const_string "XF")))])
1207 (define_insn_and_split "*cmpfp_0_cc"
1208 [(set (reg:CCFP FLAGS_REG)
1210 (match_operand 1 "register_operand" "f")
1211 (match_operand 2 "const0_operand" "")))
1212 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1213 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1214 && TARGET_SAHF && !TARGET_CMOVE
1215 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1217 "&& reload_completed"
1220 [(compare:CCFP (match_dup 1)(match_dup 2))]
1222 (set (reg:CC FLAGS_REG)
1223 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1225 [(set_attr "type" "multi")
1226 (set_attr "unit" "i387")
1228 (cond [(match_operand:SF 1 "" "")
1230 (match_operand:DF 1 "" "")
1233 (const_string "XF")))])
1235 (define_insn "*cmpfp_xf"
1236 [(set (match_operand:HI 0 "register_operand" "=a")
1239 (match_operand:XF 1 "register_operand" "f")
1240 (match_operand:XF 2 "register_operand" "f"))]
1243 "* return output_fp_compare (insn, operands, 0, 0);"
1244 [(set_attr "type" "multi")
1245 (set_attr "unit" "i387")
1246 (set_attr "mode" "XF")])
1248 (define_insn_and_split "*cmpfp_xf_cc"
1249 [(set (reg:CCFP FLAGS_REG)
1251 (match_operand:XF 1 "register_operand" "f")
1252 (match_operand:XF 2 "register_operand" "f")))
1253 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1255 && TARGET_SAHF && !TARGET_CMOVE"
1257 "&& reload_completed"
1260 [(compare:CCFP (match_dup 1)(match_dup 2))]
1262 (set (reg:CC FLAGS_REG)
1263 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1265 [(set_attr "type" "multi")
1266 (set_attr "unit" "i387")
1267 (set_attr "mode" "XF")])
1269 (define_insn "*cmpfp_<mode>"
1270 [(set (match_operand:HI 0 "register_operand" "=a")
1273 (match_operand:MODEF 1 "register_operand" "f")
1274 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1277 "* return output_fp_compare (insn, operands, 0, 0);"
1278 [(set_attr "type" "multi")
1279 (set_attr "unit" "i387")
1280 (set_attr "mode" "<MODE>")])
1282 (define_insn_and_split "*cmpfp_<mode>_cc"
1283 [(set (reg:CCFP FLAGS_REG)
1285 (match_operand:MODEF 1 "register_operand" "f")
1286 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1287 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1289 && TARGET_SAHF && !TARGET_CMOVE"
1291 "&& reload_completed"
1294 [(compare:CCFP (match_dup 1)(match_dup 2))]
1296 (set (reg:CC FLAGS_REG)
1297 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1299 [(set_attr "type" "multi")
1300 (set_attr "unit" "i387")
1301 (set_attr "mode" "<MODE>")])
1303 (define_insn "*cmpfp_u"
1304 [(set (match_operand:HI 0 "register_operand" "=a")
1307 (match_operand 1 "register_operand" "f")
1308 (match_operand 2 "register_operand" "f"))]
1310 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1311 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1312 "* return output_fp_compare (insn, operands, 0, 1);"
1313 [(set_attr "type" "multi")
1314 (set_attr "unit" "i387")
1316 (cond [(match_operand:SF 1 "" "")
1318 (match_operand:DF 1 "" "")
1321 (const_string "XF")))])
1323 (define_insn_and_split "*cmpfp_u_cc"
1324 [(set (reg:CCFPU FLAGS_REG)
1326 (match_operand 1 "register_operand" "f")
1327 (match_operand 2 "register_operand" "f")))
1328 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1329 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1330 && TARGET_SAHF && !TARGET_CMOVE
1331 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1333 "&& reload_completed"
1336 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1338 (set (reg:CC FLAGS_REG)
1339 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1341 [(set_attr "type" "multi")
1342 (set_attr "unit" "i387")
1344 (cond [(match_operand:SF 1 "" "")
1346 (match_operand:DF 1 "" "")
1349 (const_string "XF")))])
1351 (define_insn "*cmpfp_<mode>"
1352 [(set (match_operand:HI 0 "register_operand" "=a")
1355 (match_operand 1 "register_operand" "f")
1356 (match_operator 3 "float_operator"
1357 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1359 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1360 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1361 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1362 "* return output_fp_compare (insn, operands, 0, 0);"
1363 [(set_attr "type" "multi")
1364 (set_attr "unit" "i387")
1365 (set_attr "fp_int_src" "true")
1366 (set_attr "mode" "<MODE>")])
1368 (define_insn_and_split "*cmpfp_<mode>_cc"
1369 [(set (reg:CCFP FLAGS_REG)
1371 (match_operand 1 "register_operand" "f")
1372 (match_operator 3 "float_operator"
1373 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1374 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1375 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1376 && TARGET_SAHF && !TARGET_CMOVE
1377 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1378 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1380 "&& reload_completed"
1385 (match_op_dup 3 [(match_dup 2)]))]
1387 (set (reg:CC FLAGS_REG)
1388 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1390 [(set_attr "type" "multi")
1391 (set_attr "unit" "i387")
1392 (set_attr "fp_int_src" "true")
1393 (set_attr "mode" "<MODE>")])
1395 ;; FP compares, step 2
1396 ;; Move the fpsw to ax.
1398 (define_insn "x86_fnstsw_1"
1399 [(set (match_operand:HI 0 "register_operand" "=a")
1400 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1403 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1404 (set_attr "mode" "SI")
1405 (set_attr "unit" "i387")])
1407 ;; FP compares, step 3
1408 ;; Get ax into flags, general case.
1410 (define_insn "x86_sahf_1"
1411 [(set (reg:CC FLAGS_REG)
1412 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1416 #ifdef HAVE_AS_IX86_SAHF
1419 return ASM_BYTE "0x9e";
1422 [(set_attr "length" "1")
1423 (set_attr "athlon_decode" "vector")
1424 (set_attr "amdfam10_decode" "direct")
1425 (set_attr "mode" "SI")])
1427 ;; Pentium Pro can do steps 1 through 3 in one go.
1428 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1429 (define_insn "*cmpfp_i_mixed"
1430 [(set (reg:CCFP FLAGS_REG)
1431 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1432 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1433 "TARGET_MIX_SSE_I387
1434 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1435 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1436 "* return output_fp_compare (insn, operands, 1, 0);"
1437 [(set_attr "type" "fcmp,ssecomi")
1438 (set_attr "prefix" "orig,maybe_vex")
1440 (if_then_else (match_operand:SF 1 "" "")
1442 (const_string "DF")))
1443 (set (attr "prefix_rep")
1444 (if_then_else (eq_attr "type" "ssecomi")
1446 (const_string "*")))
1447 (set (attr "prefix_data16")
1448 (cond [(eq_attr "type" "fcmp")
1450 (eq_attr "mode" "DF")
1453 (const_string "0")))
1454 (set_attr "athlon_decode" "vector")
1455 (set_attr "amdfam10_decode" "direct")])
1457 (define_insn "*cmpfp_i_sse"
1458 [(set (reg:CCFP FLAGS_REG)
1459 (compare:CCFP (match_operand 0 "register_operand" "x")
1460 (match_operand 1 "nonimmediate_operand" "xm")))]
1462 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1463 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1464 "* return output_fp_compare (insn, operands, 1, 0);"
1465 [(set_attr "type" "ssecomi")
1466 (set_attr "prefix" "maybe_vex")
1468 (if_then_else (match_operand:SF 1 "" "")
1470 (const_string "DF")))
1471 (set_attr "prefix_rep" "0")
1472 (set (attr "prefix_data16")
1473 (if_then_else (eq_attr "mode" "DF")
1475 (const_string "0")))
1476 (set_attr "athlon_decode" "vector")
1477 (set_attr "amdfam10_decode" "direct")])
1479 (define_insn "*cmpfp_i_i387"
1480 [(set (reg:CCFP FLAGS_REG)
1481 (compare:CCFP (match_operand 0 "register_operand" "f")
1482 (match_operand 1 "register_operand" "f")))]
1483 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1485 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1486 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1487 "* return output_fp_compare (insn, operands, 1, 0);"
1488 [(set_attr "type" "fcmp")
1490 (cond [(match_operand:SF 1 "" "")
1492 (match_operand:DF 1 "" "")
1495 (const_string "XF")))
1496 (set_attr "athlon_decode" "vector")
1497 (set_attr "amdfam10_decode" "direct")])
1499 (define_insn "*cmpfp_iu_mixed"
1500 [(set (reg:CCFPU FLAGS_REG)
1501 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1502 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1503 "TARGET_MIX_SSE_I387
1504 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1505 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1506 "* return output_fp_compare (insn, operands, 1, 1);"
1507 [(set_attr "type" "fcmp,ssecomi")
1508 (set_attr "prefix" "orig,maybe_vex")
1510 (if_then_else (match_operand:SF 1 "" "")
1512 (const_string "DF")))
1513 (set (attr "prefix_rep")
1514 (if_then_else (eq_attr "type" "ssecomi")
1516 (const_string "*")))
1517 (set (attr "prefix_data16")
1518 (cond [(eq_attr "type" "fcmp")
1520 (eq_attr "mode" "DF")
1523 (const_string "0")))
1524 (set_attr "athlon_decode" "vector")
1525 (set_attr "amdfam10_decode" "direct")])
1527 (define_insn "*cmpfp_iu_sse"
1528 [(set (reg:CCFPU FLAGS_REG)
1529 (compare:CCFPU (match_operand 0 "register_operand" "x")
1530 (match_operand 1 "nonimmediate_operand" "xm")))]
1532 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1533 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1534 "* return output_fp_compare (insn, operands, 1, 1);"
1535 [(set_attr "type" "ssecomi")
1536 (set_attr "prefix" "maybe_vex")
1538 (if_then_else (match_operand:SF 1 "" "")
1540 (const_string "DF")))
1541 (set_attr "prefix_rep" "0")
1542 (set (attr "prefix_data16")
1543 (if_then_else (eq_attr "mode" "DF")
1545 (const_string "0")))
1546 (set_attr "athlon_decode" "vector")
1547 (set_attr "amdfam10_decode" "direct")])
1549 (define_insn "*cmpfp_iu_387"
1550 [(set (reg:CCFPU FLAGS_REG)
1551 (compare:CCFPU (match_operand 0 "register_operand" "f")
1552 (match_operand 1 "register_operand" "f")))]
1553 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1555 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1556 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1557 "* return output_fp_compare (insn, operands, 1, 1);"
1558 [(set_attr "type" "fcmp")
1560 (cond [(match_operand:SF 1 "" "")
1562 (match_operand:DF 1 "" "")
1565 (const_string "XF")))
1566 (set_attr "athlon_decode" "vector")
1567 (set_attr "amdfam10_decode" "direct")])
1569 ;; Move instructions.
1571 ;; General case of fullword move.
1573 (define_expand "movsi"
1574 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1575 (match_operand:SI 1 "general_operand" ""))]
1577 "ix86_expand_move (SImode, operands); DONE;")
1579 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1582 ;; %%% We don't use a post-inc memory reference because x86 is not a
1583 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1584 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1585 ;; targets without our curiosities, and it is just as easy to represent
1586 ;; this differently.
1588 (define_insn "*pushsi2"
1589 [(set (match_operand:SI 0 "push_operand" "=<")
1590 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1593 [(set_attr "type" "push")
1594 (set_attr "mode" "SI")])
1596 ;; For 64BIT abi we always round up to 8 bytes.
1597 (define_insn "*pushsi2_rex64"
1598 [(set (match_operand:SI 0 "push_operand" "=X")
1599 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1602 [(set_attr "type" "push")
1603 (set_attr "mode" "SI")])
1605 (define_insn "*pushsi2_prologue"
1606 [(set (match_operand:SI 0 "push_operand" "=<")
1607 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1608 (clobber (mem:BLK (scratch)))]
1611 [(set_attr "type" "push")
1612 (set_attr "mode" "SI")])
1614 (define_insn "*popsi1_epilogue"
1615 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1616 (mem:SI (reg:SI SP_REG)))
1617 (set (reg:SI SP_REG)
1618 (plus:SI (reg:SI SP_REG) (const_int 4)))
1619 (clobber (mem:BLK (scratch)))]
1622 [(set_attr "type" "pop")
1623 (set_attr "mode" "SI")])
1625 (define_insn "popsi1"
1626 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1627 (mem:SI (reg:SI SP_REG)))
1628 (set (reg:SI SP_REG)
1629 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1632 [(set_attr "type" "pop")
1633 (set_attr "mode" "SI")])
1635 (define_insn "*movsi_xor"
1636 [(set (match_operand:SI 0 "register_operand" "=r")
1637 (match_operand:SI 1 "const0_operand" ""))
1638 (clobber (reg:CC FLAGS_REG))]
1641 [(set_attr "type" "alu1")
1642 (set_attr "mode" "SI")
1643 (set_attr "length_immediate" "0")])
1645 (define_insn "*movsi_or"
1646 [(set (match_operand:SI 0 "register_operand" "=r")
1647 (match_operand:SI 1 "immediate_operand" "i"))
1648 (clobber (reg:CC FLAGS_REG))]
1650 && operands[1] == constm1_rtx"
1652 operands[1] = constm1_rtx;
1653 return "or{l}\t{%1, %0|%0, %1}";
1655 [(set_attr "type" "alu1")
1656 (set_attr "mode" "SI")
1657 (set_attr "length_immediate" "1")])
1659 (define_insn "*movsi_1"
1660 [(set (match_operand:SI 0 "nonimmediate_operand"
1661 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1662 (match_operand:SI 1 "general_operand"
1663 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1664 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1666 switch (get_attr_type (insn))
1669 if (get_attr_mode (insn) == MODE_TI)
1670 return "%vpxor\t%0, %d0";
1671 return "%vxorps\t%0, %d0";
1674 switch (get_attr_mode (insn))
1677 return "%vmovdqa\t{%1, %0|%0, %1}";
1679 return "%vmovaps\t{%1, %0|%0, %1}";
1681 return "%vmovd\t{%1, %0|%0, %1}";
1683 return "%vmovss\t{%1, %0|%0, %1}";
1689 return "pxor\t%0, %0";
1692 if (get_attr_mode (insn) == MODE_DI)
1693 return "movq\t{%1, %0|%0, %1}";
1694 return "movd\t{%1, %0|%0, %1}";
1697 return "lea{l}\t{%1, %0|%0, %1}";
1700 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1701 return "mov{l}\t{%1, %0|%0, %1}";
1705 (cond [(eq_attr "alternative" "2")
1706 (const_string "mmx")
1707 (eq_attr "alternative" "3,4,5")
1708 (const_string "mmxmov")
1709 (eq_attr "alternative" "6")
1710 (const_string "sselog1")
1711 (eq_attr "alternative" "7,8,9,10,11")
1712 (const_string "ssemov")
1713 (match_operand:DI 1 "pic_32bit_operand" "")
1714 (const_string "lea")
1716 (const_string "imov")))
1717 (set (attr "prefix")
1718 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1719 (const_string "orig")
1720 (const_string "maybe_vex")))
1721 (set (attr "prefix_data16")
1722 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1724 (const_string "*")))
1726 (cond [(eq_attr "alternative" "2,3")
1728 (eq_attr "alternative" "6,7")
1730 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1731 (const_string "V4SF")
1732 (const_string "TI"))
1733 (and (eq_attr "alternative" "8,9,10,11")
1734 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1737 (const_string "SI")))])
1739 ;; Stores and loads of ax to arbitrary constant address.
1740 ;; We fake an second form of instruction to force reload to load address
1741 ;; into register when rax is not available
1742 (define_insn "*movabssi_1_rex64"
1743 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1744 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1745 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1747 movabs{l}\t{%1, %P0|%P0, %1}
1748 mov{l}\t{%1, %a0|%a0, %1}"
1749 [(set_attr "type" "imov")
1750 (set_attr "modrm" "0,*")
1751 (set_attr "length_address" "8,0")
1752 (set_attr "length_immediate" "0,*")
1753 (set_attr "memory" "store")
1754 (set_attr "mode" "SI")])
1756 (define_insn "*movabssi_2_rex64"
1757 [(set (match_operand:SI 0 "register_operand" "=a,r")
1758 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1759 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1761 movabs{l}\t{%P1, %0|%0, %P1}
1762 mov{l}\t{%a1, %0|%0, %a1}"
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" "load")
1768 (set_attr "mode" "SI")])
1770 (define_insn "*swapsi"
1771 [(set (match_operand:SI 0 "register_operand" "+r")
1772 (match_operand:SI 1 "register_operand" "+r"))
1777 [(set_attr "type" "imov")
1778 (set_attr "mode" "SI")
1779 (set_attr "pent_pair" "np")
1780 (set_attr "athlon_decode" "vector")
1781 (set_attr "amdfam10_decode" "double")])
1783 (define_expand "movhi"
1784 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1785 (match_operand:HI 1 "general_operand" ""))]
1787 "ix86_expand_move (HImode, operands); DONE;")
1789 (define_insn "*pushhi2"
1790 [(set (match_operand:HI 0 "push_operand" "=X")
1791 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1794 [(set_attr "type" "push")
1795 (set_attr "mode" "SI")])
1797 ;; For 64BIT abi we always round up to 8 bytes.
1798 (define_insn "*pushhi2_rex64"
1799 [(set (match_operand:HI 0 "push_operand" "=X")
1800 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1803 [(set_attr "type" "push")
1804 (set_attr "mode" "DI")])
1806 (define_insn "*movhi_1"
1807 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1808 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1809 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1811 switch (get_attr_type (insn))
1814 /* movzwl is faster than movw on p2 due to partial word stalls,
1815 though not as fast as an aligned movl. */
1816 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1818 if (get_attr_mode (insn) == MODE_SI)
1819 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1821 return "mov{w}\t{%1, %0|%0, %1}";
1825 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1826 (const_string "imov")
1827 (and (eq_attr "alternative" "0")
1828 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1830 (eq (symbol_ref "TARGET_HIMODE_MATH")
1832 (const_string "imov")
1833 (and (eq_attr "alternative" "1,2")
1834 (match_operand:HI 1 "aligned_operand" ""))
1835 (const_string "imov")
1836 (and (ne (symbol_ref "TARGET_MOVX")
1838 (eq_attr "alternative" "0,2"))
1839 (const_string "imovx")
1841 (const_string "imov")))
1843 (cond [(eq_attr "type" "imovx")
1845 (and (eq_attr "alternative" "1,2")
1846 (match_operand:HI 1 "aligned_operand" ""))
1848 (and (eq_attr "alternative" "0")
1849 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1851 (eq (symbol_ref "TARGET_HIMODE_MATH")
1855 (const_string "HI")))])
1857 ;; Stores and loads of ax to arbitrary constant address.
1858 ;; We fake an second form of instruction to force reload to load address
1859 ;; into register when rax is not available
1860 (define_insn "*movabshi_1_rex64"
1861 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1862 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1863 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1865 movabs{w}\t{%1, %P0|%P0, %1}
1866 mov{w}\t{%1, %a0|%a0, %1}"
1867 [(set_attr "type" "imov")
1868 (set_attr "modrm" "0,*")
1869 (set_attr "length_address" "8,0")
1870 (set_attr "length_immediate" "0,*")
1871 (set_attr "memory" "store")
1872 (set_attr "mode" "HI")])
1874 (define_insn "*movabshi_2_rex64"
1875 [(set (match_operand:HI 0 "register_operand" "=a,r")
1876 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1877 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1879 movabs{w}\t{%P1, %0|%0, %P1}
1880 mov{w}\t{%a1, %0|%0, %a1}"
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" "load")
1886 (set_attr "mode" "HI")])
1888 (define_insn "*swaphi_1"
1889 [(set (match_operand:HI 0 "register_operand" "+r")
1890 (match_operand:HI 1 "register_operand" "+r"))
1893 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1895 [(set_attr "type" "imov")
1896 (set_attr "mode" "SI")
1897 (set_attr "pent_pair" "np")
1898 (set_attr "athlon_decode" "vector")
1899 (set_attr "amdfam10_decode" "double")])
1901 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1902 (define_insn "*swaphi_2"
1903 [(set (match_operand:HI 0 "register_operand" "+r")
1904 (match_operand:HI 1 "register_operand" "+r"))
1907 "TARGET_PARTIAL_REG_STALL"
1909 [(set_attr "type" "imov")
1910 (set_attr "mode" "HI")
1911 (set_attr "pent_pair" "np")
1912 (set_attr "athlon_decode" "vector")])
1914 (define_expand "movstricthi"
1915 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1916 (match_operand:HI 1 "general_operand" ""))]
1919 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1921 /* Don't generate memory->memory moves, go through a register */
1922 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1923 operands[1] = force_reg (HImode, operands[1]);
1926 (define_insn "*movstricthi_1"
1927 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1928 (match_operand:HI 1 "general_operand" "rn,m"))]
1929 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1930 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1931 "mov{w}\t{%1, %0|%0, %1}"
1932 [(set_attr "type" "imov")
1933 (set_attr "mode" "HI")])
1935 (define_insn "*movstricthi_xor"
1936 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1937 (match_operand:HI 1 "const0_operand" ""))
1938 (clobber (reg:CC FLAGS_REG))]
1941 [(set_attr "type" "alu1")
1942 (set_attr "mode" "HI")
1943 (set_attr "length_immediate" "0")])
1945 (define_expand "movqi"
1946 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1947 (match_operand:QI 1 "general_operand" ""))]
1949 "ix86_expand_move (QImode, operands); DONE;")
1951 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1952 ;; "push a byte". But actually we use pushl, which has the effect
1953 ;; of rounding the amount pushed up to a word.
1955 (define_insn "*pushqi2"
1956 [(set (match_operand:QI 0 "push_operand" "=X")
1957 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1960 [(set_attr "type" "push")
1961 (set_attr "mode" "SI")])
1963 ;; For 64BIT abi we always round up to 8 bytes.
1964 (define_insn "*pushqi2_rex64"
1965 [(set (match_operand:QI 0 "push_operand" "=X")
1966 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1969 [(set_attr "type" "push")
1970 (set_attr "mode" "DI")])
1972 ;; Situation is quite tricky about when to choose full sized (SImode) move
1973 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1974 ;; partial register dependency machines (such as AMD Athlon), where QImode
1975 ;; moves issue extra dependency and for partial register stalls machines
1976 ;; that don't use QImode patterns (and QImode move cause stall on the next
1979 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1980 ;; register stall machines with, where we use QImode instructions, since
1981 ;; partial register stall can be caused there. Then we use movzx.
1982 (define_insn "*movqi_1"
1983 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1984 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1985 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1987 switch (get_attr_type (insn))
1990 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1991 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1993 if (get_attr_mode (insn) == MODE_SI)
1994 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1996 return "mov{b}\t{%1, %0|%0, %1}";
2000 (cond [(and (eq_attr "alternative" "5")
2001 (not (match_operand:QI 1 "aligned_operand" "")))
2002 (const_string "imovx")
2003 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2004 (const_string "imov")
2005 (and (eq_attr "alternative" "3")
2006 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2008 (eq (symbol_ref "TARGET_QIMODE_MATH")
2010 (const_string "imov")
2011 (eq_attr "alternative" "3,5")
2012 (const_string "imovx")
2013 (and (ne (symbol_ref "TARGET_MOVX")
2015 (eq_attr "alternative" "2"))
2016 (const_string "imovx")
2018 (const_string "imov")))
2020 (cond [(eq_attr "alternative" "3,4,5")
2022 (eq_attr "alternative" "6")
2024 (eq_attr "type" "imovx")
2026 (and (eq_attr "type" "imov")
2027 (and (eq_attr "alternative" "0,1")
2028 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2030 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2032 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2035 ;; Avoid partial register stalls when not using QImode arithmetic
2036 (and (eq_attr "type" "imov")
2037 (and (eq_attr "alternative" "0,1")
2038 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2040 (eq (symbol_ref "TARGET_QIMODE_MATH")
2044 (const_string "QI")))])
2046 (define_insn "*swapqi_1"
2047 [(set (match_operand:QI 0 "register_operand" "+r")
2048 (match_operand:QI 1 "register_operand" "+r"))
2051 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2053 [(set_attr "type" "imov")
2054 (set_attr "mode" "SI")
2055 (set_attr "pent_pair" "np")
2056 (set_attr "athlon_decode" "vector")
2057 (set_attr "amdfam10_decode" "vector")])
2059 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2060 (define_insn "*swapqi_2"
2061 [(set (match_operand:QI 0 "register_operand" "+q")
2062 (match_operand:QI 1 "register_operand" "+q"))
2065 "TARGET_PARTIAL_REG_STALL"
2067 [(set_attr "type" "imov")
2068 (set_attr "mode" "QI")
2069 (set_attr "pent_pair" "np")
2070 (set_attr "athlon_decode" "vector")])
2072 (define_expand "movstrictqi"
2073 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2074 (match_operand:QI 1 "general_operand" ""))]
2077 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2079 /* Don't generate memory->memory moves, go through a register. */
2080 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2081 operands[1] = force_reg (QImode, operands[1]);
2084 (define_insn "*movstrictqi_1"
2085 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2086 (match_operand:QI 1 "general_operand" "*qn,m"))]
2087 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2088 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2089 "mov{b}\t{%1, %0|%0, %1}"
2090 [(set_attr "type" "imov")
2091 (set_attr "mode" "QI")])
2093 (define_insn "*movstrictqi_xor"
2094 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2095 (match_operand:QI 1 "const0_operand" ""))
2096 (clobber (reg:CC FLAGS_REG))]
2099 [(set_attr "type" "alu1")
2100 (set_attr "mode" "QI")
2101 (set_attr "length_immediate" "0")])
2103 (define_insn "*movsi_extv_1"
2104 [(set (match_operand:SI 0 "register_operand" "=R")
2105 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2109 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2110 [(set_attr "type" "imovx")
2111 (set_attr "mode" "SI")])
2113 (define_insn "*movhi_extv_1"
2114 [(set (match_operand:HI 0 "register_operand" "=R")
2115 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2119 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2120 [(set_attr "type" "imovx")
2121 (set_attr "mode" "SI")])
2123 (define_insn "*movqi_extv_1"
2124 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2125 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2130 switch (get_attr_type (insn))
2133 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2135 return "mov{b}\t{%h1, %0|%0, %h1}";
2139 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2140 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2141 (ne (symbol_ref "TARGET_MOVX")
2143 (const_string "imovx")
2144 (const_string "imov")))
2146 (if_then_else (eq_attr "type" "imovx")
2148 (const_string "QI")))])
2150 (define_insn "*movqi_extv_1_rex64"
2151 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2152 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2157 switch (get_attr_type (insn))
2160 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2162 return "mov{b}\t{%h1, %0|%0, %h1}";
2166 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2167 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2168 (ne (symbol_ref "TARGET_MOVX")
2170 (const_string "imovx")
2171 (const_string "imov")))
2173 (if_then_else (eq_attr "type" "imovx")
2175 (const_string "QI")))])
2177 ;; Stores and loads of ax to arbitrary constant address.
2178 ;; We fake an second form of instruction to force reload to load address
2179 ;; into register when rax is not available
2180 (define_insn "*movabsqi_1_rex64"
2181 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2182 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2183 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2185 movabs{b}\t{%1, %P0|%P0, %1}
2186 mov{b}\t{%1, %a0|%a0, %1}"
2187 [(set_attr "type" "imov")
2188 (set_attr "modrm" "0,*")
2189 (set_attr "length_address" "8,0")
2190 (set_attr "length_immediate" "0,*")
2191 (set_attr "memory" "store")
2192 (set_attr "mode" "QI")])
2194 (define_insn "*movabsqi_2_rex64"
2195 [(set (match_operand:QI 0 "register_operand" "=a,r")
2196 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2197 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2199 movabs{b}\t{%P1, %0|%0, %P1}
2200 mov{b}\t{%a1, %0|%0, %a1}"
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" "load")
2206 (set_attr "mode" "QI")])
2208 (define_insn "*movdi_extzv_1"
2209 [(set (match_operand:DI 0 "register_operand" "=R")
2210 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2214 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2215 [(set_attr "type" "imovx")
2216 (set_attr "mode" "SI")])
2218 (define_insn "*movsi_extzv_1"
2219 [(set (match_operand:SI 0 "register_operand" "=R")
2220 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2224 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2225 [(set_attr "type" "imovx")
2226 (set_attr "mode" "SI")])
2228 (define_insn "*movqi_extzv_2"
2229 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2230 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2235 switch (get_attr_type (insn))
2238 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2240 return "mov{b}\t{%h1, %0|%0, %h1}";
2244 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2245 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2246 (ne (symbol_ref "TARGET_MOVX")
2248 (const_string "imovx")
2249 (const_string "imov")))
2251 (if_then_else (eq_attr "type" "imovx")
2253 (const_string "QI")))])
2255 (define_insn "*movqi_extzv_2_rex64"
2256 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2257 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2262 switch (get_attr_type (insn))
2265 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2267 return "mov{b}\t{%h1, %0|%0, %h1}";
2271 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2272 (ne (symbol_ref "TARGET_MOVX")
2274 (const_string "imovx")
2275 (const_string "imov")))
2277 (if_then_else (eq_attr "type" "imovx")
2279 (const_string "QI")))])
2281 (define_insn "movsi_insv_1"
2282 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2285 (match_operand:SI 1 "general_operand" "Qmn"))]
2287 "mov{b}\t{%b1, %h0|%h0, %b1}"
2288 [(set_attr "type" "imov")
2289 (set_attr "mode" "QI")])
2291 (define_insn "*movsi_insv_1_rex64"
2292 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2295 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2297 "mov{b}\t{%b1, %h0|%h0, %b1}"
2298 [(set_attr "type" "imov")
2299 (set_attr "mode" "QI")])
2301 (define_insn "movdi_insv_1_rex64"
2302 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2305 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2307 "mov{b}\t{%b1, %h0|%h0, %b1}"
2308 [(set_attr "type" "imov")
2309 (set_attr "mode" "QI")])
2311 (define_insn "*movqi_insv_2"
2312 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2315 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2318 "mov{b}\t{%h1, %h0|%h0, %h1}"
2319 [(set_attr "type" "imov")
2320 (set_attr "mode" "QI")])
2322 (define_expand "movdi"
2323 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2324 (match_operand:DI 1 "general_operand" ""))]
2326 "ix86_expand_move (DImode, operands); DONE;")
2328 (define_insn "*pushdi"
2329 [(set (match_operand:DI 0 "push_operand" "=<")
2330 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2334 (define_insn "*pushdi2_rex64"
2335 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2336 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2341 [(set_attr "type" "push,multi")
2342 (set_attr "mode" "DI")])
2344 ;; Convert impossible pushes of immediate to existing instructions.
2345 ;; First try to get scratch register and go through it. In case this
2346 ;; fails, push sign extended lower part first and then overwrite
2347 ;; upper part by 32bit move.
2349 [(match_scratch:DI 2 "r")
2350 (set (match_operand:DI 0 "push_operand" "")
2351 (match_operand:DI 1 "immediate_operand" ""))]
2352 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2353 && !x86_64_immediate_operand (operands[1], DImode)"
2354 [(set (match_dup 2) (match_dup 1))
2355 (set (match_dup 0) (match_dup 2))]
2358 ;; We need to define this as both peepholer and splitter for case
2359 ;; peephole2 pass is not run.
2360 ;; "&& 1" is needed to keep it from matching the previous pattern.
2362 [(set (match_operand:DI 0 "push_operand" "")
2363 (match_operand:DI 1 "immediate_operand" ""))]
2364 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2365 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2366 [(set (match_dup 0) (match_dup 1))
2367 (set (match_dup 2) (match_dup 3))]
2368 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2369 operands[1] = gen_lowpart (DImode, operands[2]);
2370 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2375 [(set (match_operand:DI 0 "push_operand" "")
2376 (match_operand:DI 1 "immediate_operand" ""))]
2377 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2378 ? epilogue_completed : reload_completed)
2379 && !symbolic_operand (operands[1], DImode)
2380 && !x86_64_immediate_operand (operands[1], DImode)"
2381 [(set (match_dup 0) (match_dup 1))
2382 (set (match_dup 2) (match_dup 3))]
2383 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2384 operands[1] = gen_lowpart (DImode, operands[2]);
2385 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2389 (define_insn "*pushdi2_prologue_rex64"
2390 [(set (match_operand:DI 0 "push_operand" "=<")
2391 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2392 (clobber (mem:BLK (scratch)))]
2395 [(set_attr "type" "push")
2396 (set_attr "mode" "DI")])
2398 (define_insn "*popdi1_epilogue_rex64"
2399 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2400 (mem:DI (reg:DI SP_REG)))
2401 (set (reg:DI SP_REG)
2402 (plus:DI (reg:DI SP_REG) (const_int 8)))
2403 (clobber (mem:BLK (scratch)))]
2406 [(set_attr "type" "pop")
2407 (set_attr "mode" "DI")])
2409 (define_insn "popdi1"
2410 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2411 (mem:DI (reg:DI SP_REG)))
2412 (set (reg:DI SP_REG)
2413 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2416 [(set_attr "type" "pop")
2417 (set_attr "mode" "DI")])
2419 (define_insn "*movdi_xor_rex64"
2420 [(set (match_operand:DI 0 "register_operand" "=r")
2421 (match_operand:DI 1 "const0_operand" ""))
2422 (clobber (reg:CC FLAGS_REG))]
2424 && reload_completed"
2426 [(set_attr "type" "alu1")
2427 (set_attr "mode" "SI")
2428 (set_attr "length_immediate" "0")])
2430 (define_insn "*movdi_or_rex64"
2431 [(set (match_operand:DI 0 "register_operand" "=r")
2432 (match_operand:DI 1 "const_int_operand" "i"))
2433 (clobber (reg:CC FLAGS_REG))]
2436 && operands[1] == constm1_rtx"
2438 operands[1] = constm1_rtx;
2439 return "or{q}\t{%1, %0|%0, %1}";
2441 [(set_attr "type" "alu1")
2442 (set_attr "mode" "DI")
2443 (set_attr "length_immediate" "1")])
2445 (define_insn "*movdi_2"
2446 [(set (match_operand:DI 0 "nonimmediate_operand"
2447 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2448 (match_operand:DI 1 "general_operand"
2449 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2450 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2455 movq\t{%1, %0|%0, %1}
2456 movq\t{%1, %0|%0, %1}
2458 %vmovq\t{%1, %0|%0, %1}
2459 %vmovdqa\t{%1, %0|%0, %1}
2460 %vmovq\t{%1, %0|%0, %1}
2462 movlps\t{%1, %0|%0, %1}
2463 movaps\t{%1, %0|%0, %1}
2464 movlps\t{%1, %0|%0, %1}"
2465 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2466 (set (attr "prefix")
2467 (if_then_else (eq_attr "alternative" "5,6,7,8")
2468 (const_string "vex")
2469 (const_string "orig")))
2470 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2473 [(set (match_operand:DI 0 "push_operand" "")
2474 (match_operand:DI 1 "general_operand" ""))]
2475 "!TARGET_64BIT && reload_completed
2476 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2478 "ix86_split_long_move (operands); DONE;")
2480 ;; %%% This multiword shite has got to go.
2482 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2483 (match_operand:DI 1 "general_operand" ""))]
2484 "!TARGET_64BIT && reload_completed
2485 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2486 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2488 "ix86_split_long_move (operands); DONE;")
2490 (define_insn "*movdi_1_rex64"
2491 [(set (match_operand:DI 0 "nonimmediate_operand"
2492 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2493 (match_operand:DI 1 "general_operand"
2494 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2495 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2497 switch (get_attr_type (insn))
2500 if (SSE_REG_P (operands[0]))
2501 return "movq2dq\t{%1, %0|%0, %1}";
2503 return "movdq2q\t{%1, %0|%0, %1}";
2508 if (get_attr_mode (insn) == MODE_TI)
2509 return "vmovdqa\t{%1, %0|%0, %1}";
2511 return "vmovq\t{%1, %0|%0, %1}";
2514 if (get_attr_mode (insn) == MODE_TI)
2515 return "movdqa\t{%1, %0|%0, %1}";
2519 /* Moves from and into integer register is done using movd
2520 opcode with REX prefix. */
2521 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2522 return "movd\t{%1, %0|%0, %1}";
2523 return "movq\t{%1, %0|%0, %1}";
2526 return "%vpxor\t%0, %d0";
2529 return "pxor\t%0, %0";
2535 return "lea{q}\t{%a1, %0|%0, %a1}";
2538 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2539 if (get_attr_mode (insn) == MODE_SI)
2540 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2541 else if (which_alternative == 2)
2542 return "movabs{q}\t{%1, %0|%0, %1}";
2544 return "mov{q}\t{%1, %0|%0, %1}";
2548 (cond [(eq_attr "alternative" "5")
2549 (const_string "mmx")
2550 (eq_attr "alternative" "6,7,8,9,10")
2551 (const_string "mmxmov")
2552 (eq_attr "alternative" "11")
2553 (const_string "sselog1")
2554 (eq_attr "alternative" "12,13,14,15,16")
2555 (const_string "ssemov")
2556 (eq_attr "alternative" "17,18")
2557 (const_string "ssecvt")
2558 (eq_attr "alternative" "4")
2559 (const_string "multi")
2560 (match_operand:DI 1 "pic_32bit_operand" "")
2561 (const_string "lea")
2563 (const_string "imov")))
2566 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2568 (const_string "*")))
2569 (set (attr "length_immediate")
2571 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2573 (const_string "*")))
2574 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2575 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2576 (set (attr "prefix")
2577 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2578 (const_string "maybe_vex")
2579 (const_string "orig")))
2580 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2582 ;; Stores and loads of ax to arbitrary constant address.
2583 ;; We fake an second form of instruction to force reload to load address
2584 ;; into register when rax is not available
2585 (define_insn "*movabsdi_1_rex64"
2586 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2587 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2588 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2590 movabs{q}\t{%1, %P0|%P0, %1}
2591 mov{q}\t{%1, %a0|%a0, %1}"
2592 [(set_attr "type" "imov")
2593 (set_attr "modrm" "0,*")
2594 (set_attr "length_address" "8,0")
2595 (set_attr "length_immediate" "0,*")
2596 (set_attr "memory" "store")
2597 (set_attr "mode" "DI")])
2599 (define_insn "*movabsdi_2_rex64"
2600 [(set (match_operand:DI 0 "register_operand" "=a,r")
2601 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2602 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2604 movabs{q}\t{%P1, %0|%0, %P1}
2605 mov{q}\t{%a1, %0|%0, %a1}"
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" "load")
2611 (set_attr "mode" "DI")])
2613 ;; Convert impossible stores of immediate to existing instructions.
2614 ;; First try to get scratch register and go through it. In case this
2615 ;; fails, move by 32bit parts.
2617 [(match_scratch:DI 2 "r")
2618 (set (match_operand:DI 0 "memory_operand" "")
2619 (match_operand:DI 1 "immediate_operand" ""))]
2620 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2621 && !x86_64_immediate_operand (operands[1], DImode)"
2622 [(set (match_dup 2) (match_dup 1))
2623 (set (match_dup 0) (match_dup 2))]
2626 ;; We need to define this as both peepholer and splitter for case
2627 ;; peephole2 pass is not run.
2628 ;; "&& 1" is needed to keep it from matching the previous pattern.
2630 [(set (match_operand:DI 0 "memory_operand" "")
2631 (match_operand:DI 1 "immediate_operand" ""))]
2632 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2633 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2634 [(set (match_dup 2) (match_dup 3))
2635 (set (match_dup 4) (match_dup 5))]
2636 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2639 [(set (match_operand:DI 0 "memory_operand" "")
2640 (match_operand:DI 1 "immediate_operand" ""))]
2641 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2642 ? epilogue_completed : reload_completed)
2643 && !symbolic_operand (operands[1], DImode)
2644 && !x86_64_immediate_operand (operands[1], DImode)"
2645 [(set (match_dup 2) (match_dup 3))
2646 (set (match_dup 4) (match_dup 5))]
2647 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2649 (define_insn "*swapdi_rex64"
2650 [(set (match_operand:DI 0 "register_operand" "+r")
2651 (match_operand:DI 1 "register_operand" "+r"))
2656 [(set_attr "type" "imov")
2657 (set_attr "mode" "DI")
2658 (set_attr "pent_pair" "np")
2659 (set_attr "athlon_decode" "vector")
2660 (set_attr "amdfam10_decode" "double")])
2662 (define_expand "movoi"
2663 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2664 (match_operand:OI 1 "general_operand" ""))]
2666 "ix86_expand_move (OImode, operands); DONE;")
2668 (define_insn "*movoi_internal"
2669 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2670 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2672 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2674 switch (which_alternative)
2677 return "vxorps\t%0, %0, %0";
2680 if (misaligned_operand (operands[0], OImode)
2681 || misaligned_operand (operands[1], OImode))
2682 return "vmovdqu\t{%1, %0|%0, %1}";
2684 return "vmovdqa\t{%1, %0|%0, %1}";
2689 [(set_attr "type" "sselog1,ssemov,ssemov")
2690 (set_attr "prefix" "vex")
2691 (set_attr "mode" "OI")])
2693 (define_expand "movti"
2694 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2695 (match_operand:TI 1 "nonimmediate_operand" ""))]
2696 "TARGET_SSE || TARGET_64BIT"
2699 ix86_expand_move (TImode, operands);
2700 else if (push_operand (operands[0], TImode))
2701 ix86_expand_push (TImode, operands[1]);
2703 ix86_expand_vector_move (TImode, operands);
2707 (define_insn "*movti_internal"
2708 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2709 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2710 "TARGET_SSE && !TARGET_64BIT
2711 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2713 switch (which_alternative)
2716 if (get_attr_mode (insn) == MODE_V4SF)
2717 return "%vxorps\t%0, %d0";
2719 return "%vpxor\t%0, %d0";
2722 /* TDmode values are passed as TImode on the stack. Moving them
2723 to stack may result in unaligned memory access. */
2724 if (misaligned_operand (operands[0], TImode)
2725 || misaligned_operand (operands[1], TImode))
2727 if (get_attr_mode (insn) == MODE_V4SF)
2728 return "%vmovups\t{%1, %0|%0, %1}";
2730 return "%vmovdqu\t{%1, %0|%0, %1}";
2734 if (get_attr_mode (insn) == MODE_V4SF)
2735 return "%vmovaps\t{%1, %0|%0, %1}";
2737 return "%vmovdqa\t{%1, %0|%0, %1}";
2743 [(set_attr "type" "sselog1,ssemov,ssemov")
2744 (set_attr "prefix" "maybe_vex")
2746 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2747 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2748 (const_string "V4SF")
2749 (and (eq_attr "alternative" "2")
2750 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2752 (const_string "V4SF")]
2753 (const_string "TI")))])
2755 (define_insn "*movti_rex64"
2756 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2757 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2759 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2761 switch (which_alternative)
2767 if (get_attr_mode (insn) == MODE_V4SF)
2768 return "%vxorps\t%0, %d0";
2770 return "%vpxor\t%0, %d0";
2773 /* TDmode values are passed as TImode on the stack. Moving them
2774 to stack may result in unaligned memory access. */
2775 if (misaligned_operand (operands[0], TImode)
2776 || misaligned_operand (operands[1], TImode))
2778 if (get_attr_mode (insn) == MODE_V4SF)
2779 return "%vmovups\t{%1, %0|%0, %1}";
2781 return "%vmovdqu\t{%1, %0|%0, %1}";
2785 if (get_attr_mode (insn) == MODE_V4SF)
2786 return "%vmovaps\t{%1, %0|%0, %1}";
2788 return "%vmovdqa\t{%1, %0|%0, %1}";
2794 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2795 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2797 (cond [(eq_attr "alternative" "2,3")
2799 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2801 (const_string "V4SF")
2802 (const_string "TI"))
2803 (eq_attr "alternative" "4")
2805 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2807 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2809 (const_string "V4SF")
2810 (const_string "TI"))]
2811 (const_string "DI")))])
2814 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2815 (match_operand:TI 1 "general_operand" ""))]
2816 "reload_completed && !SSE_REG_P (operands[0])
2817 && !SSE_REG_P (operands[1])"
2819 "ix86_split_long_move (operands); DONE;")
2821 ;; This expands to what emit_move_complex would generate if we didn't
2822 ;; have a movti pattern. Having this avoids problems with reload on
2823 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2824 ;; to have around all the time.
2825 (define_expand "movcdi"
2826 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2827 (match_operand:CDI 1 "general_operand" ""))]
2830 if (push_operand (operands[0], CDImode))
2831 emit_move_complex_push (CDImode, operands[0], operands[1]);
2833 emit_move_complex_parts (operands[0], operands[1]);
2837 (define_expand "movsf"
2838 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2839 (match_operand:SF 1 "general_operand" ""))]
2841 "ix86_expand_move (SFmode, operands); DONE;")
2843 (define_insn "*pushsf"
2844 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2845 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2848 /* Anything else should be already split before reg-stack. */
2849 gcc_assert (which_alternative == 1);
2850 return "push{l}\t%1";
2852 [(set_attr "type" "multi,push,multi")
2853 (set_attr "unit" "i387,*,*")
2854 (set_attr "mode" "SF,SI,SF")])
2856 (define_insn "*pushsf_rex64"
2857 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2858 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2861 /* Anything else should be already split before reg-stack. */
2862 gcc_assert (which_alternative == 1);
2863 return "push{q}\t%q1";
2865 [(set_attr "type" "multi,push,multi")
2866 (set_attr "unit" "i387,*,*")
2867 (set_attr "mode" "SF,DI,SF")])
2870 [(set (match_operand:SF 0 "push_operand" "")
2871 (match_operand:SF 1 "memory_operand" ""))]
2873 && MEM_P (operands[1])
2874 && (operands[2] = find_constant_src (insn))"
2878 ;; %%% Kill this when call knows how to work this out.
2880 [(set (match_operand:SF 0 "push_operand" "")
2881 (match_operand:SF 1 "any_fp_register_operand" ""))]
2883 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2884 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2887 [(set (match_operand:SF 0 "push_operand" "")
2888 (match_operand:SF 1 "any_fp_register_operand" ""))]
2890 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2891 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2893 (define_insn "*movsf_1"
2894 [(set (match_operand:SF 0 "nonimmediate_operand"
2895 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2896 (match_operand:SF 1 "general_operand"
2897 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2898 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2899 && (reload_in_progress || reload_completed
2900 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2901 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2902 && standard_80387_constant_p (operands[1]))
2903 || GET_CODE (operands[1]) != CONST_DOUBLE
2904 || memory_operand (operands[0], SFmode))"
2906 switch (which_alternative)
2910 return output_387_reg_move (insn, operands);
2913 return standard_80387_constant_opcode (operands[1]);
2917 return "mov{l}\t{%1, %0|%0, %1}";
2919 if (get_attr_mode (insn) == MODE_TI)
2920 return "%vpxor\t%0, %d0";
2922 return "%vxorps\t%0, %d0";
2924 if (get_attr_mode (insn) == MODE_V4SF)
2925 return "%vmovaps\t{%1, %0|%0, %1}";
2927 return "%vmovss\t{%1, %d0|%d0, %1}";
2930 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2931 : "vmovss\t{%1, %0|%0, %1}";
2933 return "movss\t{%1, %0|%0, %1}";
2935 return "%vmovss\t{%1, %0|%0, %1}";
2937 case 9: case 10: case 14: case 15:
2938 return "movd\t{%1, %0|%0, %1}";
2940 return "%vmovd\t{%1, %0|%0, %1}";
2943 return "movq\t{%1, %0|%0, %1}";
2949 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2950 (set (attr "prefix")
2951 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2952 (const_string "maybe_vex")
2953 (const_string "orig")))
2955 (cond [(eq_attr "alternative" "3,4,9,10")
2957 (eq_attr "alternative" "5")
2959 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2961 (ne (symbol_ref "TARGET_SSE2")
2963 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2966 (const_string "V4SF"))
2967 /* For architectures resolving dependencies on
2968 whole SSE registers use APS move to break dependency
2969 chains, otherwise use short move to avoid extra work.
2971 Do the same for architectures resolving dependencies on
2972 the parts. While in DF mode it is better to always handle
2973 just register parts, the SF mode is different due to lack
2974 of instructions to load just part of the register. It is
2975 better to maintain the whole registers in single format
2976 to avoid problems on using packed logical operations. */
2977 (eq_attr "alternative" "6")
2979 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2981 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2983 (const_string "V4SF")
2984 (const_string "SF"))
2985 (eq_attr "alternative" "11")
2986 (const_string "DI")]
2987 (const_string "SF")))])
2989 (define_insn "*swapsf"
2990 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2991 (match_operand:SF 1 "fp_register_operand" "+f"))
2994 "reload_completed || TARGET_80387"
2996 if (STACK_TOP_P (operands[0]))
3001 [(set_attr "type" "fxch")
3002 (set_attr "mode" "SF")])
3004 (define_expand "movdf"
3005 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3006 (match_operand:DF 1 "general_operand" ""))]
3008 "ix86_expand_move (DFmode, operands); DONE;")
3010 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3011 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3012 ;; On the average, pushdf using integers can be still shorter. Allow this
3013 ;; pattern for optimize_size too.
3015 (define_insn "*pushdf_nointeger"
3016 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3017 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3018 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3020 /* This insn should be already split before reg-stack. */
3023 [(set_attr "type" "multi")
3024 (set_attr "unit" "i387,*,*,*")
3025 (set_attr "mode" "DF,SI,SI,DF")])
3027 (define_insn "*pushdf_integer"
3028 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3029 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3030 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3032 /* This insn should be already split before reg-stack. */
3035 [(set_attr "type" "multi")
3036 (set_attr "unit" "i387,*,*")
3037 (set_attr "mode" "DF,SI,DF")])
3039 ;; %%% Kill this when call knows how to work this out.
3041 [(set (match_operand:DF 0 "push_operand" "")
3042 (match_operand:DF 1 "any_fp_register_operand" ""))]
3044 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3045 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3049 [(set (match_operand:DF 0 "push_operand" "")
3050 (match_operand:DF 1 "general_operand" ""))]
3053 "ix86_split_long_move (operands); DONE;")
3055 ;; Moving is usually shorter when only FP registers are used. This separate
3056 ;; movdf pattern avoids the use of integer registers for FP operations
3057 ;; when optimizing for size.
3059 (define_insn "*movdf_nointeger"
3060 [(set (match_operand:DF 0 "nonimmediate_operand"
3061 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3062 (match_operand:DF 1 "general_operand"
3063 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3064 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3065 && ((optimize_function_for_size_p (cfun)
3066 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3067 && (reload_in_progress || reload_completed
3068 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3069 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3070 && optimize_function_for_size_p (cfun)
3071 && !memory_operand (operands[0], DFmode)
3072 && standard_80387_constant_p (operands[1]))
3073 || GET_CODE (operands[1]) != CONST_DOUBLE
3074 || ((optimize_function_for_size_p (cfun)
3075 || !TARGET_MEMORY_MISMATCH_STALL
3076 || reload_in_progress || reload_completed)
3077 && memory_operand (operands[0], DFmode)))"
3079 switch (which_alternative)
3083 return output_387_reg_move (insn, operands);
3086 return standard_80387_constant_opcode (operands[1]);
3092 switch (get_attr_mode (insn))
3095 return "%vxorps\t%0, %d0";
3097 return "%vxorpd\t%0, %d0";
3099 return "%vpxor\t%0, %d0";
3106 switch (get_attr_mode (insn))
3109 return "%vmovaps\t{%1, %0|%0, %1}";
3111 return "%vmovapd\t{%1, %0|%0, %1}";
3113 return "%vmovdqa\t{%1, %0|%0, %1}";
3115 return "%vmovq\t{%1, %0|%0, %1}";
3119 if (REG_P (operands[0]) && REG_P (operands[1]))
3120 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3122 return "vmovsd\t{%1, %0|%0, %1}";
3125 return "movsd\t{%1, %0|%0, %1}";
3129 if (REG_P (operands[0]))
3130 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3132 return "vmovlpd\t{%1, %0|%0, %1}";
3135 return "movlpd\t{%1, %0|%0, %1}";
3139 if (REG_P (operands[0]))
3140 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3142 return "vmovlps\t{%1, %0|%0, %1}";
3145 return "movlps\t{%1, %0|%0, %1}";
3154 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3155 (set (attr "prefix")
3156 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3157 (const_string "orig")
3158 (const_string "maybe_vex")))
3159 (set (attr "prefix_data16")
3160 (if_then_else (eq_attr "mode" "V1DF")
3162 (const_string "*")))
3164 (cond [(eq_attr "alternative" "0,1,2")
3166 (eq_attr "alternative" "3,4")
3169 /* For SSE1, we have many fewer alternatives. */
3170 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3171 (cond [(eq_attr "alternative" "5,6")
3172 (const_string "V4SF")
3174 (const_string "V2SF"))
3176 /* xorps is one byte shorter. */
3177 (eq_attr "alternative" "5")
3178 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3180 (const_string "V4SF")
3181 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3185 (const_string "V2DF"))
3187 /* For architectures resolving dependencies on
3188 whole SSE registers use APD move to break dependency
3189 chains, otherwise use short move to avoid extra work.
3191 movaps encodes one byte shorter. */
3192 (eq_attr "alternative" "6")
3194 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3196 (const_string "V4SF")
3197 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3199 (const_string "V2DF")
3201 (const_string "DF"))
3202 /* For architectures resolving dependencies on register
3203 parts we may avoid extra work to zero out upper part
3205 (eq_attr "alternative" "7")
3207 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3209 (const_string "V1DF")
3210 (const_string "DF"))
3212 (const_string "DF")))])
3214 (define_insn "*movdf_integer_rex64"
3215 [(set (match_operand:DF 0 "nonimmediate_operand"
3216 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3217 (match_operand:DF 1 "general_operand"
3218 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3219 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3220 && (reload_in_progress || reload_completed
3221 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3222 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3223 && optimize_function_for_size_p (cfun)
3224 && standard_80387_constant_p (operands[1]))
3225 || GET_CODE (operands[1]) != CONST_DOUBLE
3226 || memory_operand (operands[0], DFmode))"
3228 switch (which_alternative)
3232 return output_387_reg_move (insn, operands);
3235 return standard_80387_constant_opcode (operands[1]);
3242 switch (get_attr_mode (insn))
3245 return "%vxorps\t%0, %d0";
3247 return "%vxorpd\t%0, %d0";
3249 return "%vpxor\t%0, %d0";
3256 switch (get_attr_mode (insn))
3259 return "%vmovaps\t{%1, %0|%0, %1}";
3261 return "%vmovapd\t{%1, %0|%0, %1}";
3263 return "%vmovdqa\t{%1, %0|%0, %1}";
3265 return "%vmovq\t{%1, %0|%0, %1}";
3269 if (REG_P (operands[0]) && REG_P (operands[1]))
3270 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3272 return "vmovsd\t{%1, %0|%0, %1}";
3275 return "movsd\t{%1, %0|%0, %1}";
3277 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3279 return "%vmovlps\t{%1, %d0|%d0, %1}";
3286 return "%vmovd\t{%1, %0|%0, %1}";
3292 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3293 (set (attr "prefix")
3294 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3295 (const_string "orig")
3296 (const_string "maybe_vex")))
3297 (set (attr "prefix_data16")
3298 (if_then_else (eq_attr "mode" "V1DF")
3300 (const_string "*")))
3302 (cond [(eq_attr "alternative" "0,1,2")
3304 (eq_attr "alternative" "3,4,9,10")
3307 /* For SSE1, we have many fewer alternatives. */
3308 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3309 (cond [(eq_attr "alternative" "5,6")
3310 (const_string "V4SF")
3312 (const_string "V2SF"))
3314 /* xorps is one byte shorter. */
3315 (eq_attr "alternative" "5")
3316 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3318 (const_string "V4SF")
3319 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3323 (const_string "V2DF"))
3325 /* For architectures resolving dependencies on
3326 whole SSE registers use APD move to break dependency
3327 chains, otherwise use short move to avoid extra work.
3329 movaps encodes one byte shorter. */
3330 (eq_attr "alternative" "6")
3332 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3334 (const_string "V4SF")
3335 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3337 (const_string "V2DF")
3339 (const_string "DF"))
3340 /* For architectures resolving dependencies on register
3341 parts we may avoid extra work to zero out upper part
3343 (eq_attr "alternative" "7")
3345 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3347 (const_string "V1DF")
3348 (const_string "DF"))
3350 (const_string "DF")))])
3352 (define_insn "*movdf_integer"
3353 [(set (match_operand:DF 0 "nonimmediate_operand"
3354 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3355 (match_operand:DF 1 "general_operand"
3356 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3357 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3358 && optimize_function_for_speed_p (cfun)
3359 && TARGET_INTEGER_DFMODE_MOVES
3360 && (reload_in_progress || reload_completed
3361 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3362 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3363 && optimize_function_for_size_p (cfun)
3364 && standard_80387_constant_p (operands[1]))
3365 || GET_CODE (operands[1]) != CONST_DOUBLE
3366 || memory_operand (operands[0], DFmode))"
3368 switch (which_alternative)
3372 return output_387_reg_move (insn, operands);
3375 return standard_80387_constant_opcode (operands[1]);
3382 switch (get_attr_mode (insn))
3385 return "xorps\t%0, %0";
3387 return "xorpd\t%0, %0";
3389 return "pxor\t%0, %0";
3396 switch (get_attr_mode (insn))
3399 return "movaps\t{%1, %0|%0, %1}";
3401 return "movapd\t{%1, %0|%0, %1}";
3403 return "movdqa\t{%1, %0|%0, %1}";
3405 return "movq\t{%1, %0|%0, %1}";
3407 return "movsd\t{%1, %0|%0, %1}";
3409 return "movlpd\t{%1, %0|%0, %1}";
3411 return "movlps\t{%1, %0|%0, %1}";
3420 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3421 (set (attr "prefix_data16")
3422 (if_then_else (eq_attr "mode" "V1DF")
3424 (const_string "*")))
3426 (cond [(eq_attr "alternative" "0,1,2")
3428 (eq_attr "alternative" "3,4")
3431 /* For SSE1, we have many fewer alternatives. */
3432 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3433 (cond [(eq_attr "alternative" "5,6")
3434 (const_string "V4SF")
3436 (const_string "V2SF"))
3438 /* xorps is one byte shorter. */
3439 (eq_attr "alternative" "5")
3440 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3442 (const_string "V4SF")
3443 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3447 (const_string "V2DF"))
3449 /* For architectures resolving dependencies on
3450 whole SSE registers use APD move to break dependency
3451 chains, otherwise use short move to avoid extra work.
3453 movaps encodes one byte shorter. */
3454 (eq_attr "alternative" "6")
3456 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3458 (const_string "V4SF")
3459 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3461 (const_string "V2DF")
3463 (const_string "DF"))
3464 /* For architectures resolving dependencies on register
3465 parts we may avoid extra work to zero out upper part
3467 (eq_attr "alternative" "7")
3469 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3471 (const_string "V1DF")
3472 (const_string "DF"))
3474 (const_string "DF")))])
3477 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3478 (match_operand:DF 1 "general_operand" ""))]
3480 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3481 && ! (ANY_FP_REG_P (operands[0]) ||
3482 (GET_CODE (operands[0]) == SUBREG
3483 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3484 && ! (ANY_FP_REG_P (operands[1]) ||
3485 (GET_CODE (operands[1]) == SUBREG
3486 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3488 "ix86_split_long_move (operands); DONE;")
3490 (define_insn "*swapdf"
3491 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3492 (match_operand:DF 1 "fp_register_operand" "+f"))
3495 "reload_completed || TARGET_80387"
3497 if (STACK_TOP_P (operands[0]))
3502 [(set_attr "type" "fxch")
3503 (set_attr "mode" "DF")])
3505 (define_expand "movxf"
3506 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3507 (match_operand:XF 1 "general_operand" ""))]
3509 "ix86_expand_move (XFmode, operands); DONE;")
3511 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3512 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3513 ;; Pushing using integer instructions is longer except for constants
3514 ;; and direct memory references.
3515 ;; (assuming that any given constant is pushed only once, but this ought to be
3516 ;; handled elsewhere).
3518 (define_insn "*pushxf_nointeger"
3519 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3520 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3521 "optimize_function_for_size_p (cfun)"
3523 /* This insn should be already split before reg-stack. */
3526 [(set_attr "type" "multi")
3527 (set_attr "unit" "i387,*,*")
3528 (set_attr "mode" "XF,SI,SI")])
3530 (define_insn "*pushxf_integer"
3531 [(set (match_operand:XF 0 "push_operand" "=<,<")
3532 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3533 "optimize_function_for_speed_p (cfun)"
3535 /* This insn should be already split before reg-stack. */
3538 [(set_attr "type" "multi")
3539 (set_attr "unit" "i387,*")
3540 (set_attr "mode" "XF,SI")])
3543 [(set (match_operand 0 "push_operand" "")
3544 (match_operand 1 "general_operand" ""))]
3546 && (GET_MODE (operands[0]) == XFmode
3547 || GET_MODE (operands[0]) == DFmode)
3548 && !ANY_FP_REG_P (operands[1])"
3550 "ix86_split_long_move (operands); DONE;")
3553 [(set (match_operand:XF 0 "push_operand" "")
3554 (match_operand:XF 1 "any_fp_register_operand" ""))]
3556 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3557 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3558 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3560 ;; Do not use integer registers when optimizing for size
3561 (define_insn "*movxf_nointeger"
3562 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3563 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3564 "optimize_function_for_size_p (cfun)
3565 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3566 && (reload_in_progress || reload_completed
3567 || standard_80387_constant_p (operands[1])
3568 || GET_CODE (operands[1]) != CONST_DOUBLE
3569 || memory_operand (operands[0], XFmode))"
3571 switch (which_alternative)
3575 return output_387_reg_move (insn, operands);
3578 return standard_80387_constant_opcode (operands[1]);
3586 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3587 (set_attr "mode" "XF,XF,XF,SI,SI")])
3589 (define_insn "*movxf_integer"
3590 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3591 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3592 "optimize_function_for_speed_p (cfun)
3593 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3594 && (reload_in_progress || reload_completed
3595 || GET_CODE (operands[1]) != CONST_DOUBLE
3596 || memory_operand (operands[0], XFmode))"
3598 switch (which_alternative)
3602 return output_387_reg_move (insn, operands);
3605 return standard_80387_constant_opcode (operands[1]);
3614 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3615 (set_attr "mode" "XF,XF,XF,SI,SI")])
3617 (define_expand "movtf"
3618 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3619 (match_operand:TF 1 "nonimmediate_operand" ""))]
3622 ix86_expand_move (TFmode, operands);
3626 (define_insn "*movtf_internal"
3627 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3628 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3630 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3632 switch (which_alternative)
3636 if (get_attr_mode (insn) == MODE_V4SF)
3637 return "%vmovaps\t{%1, %0|%0, %1}";
3639 return "%vmovdqa\t{%1, %0|%0, %1}";
3641 if (get_attr_mode (insn) == MODE_V4SF)
3642 return "%vxorps\t%0, %d0";
3644 return "%vpxor\t%0, %d0";
3652 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3653 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3655 (cond [(eq_attr "alternative" "0,2")
3657 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3659 (const_string "V4SF")
3660 (const_string "TI"))
3661 (eq_attr "alternative" "1")
3663 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3665 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3667 (const_string "V4SF")
3668 (const_string "TI"))]
3669 (const_string "DI")))])
3671 (define_insn "*pushtf_sse"
3672 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3673 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3676 /* This insn should be already split before reg-stack. */
3679 [(set_attr "type" "multi")
3680 (set_attr "unit" "sse,*,*")
3681 (set_attr "mode" "TF,SI,SI")])
3684 [(set (match_operand:TF 0 "push_operand" "")
3685 (match_operand:TF 1 "general_operand" ""))]
3686 "TARGET_SSE2 && reload_completed
3687 && !SSE_REG_P (operands[1])"
3689 "ix86_split_long_move (operands); DONE;")
3692 [(set (match_operand:TF 0 "push_operand" "")
3693 (match_operand:TF 1 "any_fp_register_operand" ""))]
3695 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3696 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3700 [(set (match_operand 0 "nonimmediate_operand" "")
3701 (match_operand 1 "general_operand" ""))]
3703 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3704 && GET_MODE (operands[0]) == XFmode
3705 && ! (ANY_FP_REG_P (operands[0]) ||
3706 (GET_CODE (operands[0]) == SUBREG
3707 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3708 && ! (ANY_FP_REG_P (operands[1]) ||
3709 (GET_CODE (operands[1]) == SUBREG
3710 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3712 "ix86_split_long_move (operands); DONE;")
3715 [(set (match_operand 0 "register_operand" "")
3716 (match_operand 1 "memory_operand" ""))]
3718 && MEM_P (operands[1])
3719 && (GET_MODE (operands[0]) == TFmode
3720 || GET_MODE (operands[0]) == XFmode
3721 || GET_MODE (operands[0]) == SFmode
3722 || GET_MODE (operands[0]) == DFmode)
3723 && (operands[2] = find_constant_src (insn))"
3724 [(set (match_dup 0) (match_dup 2))]
3726 rtx c = operands[2];
3727 rtx r = operands[0];
3729 if (GET_CODE (r) == SUBREG)
3734 if (!standard_sse_constant_p (c))
3737 else if (FP_REG_P (r))
3739 if (!standard_80387_constant_p (c))
3742 else if (MMX_REG_P (r))
3747 [(set (match_operand 0 "register_operand" "")
3748 (float_extend (match_operand 1 "memory_operand" "")))]
3750 && MEM_P (operands[1])
3751 && (GET_MODE (operands[0]) == TFmode
3752 || GET_MODE (operands[0]) == XFmode
3753 || GET_MODE (operands[0]) == SFmode
3754 || GET_MODE (operands[0]) == DFmode)
3755 && (operands[2] = find_constant_src (insn))"
3756 [(set (match_dup 0) (match_dup 2))]
3758 rtx c = operands[2];
3759 rtx r = operands[0];
3761 if (GET_CODE (r) == SUBREG)
3766 if (!standard_sse_constant_p (c))
3769 else if (FP_REG_P (r))
3771 if (!standard_80387_constant_p (c))
3774 else if (MMX_REG_P (r))
3778 (define_insn "swapxf"
3779 [(set (match_operand:XF 0 "register_operand" "+f")
3780 (match_operand:XF 1 "register_operand" "+f"))
3785 if (STACK_TOP_P (operands[0]))
3790 [(set_attr "type" "fxch")
3791 (set_attr "mode" "XF")])
3793 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3795 [(set (match_operand:X87MODEF 0 "register_operand" "")
3796 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3797 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3798 && (standard_80387_constant_p (operands[1]) == 8
3799 || standard_80387_constant_p (operands[1]) == 9)"
3800 [(set (match_dup 0)(match_dup 1))
3802 (neg:X87MODEF (match_dup 0)))]
3806 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3807 if (real_isnegzero (&r))
3808 operands[1] = CONST0_RTX (<MODE>mode);
3810 operands[1] = CONST1_RTX (<MODE>mode);
3814 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3815 (match_operand:TF 1 "general_operand" ""))]
3817 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3819 "ix86_split_long_move (operands); DONE;")
3821 ;; Zero extension instructions
3823 (define_expand "zero_extendhisi2"
3824 [(set (match_operand:SI 0 "register_operand" "")
3825 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3828 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3830 operands[1] = force_reg (HImode, operands[1]);
3831 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3836 (define_insn "zero_extendhisi2_and"
3837 [(set (match_operand:SI 0 "register_operand" "=r")
3838 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3839 (clobber (reg:CC FLAGS_REG))]
3840 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3842 [(set_attr "type" "alu1")
3843 (set_attr "mode" "SI")])
3846 [(set (match_operand:SI 0 "register_operand" "")
3847 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3848 (clobber (reg:CC FLAGS_REG))]
3849 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3850 && optimize_function_for_speed_p (cfun)"
3851 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3852 (clobber (reg:CC FLAGS_REG))])]
3855 (define_insn "*zero_extendhisi2_movzwl"
3856 [(set (match_operand:SI 0 "register_operand" "=r")
3857 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3858 "!TARGET_ZERO_EXTEND_WITH_AND
3859 || optimize_function_for_size_p (cfun)"
3860 "movz{wl|x}\t{%1, %0|%0, %1}"
3861 [(set_attr "type" "imovx")
3862 (set_attr "mode" "SI")])
3864 (define_expand "zero_extendqihi2"
3866 [(set (match_operand:HI 0 "register_operand" "")
3867 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3868 (clobber (reg:CC FLAGS_REG))])]
3872 (define_insn "*zero_extendqihi2_and"
3873 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3874 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3875 (clobber (reg:CC FLAGS_REG))]
3876 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3878 [(set_attr "type" "alu1")
3879 (set_attr "mode" "HI")])
3881 (define_insn "*zero_extendqihi2_movzbw_and"
3882 [(set (match_operand:HI 0 "register_operand" "=r,r")
3883 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3884 (clobber (reg:CC FLAGS_REG))]
3885 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3887 [(set_attr "type" "imovx,alu1")
3888 (set_attr "mode" "HI")])
3890 ; zero extend to SImode here to avoid partial register stalls
3891 (define_insn "*zero_extendqihi2_movzbl"
3892 [(set (match_operand:HI 0 "register_operand" "=r")
3893 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3894 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3895 && reload_completed"
3896 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3897 [(set_attr "type" "imovx")
3898 (set_attr "mode" "SI")])
3900 ;; For the movzbw case strip only the clobber
3902 [(set (match_operand:HI 0 "register_operand" "")
3903 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3904 (clobber (reg:CC FLAGS_REG))]
3906 && (!TARGET_ZERO_EXTEND_WITH_AND
3907 || optimize_function_for_size_p (cfun))
3908 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3909 [(set (match_operand:HI 0 "register_operand" "")
3910 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3912 ;; When source and destination does not overlap, clear destination
3913 ;; first and then do the movb
3915 [(set (match_operand:HI 0 "register_operand" "")
3916 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3917 (clobber (reg:CC FLAGS_REG))]
3919 && ANY_QI_REG_P (operands[0])
3920 && (TARGET_ZERO_EXTEND_WITH_AND
3921 && optimize_function_for_speed_p (cfun))
3922 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3923 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3925 operands[2] = gen_lowpart (QImode, operands[0]);
3926 ix86_expand_clear (operands[0]);
3929 ;; Rest is handled by single and.
3931 [(set (match_operand:HI 0 "register_operand" "")
3932 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3933 (clobber (reg:CC FLAGS_REG))]
3935 && true_regnum (operands[0]) == true_regnum (operands[1])"
3936 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3937 (clobber (reg:CC FLAGS_REG))])]
3940 (define_expand "zero_extendqisi2"
3942 [(set (match_operand:SI 0 "register_operand" "")
3943 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3944 (clobber (reg:CC FLAGS_REG))])]
3948 (define_insn "*zero_extendqisi2_and"
3949 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3950 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3951 (clobber (reg:CC FLAGS_REG))]
3952 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3954 [(set_attr "type" "alu1")
3955 (set_attr "mode" "SI")])
3957 (define_insn "*zero_extendqisi2_movzbl_and"
3958 [(set (match_operand:SI 0 "register_operand" "=r,r")
3959 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3960 (clobber (reg:CC FLAGS_REG))]
3961 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3963 [(set_attr "type" "imovx,alu1")
3964 (set_attr "mode" "SI")])
3966 (define_insn "*zero_extendqisi2_movzbl"
3967 [(set (match_operand:SI 0 "register_operand" "=r")
3968 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3969 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3970 && reload_completed"
3971 "movz{bl|x}\t{%1, %0|%0, %1}"
3972 [(set_attr "type" "imovx")
3973 (set_attr "mode" "SI")])
3975 ;; For the movzbl case strip only the clobber
3977 [(set (match_operand:SI 0 "register_operand" "")
3978 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3979 (clobber (reg:CC FLAGS_REG))]
3981 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3982 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3984 (zero_extend:SI (match_dup 1)))])
3986 ;; When source and destination does not overlap, clear destination
3987 ;; first and then do the movb
3989 [(set (match_operand:SI 0 "register_operand" "")
3990 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3991 (clobber (reg:CC FLAGS_REG))]
3993 && ANY_QI_REG_P (operands[0])
3994 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3995 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3996 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3997 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3999 operands[2] = gen_lowpart (QImode, operands[0]);
4000 ix86_expand_clear (operands[0]);
4003 ;; Rest is handled by single and.
4005 [(set (match_operand:SI 0 "register_operand" "")
4006 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4007 (clobber (reg:CC FLAGS_REG))]
4009 && true_regnum (operands[0]) == true_regnum (operands[1])"
4010 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4011 (clobber (reg:CC FLAGS_REG))])]
4014 ;; %%% Kill me once multi-word ops are sane.
4015 (define_expand "zero_extendsidi2"
4016 [(set (match_operand:DI 0 "register_operand" "")
4017 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4022 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4027 (define_insn "zero_extendsidi2_32"
4028 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4030 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
4031 (clobber (reg:CC FLAGS_REG))]
4037 movd\t{%1, %0|%0, %1}
4038 movd\t{%1, %0|%0, %1}
4039 %vmovd\t{%1, %0|%0, %1}
4040 %vmovd\t{%1, %0|%0, %1}"
4041 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4042 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4043 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4045 (define_insn "zero_extendsidi2_rex64"
4046 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4048 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4051 mov\t{%k1, %k0|%k0, %k1}
4053 movd\t{%1, %0|%0, %1}
4054 movd\t{%1, %0|%0, %1}
4055 %vmovd\t{%1, %0|%0, %1}
4056 %vmovd\t{%1, %0|%0, %1}"
4057 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4058 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4059 (set_attr "prefix_0f" "0,*,*,*,*,*")
4060 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4063 [(set (match_operand:DI 0 "memory_operand" "")
4064 (zero_extend:DI (match_dup 0)))]
4066 [(set (match_dup 4) (const_int 0))]
4067 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4070 [(set (match_operand:DI 0 "register_operand" "")
4071 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4072 (clobber (reg:CC FLAGS_REG))]
4073 "!TARGET_64BIT && reload_completed
4074 && true_regnum (operands[0]) == true_regnum (operands[1])"
4075 [(set (match_dup 4) (const_int 0))]
4076 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4079 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4080 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4081 (clobber (reg:CC FLAGS_REG))]
4082 "!TARGET_64BIT && reload_completed
4083 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4084 [(set (match_dup 3) (match_dup 1))
4085 (set (match_dup 4) (const_int 0))]
4086 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4088 (define_insn "zero_extendhidi2"
4089 [(set (match_operand:DI 0 "register_operand" "=r")
4090 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4092 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4093 [(set_attr "type" "imovx")
4094 (set_attr "mode" "SI")])
4096 (define_insn "zero_extendqidi2"
4097 [(set (match_operand:DI 0 "register_operand" "=r")
4098 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4100 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4101 [(set_attr "type" "imovx")
4102 (set_attr "mode" "SI")])
4104 ;; Sign extension instructions
4106 (define_expand "extendsidi2"
4107 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4108 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4109 (clobber (reg:CC FLAGS_REG))
4110 (clobber (match_scratch:SI 2 ""))])]
4115 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4120 (define_insn "*extendsidi2_1"
4121 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4122 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4123 (clobber (reg:CC FLAGS_REG))
4124 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4128 (define_insn "extendsidi2_rex64"
4129 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4130 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4134 movs{lq|x}\t{%1, %0|%0, %1}"
4135 [(set_attr "type" "imovx")
4136 (set_attr "mode" "DI")
4137 (set_attr "prefix_0f" "0")
4138 (set_attr "modrm" "0,1")])
4140 (define_insn "extendhidi2"
4141 [(set (match_operand:DI 0 "register_operand" "=r")
4142 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4144 "movs{wq|x}\t{%1, %0|%0, %1}"
4145 [(set_attr "type" "imovx")
4146 (set_attr "mode" "DI")])
4148 (define_insn "extendqidi2"
4149 [(set (match_operand:DI 0 "register_operand" "=r")
4150 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4152 "movs{bq|x}\t{%1, %0|%0, %1}"
4153 [(set_attr "type" "imovx")
4154 (set_attr "mode" "DI")])
4156 ;; Extend to memory case when source register does die.
4158 [(set (match_operand:DI 0 "memory_operand" "")
4159 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4160 (clobber (reg:CC FLAGS_REG))
4161 (clobber (match_operand:SI 2 "register_operand" ""))]
4163 && dead_or_set_p (insn, operands[1])
4164 && !reg_mentioned_p (operands[1], operands[0]))"
4165 [(set (match_dup 3) (match_dup 1))
4166 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4167 (clobber (reg:CC FLAGS_REG))])
4168 (set (match_dup 4) (match_dup 1))]
4169 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4171 ;; Extend to memory case when source register does not die.
4173 [(set (match_operand:DI 0 "memory_operand" "")
4174 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4175 (clobber (reg:CC FLAGS_REG))
4176 (clobber (match_operand:SI 2 "register_operand" ""))]
4180 split_di (&operands[0], 1, &operands[3], &operands[4]);
4182 emit_move_insn (operands[3], operands[1]);
4184 /* Generate a cltd if possible and doing so it profitable. */
4185 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4186 && true_regnum (operands[1]) == AX_REG
4187 && true_regnum (operands[2]) == DX_REG)
4189 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4193 emit_move_insn (operands[2], operands[1]);
4194 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4196 emit_move_insn (operands[4], operands[2]);
4200 ;; Extend to register case. Optimize case where source and destination
4201 ;; registers match and cases where we can use cltd.
4203 [(set (match_operand:DI 0 "register_operand" "")
4204 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4205 (clobber (reg:CC FLAGS_REG))
4206 (clobber (match_scratch:SI 2 ""))]
4210 split_di (&operands[0], 1, &operands[3], &operands[4]);
4212 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4213 emit_move_insn (operands[3], operands[1]);
4215 /* Generate a cltd if possible and doing so it profitable. */
4216 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4217 && true_regnum (operands[3]) == AX_REG)
4219 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4223 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4224 emit_move_insn (operands[4], operands[1]);
4226 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4230 (define_insn "extendhisi2"
4231 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4232 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4235 switch (get_attr_prefix_0f (insn))
4238 return "{cwtl|cwde}";
4240 return "movs{wl|x}\t{%1, %0|%0, %1}";
4243 [(set_attr "type" "imovx")
4244 (set_attr "mode" "SI")
4245 (set (attr "prefix_0f")
4246 ;; movsx is short decodable while cwtl is vector decoded.
4247 (if_then_else (and (eq_attr "cpu" "!k6")
4248 (eq_attr "alternative" "0"))
4250 (const_string "1")))
4252 (if_then_else (eq_attr "prefix_0f" "0")
4254 (const_string "1")))])
4256 (define_insn "*extendhisi2_zext"
4257 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4259 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4262 switch (get_attr_prefix_0f (insn))
4265 return "{cwtl|cwde}";
4267 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4270 [(set_attr "type" "imovx")
4271 (set_attr "mode" "SI")
4272 (set (attr "prefix_0f")
4273 ;; movsx is short decodable while cwtl is vector decoded.
4274 (if_then_else (and (eq_attr "cpu" "!k6")
4275 (eq_attr "alternative" "0"))
4277 (const_string "1")))
4279 (if_then_else (eq_attr "prefix_0f" "0")
4281 (const_string "1")))])
4283 (define_insn "extendqihi2"
4284 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4285 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4288 switch (get_attr_prefix_0f (insn))
4291 return "{cbtw|cbw}";
4293 return "movs{bw|x}\t{%1, %0|%0, %1}";
4296 [(set_attr "type" "imovx")
4297 (set_attr "mode" "HI")
4298 (set (attr "prefix_0f")
4299 ;; movsx is short decodable while cwtl is vector decoded.
4300 (if_then_else (and (eq_attr "cpu" "!k6")
4301 (eq_attr "alternative" "0"))
4303 (const_string "1")))
4305 (if_then_else (eq_attr "prefix_0f" "0")
4307 (const_string "1")))])
4309 (define_insn "extendqisi2"
4310 [(set (match_operand:SI 0 "register_operand" "=r")
4311 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4313 "movs{bl|x}\t{%1, %0|%0, %1}"
4314 [(set_attr "type" "imovx")
4315 (set_attr "mode" "SI")])
4317 (define_insn "*extendqisi2_zext"
4318 [(set (match_operand:DI 0 "register_operand" "=r")
4320 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4322 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4323 [(set_attr "type" "imovx")
4324 (set_attr "mode" "SI")])
4326 ;; Conversions between float and double.
4328 ;; These are all no-ops in the model used for the 80387. So just
4331 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4332 (define_insn "*dummy_extendsfdf2"
4333 [(set (match_operand:DF 0 "push_operand" "=<")
4334 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4339 [(set (match_operand:DF 0 "push_operand" "")
4340 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4342 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4343 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4345 (define_insn "*dummy_extendsfxf2"
4346 [(set (match_operand:XF 0 "push_operand" "=<")
4347 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4352 [(set (match_operand:XF 0 "push_operand" "")
4353 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4355 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4356 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4357 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4360 [(set (match_operand:XF 0 "push_operand" "")
4361 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4363 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4364 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4365 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4367 (define_expand "extendsfdf2"
4368 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4369 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4370 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4372 /* ??? Needed for compress_float_constant since all fp constants
4373 are LEGITIMATE_CONSTANT_P. */
4374 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4376 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4377 && standard_80387_constant_p (operands[1]) > 0)
4379 operands[1] = simplify_const_unary_operation
4380 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4381 emit_move_insn_1 (operands[0], operands[1]);
4384 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4388 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4390 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4392 We do the conversion post reload to avoid producing of 128bit spills
4393 that might lead to ICE on 32bit target. The sequence unlikely combine
4396 [(set (match_operand:DF 0 "register_operand" "")
4398 (match_operand:SF 1 "nonimmediate_operand" "")))]
4399 "TARGET_USE_VECTOR_FP_CONVERTS
4400 && optimize_insn_for_speed_p ()
4401 && reload_completed && SSE_REG_P (operands[0])"
4406 (parallel [(const_int 0) (const_int 1)]))))]
4408 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4409 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4410 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4411 Try to avoid move when unpacking can be done in source. */
4412 if (REG_P (operands[1]))
4414 /* If it is unsafe to overwrite upper half of source, we need
4415 to move to destination and unpack there. */
4416 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4417 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4418 && true_regnum (operands[0]) != true_regnum (operands[1]))
4420 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4421 emit_move_insn (tmp, operands[1]);
4424 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4425 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4429 emit_insn (gen_vec_setv4sf_0 (operands[3],
4430 CONST0_RTX (V4SFmode), operands[1]));
4433 (define_insn "*extendsfdf2_mixed"
4434 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4436 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4437 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4439 switch (which_alternative)
4443 return output_387_reg_move (insn, operands);
4446 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4452 [(set_attr "type" "fmov,fmov,ssecvt")
4453 (set_attr "prefix" "orig,orig,maybe_vex")
4454 (set_attr "mode" "SF,XF,DF")])
4456 (define_insn "*extendsfdf2_sse"
4457 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4458 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4459 "TARGET_SSE2 && TARGET_SSE_MATH"
4460 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4461 [(set_attr "type" "ssecvt")
4462 (set_attr "prefix" "maybe_vex")
4463 (set_attr "mode" "DF")])
4465 (define_insn "*extendsfdf2_i387"
4466 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4467 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4469 "* return output_387_reg_move (insn, operands);"
4470 [(set_attr "type" "fmov")
4471 (set_attr "mode" "SF,XF")])
4473 (define_expand "extend<mode>xf2"
4474 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4475 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4478 /* ??? Needed for compress_float_constant since all fp constants
4479 are LEGITIMATE_CONSTANT_P. */
4480 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4482 if (standard_80387_constant_p (operands[1]) > 0)
4484 operands[1] = simplify_const_unary_operation
4485 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4486 emit_move_insn_1 (operands[0], operands[1]);
4489 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4493 (define_insn "*extend<mode>xf2_i387"
4494 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4496 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4498 "* return output_387_reg_move (insn, operands);"
4499 [(set_attr "type" "fmov")
4500 (set_attr "mode" "<MODE>,XF")])
4502 ;; %%% This seems bad bad news.
4503 ;; This cannot output into an f-reg because there is no way to be sure
4504 ;; of truncating in that case. Otherwise this is just like a simple move
4505 ;; insn. So we pretend we can output to a reg in order to get better
4506 ;; register preferencing, but we really use a stack slot.
4508 ;; Conversion from DFmode to SFmode.
4510 (define_expand "truncdfsf2"
4511 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4513 (match_operand:DF 1 "nonimmediate_operand" "")))]
4514 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4516 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4518 else if (flag_unsafe_math_optimizations)
4522 enum ix86_stack_slot slot = (virtuals_instantiated
4525 rtx temp = assign_386_stack_local (SFmode, slot);
4526 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4531 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4533 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4535 We do the conversion post reload to avoid producing of 128bit spills
4536 that might lead to ICE on 32bit target. The sequence unlikely combine
4539 [(set (match_operand:SF 0 "register_operand" "")
4541 (match_operand:DF 1 "nonimmediate_operand" "")))]
4542 "TARGET_USE_VECTOR_FP_CONVERTS
4543 && optimize_insn_for_speed_p ()
4544 && reload_completed && SSE_REG_P (operands[0])"
4547 (float_truncate:V2SF
4551 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4552 operands[3] = CONST0_RTX (V2SFmode);
4553 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4554 /* Use movsd for loading from memory, unpcklpd for registers.
4555 Try to avoid move when unpacking can be done in source, or SSE3
4556 movddup is available. */
4557 if (REG_P (operands[1]))
4560 && true_regnum (operands[0]) != true_regnum (operands[1])
4561 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4562 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4564 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4565 emit_move_insn (tmp, operands[1]);
4568 else if (!TARGET_SSE3)
4569 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4570 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4573 emit_insn (gen_sse2_loadlpd (operands[4],
4574 CONST0_RTX (V2DFmode), operands[1]));
4577 (define_expand "truncdfsf2_with_temp"
4578 [(parallel [(set (match_operand:SF 0 "" "")
4579 (float_truncate:SF (match_operand:DF 1 "" "")))
4580 (clobber (match_operand:SF 2 "" ""))])]
4583 (define_insn "*truncdfsf_fast_mixed"
4584 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4586 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4587 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4589 switch (which_alternative)
4592 return output_387_reg_move (insn, operands);
4594 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4599 [(set_attr "type" "fmov,ssecvt")
4600 (set_attr "prefix" "orig,maybe_vex")
4601 (set_attr "mode" "SF")])
4603 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4604 ;; because nothing we do here is unsafe.
4605 (define_insn "*truncdfsf_fast_sse"
4606 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4608 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4609 "TARGET_SSE2 && TARGET_SSE_MATH"
4610 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4611 [(set_attr "type" "ssecvt")
4612 (set_attr "prefix" "maybe_vex")
4613 (set_attr "mode" "SF")])
4615 (define_insn "*truncdfsf_fast_i387"
4616 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4618 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4619 "TARGET_80387 && flag_unsafe_math_optimizations"
4620 "* return output_387_reg_move (insn, operands);"
4621 [(set_attr "type" "fmov")
4622 (set_attr "mode" "SF")])
4624 (define_insn "*truncdfsf_mixed"
4625 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4627 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4628 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4629 "TARGET_MIX_SSE_I387"
4631 switch (which_alternative)
4634 return output_387_reg_move (insn, operands);
4636 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4642 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4643 (set_attr "unit" "*,*,i387,i387,i387")
4644 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4645 (set_attr "mode" "SF")])
4647 (define_insn "*truncdfsf_i387"
4648 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4650 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4651 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4654 switch (which_alternative)
4657 return output_387_reg_move (insn, operands);
4663 [(set_attr "type" "fmov,multi,multi,multi")
4664 (set_attr "unit" "*,i387,i387,i387")
4665 (set_attr "mode" "SF")])
4667 (define_insn "*truncdfsf2_i387_1"
4668 [(set (match_operand:SF 0 "memory_operand" "=m")
4670 (match_operand:DF 1 "register_operand" "f")))]
4672 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4673 && !TARGET_MIX_SSE_I387"
4674 "* return output_387_reg_move (insn, operands);"
4675 [(set_attr "type" "fmov")
4676 (set_attr "mode" "SF")])
4679 [(set (match_operand:SF 0 "register_operand" "")
4681 (match_operand:DF 1 "fp_register_operand" "")))
4682 (clobber (match_operand 2 "" ""))]
4684 [(set (match_dup 2) (match_dup 1))
4685 (set (match_dup 0) (match_dup 2))]
4687 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4690 ;; Conversion from XFmode to {SF,DF}mode
4692 (define_expand "truncxf<mode>2"
4693 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4694 (float_truncate:MODEF
4695 (match_operand:XF 1 "register_operand" "")))
4696 (clobber (match_dup 2))])]
4699 if (flag_unsafe_math_optimizations)
4701 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4702 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4703 if (reg != operands[0])
4704 emit_move_insn (operands[0], reg);
4709 enum ix86_stack_slot slot = (virtuals_instantiated
4712 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4716 (define_insn "*truncxfsf2_mixed"
4717 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4719 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4720 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4723 gcc_assert (!which_alternative);
4724 return output_387_reg_move (insn, operands);
4726 [(set_attr "type" "fmov,multi,multi,multi")
4727 (set_attr "unit" "*,i387,i387,i387")
4728 (set_attr "mode" "SF")])
4730 (define_insn "*truncxfdf2_mixed"
4731 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4733 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4734 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4737 gcc_assert (!which_alternative);
4738 return output_387_reg_move (insn, operands);
4740 [(set_attr "type" "fmov,multi,multi,multi")
4741 (set_attr "unit" "*,i387,i387,i387")
4742 (set_attr "mode" "DF")])
4744 (define_insn "truncxf<mode>2_i387_noop"
4745 [(set (match_operand:MODEF 0 "register_operand" "=f")
4746 (float_truncate:MODEF
4747 (match_operand:XF 1 "register_operand" "f")))]
4748 "TARGET_80387 && flag_unsafe_math_optimizations"
4749 "* return output_387_reg_move (insn, operands);"
4750 [(set_attr "type" "fmov")
4751 (set_attr "mode" "<MODE>")])
4753 (define_insn "*truncxf<mode>2_i387"
4754 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4755 (float_truncate:MODEF
4756 (match_operand:XF 1 "register_operand" "f")))]
4758 "* return output_387_reg_move (insn, operands);"
4759 [(set_attr "type" "fmov")
4760 (set_attr "mode" "<MODE>")])
4763 [(set (match_operand:MODEF 0 "register_operand" "")
4764 (float_truncate:MODEF
4765 (match_operand:XF 1 "register_operand" "")))
4766 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4767 "TARGET_80387 && reload_completed"
4768 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4769 (set (match_dup 0) (match_dup 2))]
4773 [(set (match_operand:MODEF 0 "memory_operand" "")
4774 (float_truncate:MODEF
4775 (match_operand:XF 1 "register_operand" "")))
4776 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4778 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4781 ;; Signed conversion to DImode.
4783 (define_expand "fix_truncxfdi2"
4784 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4785 (fix:DI (match_operand:XF 1 "register_operand" "")))
4786 (clobber (reg:CC FLAGS_REG))])]
4791 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4796 (define_expand "fix_trunc<mode>di2"
4797 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4798 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4799 (clobber (reg:CC FLAGS_REG))])]
4800 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4803 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4805 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4808 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4810 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4811 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4812 if (out != operands[0])
4813 emit_move_insn (operands[0], out);
4818 ;; Signed conversion to SImode.
4820 (define_expand "fix_truncxfsi2"
4821 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4822 (fix:SI (match_operand:XF 1 "register_operand" "")))
4823 (clobber (reg:CC FLAGS_REG))])]
4828 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4833 (define_expand "fix_trunc<mode>si2"
4834 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4835 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4836 (clobber (reg:CC FLAGS_REG))])]
4837 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4840 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4842 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4845 if (SSE_FLOAT_MODE_P (<MODE>mode))
4847 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4848 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4849 if (out != operands[0])
4850 emit_move_insn (operands[0], out);
4855 ;; Signed conversion to HImode.
4857 (define_expand "fix_trunc<mode>hi2"
4858 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4859 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4860 (clobber (reg:CC FLAGS_REG))])]
4862 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4866 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4871 ;; Unsigned conversion to SImode.
4873 (define_expand "fixuns_trunc<mode>si2"
4875 [(set (match_operand:SI 0 "register_operand" "")
4877 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4879 (clobber (match_scratch:<ssevecmode> 3 ""))
4880 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4881 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4883 enum machine_mode mode = <MODE>mode;
4884 enum machine_mode vecmode = <ssevecmode>mode;
4885 REAL_VALUE_TYPE TWO31r;
4888 if (optimize_insn_for_size_p ())
4891 real_ldexp (&TWO31r, &dconst1, 31);
4892 two31 = const_double_from_real_value (TWO31r, mode);
4893 two31 = ix86_build_const_vector (mode, true, two31);
4894 operands[2] = force_reg (vecmode, two31);
4897 (define_insn_and_split "*fixuns_trunc<mode>_1"
4898 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4900 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4901 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4902 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4903 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4904 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4905 && optimize_function_for_speed_p (cfun)"
4907 "&& reload_completed"
4910 ix86_split_convert_uns_si_sse (operands);
4914 ;; Unsigned conversion to HImode.
4915 ;; Without these patterns, we'll try the unsigned SI conversion which
4916 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4918 (define_expand "fixuns_trunc<mode>hi2"
4920 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4921 (set (match_operand:HI 0 "nonimmediate_operand" "")
4922 (subreg:HI (match_dup 2) 0))]
4923 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4924 "operands[2] = gen_reg_rtx (SImode);")
4926 ;; When SSE is available, it is always faster to use it!
4927 (define_insn "fix_trunc<mode>di_sse"
4928 [(set (match_operand:DI 0 "register_operand" "=r,r")
4929 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4930 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4931 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4932 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4933 [(set_attr "type" "sseicvt")
4934 (set_attr "prefix" "maybe_vex")
4935 (set_attr "prefix_rex" "1")
4936 (set_attr "mode" "<MODE>")
4937 (set_attr "athlon_decode" "double,vector")
4938 (set_attr "amdfam10_decode" "double,double")])
4940 (define_insn "fix_trunc<mode>si_sse"
4941 [(set (match_operand:SI 0 "register_operand" "=r,r")
4942 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4943 "SSE_FLOAT_MODE_P (<MODE>mode)
4944 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4945 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4946 [(set_attr "type" "sseicvt")
4947 (set_attr "prefix" "maybe_vex")
4948 (set_attr "mode" "<MODE>")
4949 (set_attr "athlon_decode" "double,vector")
4950 (set_attr "amdfam10_decode" "double,double")])
4952 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4954 [(set (match_operand:MODEF 0 "register_operand" "")
4955 (match_operand:MODEF 1 "memory_operand" ""))
4956 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4957 (fix:SSEMODEI24 (match_dup 0)))]
4958 "TARGET_SHORTEN_X87_SSE
4959 && peep2_reg_dead_p (2, operands[0])"
4960 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4963 ;; Avoid vector decoded forms of the instruction.
4965 [(match_scratch:DF 2 "Y2")
4966 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4967 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4968 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4969 [(set (match_dup 2) (match_dup 1))
4970 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4974 [(match_scratch:SF 2 "x")
4975 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4976 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4977 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4978 [(set (match_dup 2) (match_dup 1))
4979 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4982 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4983 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4984 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4985 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4987 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4988 && (TARGET_64BIT || <MODE>mode != DImode))
4990 && can_create_pseudo_p ()"
4995 if (memory_operand (operands[0], VOIDmode))
4996 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4999 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5000 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5006 [(set_attr "type" "fisttp")
5007 (set_attr "mode" "<MODE>")])
5009 (define_insn "fix_trunc<mode>_i387_fisttp"
5010 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5011 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5012 (clobber (match_scratch:XF 2 "=&1f"))]
5013 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5015 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5016 && (TARGET_64BIT || <MODE>mode != DImode))
5017 && TARGET_SSE_MATH)"
5018 "* return output_fix_trunc (insn, operands, 1);"
5019 [(set_attr "type" "fisttp")
5020 (set_attr "mode" "<MODE>")])
5022 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5023 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5024 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5025 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5026 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5027 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5029 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5030 && (TARGET_64BIT || <MODE>mode != DImode))
5031 && TARGET_SSE_MATH)"
5033 [(set_attr "type" "fisttp")
5034 (set_attr "mode" "<MODE>")])
5037 [(set (match_operand:X87MODEI 0 "register_operand" "")
5038 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5039 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5040 (clobber (match_scratch 3 ""))]
5042 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5043 (clobber (match_dup 3))])
5044 (set (match_dup 0) (match_dup 2))]
5048 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5049 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5050 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5051 (clobber (match_scratch 3 ""))]
5053 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5054 (clobber (match_dup 3))])]
5057 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5058 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5059 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5060 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5061 ;; function in i386.c.
5062 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5063 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5064 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5065 (clobber (reg:CC FLAGS_REG))]
5066 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5068 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5069 && (TARGET_64BIT || <MODE>mode != DImode))
5070 && can_create_pseudo_p ()"
5075 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5077 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5078 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5079 if (memory_operand (operands[0], VOIDmode))
5080 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5081 operands[2], operands[3]));
5084 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5085 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5086 operands[2], operands[3],
5091 [(set_attr "type" "fistp")
5092 (set_attr "i387_cw" "trunc")
5093 (set_attr "mode" "<MODE>")])
5095 (define_insn "fix_truncdi_i387"
5096 [(set (match_operand:DI 0 "memory_operand" "=m")
5097 (fix:DI (match_operand 1 "register_operand" "f")))
5098 (use (match_operand:HI 2 "memory_operand" "m"))
5099 (use (match_operand:HI 3 "memory_operand" "m"))
5100 (clobber (match_scratch:XF 4 "=&1f"))]
5101 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5103 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5104 "* return output_fix_trunc (insn, operands, 0);"
5105 [(set_attr "type" "fistp")
5106 (set_attr "i387_cw" "trunc")
5107 (set_attr "mode" "DI")])
5109 (define_insn "fix_truncdi_i387_with_temp"
5110 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5111 (fix:DI (match_operand 1 "register_operand" "f,f")))
5112 (use (match_operand:HI 2 "memory_operand" "m,m"))
5113 (use (match_operand:HI 3 "memory_operand" "m,m"))
5114 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5115 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5116 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5118 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5120 [(set_attr "type" "fistp")
5121 (set_attr "i387_cw" "trunc")
5122 (set_attr "mode" "DI")])
5125 [(set (match_operand:DI 0 "register_operand" "")
5126 (fix:DI (match_operand 1 "register_operand" "")))
5127 (use (match_operand:HI 2 "memory_operand" ""))
5128 (use (match_operand:HI 3 "memory_operand" ""))
5129 (clobber (match_operand:DI 4 "memory_operand" ""))
5130 (clobber (match_scratch 5 ""))]
5132 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5135 (clobber (match_dup 5))])
5136 (set (match_dup 0) (match_dup 4))]
5140 [(set (match_operand:DI 0 "memory_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 0) (fix:DI (match_dup 1)))
5150 (clobber (match_dup 5))])]
5153 (define_insn "fix_trunc<mode>_i387"
5154 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5155 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5156 (use (match_operand:HI 2 "memory_operand" "m"))
5157 (use (match_operand:HI 3 "memory_operand" "m"))]
5158 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5160 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5161 "* return output_fix_trunc (insn, operands, 0);"
5162 [(set_attr "type" "fistp")
5163 (set_attr "i387_cw" "trunc")
5164 (set_attr "mode" "<MODE>")])
5166 (define_insn "fix_trunc<mode>_i387_with_temp"
5167 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5168 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5169 (use (match_operand:HI 2 "memory_operand" "m,m"))
5170 (use (match_operand:HI 3 "memory_operand" "m,m"))
5171 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5172 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5174 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5176 [(set_attr "type" "fistp")
5177 (set_attr "i387_cw" "trunc")
5178 (set_attr "mode" "<MODE>")])
5181 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5182 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5183 (use (match_operand:HI 2 "memory_operand" ""))
5184 (use (match_operand:HI 3 "memory_operand" ""))
5185 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5187 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5189 (use (match_dup 3))])
5190 (set (match_dup 0) (match_dup 4))]
5194 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5195 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5196 (use (match_operand:HI 2 "memory_operand" ""))
5197 (use (match_operand:HI 3 "memory_operand" ""))
5198 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5200 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5202 (use (match_dup 3))])]
5205 (define_insn "x86_fnstcw_1"
5206 [(set (match_operand:HI 0 "memory_operand" "=m")
5207 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5210 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5211 (set_attr "mode" "HI")
5212 (set_attr "unit" "i387")])
5214 (define_insn "x86_fldcw_1"
5215 [(set (reg:HI FPCR_REG)
5216 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5219 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5220 (set_attr "mode" "HI")
5221 (set_attr "unit" "i387")
5222 (set_attr "athlon_decode" "vector")
5223 (set_attr "amdfam10_decode" "vector")])
5225 ;; Conversion between fixed point and floating point.
5227 ;; Even though we only accept memory inputs, the backend _really_
5228 ;; wants to be able to do this between registers.
5230 (define_expand "floathi<mode>2"
5231 [(set (match_operand:X87MODEF 0 "register_operand" "")
5232 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5234 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5235 || TARGET_MIX_SSE_I387)"
5238 ;; Pre-reload splitter to add memory clobber to the pattern.
5239 (define_insn_and_split "*floathi<mode>2_1"
5240 [(set (match_operand:X87MODEF 0 "register_operand" "")
5241 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5243 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5244 || TARGET_MIX_SSE_I387)
5245 && can_create_pseudo_p ()"
5248 [(parallel [(set (match_dup 0)
5249 (float:X87MODEF (match_dup 1)))
5250 (clobber (match_dup 2))])]
5251 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5253 (define_insn "*floathi<mode>2_i387_with_temp"
5254 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5255 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5256 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5258 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5259 || TARGET_MIX_SSE_I387)"
5261 [(set_attr "type" "fmov,multi")
5262 (set_attr "mode" "<MODE>")
5263 (set_attr "unit" "*,i387")
5264 (set_attr "fp_int_src" "true")])
5266 (define_insn "*floathi<mode>2_i387"
5267 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5268 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5270 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5271 || TARGET_MIX_SSE_I387)"
5273 [(set_attr "type" "fmov")
5274 (set_attr "mode" "<MODE>")
5275 (set_attr "fp_int_src" "true")])
5278 [(set (match_operand:X87MODEF 0 "register_operand" "")
5279 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5280 (clobber (match_operand:HI 2 "memory_operand" ""))]
5282 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5283 || TARGET_MIX_SSE_I387)
5284 && reload_completed"
5285 [(set (match_dup 2) (match_dup 1))
5286 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5290 [(set (match_operand:X87MODEF 0 "register_operand" "")
5291 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5292 (clobber (match_operand:HI 2 "memory_operand" ""))]
5294 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5295 || TARGET_MIX_SSE_I387)
5296 && reload_completed"
5297 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5300 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5301 [(set (match_operand:X87MODEF 0 "register_operand" "")
5303 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5305 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5306 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5308 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5309 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5310 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5312 rtx reg = gen_reg_rtx (XFmode);
5315 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5317 if (<X87MODEF:MODE>mode == SFmode)
5318 insn = gen_truncxfsf2 (operands[0], reg);
5319 else if (<X87MODEF:MODE>mode == DFmode)
5320 insn = gen_truncxfdf2 (operands[0], reg);
5329 ;; Pre-reload splitter to add memory clobber to the pattern.
5330 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5331 [(set (match_operand:X87MODEF 0 "register_operand" "")
5332 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5334 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5335 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5336 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5337 || TARGET_MIX_SSE_I387))
5338 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5339 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5340 && ((<SSEMODEI24:MODE>mode == SImode
5341 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5342 && optimize_function_for_speed_p (cfun)
5343 && flag_trapping_math)
5344 || !(TARGET_INTER_UNIT_CONVERSIONS
5345 || optimize_function_for_size_p (cfun)))))
5346 && can_create_pseudo_p ()"
5349 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5350 (clobber (match_dup 2))])]
5352 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5354 /* Avoid store forwarding (partial memory) stall penalty
5355 by passing DImode value through XMM registers. */
5356 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5357 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5358 && optimize_function_for_speed_p (cfun))
5360 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5367 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5368 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5370 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5371 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5372 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5373 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5375 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5376 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5377 (set_attr "unit" "*,i387,*,*,*")
5378 (set_attr "athlon_decode" "*,*,double,direct,double")
5379 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5380 (set_attr "fp_int_src" "true")])
5382 (define_insn "*floatsi<mode>2_vector_mixed"
5383 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5384 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5385 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5386 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5390 [(set_attr "type" "fmov,sseicvt")
5391 (set_attr "mode" "<MODE>,<ssevecmode>")
5392 (set_attr "unit" "i387,*")
5393 (set_attr "athlon_decode" "*,direct")
5394 (set_attr "amdfam10_decode" "*,double")
5395 (set_attr "fp_int_src" "true")])
5397 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5398 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5400 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5401 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5402 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5403 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5405 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5406 (set_attr "mode" "<MODEF:MODE>")
5407 (set_attr "unit" "*,i387,*,*")
5408 (set_attr "athlon_decode" "*,*,double,direct")
5409 (set_attr "amdfam10_decode" "*,*,vector,double")
5410 (set_attr "fp_int_src" "true")])
5413 [(set (match_operand:MODEF 0 "register_operand" "")
5414 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5415 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5416 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5417 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5418 && TARGET_INTER_UNIT_CONVERSIONS
5420 && (SSE_REG_P (operands[0])
5421 || (GET_CODE (operands[0]) == SUBREG
5422 && SSE_REG_P (operands[0])))"
5423 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5427 [(set (match_operand:MODEF 0 "register_operand" "")
5428 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5429 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5430 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5431 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5432 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5434 && (SSE_REG_P (operands[0])
5435 || (GET_CODE (operands[0]) == SUBREG
5436 && SSE_REG_P (operands[0])))"
5437 [(set (match_dup 2) (match_dup 1))
5438 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5441 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5442 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5444 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
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))"
5450 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5451 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5452 [(set_attr "type" "fmov,sseicvt,sseicvt")
5453 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5454 (set_attr "mode" "<MODEF:MODE>")
5455 (set (attr "prefix_rex")
5457 (and (eq_attr "prefix" "maybe_vex")
5458 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5460 (const_string "*")))
5461 (set_attr "unit" "i387,*,*")
5462 (set_attr "athlon_decode" "*,double,direct")
5463 (set_attr "amdfam10_decode" "*,vector,double")
5464 (set_attr "fp_int_src" "true")])
5466 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5467 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5469 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5470 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5471 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5472 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5475 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5476 [(set_attr "type" "fmov,sseicvt")
5477 (set_attr "prefix" "orig,maybe_vex")
5478 (set_attr "mode" "<MODEF:MODE>")
5479 (set (attr "prefix_rex")
5481 (and (eq_attr "prefix" "maybe_vex")
5482 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5484 (const_string "*")))
5485 (set_attr "athlon_decode" "*,direct")
5486 (set_attr "amdfam10_decode" "*,double")
5487 (set_attr "fp_int_src" "true")])
5489 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5490 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5492 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5493 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5494 "TARGET_SSE2 && TARGET_SSE_MATH
5495 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5497 [(set_attr "type" "sseicvt")
5498 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5499 (set_attr "athlon_decode" "double,direct,double")
5500 (set_attr "amdfam10_decode" "vector,double,double")
5501 (set_attr "fp_int_src" "true")])
5503 (define_insn "*floatsi<mode>2_vector_sse"
5504 [(set (match_operand:MODEF 0 "register_operand" "=x")
5505 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5506 "TARGET_SSE2 && TARGET_SSE_MATH
5507 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5509 [(set_attr "type" "sseicvt")
5510 (set_attr "mode" "<MODE>")
5511 (set_attr "athlon_decode" "direct")
5512 (set_attr "amdfam10_decode" "double")
5513 (set_attr "fp_int_src" "true")])
5516 [(set (match_operand:MODEF 0 "register_operand" "")
5517 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5518 (clobber (match_operand:SI 2 "memory_operand" ""))]
5519 "TARGET_SSE2 && TARGET_SSE_MATH
5520 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5522 && (SSE_REG_P (operands[0])
5523 || (GET_CODE (operands[0]) == SUBREG
5524 && SSE_REG_P (operands[0])))"
5527 rtx op1 = operands[1];
5529 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5531 if (GET_CODE (op1) == SUBREG)
5532 op1 = SUBREG_REG (op1);
5534 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5536 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5537 emit_insn (gen_sse2_loadld (operands[4],
5538 CONST0_RTX (V4SImode), operands[1]));
5540 /* We can ignore possible trapping value in the
5541 high part of SSE register for non-trapping math. */
5542 else if (SSE_REG_P (op1) && !flag_trapping_math)
5543 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5546 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5547 emit_move_insn (operands[2], operands[1]);
5548 emit_insn (gen_sse2_loadld (operands[4],
5549 CONST0_RTX (V4SImode), operands[2]));
5552 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5557 [(set (match_operand:MODEF 0 "register_operand" "")
5558 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5559 (clobber (match_operand:SI 2 "memory_operand" ""))]
5560 "TARGET_SSE2 && TARGET_SSE_MATH
5561 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5563 && (SSE_REG_P (operands[0])
5564 || (GET_CODE (operands[0]) == SUBREG
5565 && SSE_REG_P (operands[0])))"
5568 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5570 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5572 emit_insn (gen_sse2_loadld (operands[4],
5573 CONST0_RTX (V4SImode), operands[1]));
5575 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5580 [(set (match_operand:MODEF 0 "register_operand" "")
5581 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5582 "TARGET_SSE2 && TARGET_SSE_MATH
5583 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5585 && (SSE_REG_P (operands[0])
5586 || (GET_CODE (operands[0]) == SUBREG
5587 && SSE_REG_P (operands[0])))"
5590 rtx op1 = operands[1];
5592 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5594 if (GET_CODE (op1) == SUBREG)
5595 op1 = SUBREG_REG (op1);
5597 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5599 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5600 emit_insn (gen_sse2_loadld (operands[4],
5601 CONST0_RTX (V4SImode), operands[1]));
5603 /* We can ignore possible trapping value in the
5604 high part of SSE register for non-trapping math. */
5605 else if (SSE_REG_P (op1) && !flag_trapping_math)
5606 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5610 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5615 [(set (match_operand:MODEF 0 "register_operand" "")
5616 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5617 "TARGET_SSE2 && TARGET_SSE_MATH
5618 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5620 && (SSE_REG_P (operands[0])
5621 || (GET_CODE (operands[0]) == SUBREG
5622 && SSE_REG_P (operands[0])))"
5625 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5627 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5629 emit_insn (gen_sse2_loadld (operands[4],
5630 CONST0_RTX (V4SImode), operands[1]));
5632 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5636 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5637 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5639 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5640 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5641 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5642 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5644 [(set_attr "type" "sseicvt")
5645 (set_attr "mode" "<MODEF:MODE>")
5646 (set_attr "athlon_decode" "double,direct")
5647 (set_attr "amdfam10_decode" "vector,double")
5648 (set_attr "fp_int_src" "true")])
5650 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5651 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5653 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5654 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5655 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5656 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5657 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5658 [(set_attr "type" "sseicvt")
5659 (set_attr "prefix" "maybe_vex")
5660 (set_attr "mode" "<MODEF:MODE>")
5661 (set (attr "prefix_rex")
5663 (and (eq_attr "prefix" "maybe_vex")
5664 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5666 (const_string "*")))
5667 (set_attr "athlon_decode" "double,direct")
5668 (set_attr "amdfam10_decode" "vector,double")
5669 (set_attr "fp_int_src" "true")])
5672 [(set (match_operand:MODEF 0 "register_operand" "")
5673 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5674 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5675 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5676 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5677 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5679 && (SSE_REG_P (operands[0])
5680 || (GET_CODE (operands[0]) == SUBREG
5681 && SSE_REG_P (operands[0])))"
5682 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5685 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5686 [(set (match_operand:MODEF 0 "register_operand" "=x")
5688 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5689 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5690 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5691 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5692 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5693 [(set_attr "type" "sseicvt")
5694 (set_attr "prefix" "maybe_vex")
5695 (set_attr "mode" "<MODEF:MODE>")
5696 (set (attr "prefix_rex")
5698 (and (eq_attr "prefix" "maybe_vex")
5699 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5701 (const_string "*")))
5702 (set_attr "athlon_decode" "direct")
5703 (set_attr "amdfam10_decode" "double")
5704 (set_attr "fp_int_src" "true")])
5707 [(set (match_operand:MODEF 0 "register_operand" "")
5708 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5709 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5710 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5711 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5712 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5714 && (SSE_REG_P (operands[0])
5715 || (GET_CODE (operands[0]) == SUBREG
5716 && SSE_REG_P (operands[0])))"
5717 [(set (match_dup 2) (match_dup 1))
5718 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5722 [(set (match_operand:MODEF 0 "register_operand" "")
5723 (float:MODEF (match_operand:SSEMODEI24 1 "memory_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
5728 && (SSE_REG_P (operands[0])
5729 || (GET_CODE (operands[0]) == SUBREG
5730 && SSE_REG_P (operands[0])))"
5731 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5734 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5735 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5737 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5738 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5740 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5744 [(set_attr "type" "fmov,multi")
5745 (set_attr "mode" "<X87MODEF:MODE>")
5746 (set_attr "unit" "*,i387")
5747 (set_attr "fp_int_src" "true")])
5749 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5750 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5752 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5754 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5756 [(set_attr "type" "fmov")
5757 (set_attr "mode" "<X87MODEF:MODE>")
5758 (set_attr "fp_int_src" "true")])
5761 [(set (match_operand:X87MODEF 0 "register_operand" "")
5762 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5763 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5765 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5767 && FP_REG_P (operands[0])"
5768 [(set (match_dup 2) (match_dup 1))
5769 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5773 [(set (match_operand:X87MODEF 0 "register_operand" "")
5774 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5775 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5777 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5779 && FP_REG_P (operands[0])"
5780 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5783 ;; Avoid store forwarding (partial memory) stall penalty
5784 ;; by passing DImode value through XMM registers. */
5786 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5787 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5789 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5790 (clobber (match_scratch:V4SI 3 "=X,x"))
5791 (clobber (match_scratch:V4SI 4 "=X,x"))
5792 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5793 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5794 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5795 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5797 [(set_attr "type" "multi")
5798 (set_attr "mode" "<X87MODEF:MODE>")
5799 (set_attr "unit" "i387")
5800 (set_attr "fp_int_src" "true")])
5803 [(set (match_operand:X87MODEF 0 "register_operand" "")
5804 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5805 (clobber (match_scratch:V4SI 3 ""))
5806 (clobber (match_scratch:V4SI 4 ""))
5807 (clobber (match_operand:DI 2 "memory_operand" ""))]
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 && FP_REG_P (operands[0])"
5813 [(set (match_dup 2) (match_dup 3))
5814 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5816 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5817 Assemble the 64-bit DImode value in an xmm register. */
5818 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5819 gen_rtx_SUBREG (SImode, operands[1], 0)));
5820 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5821 gen_rtx_SUBREG (SImode, operands[1], 4)));
5822 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5825 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5829 [(set (match_operand:X87MODEF 0 "register_operand" "")
5830 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5831 (clobber (match_scratch:V4SI 3 ""))
5832 (clobber (match_scratch:V4SI 4 ""))
5833 (clobber (match_operand:DI 2 "memory_operand" ""))]
5834 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5835 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5836 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5838 && FP_REG_P (operands[0])"
5839 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5842 ;; Avoid store forwarding (partial memory) stall penalty by extending
5843 ;; SImode value to DImode through XMM register instead of pushing two
5844 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5845 ;; targets benefit from this optimization. Also note that fild
5846 ;; loads from memory only.
5848 (define_insn "*floatunssi<mode>2_1"
5849 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5850 (unsigned_float:X87MODEF
5851 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5852 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5853 (clobber (match_scratch:SI 3 "=X,x"))]
5855 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5858 [(set_attr "type" "multi")
5859 (set_attr "mode" "<MODE>")])
5862 [(set (match_operand:X87MODEF 0 "register_operand" "")
5863 (unsigned_float:X87MODEF
5864 (match_operand:SI 1 "register_operand" "")))
5865 (clobber (match_operand:DI 2 "memory_operand" ""))
5866 (clobber (match_scratch:SI 3 ""))]
5868 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5870 && reload_completed"
5871 [(set (match_dup 2) (match_dup 1))
5873 (float:X87MODEF (match_dup 2)))]
5874 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5877 [(set (match_operand:X87MODEF 0 "register_operand" "")
5878 (unsigned_float:X87MODEF
5879 (match_operand:SI 1 "memory_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 3))
5888 (float:X87MODEF (match_dup 2)))]
5890 emit_move_insn (operands[3], operands[1]);
5891 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5894 (define_expand "floatunssi<mode>2"
5896 [(set (match_operand:X87MODEF 0 "register_operand" "")
5897 (unsigned_float:X87MODEF
5898 (match_operand:SI 1 "nonimmediate_operand" "")))
5899 (clobber (match_dup 2))
5900 (clobber (match_scratch:SI 3 ""))])]
5902 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5904 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5906 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5908 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5913 enum ix86_stack_slot slot = (virtuals_instantiated
5916 operands[2] = assign_386_stack_local (DImode, slot);
5920 (define_expand "floatunsdisf2"
5921 [(use (match_operand:SF 0 "register_operand" ""))
5922 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5923 "TARGET_64BIT && TARGET_SSE_MATH"
5924 "x86_emit_floatuns (operands); DONE;")
5926 (define_expand "floatunsdidf2"
5927 [(use (match_operand:DF 0 "register_operand" ""))
5928 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5929 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5930 && TARGET_SSE2 && TARGET_SSE_MATH"
5933 x86_emit_floatuns (operands);
5935 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5941 (define_expand "add<mode>3"
5942 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5943 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5944 (match_operand:SDWIM 2 "<general_operand>" "")))]
5946 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5948 (define_insn_and_split "*add<dwi>3_doubleword"
5949 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5951 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5952 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5953 (clobber (reg:CC FLAGS_REG))]
5954 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5957 [(parallel [(set (reg:CC FLAGS_REG)
5958 (unspec:CC [(match_dup 1) (match_dup 2)]
5961 (plus:DWIH (match_dup 1) (match_dup 2)))])
5962 (parallel [(set (match_dup 3)
5966 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5968 (clobber (reg:CC FLAGS_REG))])]
5969 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5971 (define_insn "*add<mode>3_cc"
5972 [(set (reg:CC FLAGS_REG)
5974 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5975 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5977 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5978 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5979 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5980 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5981 [(set_attr "type" "alu")
5982 (set_attr "mode" "<MODE>")])
5984 (define_insn "addqi3_cc"
5985 [(set (reg:CC FLAGS_REG)
5987 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5988 (match_operand:QI 2 "general_operand" "qn,qm")]
5990 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5991 (plus:QI (match_dup 1) (match_dup 2)))]
5992 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5993 "add{b}\t{%2, %0|%0, %2}"
5994 [(set_attr "type" "alu")
5995 (set_attr "mode" "QI")])
5997 (define_insn "*lea_1"
5998 [(set (match_operand:DWIH 0 "register_operand" "=r")
5999 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
6001 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
6002 [(set_attr "type" "lea")
6003 (set_attr "mode" "<MODE>")])
6005 (define_insn "*lea_2"
6006 [(set (match_operand:SI 0 "register_operand" "=r")
6007 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6009 "lea{l}\t{%a1, %0|%0, %a1}"
6010 [(set_attr "type" "lea")
6011 (set_attr "mode" "SI")])
6013 (define_insn "*lea_2_zext"
6014 [(set (match_operand:DI 0 "register_operand" "=r")
6016 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6018 "lea{l}\t{%a1, %k0|%k0, %a1}"
6019 [(set_attr "type" "lea")
6020 (set_attr "mode" "SI")])
6022 (define_insn "*add<mode>_1"
6023 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6025 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6026 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6027 (clobber (reg:CC FLAGS_REG))]
6028 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6030 switch (get_attr_type (insn))
6033 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6034 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6037 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6038 if (operands[2] == const1_rtx)
6039 return "inc{<imodesuffix>}\t%0";
6042 gcc_assert (operands[2] == constm1_rtx);
6043 return "dec{<imodesuffix>}\t%0";
6047 /* Use add as much as possible to replace lea for AGU optimization. */
6048 if (which_alternative == 2 && TARGET_OPT_AGU)
6049 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6051 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6052 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6053 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6055 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6059 (cond [(and (eq_attr "alternative" "2")
6060 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6061 (const_string "lea")
6062 (eq_attr "alternative" "3")
6063 (const_string "lea")
6064 ; Current assemblers are broken and do not allow @GOTOFF in
6065 ; ought but a memory context.
6066 (match_operand:SWI48 2 "pic_symbolic_operand" "")
6067 (const_string "lea")
6068 (match_operand:SWI48 2 "incdec_operand" "")
6069 (const_string "incdec")
6071 (const_string "alu")))
6072 (set (attr "length_immediate")
6074 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6076 (const_string "*")))
6077 (set_attr "mode" "<MODE>")])
6079 ;; It may seem that nonimmediate operand is proper one for operand 1.
6080 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6081 ;; we take care in ix86_binary_operator_ok to not allow two memory
6082 ;; operands so proper swapping will be done in reload. This allow
6083 ;; patterns constructed from addsi_1 to match.
6085 (define_insn "*addsi_1_zext"
6086 [(set (match_operand:DI 0 "register_operand" "=r,r")
6088 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6089 (match_operand:SI 2 "general_operand" "g,li"))))
6090 (clobber (reg:CC FLAGS_REG))]
6091 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6093 switch (get_attr_type (insn))
6096 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6097 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6100 if (operands[2] == const1_rtx)
6101 return "inc{l}\t%k0";
6104 gcc_assert (operands[2] == constm1_rtx);
6105 return "dec{l}\t%k0";
6109 if (x86_maybe_negate_const_int (&operands[2], SImode))
6110 return "sub{l}\t{%2, %k0|%k0, %2}";
6112 return "add{l}\t{%2, %k0|%k0, %2}";
6116 (cond [(eq_attr "alternative" "1")
6117 (const_string "lea")
6118 ; Current assemblers are broken and do not allow @GOTOFF in
6119 ; ought but a memory context.
6120 (match_operand:SI 2 "pic_symbolic_operand" "")
6121 (const_string "lea")
6122 (match_operand:SI 2 "incdec_operand" "")
6123 (const_string "incdec")
6125 (const_string "alu")))
6126 (set (attr "length_immediate")
6128 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6130 (const_string "*")))
6131 (set_attr "mode" "SI")])
6133 (define_insn "*addhi_1"
6134 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6135 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6136 (match_operand:HI 2 "general_operand" "rn,rm")))
6137 (clobber (reg:CC FLAGS_REG))]
6138 "TARGET_PARTIAL_REG_STALL
6139 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6141 switch (get_attr_type (insn))
6144 if (operands[2] == const1_rtx)
6145 return "inc{w}\t%0";
6148 gcc_assert (operands[2] == constm1_rtx);
6149 return "dec{w}\t%0";
6153 if (x86_maybe_negate_const_int (&operands[2], HImode))
6154 return "sub{w}\t{%2, %0|%0, %2}";
6156 return "add{w}\t{%2, %0|%0, %2}";
6160 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6161 (const_string "incdec")
6162 (const_string "alu")))
6163 (set (attr "length_immediate")
6165 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6167 (const_string "*")))
6168 (set_attr "mode" "HI")])
6170 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6171 ;; type optimizations enabled by define-splits. This is not important
6172 ;; for PII, and in fact harmful because of partial register stalls.
6174 (define_insn "*addhi_1_lea"
6175 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6176 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6177 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6178 (clobber (reg:CC FLAGS_REG))]
6179 "!TARGET_PARTIAL_REG_STALL
6180 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6182 switch (get_attr_type (insn))
6187 if (operands[2] == const1_rtx)
6188 return "inc{w}\t%0";
6191 gcc_assert (operands[2] == constm1_rtx);
6192 return "dec{w}\t%0";
6196 if (x86_maybe_negate_const_int (&operands[2], HImode))
6197 return "sub{w}\t{%2, %0|%0, %2}";
6199 return "add{w}\t{%2, %0|%0, %2}";
6203 (if_then_else (eq_attr "alternative" "2")
6204 (const_string "lea")
6205 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6206 (const_string "incdec")
6207 (const_string "alu"))))
6208 (set (attr "length_immediate")
6210 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6212 (const_string "*")))
6213 (set_attr "mode" "HI,HI,SI")])
6215 (define_insn "*addqi_1"
6216 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6217 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6218 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6219 (clobber (reg:CC FLAGS_REG))]
6220 "TARGET_PARTIAL_REG_STALL
6221 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6223 int widen = (which_alternative == 2);
6224 switch (get_attr_type (insn))
6227 if (operands[2] == const1_rtx)
6228 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6231 gcc_assert (operands[2] == constm1_rtx);
6232 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6236 if (x86_maybe_negate_const_int (&operands[2], QImode))
6239 return "sub{l}\t{%2, %k0|%k0, %2}";
6241 return "sub{b}\t{%2, %0|%0, %2}";
6244 return "add{l}\t{%k2, %k0|%k0, %k2}";
6246 return "add{b}\t{%2, %0|%0, %2}";
6250 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6251 (const_string "incdec")
6252 (const_string "alu")))
6253 (set (attr "length_immediate")
6255 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6257 (const_string "*")))
6258 (set_attr "mode" "QI,QI,SI")])
6260 ;; %%% Potential partial reg stall on alternative 2. What to do?
6261 (define_insn "*addqi_1_lea"
6262 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6263 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6264 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6265 (clobber (reg:CC FLAGS_REG))]
6266 "!TARGET_PARTIAL_REG_STALL
6267 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6269 int widen = (which_alternative == 2);
6270 switch (get_attr_type (insn))
6275 if (operands[2] == const1_rtx)
6276 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6279 gcc_assert (operands[2] == constm1_rtx);
6280 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6284 if (x86_maybe_negate_const_int (&operands[2], QImode))
6287 return "sub{l}\t{%2, %k0|%k0, %2}";
6289 return "sub{b}\t{%2, %0|%0, %2}";
6292 return "add{l}\t{%k2, %k0|%k0, %k2}";
6294 return "add{b}\t{%2, %0|%0, %2}";
6298 (if_then_else (eq_attr "alternative" "3")
6299 (const_string "lea")
6300 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6301 (const_string "incdec")
6302 (const_string "alu"))))
6303 (set (attr "length_immediate")
6305 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6307 (const_string "*")))
6308 (set_attr "mode" "QI,QI,SI,SI")])
6310 (define_insn "*addqi_1_slp"
6311 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6312 (plus:QI (match_dup 0)
6313 (match_operand:QI 1 "general_operand" "qn,qnm")))
6314 (clobber (reg:CC FLAGS_REG))]
6315 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6316 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6318 switch (get_attr_type (insn))
6321 if (operands[1] == const1_rtx)
6322 return "inc{b}\t%0";
6325 gcc_assert (operands[1] == constm1_rtx);
6326 return "dec{b}\t%0";
6330 if (x86_maybe_negate_const_int (&operands[1], QImode))
6331 return "sub{b}\t{%1, %0|%0, %1}";
6333 return "add{b}\t{%1, %0|%0, %1}";
6337 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6338 (const_string "incdec")
6339 (const_string "alu1")))
6340 (set (attr "memory")
6341 (if_then_else (match_operand 1 "memory_operand" "")
6342 (const_string "load")
6343 (const_string "none")))
6344 (set_attr "mode" "QI")])
6346 (define_insn "*add<mode>_2"
6347 [(set (reg FLAGS_REG)
6350 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6351 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6353 (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6354 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6355 "ix86_match_ccmode (insn, CCGOCmode)
6356 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6357 /* Current assemblers are broken and do not allow @GOTOFF in
6358 ought but a memory context. */
6359 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6361 switch (get_attr_type (insn))
6364 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6365 if (operands[2] == const1_rtx)
6366 return "inc{<imodesuffix>}\t%0";
6369 gcc_assert (operands[2] == constm1_rtx);
6370 return "dec{<imodesuffix>}\t%0";
6374 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6375 /* ???? In DImode, we ought to handle there the 32bit case too
6376 - do we need new constraint? */
6377 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6378 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6380 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6384 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6385 (const_string "incdec")
6386 (const_string "alu")))
6387 (set (attr "length_immediate")
6389 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6391 (const_string "*")))
6392 (set_attr "mode" "<MODE>")])
6394 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6395 (define_insn "*addsi_2_zext"
6396 [(set (reg FLAGS_REG)
6398 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6399 (match_operand:SI 2 "general_operand" "g"))
6401 (set (match_operand:DI 0 "register_operand" "=r")
6402 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6403 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6404 && ix86_binary_operator_ok (PLUS, SImode, operands)
6405 /* Current assemblers are broken and do not allow @GOTOFF in
6406 ought but a memory context. */
6407 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6409 switch (get_attr_type (insn))
6412 if (operands[2] == const1_rtx)
6413 return "inc{l}\t%k0";
6416 gcc_assert (operands[2] == constm1_rtx);
6417 return "dec{l}\t%k0";
6421 if (x86_maybe_negate_const_int (&operands[2], SImode))
6422 return "sub{l}\t{%2, %k0|%k0, %2}";
6424 return "add{l}\t{%2, %k0|%k0, %2}";
6428 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6429 (const_string "incdec")
6430 (const_string "alu")))
6431 (set (attr "length_immediate")
6433 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6435 (const_string "*")))
6436 (set_attr "mode" "SI")])
6438 (define_insn "*addhi_2"
6439 [(set (reg FLAGS_REG)
6441 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6442 (match_operand:HI 2 "general_operand" "rmn,rn"))
6444 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6445 (plus:HI (match_dup 1) (match_dup 2)))]
6446 "ix86_match_ccmode (insn, CCGOCmode)
6447 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6449 switch (get_attr_type (insn))
6452 if (operands[2] == const1_rtx)
6453 return "inc{w}\t%0";
6456 gcc_assert (operands[2] == constm1_rtx);
6457 return "dec{w}\t%0";
6461 if (x86_maybe_negate_const_int (&operands[2], HImode))
6462 return "sub{w}\t{%2, %0|%0, %2}";
6464 return "add{w}\t{%2, %0|%0, %2}";
6468 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6469 (const_string "incdec")
6470 (const_string "alu")))
6471 (set (attr "length_immediate")
6473 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6475 (const_string "*")))
6476 (set_attr "mode" "HI")])
6478 (define_insn "*addqi_2"
6479 [(set (reg FLAGS_REG)
6481 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6482 (match_operand:QI 2 "general_operand" "qmn,qn"))
6484 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6485 (plus:QI (match_dup 1) (match_dup 2)))]
6486 "ix86_match_ccmode (insn, CCGOCmode)
6487 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6489 switch (get_attr_type (insn))
6492 if (operands[2] == const1_rtx)
6493 return "inc{b}\t%0";
6496 gcc_assert (operands[2] == constm1_rtx
6497 || (CONST_INT_P (operands[2])
6498 && INTVAL (operands[2]) == 255));
6499 return "dec{b}\t%0";
6503 if (x86_maybe_negate_const_int (&operands[2], QImode))
6504 return "sub{b}\t{%2, %0|%0, %2}";
6506 return "add{b}\t{%2, %0|%0, %2}";
6510 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6511 (const_string "incdec")
6512 (const_string "alu")))
6513 (set_attr "mode" "QI")])
6515 (define_insn "*add<mode>_3"
6516 [(set (reg FLAGS_REG)
6518 (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6519 (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6520 (clobber (match_scratch:SWI48 0 "=r"))]
6521 "ix86_match_ccmode (insn, CCZmode)
6522 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6523 /* Current assemblers are broken and do not allow @GOTOFF in
6524 ought but a memory context. */
6525 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6527 switch (get_attr_type (insn))
6530 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6531 if (operands[2] == const1_rtx)
6532 return "inc{<imodesuffix>}\t%0";
6535 gcc_assert (operands[2] == constm1_rtx);
6536 return "dec{<imodesuffix>}\t%0";
6540 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6541 /* ???? In DImode, we ought to handle there the 32bit case too
6542 - do we need new constraint? */
6543 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6544 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6546 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6550 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6551 (const_string "incdec")
6552 (const_string "alu")))
6553 (set (attr "length_immediate")
6555 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6557 (const_string "*")))
6558 (set_attr "mode" "<MODE>")])
6560 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6561 (define_insn "*addsi_3_zext"
6562 [(set (reg FLAGS_REG)
6564 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6565 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6566 (set (match_operand:DI 0 "register_operand" "=r")
6567 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6568 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6569 && ix86_binary_operator_ok (PLUS, SImode, operands)
6570 /* Current assemblers are broken and do not allow @GOTOFF in
6571 ought but a memory context. */
6572 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6574 switch (get_attr_type (insn))
6577 if (operands[2] == const1_rtx)
6578 return "inc{l}\t%k0";
6581 gcc_assert (operands[2] == constm1_rtx);
6582 return "dec{l}\t%k0";
6586 if (x86_maybe_negate_const_int (&operands[2], SImode))
6587 return "sub{l}\t{%2, %k0|%k0, %2}";
6589 return "add{l}\t{%2, %k0|%k0, %2}";
6593 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6594 (const_string "incdec")
6595 (const_string "alu")))
6596 (set (attr "length_immediate")
6598 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6600 (const_string "*")))
6601 (set_attr "mode" "SI")])
6603 (define_insn "*addhi_3"
6604 [(set (reg FLAGS_REG)
6606 (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6607 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6608 (clobber (match_scratch:HI 0 "=r"))]
6609 "ix86_match_ccmode (insn, CCZmode)
6610 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6612 switch (get_attr_type (insn))
6615 if (operands[2] == const1_rtx)
6616 return "inc{w}\t%0";
6619 gcc_assert (operands[2] == constm1_rtx);
6620 return "dec{w}\t%0";
6624 if (x86_maybe_negate_const_int (&operands[2], HImode))
6625 return "sub{w}\t{%2, %0|%0, %2}";
6627 return "add{w}\t{%2, %0|%0, %2}";
6631 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6632 (const_string "incdec")
6633 (const_string "alu")))
6634 (set (attr "length_immediate")
6636 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6638 (const_string "*")))
6639 (set_attr "mode" "HI")])
6641 (define_insn "*addqi_3"
6642 [(set (reg FLAGS_REG)
6644 (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6645 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6646 (clobber (match_scratch:QI 0 "=q"))]
6647 "ix86_match_ccmode (insn, CCZmode)
6648 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6650 switch (get_attr_type (insn))
6653 if (operands[2] == const1_rtx)
6654 return "inc{b}\t%0";
6657 gcc_assert (operands[2] == constm1_rtx
6658 || (CONST_INT_P (operands[2])
6659 && INTVAL (operands[2]) == 255));
6660 return "dec{b}\t%0";
6664 if (x86_maybe_negate_const_int (&operands[2], QImode))
6665 return "sub{b}\t{%2, %0|%0, %2}";
6667 return "add{b}\t{%2, %0|%0, %2}";
6671 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6672 (const_string "incdec")
6673 (const_string "alu")))
6674 (set_attr "mode" "QI")])
6676 ; For comparisons against 1, -1 and 128, we may generate better code
6677 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6678 ; is matched then. We can't accept general immediate, because for
6679 ; case of overflows, the result is messed up.
6680 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6681 ; only for comparisons not depending on it.
6683 (define_insn "*adddi_4"
6684 [(set (reg FLAGS_REG)
6686 (match_operand:DI 1 "nonimmediate_operand" "0")
6687 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6688 (clobber (match_scratch:DI 0 "=rm"))]
6690 && ix86_match_ccmode (insn, CCGCmode)"
6692 switch (get_attr_type (insn))
6695 if (operands[2] == constm1_rtx)
6696 return "inc{q}\t%0";
6699 gcc_assert (operands[2] == const1_rtx);
6700 return "dec{q}\t%0";
6704 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6705 if (x86_maybe_negate_const_int (&operands[2], DImode))
6706 return "add{q}\t{%2, %0|%0, %2}";
6708 return "sub{q}\t{%2, %0|%0, %2}";
6712 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6713 (const_string "incdec")
6714 (const_string "alu")))
6715 (set (attr "length_immediate")
6717 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6719 (const_string "*")))
6720 (set_attr "mode" "DI")])
6722 ; For comparisons against 1, -1 and 128, we may generate better code
6723 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6724 ; is matched then. We can't accept general immediate, because for
6725 ; case of overflows, the result is messed up.
6726 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6727 ; only for comparisons not depending on it.
6729 (define_insn "*addsi_4"
6730 [(set (reg FLAGS_REG)
6732 (match_operand:SI 1 "nonimmediate_operand" "0")
6733 (match_operand:SI 2 "const_int_operand" "n")))
6734 (clobber (match_scratch:SI 0 "=rm"))]
6735 "ix86_match_ccmode (insn, CCGCmode)"
6737 switch (get_attr_type (insn))
6740 if (operands[2] == constm1_rtx)
6741 return "inc{l}\t%0";
6744 gcc_assert (operands[2] == const1_rtx);
6745 return "dec{l}\t%0";
6749 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6750 if (x86_maybe_negate_const_int (&operands[2], SImode))
6751 return "add{l}\t{%2, %0|%0, %2}";
6753 return "sub{l}\t{%2, %0|%0, %2}";
6757 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6758 (const_string "incdec")
6759 (const_string "alu")))
6760 (set (attr "length_immediate")
6762 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6764 (const_string "*")))
6765 (set_attr "mode" "SI")])
6767 ; See comments above addsi_4 for details.
6769 (define_insn "*addhi_4"
6770 [(set (reg FLAGS_REG)
6772 (match_operand:HI 1 "nonimmediate_operand" "0")
6773 (match_operand:HI 2 "const_int_operand" "n")))
6774 (clobber (match_scratch:HI 0 "=rm"))]
6775 "ix86_match_ccmode (insn, CCGCmode)"
6777 switch (get_attr_type (insn))
6780 if (operands[2] == constm1_rtx)
6781 return "inc{w}\t%0";
6784 gcc_assert (operands[2] == const1_rtx);
6785 return "dec{w}\t%0";
6789 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6790 if (x86_maybe_negate_const_int (&operands[2], HImode))
6791 return "add{w}\t{%2, %0|%0, %2}";
6793 return "sub{w}\t{%2, %0|%0, %2}";
6797 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6798 (const_string "incdec")
6799 (const_string "alu")))
6800 (set (attr "length_immediate")
6802 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6804 (const_string "*")))
6805 (set_attr "mode" "HI")])
6807 ; See comments above addsi_4 for details.
6809 (define_insn "*addqi_4"
6810 [(set (reg FLAGS_REG)
6812 (match_operand:QI 1 "nonimmediate_operand" "0")
6813 (match_operand:QI 2 "const_int_operand" "n")))
6814 (clobber (match_scratch:QI 0 "=qm"))]
6815 "ix86_match_ccmode (insn, CCGCmode)"
6817 switch (get_attr_type (insn))
6820 if (operands[2] == constm1_rtx
6821 || (CONST_INT_P (operands[2])
6822 && INTVAL (operands[2]) == 255))
6823 return "inc{b}\t%0";
6826 gcc_assert (operands[2] == const1_rtx);
6827 return "dec{b}\t%0";
6831 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6832 if (x86_maybe_negate_const_int (&operands[2], QImode))
6833 return "add{b}\t{%2, %0|%0, %2}";
6835 return "sub{b}\t{%2, %0|%0, %2}";
6839 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6840 (const_string "incdec")
6841 (const_string "alu")))
6842 (set_attr "mode" "QI")])
6844 (define_insn "*add<mode>_5"
6845 [(set (reg FLAGS_REG)
6848 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6849 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6851 (clobber (match_scratch:SWI48 0 "=r"))]
6852 "ix86_match_ccmode (insn, CCGOCmode)
6853 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6854 /* Current assemblers are broken and do not allow @GOTOFF in
6855 ought but a memory context. */
6856 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6858 switch (get_attr_type (insn))
6861 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6862 if (operands[2] == const1_rtx)
6863 return "inc{<imodesuffix>}\t%0";
6866 gcc_assert (operands[2] == constm1_rtx);
6867 return "dec{<imodesuffix>}\t%0";
6871 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6872 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6873 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6875 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6879 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6880 (const_string "incdec")
6881 (const_string "alu")))
6882 (set (attr "length_immediate")
6884 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6886 (const_string "*")))
6887 (set_attr "mode" "<MODE>")])
6889 (define_insn "*addhi_5"
6890 [(set (reg FLAGS_REG)
6892 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6893 (match_operand:HI 2 "general_operand" "rmn"))
6895 (clobber (match_scratch:HI 0 "=r"))]
6896 "ix86_match_ccmode (insn, CCGOCmode)
6897 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6899 switch (get_attr_type (insn))
6902 if (operands[2] == const1_rtx)
6903 return "inc{w}\t%0";
6906 gcc_assert (operands[2] == constm1_rtx);
6907 return "dec{w}\t%0";
6911 if (x86_maybe_negate_const_int (&operands[2], HImode))
6912 return "sub{w}\t{%2, %0|%0, %2}";
6914 return "add{w}\t{%2, %0|%0, %2}";
6918 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6919 (const_string "incdec")
6920 (const_string "alu")))
6921 (set (attr "length_immediate")
6923 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6925 (const_string "*")))
6926 (set_attr "mode" "HI")])
6928 (define_insn "*addqi_5"
6929 [(set (reg FLAGS_REG)
6931 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6932 (match_operand:QI 2 "general_operand" "qmn"))
6934 (clobber (match_scratch:QI 0 "=q"))]
6935 "ix86_match_ccmode (insn, CCGOCmode)
6936 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6938 switch (get_attr_type (insn))
6941 if (operands[2] == const1_rtx)
6942 return "inc{b}\t%0";
6945 gcc_assert (operands[2] == constm1_rtx
6946 || (CONST_INT_P (operands[2])
6947 && INTVAL (operands[2]) == 255));
6948 return "dec{b}\t%0";
6952 if (x86_maybe_negate_const_int (&operands[2], QImode))
6953 return "sub{b}\t{%2, %0|%0, %2}";
6955 return "add{b}\t{%2, %0|%0, %2}";
6959 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6960 (const_string "incdec")
6961 (const_string "alu")))
6962 (set_attr "mode" "QI")])
6964 (define_insn "*addqi_ext_1_rex64"
6965 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6970 (match_operand 1 "ext_register_operand" "0")
6973 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6974 (clobber (reg:CC FLAGS_REG))]
6977 switch (get_attr_type (insn))
6980 if (operands[2] == const1_rtx)
6981 return "inc{b}\t%h0";
6984 gcc_assert (operands[2] == constm1_rtx
6985 || (CONST_INT_P (operands[2])
6986 && INTVAL (operands[2]) == 255));
6987 return "dec{b}\t%h0";
6991 return "add{b}\t{%2, %h0|%h0, %2}";
6995 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6996 (const_string "incdec")
6997 (const_string "alu")))
6998 (set_attr "modrm" "1")
6999 (set_attr "mode" "QI")])
7001 (define_insn "addqi_ext_1"
7002 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7007 (match_operand 1 "ext_register_operand" "0")
7010 (match_operand:QI 2 "general_operand" "Qmn")))
7011 (clobber (reg:CC FLAGS_REG))]
7014 switch (get_attr_type (insn))
7017 if (operands[2] == const1_rtx)
7018 return "inc{b}\t%h0";
7021 gcc_assert (operands[2] == constm1_rtx
7022 || (CONST_INT_P (operands[2])
7023 && INTVAL (operands[2]) == 255));
7024 return "dec{b}\t%h0";
7028 return "add{b}\t{%2, %h0|%h0, %2}";
7032 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7033 (const_string "incdec")
7034 (const_string "alu")))
7035 (set_attr "modrm" "1")
7036 (set_attr "mode" "QI")])
7038 (define_insn "*addqi_ext_2"
7039 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7044 (match_operand 1 "ext_register_operand" "%0")
7048 (match_operand 2 "ext_register_operand" "Q")
7051 (clobber (reg:CC FLAGS_REG))]
7053 "add{b}\t{%h2, %h0|%h0, %h2}"
7054 [(set_attr "type" "alu")
7055 (set_attr "mode" "QI")])
7057 ;; The lea patterns for non-Pmodes needs to be matched by
7058 ;; several insns converted to real lea by splitters.
7060 (define_insn_and_split "*lea_general_1"
7061 [(set (match_operand 0 "register_operand" "=r")
7062 (plus (plus (match_operand 1 "index_register_operand" "l")
7063 (match_operand 2 "register_operand" "r"))
7064 (match_operand 3 "immediate_operand" "i")))]
7065 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7066 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7067 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7068 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7069 && GET_MODE (operands[0]) == GET_MODE (operands[2])
7070 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7071 || GET_MODE (operands[3]) == VOIDmode)"
7073 "&& reload_completed"
7077 operands[0] = gen_lowpart (SImode, operands[0]);
7078 operands[1] = gen_lowpart (Pmode, operands[1]);
7079 operands[2] = gen_lowpart (Pmode, operands[2]);
7080 operands[3] = gen_lowpart (Pmode, operands[3]);
7081 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7083 if (Pmode != SImode)
7084 pat = gen_rtx_SUBREG (SImode, pat, 0);
7085 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7088 [(set_attr "type" "lea")
7089 (set_attr "mode" "SI")])
7091 (define_insn_and_split "*lea_general_1_zext"
7092 [(set (match_operand:DI 0 "register_operand" "=r")
7095 (match_operand:SI 1 "index_register_operand" "l")
7096 (match_operand:SI 2 "register_operand" "r"))
7097 (match_operand:SI 3 "immediate_operand" "i"))))]
7100 "&& reload_completed"
7102 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7104 (match_dup 3)) 0)))]
7106 operands[1] = gen_lowpart (Pmode, operands[1]);
7107 operands[2] = gen_lowpart (Pmode, operands[2]);
7108 operands[3] = gen_lowpart (Pmode, operands[3]);
7110 [(set_attr "type" "lea")
7111 (set_attr "mode" "SI")])
7113 (define_insn_and_split "*lea_general_2"
7114 [(set (match_operand 0 "register_operand" "=r")
7115 (plus (mult (match_operand 1 "index_register_operand" "l")
7116 (match_operand 2 "const248_operand" "i"))
7117 (match_operand 3 "nonmemory_operand" "ri")))]
7118 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7119 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7120 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7121 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7122 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7123 || GET_MODE (operands[3]) == VOIDmode)"
7125 "&& reload_completed"
7129 operands[0] = gen_lowpart (SImode, operands[0]);
7130 operands[1] = gen_lowpart (Pmode, operands[1]);
7131 operands[3] = gen_lowpart (Pmode, operands[3]);
7132 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7134 if (Pmode != SImode)
7135 pat = gen_rtx_SUBREG (SImode, pat, 0);
7136 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7139 [(set_attr "type" "lea")
7140 (set_attr "mode" "SI")])
7142 (define_insn_and_split "*lea_general_2_zext"
7143 [(set (match_operand:DI 0 "register_operand" "=r")
7146 (match_operand:SI 1 "index_register_operand" "l")
7147 (match_operand:SI 2 "const248_operand" "n"))
7148 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7151 "&& reload_completed"
7153 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7155 (match_dup 3)) 0)))]
7157 operands[1] = gen_lowpart (Pmode, operands[1]);
7158 operands[3] = gen_lowpart (Pmode, operands[3]);
7160 [(set_attr "type" "lea")
7161 (set_attr "mode" "SI")])
7163 (define_insn_and_split "*lea_general_3"
7164 [(set (match_operand 0 "register_operand" "=r")
7165 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7166 (match_operand 2 "const248_operand" "i"))
7167 (match_operand 3 "register_operand" "r"))
7168 (match_operand 4 "immediate_operand" "i")))]
7169 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7170 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7171 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7172 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7173 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7175 "&& reload_completed"
7179 operands[0] = gen_lowpart (SImode, operands[0]);
7180 operands[1] = gen_lowpart (Pmode, operands[1]);
7181 operands[3] = gen_lowpart (Pmode, operands[3]);
7182 operands[4] = gen_lowpart (Pmode, operands[4]);
7183 pat = gen_rtx_PLUS (Pmode,
7184 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7188 if (Pmode != SImode)
7189 pat = gen_rtx_SUBREG (SImode, pat, 0);
7190 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7193 [(set_attr "type" "lea")
7194 (set_attr "mode" "SI")])
7196 (define_insn_and_split "*lea_general_3_zext"
7197 [(set (match_operand:DI 0 "register_operand" "=r")
7201 (match_operand:SI 1 "index_register_operand" "l")
7202 (match_operand:SI 2 "const248_operand" "n"))
7203 (match_operand:SI 3 "register_operand" "r"))
7204 (match_operand:SI 4 "immediate_operand" "i"))))]
7207 "&& reload_completed"
7209 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7212 (match_dup 4)) 0)))]
7214 operands[1] = gen_lowpart (Pmode, operands[1]);
7215 operands[3] = gen_lowpart (Pmode, operands[3]);
7216 operands[4] = gen_lowpart (Pmode, operands[4]);
7218 [(set_attr "type" "lea")
7219 (set_attr "mode" "SI")])
7221 ;; Convert lea to the lea pattern to avoid flags dependency.
7223 [(set (match_operand:DI 0 "register_operand" "")
7224 (plus:DI (match_operand:DI 1 "register_operand" "")
7225 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7226 (clobber (reg:CC FLAGS_REG))]
7227 "TARGET_64BIT && reload_completed
7228 && ix86_lea_for_add_ok (PLUS, insn, operands)"
7230 (plus:DI (match_dup 1)
7234 ;; Convert lea to the lea pattern to avoid flags dependency.
7236 [(set (match_operand 0 "register_operand" "")
7237 (plus (match_operand 1 "register_operand" "")
7238 (match_operand 2 "nonmemory_operand" "")))
7239 (clobber (reg:CC FLAGS_REG))]
7240 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
7244 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7245 may confuse gen_lowpart. */
7246 if (GET_MODE (operands[0]) != Pmode)
7248 operands[1] = gen_lowpart (Pmode, operands[1]);
7249 operands[2] = gen_lowpart (Pmode, operands[2]);
7251 operands[0] = gen_lowpart (SImode, operands[0]);
7252 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7253 if (Pmode != SImode)
7254 pat = gen_rtx_SUBREG (SImode, pat, 0);
7255 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7259 ;; Convert lea to the lea pattern to avoid flags dependency.
7261 [(set (match_operand:DI 0 "register_operand" "")
7263 (plus:SI (match_operand:SI 1 "register_operand" "")
7264 (match_operand:SI 2 "nonmemory_operand" ""))))
7265 (clobber (reg:CC FLAGS_REG))]
7266 "TARGET_64BIT && reload_completed
7267 && true_regnum (operands[0]) != true_regnum (operands[1])"
7269 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7271 operands[1] = gen_lowpart (Pmode, operands[1]);
7272 operands[2] = gen_lowpart (Pmode, operands[2]);
7275 ;; Subtract instructions
7277 (define_expand "sub<mode>3"
7278 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7279 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7280 (match_operand:SDWIM 2 "<general_operand>" "")))]
7282 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7284 (define_insn_and_split "*sub<dwi>3_doubleword"
7285 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7287 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7288 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7289 (clobber (reg:CC FLAGS_REG))]
7290 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7293 [(parallel [(set (reg:CC FLAGS_REG)
7294 (compare:CC (match_dup 1) (match_dup 2)))
7296 (minus:DWIH (match_dup 1) (match_dup 2)))])
7297 (parallel [(set (match_dup 3)
7301 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7303 (clobber (reg:CC FLAGS_REG))])]
7304 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7306 (define_insn "*sub<mode>_1"
7307 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7309 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7310 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7311 (clobber (reg:CC FLAGS_REG))]
7312 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7313 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7314 [(set_attr "type" "alu")
7315 (set_attr "mode" "<MODE>")])
7317 (define_insn "*subsi_1_zext"
7318 [(set (match_operand:DI 0 "register_operand" "=r")
7320 (minus:SI (match_operand:SI 1 "register_operand" "0")
7321 (match_operand:SI 2 "general_operand" "g"))))
7322 (clobber (reg:CC FLAGS_REG))]
7323 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7324 "sub{l}\t{%2, %k0|%k0, %2}"
7325 [(set_attr "type" "alu")
7326 (set_attr "mode" "SI")])
7328 (define_insn "*subqi_1_slp"
7329 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7330 (minus:QI (match_dup 0)
7331 (match_operand:QI 1 "general_operand" "qn,qm")))
7332 (clobber (reg:CC FLAGS_REG))]
7333 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7334 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7335 "sub{b}\t{%1, %0|%0, %1}"
7336 [(set_attr "type" "alu1")
7337 (set_attr "mode" "QI")])
7339 (define_insn "*sub<mode>_2"
7340 [(set (reg FLAGS_REG)
7343 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7344 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7346 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7347 (minus:SWI (match_dup 1) (match_dup 2)))]
7348 "ix86_match_ccmode (insn, CCGOCmode)
7349 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7350 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7351 [(set_attr "type" "alu")
7352 (set_attr "mode" "<MODE>")])
7354 (define_insn "*subsi_2_zext"
7355 [(set (reg FLAGS_REG)
7357 (minus:SI (match_operand:SI 1 "register_operand" "0")
7358 (match_operand:SI 2 "general_operand" "g"))
7360 (set (match_operand:DI 0 "register_operand" "=r")
7362 (minus:SI (match_dup 1)
7364 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7365 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7366 "sub{l}\t{%2, %k0|%k0, %2}"
7367 [(set_attr "type" "alu")
7368 (set_attr "mode" "SI")])
7370 (define_insn "*sub<mode>_3"
7371 [(set (reg FLAGS_REG)
7372 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7373 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7374 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7375 (minus:SWI (match_dup 1) (match_dup 2)))]
7376 "ix86_match_ccmode (insn, CCmode)
7377 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7378 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7379 [(set_attr "type" "alu")
7380 (set_attr "mode" "<MODE>")])
7382 (define_insn "*subsi_3_zext"
7383 [(set (reg FLAGS_REG)
7384 (compare (match_operand:SI 1 "register_operand" "0")
7385 (match_operand:SI 2 "general_operand" "g")))
7386 (set (match_operand:DI 0 "register_operand" "=r")
7388 (minus:SI (match_dup 1)
7390 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7391 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7392 "sub{l}\t{%2, %1|%1, %2}"
7393 [(set_attr "type" "alu")
7394 (set_attr "mode" "SI")])
7396 ;; Add with carry and subtract with borrow
7398 (define_expand "<plusminus_insn><mode>3_carry"
7400 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7402 (match_operand:SWI 1 "nonimmediate_operand" "")
7403 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7404 [(match_operand 3 "flags_reg_operand" "")
7406 (match_operand:SWI 2 "<general_operand>" ""))))
7407 (clobber (reg:CC FLAGS_REG))])]
7408 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7411 (define_insn "*<plusminus_insn><mode>3_carry"
7412 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7414 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7416 (match_operator 3 "ix86_carry_flag_operator"
7417 [(reg FLAGS_REG) (const_int 0)])
7418 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7419 (clobber (reg:CC FLAGS_REG))]
7420 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7421 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7422 [(set_attr "type" "alu")
7423 (set_attr "use_carry" "1")
7424 (set_attr "pent_pair" "pu")
7425 (set_attr "mode" "<MODE>")])
7427 (define_insn "*addsi3_carry_zext"
7428 [(set (match_operand:DI 0 "register_operand" "=r")
7430 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7431 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7432 [(reg FLAGS_REG) (const_int 0)])
7433 (match_operand:SI 2 "general_operand" "g")))))
7434 (clobber (reg:CC FLAGS_REG))]
7435 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7436 "adc{l}\t{%2, %k0|%k0, %2}"
7437 [(set_attr "type" "alu")
7438 (set_attr "use_carry" "1")
7439 (set_attr "pent_pair" "pu")
7440 (set_attr "mode" "SI")])
7442 (define_insn "*subsi3_carry_zext"
7443 [(set (match_operand:DI 0 "register_operand" "=r")
7445 (minus:SI (match_operand:SI 1 "register_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 (MINUS, SImode, operands)"
7451 "sbb{l}\t{%2, %k0|%k0, %2}"
7452 [(set_attr "type" "alu")
7453 (set_attr "pent_pair" "pu")
7454 (set_attr "mode" "SI")])
7456 ;; Overflow setting add and subtract instructions
7458 (define_insn "*add<mode>3_cconly_overflow"
7459 [(set (reg:CCC FLAGS_REG)
7462 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7463 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7465 (clobber (match_scratch:SWI 0 "=<r>"))]
7466 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7467 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7468 [(set_attr "type" "alu")
7469 (set_attr "mode" "<MODE>")])
7471 (define_insn "*sub<mode>3_cconly_overflow"
7472 [(set (reg:CCC FLAGS_REG)
7475 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7476 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7479 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7480 [(set_attr "type" "icmp")
7481 (set_attr "mode" "<MODE>")])
7483 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7484 [(set (reg:CCC FLAGS_REG)
7487 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7488 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7490 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7491 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7492 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7493 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7494 [(set_attr "type" "alu")
7495 (set_attr "mode" "<MODE>")])
7497 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7498 [(set (reg:CCC FLAGS_REG)
7501 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7502 (match_operand:SI 2 "general_operand" "g"))
7504 (set (match_operand:DI 0 "register_operand" "=r")
7505 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7506 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7507 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7508 [(set_attr "type" "alu")
7509 (set_attr "mode" "SI")])
7511 ;; The patterns that match these are at the end of this file.
7513 (define_expand "<plusminus_insn>xf3"
7514 [(set (match_operand:XF 0 "register_operand" "")
7516 (match_operand:XF 1 "register_operand" "")
7517 (match_operand:XF 2 "register_operand" "")))]
7521 (define_expand "<plusminus_insn><mode>3"
7522 [(set (match_operand:MODEF 0 "register_operand" "")
7524 (match_operand:MODEF 1 "register_operand" "")
7525 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7526 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7527 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7530 ;; Multiply instructions
7532 (define_expand "mul<mode>3"
7533 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7535 (match_operand:SWIM248 1 "register_operand" "")
7536 (match_operand:SWIM248 2 "<general_operand>" "")))
7537 (clobber (reg:CC FLAGS_REG))])]
7541 (define_expand "mulqi3"
7542 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7544 (match_operand:QI 1 "register_operand" "")
7545 (match_operand:QI 2 "nonimmediate_operand" "")))
7546 (clobber (reg:CC FLAGS_REG))])]
7547 "TARGET_QIMODE_MATH"
7551 ;; IMUL reg32/64, reg32/64, imm8 Direct
7552 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7553 ;; IMUL reg32/64, reg32/64, imm32 Direct
7554 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7555 ;; IMUL reg32/64, reg32/64 Direct
7556 ;; IMUL reg32/64, mem32/64 Direct
7558 (define_insn "*mul<mode>3_1"
7559 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7561 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7562 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7563 (clobber (reg:CC FLAGS_REG))]
7564 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7566 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7567 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7568 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7569 [(set_attr "type" "imul")
7570 (set_attr "prefix_0f" "0,0,1")
7571 (set (attr "athlon_decode")
7572 (cond [(eq_attr "cpu" "athlon")
7573 (const_string "vector")
7574 (eq_attr "alternative" "1")
7575 (const_string "vector")
7576 (and (eq_attr "alternative" "2")
7577 (match_operand 1 "memory_operand" ""))
7578 (const_string "vector")]
7579 (const_string "direct")))
7580 (set (attr "amdfam10_decode")
7581 (cond [(and (eq_attr "alternative" "0,1")
7582 (match_operand 1 "memory_operand" ""))
7583 (const_string "vector")]
7584 (const_string "direct")))
7585 (set_attr "mode" "<MODE>")])
7587 (define_insn "*mulsi3_1_zext"
7588 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7590 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7591 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7592 (clobber (reg:CC FLAGS_REG))]
7594 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7596 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7597 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7598 imul{l}\t{%2, %k0|%k0, %2}"
7599 [(set_attr "type" "imul")
7600 (set_attr "prefix_0f" "0,0,1")
7601 (set (attr "athlon_decode")
7602 (cond [(eq_attr "cpu" "athlon")
7603 (const_string "vector")
7604 (eq_attr "alternative" "1")
7605 (const_string "vector")
7606 (and (eq_attr "alternative" "2")
7607 (match_operand 1 "memory_operand" ""))
7608 (const_string "vector")]
7609 (const_string "direct")))
7610 (set (attr "amdfam10_decode")
7611 (cond [(and (eq_attr "alternative" "0,1")
7612 (match_operand 1 "memory_operand" ""))
7613 (const_string "vector")]
7614 (const_string "direct")))
7615 (set_attr "mode" "SI")])
7618 ;; IMUL reg16, reg16, imm8 VectorPath
7619 ;; IMUL reg16, mem16, imm8 VectorPath
7620 ;; IMUL reg16, reg16, imm16 VectorPath
7621 ;; IMUL reg16, mem16, imm16 VectorPath
7622 ;; IMUL reg16, reg16 Direct
7623 ;; IMUL reg16, mem16 Direct
7625 (define_insn "*mulhi3_1"
7626 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7627 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7628 (match_operand:HI 2 "general_operand" "K,n,mr")))
7629 (clobber (reg:CC FLAGS_REG))]
7631 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7633 imul{w}\t{%2, %1, %0|%0, %1, %2}
7634 imul{w}\t{%2, %1, %0|%0, %1, %2}
7635 imul{w}\t{%2, %0|%0, %2}"
7636 [(set_attr "type" "imul")
7637 (set_attr "prefix_0f" "0,0,1")
7638 (set (attr "athlon_decode")
7639 (cond [(eq_attr "cpu" "athlon")
7640 (const_string "vector")
7641 (eq_attr "alternative" "1,2")
7642 (const_string "vector")]
7643 (const_string "direct")))
7644 (set (attr "amdfam10_decode")
7645 (cond [(eq_attr "alternative" "0,1")
7646 (const_string "vector")]
7647 (const_string "direct")))
7648 (set_attr "mode" "HI")])
7654 (define_insn "*mulqi3_1"
7655 [(set (match_operand:QI 0 "register_operand" "=a")
7656 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7657 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7658 (clobber (reg:CC FLAGS_REG))]
7660 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7662 [(set_attr "type" "imul")
7663 (set_attr "length_immediate" "0")
7664 (set (attr "athlon_decode")
7665 (if_then_else (eq_attr "cpu" "athlon")
7666 (const_string "vector")
7667 (const_string "direct")))
7668 (set_attr "amdfam10_decode" "direct")
7669 (set_attr "mode" "QI")])
7671 (define_expand "<u>mul<mode><dwi>3"
7672 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7675 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7677 (match_operand:DWIH 2 "register_operand" ""))))
7678 (clobber (reg:CC FLAGS_REG))])]
7682 (define_expand "<u>mulqihi3"
7683 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7686 (match_operand:QI 1 "nonimmediate_operand" ""))
7688 (match_operand:QI 2 "register_operand" ""))))
7689 (clobber (reg:CC FLAGS_REG))])]
7690 "TARGET_QIMODE_MATH"
7693 (define_insn "*<u>mul<mode><dwi>3_1"
7694 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7697 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7699 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7700 (clobber (reg:CC FLAGS_REG))]
7701 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7702 "<sgnprefix>mul{<imodesuffix>}\t%2"
7703 [(set_attr "type" "imul")
7704 (set_attr "length_immediate" "0")
7705 (set (attr "athlon_decode")
7706 (if_then_else (eq_attr "cpu" "athlon")
7707 (const_string "vector")
7708 (const_string "double")))
7709 (set_attr "amdfam10_decode" "double")
7710 (set_attr "mode" "<MODE>")])
7712 (define_insn "*<u>mulqihi3_1"
7713 [(set (match_operand:HI 0 "register_operand" "=a")
7716 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7718 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7719 (clobber (reg:CC FLAGS_REG))]
7721 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7722 "<sgnprefix>mul{b}\t%2"
7723 [(set_attr "type" "imul")
7724 (set_attr "length_immediate" "0")
7725 (set (attr "athlon_decode")
7726 (if_then_else (eq_attr "cpu" "athlon")
7727 (const_string "vector")
7728 (const_string "direct")))
7729 (set_attr "amdfam10_decode" "direct")
7730 (set_attr "mode" "QI")])
7732 (define_expand "<s>mul<mode>3_highpart"
7733 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7738 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7740 (match_operand:SWI48 2 "register_operand" "")))
7742 (clobber (match_scratch:SWI48 3 ""))
7743 (clobber (reg:CC FLAGS_REG))])]
7745 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7747 (define_insn "*<s>muldi3_highpart_1"
7748 [(set (match_operand:DI 0 "register_operand" "=d")
7753 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7755 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7757 (clobber (match_scratch:DI 3 "=1"))
7758 (clobber (reg:CC FLAGS_REG))]
7760 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7761 "<sgnprefix>mul{q}\t%2"
7762 [(set_attr "type" "imul")
7763 (set_attr "length_immediate" "0")
7764 (set (attr "athlon_decode")
7765 (if_then_else (eq_attr "cpu" "athlon")
7766 (const_string "vector")
7767 (const_string "double")))
7768 (set_attr "amdfam10_decode" "double")
7769 (set_attr "mode" "DI")])
7771 (define_insn "*<s>mulsi3_highpart_1"
7772 [(set (match_operand:SI 0 "register_operand" "=d")
7777 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7779 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7781 (clobber (match_scratch:SI 3 "=1"))
7782 (clobber (reg:CC FLAGS_REG))]
7783 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7784 "<sgnprefix>mul{l}\t%2"
7785 [(set_attr "type" "imul")
7786 (set_attr "length_immediate" "0")
7787 (set (attr "athlon_decode")
7788 (if_then_else (eq_attr "cpu" "athlon")
7789 (const_string "vector")
7790 (const_string "double")))
7791 (set_attr "amdfam10_decode" "double")
7792 (set_attr "mode" "SI")])
7794 (define_insn "*<s>mulsi3_highpart_zext"
7795 [(set (match_operand:DI 0 "register_operand" "=d")
7796 (zero_extend:DI (truncate:SI
7798 (mult:DI (any_extend:DI
7799 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7801 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7803 (clobber (match_scratch:SI 3 "=1"))
7804 (clobber (reg:CC FLAGS_REG))]
7806 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7807 "<sgnprefix>mul{l}\t%2"
7808 [(set_attr "type" "imul")
7809 (set_attr "length_immediate" "0")
7810 (set (attr "athlon_decode")
7811 (if_then_else (eq_attr "cpu" "athlon")
7812 (const_string "vector")
7813 (const_string "double")))
7814 (set_attr "amdfam10_decode" "double")
7815 (set_attr "mode" "SI")])
7817 ;; The patterns that match these are at the end of this file.
7819 (define_expand "mulxf3"
7820 [(set (match_operand:XF 0 "register_operand" "")
7821 (mult:XF (match_operand:XF 1 "register_operand" "")
7822 (match_operand:XF 2 "register_operand" "")))]
7826 (define_expand "mul<mode>3"
7827 [(set (match_operand:MODEF 0 "register_operand" "")
7828 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7829 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7830 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7831 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7834 ;; Divide instructions
7836 (define_insn "<u>divqi3"
7837 [(set (match_operand:QI 0 "register_operand" "=a")
7839 (match_operand:HI 1 "register_operand" "0")
7840 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7841 (clobber (reg:CC FLAGS_REG))]
7842 "TARGET_QIMODE_MATH"
7843 "<sgnprefix>div{b}\t%2"
7844 [(set_attr "type" "idiv")
7845 (set_attr "mode" "QI")])
7847 ;; The patterns that match these are at the end of this file.
7849 (define_expand "divxf3"
7850 [(set (match_operand:XF 0 "register_operand" "")
7851 (div:XF (match_operand:XF 1 "register_operand" "")
7852 (match_operand:XF 2 "register_operand" "")))]
7856 (define_expand "divdf3"
7857 [(set (match_operand:DF 0 "register_operand" "")
7858 (div:DF (match_operand:DF 1 "register_operand" "")
7859 (match_operand:DF 2 "nonimmediate_operand" "")))]
7860 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7861 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7864 (define_expand "divsf3"
7865 [(set (match_operand:SF 0 "register_operand" "")
7866 (div:SF (match_operand:SF 1 "register_operand" "")
7867 (match_operand:SF 2 "nonimmediate_operand" "")))]
7868 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7871 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7872 && flag_finite_math_only && !flag_trapping_math
7873 && flag_unsafe_math_optimizations)
7875 ix86_emit_swdivsf (operands[0], operands[1],
7876 operands[2], SFmode);
7881 ;; Divmod instructions.
7883 (define_expand "divmod<mode>4"
7884 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7886 (match_operand:SWIM248 1 "register_operand" "")
7887 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7888 (set (match_operand:SWIM248 3 "register_operand" "")
7889 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7890 (clobber (reg:CC FLAGS_REG))])]
7894 (define_insn_and_split "*divmod<mode>4"
7895 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7896 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7897 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7898 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7899 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7900 (clobber (reg:CC FLAGS_REG))]
7903 "&& reload_completed"
7904 [(parallel [(set (match_dup 1)
7905 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7906 (clobber (reg:CC FLAGS_REG))])
7907 (parallel [(set (match_dup 0)
7908 (div:SWIM248 (match_dup 2) (match_dup 3)))
7910 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7912 (clobber (reg:CC FLAGS_REG))])]
7914 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
7916 if (<MODE>mode != HImode
7917 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7918 operands[4] = operands[2];
7921 /* Avoid use of cltd in favor of a mov+shift. */
7922 emit_move_insn (operands[1], operands[2]);
7923 operands[4] = operands[1];
7926 [(set_attr "type" "multi")
7927 (set_attr "mode" "<MODE>")])
7929 (define_insn "*divmod<mode>4_noext"
7930 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7931 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7932 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7933 (set (match_operand:SWIM248 1 "register_operand" "=d")
7934 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7935 (use (match_operand:SWIM248 4 "register_operand" "1"))
7936 (clobber (reg:CC FLAGS_REG))]
7938 "idiv{<imodesuffix>}\t%3"
7939 [(set_attr "type" "idiv")
7940 (set_attr "mode" "<MODE>")])
7942 (define_expand "udivmod<mode>4"
7943 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7945 (match_operand:SWIM248 1 "register_operand" "")
7946 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7947 (set (match_operand:SWIM248 3 "register_operand" "")
7948 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7949 (clobber (reg:CC FLAGS_REG))])]
7953 (define_insn_and_split "*udivmod<mode>4"
7954 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7955 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7956 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7957 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7958 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7959 (clobber (reg:CC FLAGS_REG))]
7962 "&& reload_completed"
7963 [(set (match_dup 1) (const_int 0))
7964 (parallel [(set (match_dup 0)
7965 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7967 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7969 (clobber (reg:CC FLAGS_REG))])]
7971 [(set_attr "type" "multi")
7972 (set_attr "mode" "<MODE>")])
7974 (define_insn "*udivmod<mode>4_noext"
7975 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7976 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7977 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7978 (set (match_operand:SWIM248 1 "register_operand" "=d")
7979 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7980 (use (match_operand:SWIM248 4 "register_operand" "1"))
7981 (clobber (reg:CC FLAGS_REG))]
7983 "div{<imodesuffix>}\t%3"
7984 [(set_attr "type" "idiv")
7985 (set_attr "mode" "<MODE>")])
7987 ;; We cannot use div/idiv for double division, because it causes
7988 ;; "division by zero" on the overflow and that's not what we expect
7989 ;; from truncate. Because true (non truncating) double division is
7990 ;; never generated, we can't create this insn anyway.
7993 ; [(set (match_operand:SI 0 "register_operand" "=a")
7995 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7997 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7998 ; (set (match_operand:SI 3 "register_operand" "=d")
8000 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8001 ; (clobber (reg:CC FLAGS_REG))]
8003 ; "div{l}\t{%2, %0|%0, %2}"
8004 ; [(set_attr "type" "idiv")])
8006 ;;- Logical AND instructions
8008 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8009 ;; Note that this excludes ah.
8011 (define_expand "testsi_ccno_1"
8012 [(set (reg:CCNO FLAGS_REG)
8014 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8015 (match_operand:SI 1 "nonmemory_operand" ""))
8020 (define_expand "testqi_ccz_1"
8021 [(set (reg:CCZ FLAGS_REG)
8022 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8023 (match_operand:QI 1 "nonmemory_operand" ""))
8028 (define_insn "*testdi_1"
8029 [(set (reg FLAGS_REG)
8032 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8033 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8035 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8036 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8038 test{l}\t{%k1, %k0|%k0, %k1}
8039 test{l}\t{%k1, %k0|%k0, %k1}
8040 test{q}\t{%1, %0|%0, %1}
8041 test{q}\t{%1, %0|%0, %1}
8042 test{q}\t{%1, %0|%0, %1}"
8043 [(set_attr "type" "test")
8044 (set_attr "modrm" "0,1,0,1,1")
8045 (set_attr "mode" "SI,SI,DI,DI,DI")])
8047 (define_insn "*testqi_1_maybe_si"
8048 [(set (reg FLAGS_REG)
8051 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8052 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8054 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8055 && ix86_match_ccmode (insn,
8056 CONST_INT_P (operands[1])
8057 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8059 if (which_alternative == 3)
8061 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8062 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8063 return "test{l}\t{%1, %k0|%k0, %1}";
8065 return "test{b}\t{%1, %0|%0, %1}";
8067 [(set_attr "type" "test")
8068 (set_attr "modrm" "0,1,1,1")
8069 (set_attr "mode" "QI,QI,QI,SI")
8070 (set_attr "pent_pair" "uv,np,uv,np")])
8072 (define_insn "*test<mode>_1"
8073 [(set (reg FLAGS_REG)
8076 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8077 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8079 "ix86_match_ccmode (insn, CCNOmode)
8080 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8081 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8082 [(set_attr "type" "test")
8083 (set_attr "modrm" "0,1,1")
8084 (set_attr "mode" "<MODE>")
8085 (set_attr "pent_pair" "uv,np,uv")])
8087 (define_expand "testqi_ext_ccno_0"
8088 [(set (reg:CCNO FLAGS_REG)
8092 (match_operand 0 "ext_register_operand" "")
8095 (match_operand 1 "const_int_operand" ""))
8100 (define_insn "*testqi_ext_0"
8101 [(set (reg FLAGS_REG)
8105 (match_operand 0 "ext_register_operand" "Q")
8108 (match_operand 1 "const_int_operand" "n"))
8110 "ix86_match_ccmode (insn, CCNOmode)"
8111 "test{b}\t{%1, %h0|%h0, %1}"
8112 [(set_attr "type" "test")
8113 (set_attr "mode" "QI")
8114 (set_attr "length_immediate" "1")
8115 (set_attr "modrm" "1")
8116 (set_attr "pent_pair" "np")])
8118 (define_insn "*testqi_ext_1_rex64"
8119 [(set (reg FLAGS_REG)
8123 (match_operand 0 "ext_register_operand" "Q")
8127 (match_operand:QI 1 "register_operand" "Q")))
8129 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8130 "test{b}\t{%1, %h0|%h0, %1}"
8131 [(set_attr "type" "test")
8132 (set_attr "mode" "QI")])
8134 (define_insn "*testqi_ext_1"
8135 [(set (reg FLAGS_REG)
8139 (match_operand 0 "ext_register_operand" "Q")
8143 (match_operand:QI 1 "general_operand" "Qm")))
8145 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8146 "test{b}\t{%1, %h0|%h0, %1}"
8147 [(set_attr "type" "test")
8148 (set_attr "mode" "QI")])
8150 (define_insn "*testqi_ext_2"
8151 [(set (reg FLAGS_REG)
8155 (match_operand 0 "ext_register_operand" "Q")
8159 (match_operand 1 "ext_register_operand" "Q")
8163 "ix86_match_ccmode (insn, CCNOmode)"
8164 "test{b}\t{%h1, %h0|%h0, %h1}"
8165 [(set_attr "type" "test")
8166 (set_attr "mode" "QI")])
8168 (define_insn "*testqi_ext_3_rex64"
8169 [(set (reg FLAGS_REG)
8170 (compare (zero_extract:DI
8171 (match_operand 0 "nonimmediate_operand" "rm")
8172 (match_operand:DI 1 "const_int_operand" "")
8173 (match_operand:DI 2 "const_int_operand" ""))
8176 && ix86_match_ccmode (insn, CCNOmode)
8177 && INTVAL (operands[1]) > 0
8178 && INTVAL (operands[2]) >= 0
8179 /* Ensure that resulting mask is zero or sign extended operand. */
8180 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8181 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8182 && INTVAL (operands[1]) > 32))
8183 && (GET_MODE (operands[0]) == SImode
8184 || GET_MODE (operands[0]) == DImode
8185 || GET_MODE (operands[0]) == HImode
8186 || GET_MODE (operands[0]) == QImode)"
8189 ;; Combine likes to form bit extractions for some tests. Humor it.
8190 (define_insn "*testqi_ext_3"
8191 [(set (reg FLAGS_REG)
8192 (compare (zero_extract:SI
8193 (match_operand 0 "nonimmediate_operand" "rm")
8194 (match_operand:SI 1 "const_int_operand" "")
8195 (match_operand:SI 2 "const_int_operand" ""))
8197 "ix86_match_ccmode (insn, CCNOmode)
8198 && INTVAL (operands[1]) > 0
8199 && INTVAL (operands[2]) >= 0
8200 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8201 && (GET_MODE (operands[0]) == SImode
8202 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8203 || GET_MODE (operands[0]) == HImode
8204 || GET_MODE (operands[0]) == QImode)"
8208 [(set (match_operand 0 "flags_reg_operand" "")
8209 (match_operator 1 "compare_operator"
8211 (match_operand 2 "nonimmediate_operand" "")
8212 (match_operand 3 "const_int_operand" "")
8213 (match_operand 4 "const_int_operand" ""))
8215 "ix86_match_ccmode (insn, CCNOmode)"
8216 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8218 rtx val = operands[2];
8219 HOST_WIDE_INT len = INTVAL (operands[3]);
8220 HOST_WIDE_INT pos = INTVAL (operands[4]);
8222 enum machine_mode mode, submode;
8224 mode = GET_MODE (val);
8227 /* ??? Combine likes to put non-volatile mem extractions in QImode
8228 no matter the size of the test. So find a mode that works. */
8229 if (! MEM_VOLATILE_P (val))
8231 mode = smallest_mode_for_size (pos + len, MODE_INT);
8232 val = adjust_address (val, mode, 0);
8235 else if (GET_CODE (val) == SUBREG
8236 && (submode = GET_MODE (SUBREG_REG (val)),
8237 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8238 && pos + len <= GET_MODE_BITSIZE (submode)
8239 && GET_MODE_CLASS (submode) == MODE_INT)
8241 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8243 val = SUBREG_REG (val);
8245 else if (mode == HImode && pos + len <= 8)
8247 /* Small HImode tests can be converted to QImode. */
8249 val = gen_lowpart (QImode, val);
8252 if (len == HOST_BITS_PER_WIDE_INT)
8255 mask = ((HOST_WIDE_INT)1 << len) - 1;
8258 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8261 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8262 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8263 ;; this is relatively important trick.
8264 ;; Do the conversion only post-reload to avoid limiting of the register class
8267 [(set (match_operand 0 "flags_reg_operand" "")
8268 (match_operator 1 "compare_operator"
8269 [(and (match_operand 2 "register_operand" "")
8270 (match_operand 3 "const_int_operand" ""))
8273 && QI_REG_P (operands[2])
8274 && GET_MODE (operands[2]) != QImode
8275 && ((ix86_match_ccmode (insn, CCZmode)
8276 && !(INTVAL (operands[3]) & ~(255 << 8)))
8277 || (ix86_match_ccmode (insn, CCNOmode)
8278 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8281 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8284 "operands[2] = gen_lowpart (SImode, operands[2]);
8285 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8288 [(set (match_operand 0 "flags_reg_operand" "")
8289 (match_operator 1 "compare_operator"
8290 [(and (match_operand 2 "nonimmediate_operand" "")
8291 (match_operand 3 "const_int_operand" ""))
8294 && GET_MODE (operands[2]) != QImode
8295 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8296 && ((ix86_match_ccmode (insn, CCZmode)
8297 && !(INTVAL (operands[3]) & ~255))
8298 || (ix86_match_ccmode (insn, CCNOmode)
8299 && !(INTVAL (operands[3]) & ~127)))"
8301 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8303 "operands[2] = gen_lowpart (QImode, operands[2]);
8304 operands[3] = gen_lowpart (QImode, operands[3]);")
8306 ;; %%% This used to optimize known byte-wide and operations to memory,
8307 ;; and sometimes to QImode registers. If this is considered useful,
8308 ;; it should be done with splitters.
8310 (define_expand "and<mode>3"
8311 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8312 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8313 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8315 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8317 (define_insn "*anddi_1"
8318 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8320 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8321 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8322 (clobber (reg:CC FLAGS_REG))]
8323 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8325 switch (get_attr_type (insn))
8329 enum machine_mode mode;
8331 gcc_assert (CONST_INT_P (operands[2]));
8332 if (INTVAL (operands[2]) == 0xff)
8336 gcc_assert (INTVAL (operands[2]) == 0xffff);
8340 operands[1] = gen_lowpart (mode, operands[1]);
8342 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8344 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8348 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8349 if (get_attr_mode (insn) == MODE_SI)
8350 return "and{l}\t{%k2, %k0|%k0, %k2}";
8352 return "and{q}\t{%2, %0|%0, %2}";
8355 [(set_attr "type" "alu,alu,alu,imovx")
8356 (set_attr "length_immediate" "*,*,*,0")
8357 (set (attr "prefix_rex")
8359 (and (eq_attr "type" "imovx")
8360 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8361 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8363 (const_string "*")))
8364 (set_attr "mode" "SI,DI,DI,SI")])
8366 (define_insn "*andsi_1"
8367 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8368 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8369 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8370 (clobber (reg:CC FLAGS_REG))]
8371 "ix86_binary_operator_ok (AND, SImode, operands)"
8373 switch (get_attr_type (insn))
8377 enum machine_mode mode;
8379 gcc_assert (CONST_INT_P (operands[2]));
8380 if (INTVAL (operands[2]) == 0xff)
8384 gcc_assert (INTVAL (operands[2]) == 0xffff);
8388 operands[1] = gen_lowpart (mode, operands[1]);
8390 return "movz{bl|x}\t{%1, %0|%0, %1}";
8392 return "movz{wl|x}\t{%1, %0|%0, %1}";
8396 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8397 return "and{l}\t{%2, %0|%0, %2}";
8400 [(set_attr "type" "alu,alu,imovx")
8401 (set (attr "prefix_rex")
8403 (and (eq_attr "type" "imovx")
8404 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8405 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8407 (const_string "*")))
8408 (set_attr "length_immediate" "*,*,0")
8409 (set_attr "mode" "SI")])
8411 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8412 (define_insn "*andsi_1_zext"
8413 [(set (match_operand:DI 0 "register_operand" "=r")
8415 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8416 (match_operand:SI 2 "general_operand" "g"))))
8417 (clobber (reg:CC FLAGS_REG))]
8418 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8419 "and{l}\t{%2, %k0|%k0, %2}"
8420 [(set_attr "type" "alu")
8421 (set_attr "mode" "SI")])
8423 (define_insn "*andhi_1"
8424 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8425 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8426 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8427 (clobber (reg:CC FLAGS_REG))]
8428 "ix86_binary_operator_ok (AND, HImode, operands)"
8430 switch (get_attr_type (insn))
8433 gcc_assert (CONST_INT_P (operands[2]));
8434 gcc_assert (INTVAL (operands[2]) == 0xff);
8435 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8438 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8440 return "and{w}\t{%2, %0|%0, %2}";
8443 [(set_attr "type" "alu,alu,imovx")
8444 (set_attr "length_immediate" "*,*,0")
8445 (set (attr "prefix_rex")
8447 (and (eq_attr "type" "imovx")
8448 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8450 (const_string "*")))
8451 (set_attr "mode" "HI,HI,SI")])
8453 ;; %%% Potential partial reg stall on alternative 2. What to do?
8454 (define_insn "*andqi_1"
8455 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8456 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8457 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8458 (clobber (reg:CC FLAGS_REG))]
8459 "ix86_binary_operator_ok (AND, QImode, operands)"
8461 and{b}\t{%2, %0|%0, %2}
8462 and{b}\t{%2, %0|%0, %2}
8463 and{l}\t{%k2, %k0|%k0, %k2}"
8464 [(set_attr "type" "alu")
8465 (set_attr "mode" "QI,QI,SI")])
8467 (define_insn "*andqi_1_slp"
8468 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8469 (and:QI (match_dup 0)
8470 (match_operand:QI 1 "general_operand" "qn,qmn")))
8471 (clobber (reg:CC FLAGS_REG))]
8472 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8473 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8474 "and{b}\t{%1, %0|%0, %1}"
8475 [(set_attr "type" "alu1")
8476 (set_attr "mode" "QI")])
8479 [(set (match_operand 0 "register_operand" "")
8481 (const_int -65536)))
8482 (clobber (reg:CC FLAGS_REG))]
8483 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8484 || optimize_function_for_size_p (cfun)"
8485 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8486 "operands[1] = gen_lowpart (HImode, operands[0]);")
8489 [(set (match_operand 0 "ext_register_operand" "")
8492 (clobber (reg:CC FLAGS_REG))]
8493 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8494 && reload_completed"
8495 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8496 "operands[1] = gen_lowpart (QImode, operands[0]);")
8499 [(set (match_operand 0 "ext_register_operand" "")
8501 (const_int -65281)))
8502 (clobber (reg:CC FLAGS_REG))]
8503 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8504 && reload_completed"
8505 [(parallel [(set (zero_extract:SI (match_dup 0)
8509 (zero_extract:SI (match_dup 0)
8512 (zero_extract:SI (match_dup 0)
8515 (clobber (reg:CC FLAGS_REG))])]
8516 "operands[0] = gen_lowpart (SImode, operands[0]);")
8518 (define_insn "*anddi_2"
8519 [(set (reg FLAGS_REG)
8522 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8523 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8525 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8526 (and:DI (match_dup 1) (match_dup 2)))]
8527 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8528 && ix86_binary_operator_ok (AND, DImode, operands)"
8530 and{l}\t{%k2, %k0|%k0, %k2}
8531 and{q}\t{%2, %0|%0, %2}
8532 and{q}\t{%2, %0|%0, %2}"
8533 [(set_attr "type" "alu")
8534 (set_attr "mode" "SI,DI,DI")])
8536 (define_insn "*andqi_2_maybe_si"
8537 [(set (reg FLAGS_REG)
8539 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8540 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8542 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8543 (and:QI (match_dup 1) (match_dup 2)))]
8544 "ix86_binary_operator_ok (AND, QImode, operands)
8545 && ix86_match_ccmode (insn,
8546 CONST_INT_P (operands[2])
8547 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8549 if (which_alternative == 2)
8551 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8552 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8553 return "and{l}\t{%2, %k0|%k0, %2}";
8555 return "and{b}\t{%2, %0|%0, %2}";
8557 [(set_attr "type" "alu")
8558 (set_attr "mode" "QI,QI,SI")])
8560 (define_insn "*and<mode>_2"
8561 [(set (reg FLAGS_REG)
8562 (compare (and:SWI124
8563 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8564 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8566 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8567 (and:SWI124 (match_dup 1) (match_dup 2)))]
8568 "ix86_match_ccmode (insn, CCNOmode)
8569 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8570 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8571 [(set_attr "type" "alu")
8572 (set_attr "mode" "<MODE>")])
8574 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8575 (define_insn "*andsi_2_zext"
8576 [(set (reg FLAGS_REG)
8578 (match_operand:SI 1 "nonimmediate_operand" "%0")
8579 (match_operand:SI 2 "general_operand" "g"))
8581 (set (match_operand:DI 0 "register_operand" "=r")
8582 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8583 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8584 && ix86_binary_operator_ok (AND, SImode, operands)"
8585 "and{l}\t{%2, %k0|%k0, %2}"
8586 [(set_attr "type" "alu")
8587 (set_attr "mode" "SI")])
8589 (define_insn "*andqi_2_slp"
8590 [(set (reg FLAGS_REG)
8592 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8593 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8595 (set (strict_low_part (match_dup 0))
8596 (and:QI (match_dup 0) (match_dup 1)))]
8597 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8598 && ix86_match_ccmode (insn, CCNOmode)
8599 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8600 "and{b}\t{%1, %0|%0, %1}"
8601 [(set_attr "type" "alu1")
8602 (set_attr "mode" "QI")])
8604 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8605 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8606 ;; for a QImode operand, which of course failed.
8607 (define_insn "andqi_ext_0"
8608 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8613 (match_operand 1 "ext_register_operand" "0")
8616 (match_operand 2 "const_int_operand" "n")))
8617 (clobber (reg:CC FLAGS_REG))]
8619 "and{b}\t{%2, %h0|%h0, %2}"
8620 [(set_attr "type" "alu")
8621 (set_attr "length_immediate" "1")
8622 (set_attr "modrm" "1")
8623 (set_attr "mode" "QI")])
8625 ;; Generated by peephole translating test to and. This shows up
8626 ;; often in fp comparisons.
8627 (define_insn "*andqi_ext_0_cc"
8628 [(set (reg FLAGS_REG)
8632 (match_operand 1 "ext_register_operand" "0")
8635 (match_operand 2 "const_int_operand" "n"))
8637 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8646 "ix86_match_ccmode (insn, CCNOmode)"
8647 "and{b}\t{%2, %h0|%h0, %2}"
8648 [(set_attr "type" "alu")
8649 (set_attr "length_immediate" "1")
8650 (set_attr "modrm" "1")
8651 (set_attr "mode" "QI")])
8653 (define_insn "*andqi_ext_1_rex64"
8654 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8659 (match_operand 1 "ext_register_operand" "0")
8663 (match_operand 2 "ext_register_operand" "Q"))))
8664 (clobber (reg:CC FLAGS_REG))]
8666 "and{b}\t{%2, %h0|%h0, %2}"
8667 [(set_attr "type" "alu")
8668 (set_attr "length_immediate" "0")
8669 (set_attr "mode" "QI")])
8671 (define_insn "*andqi_ext_1"
8672 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8677 (match_operand 1 "ext_register_operand" "0")
8681 (match_operand:QI 2 "general_operand" "Qm"))))
8682 (clobber (reg:CC FLAGS_REG))]
8684 "and{b}\t{%2, %h0|%h0, %2}"
8685 [(set_attr "type" "alu")
8686 (set_attr "length_immediate" "0")
8687 (set_attr "mode" "QI")])
8689 (define_insn "*andqi_ext_2"
8690 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8695 (match_operand 1 "ext_register_operand" "%0")
8699 (match_operand 2 "ext_register_operand" "Q")
8702 (clobber (reg:CC FLAGS_REG))]
8704 "and{b}\t{%h2, %h0|%h0, %h2}"
8705 [(set_attr "type" "alu")
8706 (set_attr "length_immediate" "0")
8707 (set_attr "mode" "QI")])
8709 ;; Convert wide AND instructions with immediate operand to shorter QImode
8710 ;; equivalents when possible.
8711 ;; Don't do the splitting with memory operands, since it introduces risk
8712 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8713 ;; for size, but that can (should?) be handled by generic code instead.
8715 [(set (match_operand 0 "register_operand" "")
8716 (and (match_operand 1 "register_operand" "")
8717 (match_operand 2 "const_int_operand" "")))
8718 (clobber (reg:CC FLAGS_REG))]
8720 && QI_REG_P (operands[0])
8721 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8722 && !(~INTVAL (operands[2]) & ~(255 << 8))
8723 && GET_MODE (operands[0]) != QImode"
8724 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8725 (and:SI (zero_extract:SI (match_dup 1)
8726 (const_int 8) (const_int 8))
8728 (clobber (reg:CC FLAGS_REG))])]
8729 "operands[0] = gen_lowpart (SImode, operands[0]);
8730 operands[1] = gen_lowpart (SImode, operands[1]);
8731 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8733 ;; Since AND can be encoded with sign extended immediate, this is only
8734 ;; profitable when 7th bit is not set.
8736 [(set (match_operand 0 "register_operand" "")
8737 (and (match_operand 1 "general_operand" "")
8738 (match_operand 2 "const_int_operand" "")))
8739 (clobber (reg:CC FLAGS_REG))]
8741 && ANY_QI_REG_P (operands[0])
8742 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8743 && !(~INTVAL (operands[2]) & ~255)
8744 && !(INTVAL (operands[2]) & 128)
8745 && GET_MODE (operands[0]) != QImode"
8746 [(parallel [(set (strict_low_part (match_dup 0))
8747 (and:QI (match_dup 1)
8749 (clobber (reg:CC FLAGS_REG))])]
8750 "operands[0] = gen_lowpart (QImode, operands[0]);
8751 operands[1] = gen_lowpart (QImode, operands[1]);
8752 operands[2] = gen_lowpart (QImode, operands[2]);")
8754 ;; Logical inclusive and exclusive OR instructions
8756 ;; %%% This used to optimize known byte-wide and operations to memory.
8757 ;; If this is considered useful, it should be done with splitters.
8759 (define_expand "<code><mode>3"
8760 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8761 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8762 (match_operand:SWIM 2 "<general_operand>" "")))]
8764 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8766 (define_insn "*<code><mode>_1"
8767 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8769 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8770 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8771 (clobber (reg:CC FLAGS_REG))]
8772 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8773 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8774 [(set_attr "type" "alu")
8775 (set_attr "mode" "<MODE>")])
8777 ;; %%% Potential partial reg stall on alternative 2. What to do?
8778 (define_insn "*<code>qi_1"
8779 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8780 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8781 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8782 (clobber (reg:CC FLAGS_REG))]
8783 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8785 <logicprefix>{b}\t{%2, %0|%0, %2}
8786 <logicprefix>{b}\t{%2, %0|%0, %2}
8787 <logicprefix>{l}\t{%k2, %k0|%k0, %k2}"
8788 [(set_attr "type" "alu")
8789 (set_attr "mode" "QI,QI,SI")])
8791 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8792 (define_insn "*<code>si_1_zext"
8793 [(set (match_operand:DI 0 "register_operand" "=r")
8795 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8796 (match_operand:SI 2 "general_operand" "g"))))
8797 (clobber (reg:CC FLAGS_REG))]
8798 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8799 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8800 [(set_attr "type" "alu")
8801 (set_attr "mode" "SI")])
8803 (define_insn "*<code>si_1_zext_imm"
8804 [(set (match_operand:DI 0 "register_operand" "=r")
8806 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8807 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8808 (clobber (reg:CC FLAGS_REG))]
8809 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8810 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8811 [(set_attr "type" "alu")
8812 (set_attr "mode" "SI")])
8814 (define_insn "*<code>qi_1_slp"
8815 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8816 (any_or:QI (match_dup 0)
8817 (match_operand:QI 1 "general_operand" "qmn,qn")))
8818 (clobber (reg:CC FLAGS_REG))]
8819 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8820 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8821 "<logicprefix>{b}\t{%1, %0|%0, %1}"
8822 [(set_attr "type" "alu1")
8823 (set_attr "mode" "QI")])
8825 (define_insn "*<code><mode>_2"
8826 [(set (reg FLAGS_REG)
8827 (compare (any_or:SWI
8828 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8829 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8831 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8832 (any_or:SWI (match_dup 1) (match_dup 2)))]
8833 "ix86_match_ccmode (insn, CCNOmode)
8834 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8835 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8836 [(set_attr "type" "alu")
8837 (set_attr "mode" "<MODE>")])
8839 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8840 ;; ??? Special case for immediate operand is missing - it is tricky.
8841 (define_insn "*<code>si_2_zext"
8842 [(set (reg FLAGS_REG)
8843 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8844 (match_operand:SI 2 "general_operand" "g"))
8846 (set (match_operand:DI 0 "register_operand" "=r")
8847 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8848 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8849 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8850 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8851 [(set_attr "type" "alu")
8852 (set_attr "mode" "SI")])
8854 (define_insn "*<code>si_2_zext_imm"
8855 [(set (reg FLAGS_REG)
8857 (match_operand:SI 1 "nonimmediate_operand" "%0")
8858 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8860 (set (match_operand:DI 0 "register_operand" "=r")
8861 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8862 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8863 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8864 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8865 [(set_attr "type" "alu")
8866 (set_attr "mode" "SI")])
8868 (define_insn "*<code>qi_2_slp"
8869 [(set (reg FLAGS_REG)
8870 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8871 (match_operand:QI 1 "general_operand" "qmn,qn"))
8873 (set (strict_low_part (match_dup 0))
8874 (any_or:QI (match_dup 0) (match_dup 1)))]
8875 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8876 && ix86_match_ccmode (insn, CCNOmode)
8877 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8878 "<logicprefix>{b}\t{%1, %0|%0, %1}"
8879 [(set_attr "type" "alu1")
8880 (set_attr "mode" "QI")])
8882 (define_insn "*<code><mode>_3"
8883 [(set (reg FLAGS_REG)
8884 (compare (any_or:SWI
8885 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8886 (match_operand:SWI 2 "<general_operand>" "<g>"))
8888 (clobber (match_scratch:SWI 0 "=<r>"))]
8889 "ix86_match_ccmode (insn, CCNOmode)
8890 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8891 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8892 [(set_attr "type" "alu")
8893 (set_attr "mode" "<MODE>")])
8895 (define_insn "*<code>qi_ext_0"
8896 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8901 (match_operand 1 "ext_register_operand" "0")
8904 (match_operand 2 "const_int_operand" "n")))
8905 (clobber (reg:CC FLAGS_REG))]
8906 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8907 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8908 [(set_attr "type" "alu")
8909 (set_attr "length_immediate" "1")
8910 (set_attr "modrm" "1")
8911 (set_attr "mode" "QI")])
8913 (define_insn "*<code>qi_ext_1_rex64"
8914 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8919 (match_operand 1 "ext_register_operand" "0")
8923 (match_operand 2 "ext_register_operand" "Q"))))
8924 (clobber (reg:CC FLAGS_REG))]
8926 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8927 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8928 [(set_attr "type" "alu")
8929 (set_attr "length_immediate" "0")
8930 (set_attr "mode" "QI")])
8932 (define_insn "*<code>qi_ext_1"
8933 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8938 (match_operand 1 "ext_register_operand" "0")
8942 (match_operand:QI 2 "general_operand" "Qm"))))
8943 (clobber (reg:CC FLAGS_REG))]
8945 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8946 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8947 [(set_attr "type" "alu")
8948 (set_attr "length_immediate" "0")
8949 (set_attr "mode" "QI")])
8951 (define_insn "*<code>qi_ext_2"
8952 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8956 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8959 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8962 (clobber (reg:CC FLAGS_REG))]
8963 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8964 "<logicprefix>{b}\t{%h2, %h0|%h0, %h2}"
8965 [(set_attr "type" "alu")
8966 (set_attr "length_immediate" "0")
8967 (set_attr "mode" "QI")])
8970 [(set (match_operand 0 "register_operand" "")
8971 (any_or (match_operand 1 "register_operand" "")
8972 (match_operand 2 "const_int_operand" "")))
8973 (clobber (reg:CC FLAGS_REG))]
8975 && QI_REG_P (operands[0])
8976 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8977 && !(INTVAL (operands[2]) & ~(255 << 8))
8978 && GET_MODE (operands[0]) != QImode"
8979 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8980 (any_or:SI (zero_extract:SI (match_dup 1)
8981 (const_int 8) (const_int 8))
8983 (clobber (reg:CC FLAGS_REG))])]
8984 "operands[0] = gen_lowpart (SImode, operands[0]);
8985 operands[1] = gen_lowpart (SImode, operands[1]);
8986 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8988 ;; Since OR can be encoded with sign extended immediate, this is only
8989 ;; profitable when 7th bit is set.
8991 [(set (match_operand 0 "register_operand" "")
8992 (any_or (match_operand 1 "general_operand" "")
8993 (match_operand 2 "const_int_operand" "")))
8994 (clobber (reg:CC FLAGS_REG))]
8996 && ANY_QI_REG_P (operands[0])
8997 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8998 && !(INTVAL (operands[2]) & ~255)
8999 && (INTVAL (operands[2]) & 128)
9000 && GET_MODE (operands[0]) != QImode"
9001 [(parallel [(set (strict_low_part (match_dup 0))
9002 (any_or:QI (match_dup 1)
9004 (clobber (reg:CC FLAGS_REG))])]
9005 "operands[0] = gen_lowpart (QImode, operands[0]);
9006 operands[1] = gen_lowpart (QImode, operands[1]);
9007 operands[2] = gen_lowpart (QImode, operands[2]);")
9009 (define_expand "xorqi_cc_ext_1"
9011 (set (reg:CCNO FLAGS_REG)
9015 (match_operand 1 "ext_register_operand" "")
9018 (match_operand:QI 2 "general_operand" ""))
9020 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9032 (define_insn "*xorqi_cc_ext_1_rex64"
9033 [(set (reg FLAGS_REG)
9037 (match_operand 1 "ext_register_operand" "0")
9040 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9042 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9051 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9052 "xor{b}\t{%2, %h0|%h0, %2}"
9053 [(set_attr "type" "alu")
9054 (set_attr "modrm" "1")
9055 (set_attr "mode" "QI")])
9057 (define_insn "*xorqi_cc_ext_1"
9058 [(set (reg FLAGS_REG)
9062 (match_operand 1 "ext_register_operand" "0")
9065 (match_operand:QI 2 "general_operand" "qmn"))
9067 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9076 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9077 "xor{b}\t{%2, %h0|%h0, %2}"
9078 [(set_attr "type" "alu")
9079 (set_attr "modrm" "1")
9080 (set_attr "mode" "QI")])
9082 ;; Negation instructions
9084 (define_expand "neg<mode>2"
9085 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9086 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9088 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9090 (define_insn_and_split "*neg<dwi>2_doubleword"
9091 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9092 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9093 (clobber (reg:CC FLAGS_REG))]
9094 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9098 [(set (reg:CCZ FLAGS_REG)
9099 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9100 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9103 (plus:DWIH (match_dup 3)
9104 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9106 (clobber (reg:CC FLAGS_REG))])
9109 (neg:DWIH (match_dup 2)))
9110 (clobber (reg:CC FLAGS_REG))])]
9111 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9113 (define_insn "*neg<mode>2_1"
9114 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9115 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9116 (clobber (reg:CC FLAGS_REG))]
9117 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9118 "neg{<imodesuffix>}\t%0"
9119 [(set_attr "type" "negnot")
9120 (set_attr "mode" "<MODE>")])
9122 ;; Combine is quite creative about this pattern.
9123 (define_insn "*negsi2_1_zext"
9124 [(set (match_operand:DI 0 "register_operand" "=r")
9126 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9129 (clobber (reg:CC FLAGS_REG))]
9130 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9132 [(set_attr "type" "negnot")
9133 (set_attr "mode" "SI")])
9135 ;; The problem with neg is that it does not perform (compare x 0),
9136 ;; it really performs (compare 0 x), which leaves us with the zero
9137 ;; flag being the only useful item.
9139 (define_insn "*neg<mode>2_cmpz"
9140 [(set (reg:CCZ FLAGS_REG)
9142 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9144 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9145 (neg:SWI (match_dup 1)))]
9146 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9147 "neg{<imodesuffix>}\t%0"
9148 [(set_attr "type" "negnot")
9149 (set_attr "mode" "<MODE>")])
9151 (define_insn "*negsi2_cmpz_zext"
9152 [(set (reg:CCZ FLAGS_REG)
9156 (match_operand:DI 1 "register_operand" "0")
9160 (set (match_operand:DI 0 "register_operand" "=r")
9161 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9164 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9166 [(set_attr "type" "negnot")
9167 (set_attr "mode" "SI")])
9169 ;; Changing of sign for FP values is doable using integer unit too.
9171 (define_expand "<code><mode>2"
9172 [(set (match_operand:X87MODEF 0 "register_operand" "")
9173 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9174 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9175 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9177 (define_insn "*absneg<mode>2_mixed"
9178 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9179 (match_operator:MODEF 3 "absneg_operator"
9180 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9181 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9182 (clobber (reg:CC FLAGS_REG))]
9183 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9186 (define_insn "*absneg<mode>2_sse"
9187 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9188 (match_operator:MODEF 3 "absneg_operator"
9189 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9190 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9191 (clobber (reg:CC FLAGS_REG))]
9192 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9195 (define_insn "*absneg<mode>2_i387"
9196 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9197 (match_operator:X87MODEF 3 "absneg_operator"
9198 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9199 (use (match_operand 2 "" ""))
9200 (clobber (reg:CC FLAGS_REG))]
9201 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9204 (define_expand "<code>tf2"
9205 [(set (match_operand:TF 0 "register_operand" "")
9206 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9208 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9210 (define_insn "*absnegtf2_sse"
9211 [(set (match_operand:TF 0 "register_operand" "=x,x")
9212 (match_operator:TF 3 "absneg_operator"
9213 [(match_operand:TF 1 "register_operand" "0,x")]))
9214 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9215 (clobber (reg:CC FLAGS_REG))]
9219 ;; Splitters for fp abs and neg.
9222 [(set (match_operand 0 "fp_register_operand" "")
9223 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9224 (use (match_operand 2 "" ""))
9225 (clobber (reg:CC FLAGS_REG))]
9227 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9230 [(set (match_operand 0 "register_operand" "")
9231 (match_operator 3 "absneg_operator"
9232 [(match_operand 1 "register_operand" "")]))
9233 (use (match_operand 2 "nonimmediate_operand" ""))
9234 (clobber (reg:CC FLAGS_REG))]
9235 "reload_completed && SSE_REG_P (operands[0])"
9236 [(set (match_dup 0) (match_dup 3))]
9238 enum machine_mode mode = GET_MODE (operands[0]);
9239 enum machine_mode vmode = GET_MODE (operands[2]);
9242 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9243 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9244 if (operands_match_p (operands[0], operands[2]))
9247 operands[1] = operands[2];
9250 if (GET_CODE (operands[3]) == ABS)
9251 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9253 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9258 [(set (match_operand:SF 0 "register_operand" "")
9259 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9260 (use (match_operand:V4SF 2 "" ""))
9261 (clobber (reg:CC FLAGS_REG))]
9263 [(parallel [(set (match_dup 0) (match_dup 1))
9264 (clobber (reg:CC FLAGS_REG))])]
9267 operands[0] = gen_lowpart (SImode, operands[0]);
9268 if (GET_CODE (operands[1]) == ABS)
9270 tmp = gen_int_mode (0x7fffffff, SImode);
9271 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9275 tmp = gen_int_mode (0x80000000, SImode);
9276 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9282 [(set (match_operand:DF 0 "register_operand" "")
9283 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9284 (use (match_operand 2 "" ""))
9285 (clobber (reg:CC FLAGS_REG))]
9287 [(parallel [(set (match_dup 0) (match_dup 1))
9288 (clobber (reg:CC FLAGS_REG))])]
9293 tmp = gen_lowpart (DImode, operands[0]);
9294 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9297 if (GET_CODE (operands[1]) == ABS)
9300 tmp = gen_rtx_NOT (DImode, tmp);
9304 operands[0] = gen_highpart (SImode, operands[0]);
9305 if (GET_CODE (operands[1]) == ABS)
9307 tmp = gen_int_mode (0x7fffffff, SImode);
9308 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9312 tmp = gen_int_mode (0x80000000, SImode);
9313 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9320 [(set (match_operand:XF 0 "register_operand" "")
9321 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9322 (use (match_operand 2 "" ""))
9323 (clobber (reg:CC FLAGS_REG))]
9325 [(parallel [(set (match_dup 0) (match_dup 1))
9326 (clobber (reg:CC FLAGS_REG))])]
9329 operands[0] = gen_rtx_REG (SImode,
9330 true_regnum (operands[0])
9331 + (TARGET_64BIT ? 1 : 2));
9332 if (GET_CODE (operands[1]) == ABS)
9334 tmp = GEN_INT (0x7fff);
9335 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9339 tmp = GEN_INT (0x8000);
9340 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9345 ;; Conditionalize these after reload. If they match before reload, we
9346 ;; lose the clobber and ability to use integer instructions.
9348 (define_insn "*<code><mode>2_1"
9349 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9350 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9352 && (reload_completed
9353 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9355 [(set_attr "type" "fsgn")
9356 (set_attr "mode" "<MODE>")])
9358 (define_insn "*<code>extendsfdf2"
9359 [(set (match_operand:DF 0 "register_operand" "=f")
9360 (absneg:DF (float_extend:DF
9361 (match_operand:SF 1 "register_operand" "0"))))]
9362 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9364 [(set_attr "type" "fsgn")
9365 (set_attr "mode" "DF")])
9367 (define_insn "*<code>extendsfxf2"
9368 [(set (match_operand:XF 0 "register_operand" "=f")
9369 (absneg:XF (float_extend:XF
9370 (match_operand:SF 1 "register_operand" "0"))))]
9373 [(set_attr "type" "fsgn")
9374 (set_attr "mode" "XF")])
9376 (define_insn "*<code>extenddfxf2"
9377 [(set (match_operand:XF 0 "register_operand" "=f")
9378 (absneg:XF (float_extend:XF
9379 (match_operand:DF 1 "register_operand" "0"))))]
9382 [(set_attr "type" "fsgn")
9383 (set_attr "mode" "XF")])
9385 ;; Copysign instructions
9387 (define_mode_iterator CSGNMODE [SF DF TF])
9388 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9390 (define_expand "copysign<mode>3"
9391 [(match_operand:CSGNMODE 0 "register_operand" "")
9392 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9393 (match_operand:CSGNMODE 2 "register_operand" "")]
9394 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9395 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9397 ix86_expand_copysign (operands);
9401 (define_insn_and_split "copysign<mode>3_const"
9402 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9404 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9405 (match_operand:CSGNMODE 2 "register_operand" "0")
9406 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9408 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9409 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9411 "&& reload_completed"
9414 ix86_split_copysign_const (operands);
9418 (define_insn "copysign<mode>3_var"
9419 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9421 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9422 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9423 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9424 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9426 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9427 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9428 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9432 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9434 [(match_operand:CSGNMODE 2 "register_operand" "")
9435 (match_operand:CSGNMODE 3 "register_operand" "")
9436 (match_operand:<CSGNVMODE> 4 "" "")
9437 (match_operand:<CSGNVMODE> 5 "" "")]
9439 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9440 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9441 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9442 && reload_completed"
9445 ix86_split_copysign_var (operands);
9449 ;; One complement instructions
9451 (define_expand "one_cmpl<mode>2"
9452 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9453 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9455 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9457 (define_insn "*one_cmpl<mode>2_1"
9458 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9459 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9460 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9461 "not{<imodesuffix>}\t%0"
9462 [(set_attr "type" "negnot")
9463 (set_attr "mode" "<MODE>")])
9465 ;; %%% Potential partial reg stall on alternative 1. What to do?
9466 (define_insn "*one_cmplqi2_1"
9467 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9468 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9469 "ix86_unary_operator_ok (NOT, QImode, operands)"
9473 [(set_attr "type" "negnot")
9474 (set_attr "mode" "QI,SI")])
9476 ;; ??? Currently never generated - xor is used instead.
9477 (define_insn "*one_cmplsi2_1_zext"
9478 [(set (match_operand:DI 0 "register_operand" "=r")
9480 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9481 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9483 [(set_attr "type" "negnot")
9484 (set_attr "mode" "SI")])
9486 (define_insn "*one_cmpl<mode>2_2"
9487 [(set (reg FLAGS_REG)
9488 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9490 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9491 (not:SWI (match_dup 1)))]
9492 "ix86_match_ccmode (insn, CCNOmode)
9493 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9495 [(set_attr "type" "alu1")
9496 (set_attr "mode" "<MODE>")])
9499 [(set (match_operand 0 "flags_reg_operand" "")
9500 (match_operator 2 "compare_operator"
9501 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9503 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9504 (not:SWI (match_dup 3)))]
9505 "ix86_match_ccmode (insn, CCNOmode)"
9506 [(parallel [(set (match_dup 0)
9507 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9510 (xor:SWI (match_dup 3) (const_int -1)))])]
9513 ;; ??? Currently never generated - xor is used instead.
9514 (define_insn "*one_cmplsi2_2_zext"
9515 [(set (reg FLAGS_REG)
9516 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9518 (set (match_operand:DI 0 "register_operand" "=r")
9519 (zero_extend:DI (not:SI (match_dup 1))))]
9520 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9521 && ix86_unary_operator_ok (NOT, SImode, operands)"
9523 [(set_attr "type" "alu1")
9524 (set_attr "mode" "SI")])
9527 [(set (match_operand 0 "flags_reg_operand" "")
9528 (match_operator 2 "compare_operator"
9529 [(not:SI (match_operand:SI 3 "register_operand" ""))
9531 (set (match_operand:DI 1 "register_operand" "")
9532 (zero_extend:DI (not:SI (match_dup 3))))]
9533 "ix86_match_ccmode (insn, CCNOmode)"
9534 [(parallel [(set (match_dup 0)
9535 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9538 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9541 ;; Shift instructions
9543 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9544 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9545 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9546 ;; from the assembler input.
9548 ;; This instruction shifts the target reg/mem as usual, but instead of
9549 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9550 ;; is a left shift double, bits are taken from the high order bits of
9551 ;; reg, else if the insn is a shift right double, bits are taken from the
9552 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9553 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9555 ;; Since sh[lr]d does not change the `reg' operand, that is done
9556 ;; separately, making all shifts emit pairs of shift double and normal
9557 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9558 ;; support a 63 bit shift, each shift where the count is in a reg expands
9559 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9561 ;; If the shift count is a constant, we need never emit more than one
9562 ;; shift pair, instead using moves and sign extension for counts greater
9565 (define_expand "ashl<mode>3"
9566 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9567 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9568 (match_operand:QI 2 "nonmemory_operand" "")))]
9570 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9572 (define_insn "*ashl<mode>3_doubleword"
9573 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9574 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9575 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9576 (clobber (reg:CC FLAGS_REG))]
9579 [(set_attr "type" "multi")])
9582 [(set (match_operand:DWI 0 "register_operand" "")
9583 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9584 (match_operand:QI 2 "nonmemory_operand" "")))
9585 (clobber (reg:CC FLAGS_REG))]
9586 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9588 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9590 ;; By default we don't ask for a scratch register, because when DWImode
9591 ;; values are manipulated, registers are already at a premium. But if
9592 ;; we have one handy, we won't turn it away.
9595 [(match_scratch:DWIH 3 "r")
9596 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9598 (match_operand:<DWI> 1 "nonmemory_operand" "")
9599 (match_operand:QI 2 "nonmemory_operand" "")))
9600 (clobber (reg:CC FLAGS_REG))])
9604 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9606 (define_insn "x86_64_shld"
9607 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9608 (ior:DI (ashift:DI (match_dup 0)
9609 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9610 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9611 (minus:QI (const_int 64) (match_dup 2)))))
9612 (clobber (reg:CC FLAGS_REG))]
9614 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9615 [(set_attr "type" "ishift")
9616 (set_attr "prefix_0f" "1")
9617 (set_attr "mode" "DI")
9618 (set_attr "athlon_decode" "vector")
9619 (set_attr "amdfam10_decode" "vector")])
9621 (define_insn "x86_shld"
9622 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9623 (ior:SI (ashift:SI (match_dup 0)
9624 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9625 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9626 (minus:QI (const_int 32) (match_dup 2)))))
9627 (clobber (reg:CC FLAGS_REG))]
9629 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9630 [(set_attr "type" "ishift")
9631 (set_attr "prefix_0f" "1")
9632 (set_attr "mode" "SI")
9633 (set_attr "pent_pair" "np")
9634 (set_attr "athlon_decode" "vector")
9635 (set_attr "amdfam10_decode" "vector")])
9637 (define_expand "x86_shift<mode>_adj_1"
9638 [(set (reg:CCZ FLAGS_REG)
9639 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9642 (set (match_operand:SWI48 0 "register_operand" "")
9643 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9644 (match_operand:SWI48 1 "register_operand" "")
9647 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9648 (match_operand:SWI48 3 "register_operand" "r")
9651 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9653 (define_expand "x86_shift<mode>_adj_2"
9654 [(use (match_operand:SWI48 0 "register_operand" ""))
9655 (use (match_operand:SWI48 1 "register_operand" ""))
9656 (use (match_operand:QI 2 "register_operand" ""))]
9659 rtx label = gen_label_rtx ();
9662 emit_insn (gen_testqi_ccz_1 (operands[2],
9663 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9665 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9666 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9667 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9668 gen_rtx_LABEL_REF (VOIDmode, label),
9670 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9671 JUMP_LABEL (tmp) = label;
9673 emit_move_insn (operands[0], operands[1]);
9674 ix86_expand_clear (operands[1]);
9677 LABEL_NUSES (label) = 1;
9682 (define_insn "*ashl<mode>3_1"
9683 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9684 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9685 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9686 (clobber (reg:CC FLAGS_REG))]
9687 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9689 switch (get_attr_type (insn))
9692 gcc_assert (operands[2] == const1_rtx);
9693 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9694 return "add{<imodesuffix>}\t%0, %0";
9700 if (REG_P (operands[2]))
9701 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9702 else if (operands[2] == const1_rtx
9703 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9704 return "sal{<imodesuffix>}\t%0";
9706 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9710 (cond [(eq_attr "alternative" "1")
9711 (const_string "lea")
9712 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9714 (match_operand 0 "register_operand" ""))
9715 (match_operand 2 "const1_operand" ""))
9716 (const_string "alu")
9718 (const_string "ishift")))
9719 (set (attr "length_immediate")
9721 (ior (eq_attr "type" "alu")
9722 (and (eq_attr "type" "ishift")
9723 (and (match_operand 2 "const1_operand" "")
9724 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9727 (const_string "*")))
9728 (set_attr "mode" "<MODE>")])
9730 (define_insn "*ashlsi3_1_zext"
9731 [(set (match_operand:DI 0 "register_operand" "=r,r")
9733 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9734 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9735 (clobber (reg:CC FLAGS_REG))]
9736 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9738 switch (get_attr_type (insn))
9741 gcc_assert (operands[2] == const1_rtx);
9742 return "add{l}\t%k0, %k0";
9748 if (REG_P (operands[2]))
9749 return "sal{l}\t{%b2, %k0|%k0, %b2}";
9750 else if (operands[2] == const1_rtx
9751 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9752 return "sal{l}\t%k0";
9754 return "sal{l}\t{%2, %k0|%k0, %2}";
9758 (cond [(eq_attr "alternative" "1")
9759 (const_string "lea")
9760 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9762 (match_operand 2 "const1_operand" ""))
9763 (const_string "alu")
9765 (const_string "ishift")))
9766 (set (attr "length_immediate")
9768 (ior (eq_attr "type" "alu")
9769 (and (eq_attr "type" "ishift")
9770 (and (match_operand 2 "const1_operand" "")
9771 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9774 (const_string "*")))
9775 (set_attr "mode" "SI")])
9777 (define_insn "*ashlhi3_1"
9778 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9779 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9780 (match_operand:QI 2 "nonmemory_operand" "cI")))
9781 (clobber (reg:CC FLAGS_REG))]
9782 "TARGET_PARTIAL_REG_STALL
9783 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9785 switch (get_attr_type (insn))
9788 gcc_assert (operands[2] == const1_rtx);
9789 return "add{w}\t%0, %0";
9792 if (REG_P (operands[2]))
9793 return "sal{w}\t{%b2, %0|%0, %b2}";
9794 else if (operands[2] == const1_rtx
9795 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9796 return "sal{w}\t%0";
9798 return "sal{w}\t{%2, %0|%0, %2}";
9802 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9804 (match_operand 0 "register_operand" ""))
9805 (match_operand 2 "const1_operand" ""))
9806 (const_string "alu")
9808 (const_string "ishift")))
9809 (set (attr "length_immediate")
9811 (ior (eq_attr "type" "alu")
9812 (and (eq_attr "type" "ishift")
9813 (and (match_operand 2 "const1_operand" "")
9814 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9817 (const_string "*")))
9818 (set_attr "mode" "HI")])
9820 (define_insn "*ashlhi3_1_lea"
9821 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9822 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9823 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9824 (clobber (reg:CC FLAGS_REG))]
9825 "!TARGET_PARTIAL_REG_STALL
9826 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9828 switch (get_attr_type (insn))
9833 gcc_assert (operands[2] == const1_rtx);
9834 return "add{w}\t%0, %0";
9837 if (REG_P (operands[2]))
9838 return "sal{w}\t{%b2, %0|%0, %b2}";
9839 else if (operands[2] == const1_rtx
9840 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9841 return "sal{w}\t%0";
9843 return "sal{w}\t{%2, %0|%0, %2}";
9847 (cond [(eq_attr "alternative" "1")
9848 (const_string "lea")
9849 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9851 (match_operand 0 "register_operand" ""))
9852 (match_operand 2 "const1_operand" ""))
9853 (const_string "alu")
9855 (const_string "ishift")))
9856 (set (attr "length_immediate")
9858 (ior (eq_attr "type" "alu")
9859 (and (eq_attr "type" "ishift")
9860 (and (match_operand 2 "const1_operand" "")
9861 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9864 (const_string "*")))
9865 (set_attr "mode" "HI,SI")])
9867 (define_insn "*ashlqi3_1"
9868 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9869 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9870 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9871 (clobber (reg:CC FLAGS_REG))]
9872 "TARGET_PARTIAL_REG_STALL
9873 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9875 switch (get_attr_type (insn))
9878 gcc_assert (operands[2] == const1_rtx);
9879 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9880 return "add{l}\t%k0, %k0";
9882 return "add{b}\t%0, %0";
9885 if (REG_P (operands[2]))
9887 if (get_attr_mode (insn) == MODE_SI)
9888 return "sal{l}\t{%b2, %k0|%k0, %b2}";
9890 return "sal{b}\t{%b2, %0|%0, %b2}";
9892 else if (operands[2] == const1_rtx
9893 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9895 if (get_attr_mode (insn) == MODE_SI)
9896 return "sal{l}\t%0";
9898 return "sal{b}\t%0";
9902 if (get_attr_mode (insn) == MODE_SI)
9903 return "sal{l}\t{%2, %k0|%k0, %2}";
9905 return "sal{b}\t{%2, %0|%0, %2}";
9910 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9912 (match_operand 0 "register_operand" ""))
9913 (match_operand 2 "const1_operand" ""))
9914 (const_string "alu")
9916 (const_string "ishift")))
9917 (set (attr "length_immediate")
9919 (ior (eq_attr "type" "alu")
9920 (and (eq_attr "type" "ishift")
9921 (and (match_operand 2 "const1_operand" "")
9922 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9925 (const_string "*")))
9926 (set_attr "mode" "QI,SI")])
9928 ;; %%% Potential partial reg stall on alternative 2. What to do?
9929 (define_insn "*ashlqi3_1_lea"
9930 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9931 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9932 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9933 (clobber (reg:CC FLAGS_REG))]
9934 "!TARGET_PARTIAL_REG_STALL
9935 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9937 switch (get_attr_type (insn))
9942 gcc_assert (operands[2] == const1_rtx);
9943 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9944 return "add{l}\t%k0, %k0";
9946 return "add{b}\t%0, %0";
9949 if (REG_P (operands[2]))
9951 if (get_attr_mode (insn) == MODE_SI)
9952 return "sal{l}\t{%b2, %k0|%k0, %b2}";
9954 return "sal{b}\t{%b2, %0|%0, %b2}";
9956 else if (operands[2] == const1_rtx
9957 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9959 if (get_attr_mode (insn) == MODE_SI)
9960 return "sal{l}\t%0";
9962 return "sal{b}\t%0";
9966 if (get_attr_mode (insn) == MODE_SI)
9967 return "sal{l}\t{%2, %k0|%k0, %2}";
9969 return "sal{b}\t{%2, %0|%0, %2}";
9974 (cond [(eq_attr "alternative" "2")
9975 (const_string "lea")
9976 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9978 (match_operand 0 "register_operand" ""))
9979 (match_operand 2 "const1_operand" ""))
9980 (const_string "alu")
9982 (const_string "ishift")))
9983 (set (attr "length_immediate")
9985 (ior (eq_attr "type" "alu")
9986 (and (eq_attr "type" "ishift")
9987 (and (match_operand 2 "const1_operand" "")
9988 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9991 (const_string "*")))
9992 (set_attr "mode" "QI,SI,SI")])
9994 ;; Convert lea to the lea pattern to avoid flags dependency.
9996 [(set (match_operand:DI 0 "register_operand" "")
9997 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9998 (match_operand:QI 2 "const_int_operand" "")))
9999 (clobber (reg:CC FLAGS_REG))]
10000 "TARGET_64BIT && reload_completed
10001 && true_regnum (operands[0]) != true_regnum (operands[1])"
10002 [(set (match_dup 0)
10003 (mult:DI (match_dup 1)
10005 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10007 ;; Convert lea to the lea pattern to avoid flags dependency.
10009 [(set (match_operand 0 "register_operand" "")
10010 (ashift (match_operand 1 "index_register_operand" "")
10011 (match_operand:QI 2 "const_int_operand" "")))
10012 (clobber (reg:CC FLAGS_REG))]
10014 && true_regnum (operands[0]) != true_regnum (operands[1])
10015 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10019 enum machine_mode mode = GET_MODE (operands[0]);
10021 if (GET_MODE_SIZE (mode) < 4)
10022 operands[0] = gen_lowpart (SImode, operands[0]);
10024 operands[1] = gen_lowpart (Pmode, operands[1]);
10025 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10027 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10028 if (Pmode != SImode)
10029 pat = gen_rtx_SUBREG (SImode, pat, 0);
10030 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10034 ;; Rare case of shifting RSP is handled by generating move and shift
10036 [(set (match_operand 0 "register_operand" "")
10037 (ashift (match_operand 1 "register_operand" "")
10038 (match_operand:QI 2 "const_int_operand" "")))
10039 (clobber (reg:CC FLAGS_REG))]
10041 && true_regnum (operands[0]) != true_regnum (operands[1])"
10045 emit_move_insn (operands[0], operands[1]);
10046 pat = gen_rtx_SET (VOIDmode, operands[0],
10047 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10048 operands[0], operands[2]));
10049 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10050 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10054 ;; Convert lea to the lea pattern to avoid flags dependency.
10056 [(set (match_operand:DI 0 "register_operand" "")
10058 (ashift:SI (match_operand:SI 1 "register_operand" "")
10059 (match_operand:QI 2 "const_int_operand" ""))))
10060 (clobber (reg:CC FLAGS_REG))]
10061 "TARGET_64BIT && reload_completed
10062 && true_regnum (operands[0]) != true_regnum (operands[1])"
10063 [(set (match_dup 0)
10064 (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10066 operands[1] = gen_lowpart (Pmode, operands[1]);
10067 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10070 ;; This pattern can't accept a variable shift count, since shifts by
10071 ;; zero don't affect the flags. We assume that shifts by constant
10072 ;; zero are optimized away.
10073 (define_insn "*ashl<mode>3_cmp"
10074 [(set (reg FLAGS_REG)
10076 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10077 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10079 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10080 (ashift:SWI (match_dup 1) (match_dup 2)))]
10081 "(optimize_function_for_size_p (cfun)
10082 || !TARGET_PARTIAL_FLAG_REG_STALL
10083 || (operands[2] == const1_rtx
10085 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10086 && ix86_match_ccmode (insn, CCGOCmode)
10087 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10089 switch (get_attr_type (insn))
10092 gcc_assert (operands[2] == const1_rtx);
10093 return "add{<imodesuffix>}\t%0, %0";
10096 if (operands[2] == const1_rtx
10097 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10098 return "sal{<imodesuffix>}\t%0";
10100 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10103 [(set (attr "type")
10104 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10106 (match_operand 0 "register_operand" ""))
10107 (match_operand 2 "const1_operand" ""))
10108 (const_string "alu")
10110 (const_string "ishift")))
10111 (set (attr "length_immediate")
10113 (ior (eq_attr "type" "alu")
10114 (and (eq_attr "type" "ishift")
10115 (and (match_operand 2 "const1_operand" "")
10116 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10119 (const_string "*")))
10120 (set_attr "mode" "<MODE>")])
10122 (define_insn "*ashlsi3_cmp_zext"
10123 [(set (reg FLAGS_REG)
10125 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10126 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10128 (set (match_operand:DI 0 "register_operand" "=r")
10129 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10131 && (optimize_function_for_size_p (cfun)
10132 || !TARGET_PARTIAL_FLAG_REG_STALL
10133 || (operands[2] == const1_rtx
10135 || TARGET_DOUBLE_WITH_ADD)))
10136 && ix86_match_ccmode (insn, CCGOCmode)
10137 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10139 switch (get_attr_type (insn))
10142 gcc_assert (operands[2] == const1_rtx);
10143 return "add{l}\t%k0, %k0";
10146 if (operands[2] == const1_rtx
10147 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10148 return "sal{l}\t%k0";
10150 return "sal{l}\t{%2, %k0|%k0, %2}";
10153 [(set (attr "type")
10154 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10156 (match_operand 2 "const1_operand" ""))
10157 (const_string "alu")
10159 (const_string "ishift")))
10160 (set (attr "length_immediate")
10162 (ior (eq_attr "type" "alu")
10163 (and (eq_attr "type" "ishift")
10164 (and (match_operand 2 "const1_operand" "")
10165 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10168 (const_string "*")))
10169 (set_attr "mode" "SI")])
10171 (define_insn "*ashl<mode>3_cconly"
10172 [(set (reg FLAGS_REG)
10174 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10175 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10177 (clobber (match_scratch:SWI 0 "=<r>"))]
10178 "(optimize_function_for_size_p (cfun)
10179 || !TARGET_PARTIAL_FLAG_REG_STALL
10180 || (operands[2] == const1_rtx
10182 || TARGET_DOUBLE_WITH_ADD)))
10183 && ix86_match_ccmode (insn, CCGOCmode)
10184 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10186 switch (get_attr_type (insn))
10189 gcc_assert (operands[2] == const1_rtx);
10190 return "add{<imodesuffix>}\t%0, %0";
10193 if (operands[2] == const1_rtx
10194 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10195 return "sal{<imodesuffix>}\t%0";
10197 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10200 [(set (attr "type")
10201 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10203 (match_operand 0 "register_operand" ""))
10204 (match_operand 2 "const1_operand" ""))
10205 (const_string "alu")
10207 (const_string "ishift")))
10208 (set (attr "length_immediate")
10210 (ior (eq_attr "type" "alu")
10211 (and (eq_attr "type" "ishift")
10212 (and (match_operand 2 "const1_operand" "")
10213 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10216 (const_string "*")))
10217 (set_attr "mode" "<MODE>")])
10219 ;; See comment above `ashl<mode>3' about how this works.
10221 (define_expand "<shiftrt_insn><mode>3"
10222 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
10223 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
10224 (match_operand:QI 2 "nonmemory_operand" "")))]
10226 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10228 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
10229 [(set (match_operand:DWI 0 "register_operand" "=r")
10230 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10231 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10232 (clobber (reg:CC FLAGS_REG))]
10235 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10237 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10238 [(set_attr "type" "multi")])
10240 ;; By default we don't ask for a scratch register, because when DWImode
10241 ;; values are manipulated, registers are already at a premium. But if
10242 ;; we have one handy, we won't turn it away.
10245 [(match_scratch:DWIH 3 "r")
10246 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
10248 (match_operand:<DWI> 1 "register_operand" "")
10249 (match_operand:QI 2 "nonmemory_operand" "")))
10250 (clobber (reg:CC FLAGS_REG))])
10254 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
10256 (define_insn "x86_64_shrd"
10257 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10258 (ior:DI (ashiftrt:DI (match_dup 0)
10259 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10260 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10261 (minus:QI (const_int 64) (match_dup 2)))))
10262 (clobber (reg:CC FLAGS_REG))]
10264 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10265 [(set_attr "type" "ishift")
10266 (set_attr "prefix_0f" "1")
10267 (set_attr "mode" "DI")
10268 (set_attr "athlon_decode" "vector")
10269 (set_attr "amdfam10_decode" "vector")])
10271 (define_insn "x86_shrd"
10272 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10273 (ior:SI (ashiftrt:SI (match_dup 0)
10274 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10275 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10276 (minus:QI (const_int 32) (match_dup 2)))))
10277 (clobber (reg:CC FLAGS_REG))]
10279 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10280 [(set_attr "type" "ishift")
10281 (set_attr "prefix_0f" "1")
10282 (set_attr "pent_pair" "np")
10283 (set_attr "mode" "SI")])
10285 (define_insn "ashrdi3_cvt"
10286 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10287 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10288 (match_operand:QI 2 "const_int_operand" "")))
10289 (clobber (reg:CC FLAGS_REG))]
10290 "TARGET_64BIT && INTVAL (operands[2]) == 63
10291 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10292 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10295 sar{q}\t{%2, %0|%0, %2}"
10296 [(set_attr "type" "imovx,ishift")
10297 (set_attr "prefix_0f" "0,*")
10298 (set_attr "length_immediate" "0,*")
10299 (set_attr "modrm" "0,1")
10300 (set_attr "mode" "DI")])
10302 (define_insn "ashrsi3_cvt"
10303 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10304 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10305 (match_operand:QI 2 "const_int_operand" "")))
10306 (clobber (reg:CC FLAGS_REG))]
10307 "INTVAL (operands[2]) == 31
10308 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10309 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10312 sar{l}\t{%2, %0|%0, %2}"
10313 [(set_attr "type" "imovx,ishift")
10314 (set_attr "prefix_0f" "0,*")
10315 (set_attr "length_immediate" "0,*")
10316 (set_attr "modrm" "0,1")
10317 (set_attr "mode" "SI")])
10319 (define_insn "*ashrsi3_cvt_zext"
10320 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10322 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10323 (match_operand:QI 2 "const_int_operand" ""))))
10324 (clobber (reg:CC FLAGS_REG))]
10325 "TARGET_64BIT && INTVAL (operands[2]) == 31
10326 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10327 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10330 sar{l}\t{%2, %k0|%k0, %2}"
10331 [(set_attr "type" "imovx,ishift")
10332 (set_attr "prefix_0f" "0,*")
10333 (set_attr "length_immediate" "0,*")
10334 (set_attr "modrm" "0,1")
10335 (set_attr "mode" "SI")])
10337 (define_expand "x86_shift<mode>_adj_3"
10338 [(use (match_operand:SWI48 0 "register_operand" ""))
10339 (use (match_operand:SWI48 1 "register_operand" ""))
10340 (use (match_operand:QI 2 "register_operand" ""))]
10343 rtx label = gen_label_rtx ();
10346 emit_insn (gen_testqi_ccz_1 (operands[2],
10347 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10349 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10350 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10351 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10352 gen_rtx_LABEL_REF (VOIDmode, label),
10354 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10355 JUMP_LABEL (tmp) = label;
10357 emit_move_insn (operands[0], operands[1]);
10358 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10359 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10360 emit_label (label);
10361 LABEL_NUSES (label) = 1;
10366 (define_insn "*<shiftrt_insn><mode>3_1"
10367 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10368 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10369 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10370 (clobber (reg:CC FLAGS_REG))]
10371 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10373 if (REG_P (operands[2]))
10374 return "<shiftrt>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10375 else if (operands[2] == const1_rtx
10376 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10377 return "<shiftrt>{<imodesuffix>}\t%0";
10379 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10381 [(set_attr "type" "ishift")
10382 (set (attr "length_immediate")
10384 (and (match_operand 2 "const1_operand" "")
10385 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10388 (const_string "*")))
10389 (set_attr "mode" "<MODE>")])
10391 (define_insn "*<shiftrt_insn>si3_1_zext"
10392 [(set (match_operand:DI 0 "register_operand" "=r")
10394 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10395 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10396 (clobber (reg:CC FLAGS_REG))]
10397 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10399 if (REG_P (operands[2]))
10400 return "<shiftrt>{l}\t{%b2, %k0|%k0, %b2}";
10401 else if (operands[2] == const1_rtx
10402 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10403 return "<shiftrt>{l}\t%k0";
10405 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10407 [(set_attr "type" "ishift")
10408 (set (attr "length_immediate")
10410 (and (match_operand 2 "const1_operand" "")
10411 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10414 (const_string "*")))
10415 (set_attr "mode" "SI")])
10417 (define_insn "*<shiftrt_insn>qi3_1_slp"
10418 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10419 (any_shiftrt:QI (match_dup 0)
10420 (match_operand:QI 1 "nonmemory_operand" "cI")))
10421 (clobber (reg:CC FLAGS_REG))]
10422 "(optimize_function_for_size_p (cfun)
10423 || !TARGET_PARTIAL_REG_STALL
10424 || (operands[1] == const1_rtx
10425 && TARGET_SHIFT1))"
10427 if (REG_P (operands[1]))
10428 return "<shiftrt>{b}\t{%b1, %0|%0, %b1}";
10429 else if (operands[1] == const1_rtx
10430 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10431 return "<shiftrt>{b}\t%0";
10433 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10435 [(set_attr "type" "ishift1")
10436 (set (attr "length_immediate")
10438 (and (match_operand 1 "const1_operand" "")
10439 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10442 (const_string "*")))
10443 (set_attr "mode" "QI")])
10445 ;; This pattern can't accept a variable shift count, since shifts by
10446 ;; zero don't affect the flags. We assume that shifts by constant
10447 ;; zero are optimized away.
10448 (define_insn "*<shiftrt_insn><mode>3_cmp"
10449 [(set (reg FLAGS_REG)
10452 (match_operand:SWI 1 "nonimmediate_operand" "0")
10453 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10455 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10456 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10457 "(optimize_function_for_size_p (cfun)
10458 || !TARGET_PARTIAL_FLAG_REG_STALL
10459 || (operands[2] == const1_rtx
10461 && ix86_match_ccmode (insn, CCGOCmode)
10462 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10464 if (operands[2] == const1_rtx
10465 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10466 return "<shiftrt>{<imodesuffix>}\t%0";
10468 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10470 [(set_attr "type" "ishift")
10471 (set (attr "length_immediate")
10473 (and (match_operand 2 "const1_operand" "")
10474 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10477 (const_string "*")))
10478 (set_attr "mode" "<MODE>")])
10480 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10481 [(set (reg FLAGS_REG)
10483 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10484 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10486 (set (match_operand:DI 0 "register_operand" "=r")
10487 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10489 && (optimize_function_for_size_p (cfun)
10490 || !TARGET_PARTIAL_FLAG_REG_STALL
10491 || (operands[2] == const1_rtx
10493 && ix86_match_ccmode (insn, CCGOCmode)
10494 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10496 if (operands[2] == const1_rtx
10497 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10498 return "<shiftrt>{l}\t%k0";
10500 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10502 [(set_attr "type" "ishift")
10503 (set (attr "length_immediate")
10505 (and (match_operand 2 "const1_operand" "")
10506 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10509 (const_string "*")))
10510 (set_attr "mode" "SI")])
10512 (define_insn "*<shiftrt_insn><mode>3_cconly"
10513 [(set (reg FLAGS_REG)
10516 (match_operand:SWI 1 "nonimmediate_operand" "0")
10517 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10519 (clobber (match_scratch:SWI 0 "=<r>"))]
10520 "(optimize_function_for_size_p (cfun)
10521 || !TARGET_PARTIAL_FLAG_REG_STALL
10522 || (operands[2] == const1_rtx
10524 && ix86_match_ccmode (insn, CCGOCmode)
10525 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10527 if (operands[2] == const1_rtx
10528 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10529 return "<shiftrt>{<imodesuffix>}\t%0";
10531 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10533 [(set_attr "type" "ishift")
10534 (set (attr "length_immediate")
10536 (and (match_operand 2 "const1_operand" "")
10537 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10540 (const_string "*")))
10541 (set_attr "mode" "<MODE>")])
10543 ;; Rotate instructions
10545 (define_expand "rotldi3"
10546 [(set (match_operand:DI 0 "shiftdi_operand" "")
10547 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10548 (match_operand:QI 2 "nonmemory_operand" "")))]
10553 ix86_expand_binary_operator (ROTATE, DImode, operands);
10556 if (!const_1_to_31_operand (operands[2], VOIDmode))
10558 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
10562 ;; Implement rotation using two double-precision shift instructions
10563 ;; and a scratch register.
10564 (define_insn_and_split "ix86_rotldi3"
10565 [(set (match_operand:DI 0 "register_operand" "=r")
10566 (rotate:DI (match_operand:DI 1 "register_operand" "0")
10567 (match_operand:QI 2 "const_1_to_31_operand" "I")))
10568 (clobber (reg:CC FLAGS_REG))
10569 (clobber (match_scratch:SI 3 "=&r"))]
10572 "&& reload_completed"
10573 [(set (match_dup 3) (match_dup 4))
10575 [(set (match_dup 4)
10576 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
10577 (lshiftrt:SI (match_dup 5)
10578 (minus:QI (const_int 32) (match_dup 2)))))
10579 (clobber (reg:CC FLAGS_REG))])
10581 [(set (match_dup 5)
10582 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
10583 (lshiftrt:SI (match_dup 3)
10584 (minus:QI (const_int 32) (match_dup 2)))))
10585 (clobber (reg:CC FLAGS_REG))])]
10586 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
10588 (define_insn "*rotlsi3_1_one_bit_rex64"
10589 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10590 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10591 (match_operand:QI 2 "const1_operand" "")))
10592 (clobber (reg:CC FLAGS_REG))]
10594 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10595 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
10597 [(set_attr "type" "rotate")
10598 (set_attr "length_immediate" "0")
10599 (set_attr "mode" "DI")])
10601 (define_insn "*rotldi3_1_rex64"
10602 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10603 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10604 (match_operand:QI 2 "nonmemory_operand" "e,c")))
10605 (clobber (reg:CC FLAGS_REG))]
10606 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
10608 rol{q}\t{%2, %0|%0, %2}
10609 rol{q}\t{%b2, %0|%0, %b2}"
10610 [(set_attr "type" "rotate")
10611 (set_attr "mode" "DI")])
10613 (define_expand "rotlsi3"
10614 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10615 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10616 (match_operand:QI 2 "nonmemory_operand" "")))]
10618 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
10620 (define_insn "*rotlsi3_1_one_bit"
10621 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10622 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10623 (match_operand:QI 2 "const1_operand" "")))
10624 (clobber (reg:CC FLAGS_REG))]
10625 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10626 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
10628 [(set_attr "type" "rotate")
10629 (set_attr "length_immediate" "0")
10630 (set_attr "mode" "SI")])
10632 (define_insn "*rotlsi3_1_one_bit_zext"
10633 [(set (match_operand:DI 0 "register_operand" "=r")
10635 (rotate:SI (match_operand:SI 1 "register_operand" "0")
10636 (match_operand:QI 2 "const1_operand" ""))))
10637 (clobber (reg:CC FLAGS_REG))]
10639 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10640 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
10642 [(set_attr "type" "rotate")
10643 (set_attr "length_immediate" "0")
10644 (set_attr "mode" "SI")])
10646 (define_insn "*rotlsi3_1"
10647 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
10648 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
10649 (match_operand:QI 2 "nonmemory_operand" "I,c")))
10650 (clobber (reg:CC FLAGS_REG))]
10651 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
10653 rol{l}\t{%2, %0|%0, %2}
10654 rol{l}\t{%b2, %0|%0, %b2}"
10655 [(set_attr "type" "rotate")
10656 (set_attr "mode" "SI")])
10658 (define_insn "*rotlsi3_1_zext"
10659 [(set (match_operand:DI 0 "register_operand" "=r,r")
10661 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
10662 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
10663 (clobber (reg:CC FLAGS_REG))]
10664 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
10666 rol{l}\t{%2, %k0|%k0, %2}
10667 rol{l}\t{%b2, %k0|%k0, %b2}"
10668 [(set_attr "type" "rotate")
10669 (set_attr "mode" "SI")])
10671 (define_expand "rotlhi3"
10672 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10673 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
10674 (match_operand:QI 2 "nonmemory_operand" "")))]
10675 "TARGET_HIMODE_MATH"
10676 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
10678 (define_insn "*rotlhi3_1_one_bit"
10679 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10680 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10681 (match_operand:QI 2 "const1_operand" "")))
10682 (clobber (reg:CC FLAGS_REG))]
10683 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10684 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
10686 [(set_attr "type" "rotate")
10687 (set_attr "length_immediate" "0")
10688 (set_attr "mode" "HI")])
10690 (define_insn "*rotlhi3_1"
10691 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
10692 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
10693 (match_operand:QI 2 "nonmemory_operand" "I,c")))
10694 (clobber (reg:CC FLAGS_REG))]
10695 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
10697 rol{w}\t{%2, %0|%0, %2}
10698 rol{w}\t{%b2, %0|%0, %b2}"
10699 [(set_attr "type" "rotate")
10700 (set_attr "mode" "HI")])
10703 [(set (match_operand:HI 0 "register_operand" "")
10704 (rotate:HI (match_dup 0) (const_int 8)))
10705 (clobber (reg:CC FLAGS_REG))]
10707 [(parallel [(set (strict_low_part (match_dup 0))
10708 (bswap:HI (match_dup 0)))
10709 (clobber (reg:CC FLAGS_REG))])]
10712 (define_expand "rotlqi3"
10713 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10714 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
10715 (match_operand:QI 2 "nonmemory_operand" "")))]
10716 "TARGET_QIMODE_MATH"
10717 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
10719 (define_insn "*rotlqi3_1_one_bit_slp"
10720 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10721 (rotate:QI (match_dup 0)
10722 (match_operand:QI 1 "const1_operand" "")))
10723 (clobber (reg:CC FLAGS_REG))]
10724 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10725 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
10727 [(set_attr "type" "rotate1")
10728 (set_attr "length_immediate" "0")
10729 (set_attr "mode" "QI")])
10731 (define_insn "*rotlqi3_1_one_bit"
10732 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10733 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10734 (match_operand:QI 2 "const1_operand" "")))
10735 (clobber (reg:CC FLAGS_REG))]
10736 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10737 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
10739 [(set_attr "type" "rotate")
10740 (set_attr "length_immediate" "0")
10741 (set_attr "mode" "QI")])
10743 (define_insn "*rotlqi3_1_slp"
10744 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
10745 (rotate:QI (match_dup 0)
10746 (match_operand:QI 1 "nonmemory_operand" "I,c")))
10747 (clobber (reg:CC FLAGS_REG))]
10748 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10749 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10751 rol{b}\t{%1, %0|%0, %1}
10752 rol{b}\t{%b1, %0|%0, %b1}"
10753 [(set_attr "type" "rotate1")
10754 (set_attr "mode" "QI")])
10756 (define_insn "*rotlqi3_1"
10757 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
10758 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10759 (match_operand:QI 2 "nonmemory_operand" "I,c")))
10760 (clobber (reg:CC FLAGS_REG))]
10761 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
10763 rol{b}\t{%2, %0|%0, %2}
10764 rol{b}\t{%b2, %0|%0, %b2}"
10765 [(set_attr "type" "rotate")
10766 (set_attr "mode" "QI")])
10768 (define_expand "rotrdi3"
10769 [(set (match_operand:DI 0 "shiftdi_operand" "")
10770 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10771 (match_operand:QI 2 "nonmemory_operand" "")))]
10776 ix86_expand_binary_operator (ROTATERT, DImode, operands);
10779 if (!const_1_to_31_operand (operands[2], VOIDmode))
10781 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
10785 ;; Implement rotation using two double-precision shift instructions
10786 ;; and a scratch register.
10787 (define_insn_and_split "ix86_rotrdi3"
10788 [(set (match_operand:DI 0 "register_operand" "=r")
10789 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
10790 (match_operand:QI 2 "const_1_to_31_operand" "I")))
10791 (clobber (reg:CC FLAGS_REG))
10792 (clobber (match_scratch:SI 3 "=&r"))]
10795 "&& reload_completed"
10796 [(set (match_dup 3) (match_dup 4))
10798 [(set (match_dup 4)
10799 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
10800 (ashift:SI (match_dup 5)
10801 (minus:QI (const_int 32) (match_dup 2)))))
10802 (clobber (reg:CC FLAGS_REG))])
10804 [(set (match_dup 5)
10805 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
10806 (ashift:SI (match_dup 3)
10807 (minus:QI (const_int 32) (match_dup 2)))))
10808 (clobber (reg:CC FLAGS_REG))])]
10809 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
10811 (define_insn "*rotrdi3_1_one_bit_rex64"
10812 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10813 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10814 (match_operand:QI 2 "const1_operand" "")))
10815 (clobber (reg:CC FLAGS_REG))]
10817 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10818 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
10820 [(set_attr "type" "rotate")
10821 (set_attr "length_immediate" "0")
10822 (set_attr "mode" "DI")])
10824 (define_insn "*rotrdi3_1_rex64"
10825 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10826 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10827 (match_operand:QI 2 "nonmemory_operand" "J,c")))
10828 (clobber (reg:CC FLAGS_REG))]
10829 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
10831 ror{q}\t{%2, %0|%0, %2}
10832 ror{q}\t{%b2, %0|%0, %b2}"
10833 [(set_attr "type" "rotate")
10834 (set_attr "mode" "DI")])
10836 (define_expand "rotrsi3"
10837 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10838 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10839 (match_operand:QI 2 "nonmemory_operand" "")))]
10841 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
10843 (define_insn "*rotrsi3_1_one_bit"
10844 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10845 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10846 (match_operand:QI 2 "const1_operand" "")))
10847 (clobber (reg:CC FLAGS_REG))]
10848 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10849 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
10851 [(set_attr "type" "rotate")
10852 (set_attr "length_immediate" "0")
10853 (set_attr "mode" "SI")])
10855 (define_insn "*rotrsi3_1_one_bit_zext"
10856 [(set (match_operand:DI 0 "register_operand" "=r")
10858 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
10859 (match_operand:QI 2 "const1_operand" ""))))
10860 (clobber (reg:CC FLAGS_REG))]
10862 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10863 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
10865 [(set_attr "type" "rotate")
10866 (set_attr "length_immediate" "0")
10867 (set_attr "mode" "SI")])
10869 (define_insn "*rotrsi3_1"
10870 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
10871 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
10872 (match_operand:QI 2 "nonmemory_operand" "I,c")))
10873 (clobber (reg:CC FLAGS_REG))]
10874 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
10876 ror{l}\t{%2, %0|%0, %2}
10877 ror{l}\t{%b2, %0|%0, %b2}"
10878 [(set_attr "type" "rotate")
10879 (set_attr "mode" "SI")])
10881 (define_insn "*rotrsi3_1_zext"
10882 [(set (match_operand:DI 0 "register_operand" "=r,r")
10884 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
10885 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
10886 (clobber (reg:CC FLAGS_REG))]
10887 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
10889 ror{l}\t{%2, %k0|%k0, %2}
10890 ror{l}\t{%b2, %k0|%k0, %b2}"
10891 [(set_attr "type" "rotate")
10892 (set_attr "mode" "SI")])
10894 (define_expand "rotrhi3"
10895 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10896 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
10897 (match_operand:QI 2 "nonmemory_operand" "")))]
10898 "TARGET_HIMODE_MATH"
10899 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
10901 (define_insn "*rotrhi3_one_bit"
10902 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10903 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10904 (match_operand:QI 2 "const1_operand" "")))
10905 (clobber (reg:CC FLAGS_REG))]
10906 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10907 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
10909 [(set_attr "type" "rotate")
10910 (set_attr "length_immediate" "0")
10911 (set_attr "mode" "HI")])
10913 (define_insn "*rotrhi3_1"
10914 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
10915 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
10916 (match_operand:QI 2 "nonmemory_operand" "I,c")))
10917 (clobber (reg:CC FLAGS_REG))]
10918 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
10920 ror{w}\t{%2, %0|%0, %2}
10921 ror{w}\t{%b2, %0|%0, %b2}"
10922 [(set_attr "type" "rotate")
10923 (set_attr "mode" "HI")])
10926 [(set (match_operand:HI 0 "register_operand" "")
10927 (rotatert:HI (match_dup 0) (const_int 8)))
10928 (clobber (reg:CC FLAGS_REG))]
10930 [(parallel [(set (strict_low_part (match_dup 0))
10931 (bswap:HI (match_dup 0)))
10932 (clobber (reg:CC FLAGS_REG))])]
10935 (define_expand "rotrqi3"
10936 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10937 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
10938 (match_operand:QI 2 "nonmemory_operand" "")))]
10939 "TARGET_QIMODE_MATH"
10940 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
10942 (define_insn "*rotrqi3_1_one_bit"
10943 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10944 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10945 (match_operand:QI 2 "const1_operand" "")))
10946 (clobber (reg:CC FLAGS_REG))]
10947 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10948 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
10950 [(set_attr "type" "rotate")
10951 (set_attr "length_immediate" "0")
10952 (set_attr "mode" "QI")])
10954 (define_insn "*rotrqi3_1_one_bit_slp"
10955 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10956 (rotatert:QI (match_dup 0)
10957 (match_operand:QI 1 "const1_operand" "")))
10958 (clobber (reg:CC FLAGS_REG))]
10959 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10960 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
10962 [(set_attr "type" "rotate1")
10963 (set_attr "length_immediate" "0")
10964 (set_attr "mode" "QI")])
10966 (define_insn "*rotrqi3_1"
10967 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
10968 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10969 (match_operand:QI 2 "nonmemory_operand" "I,c")))
10970 (clobber (reg:CC FLAGS_REG))]
10971 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
10973 ror{b}\t{%2, %0|%0, %2}
10974 ror{b}\t{%b2, %0|%0, %b2}"
10975 [(set_attr "type" "rotate")
10976 (set_attr "mode" "QI")])
10978 (define_insn "*rotrqi3_1_slp"
10979 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
10980 (rotatert:QI (match_dup 0)
10981 (match_operand:QI 1 "nonmemory_operand" "I,c")))
10982 (clobber (reg:CC FLAGS_REG))]
10983 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10984 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10986 ror{b}\t{%1, %0|%0, %1}
10987 ror{b}\t{%b1, %0|%0, %b1}"
10988 [(set_attr "type" "rotate1")
10989 (set_attr "mode" "QI")])
10991 ;; Bit set / bit test instructions
10993 (define_expand "extv"
10994 [(set (match_operand:SI 0 "register_operand" "")
10995 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10996 (match_operand:SI 2 "const8_operand" "")
10997 (match_operand:SI 3 "const8_operand" "")))]
11000 /* Handle extractions from %ah et al. */
11001 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
11004 /* From mips.md: extract_bit_field doesn't verify that our source
11005 matches the predicate, so check it again here. */
11006 if (! ext_register_operand (operands[1], VOIDmode))
11010 (define_expand "extzv"
11011 [(set (match_operand:SI 0 "register_operand" "")
11012 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
11013 (match_operand:SI 2 "const8_operand" "")
11014 (match_operand:SI 3 "const8_operand" "")))]
11017 /* Handle extractions from %ah et al. */
11018 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
11021 /* From mips.md: extract_bit_field doesn't verify that our source
11022 matches the predicate, so check it again here. */
11023 if (! ext_register_operand (operands[1], VOIDmode))
11027 (define_expand "insv"
11028 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
11029 (match_operand 1 "const8_operand" "")
11030 (match_operand 2 "const8_operand" ""))
11031 (match_operand 3 "register_operand" ""))]
11034 /* Handle insertions to %ah et al. */
11035 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
11038 /* From mips.md: insert_bit_field doesn't verify that our source
11039 matches the predicate, so check it again here. */
11040 if (! ext_register_operand (operands[0], VOIDmode))
11044 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
11046 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
11051 ;; %%% bts, btr, btc, bt.
11052 ;; In general these instructions are *slow* when applied to memory,
11053 ;; since they enforce atomic operation. When applied to registers,
11054 ;; it depends on the cpu implementation. They're never faster than
11055 ;; the corresponding and/ior/xor operations, so with 32-bit there's
11056 ;; no point. But in 64-bit, we can't hold the relevant immediates
11057 ;; within the instruction itself, so operating on bits in the high
11058 ;; 32-bits of a register becomes easier.
11060 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
11061 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11062 ;; negdf respectively, so they can never be disabled entirely.
11064 (define_insn "*btsq"
11065 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11067 (match_operand:DI 1 "const_0_to_63_operand" ""))
11069 (clobber (reg:CC FLAGS_REG))]
11070 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11071 "bts{q}\t{%1, %0|%0, %1}"
11072 [(set_attr "type" "alu1")
11073 (set_attr "prefix_0f" "1")
11074 (set_attr "mode" "DI")])
11076 (define_insn "*btrq"
11077 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11079 (match_operand:DI 1 "const_0_to_63_operand" ""))
11081 (clobber (reg:CC FLAGS_REG))]
11082 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11083 "btr{q}\t{%1, %0|%0, %1}"
11084 [(set_attr "type" "alu1")
11085 (set_attr "prefix_0f" "1")
11086 (set_attr "mode" "DI")])
11088 (define_insn "*btcq"
11089 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11091 (match_operand:DI 1 "const_0_to_63_operand" ""))
11092 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11093 (clobber (reg:CC FLAGS_REG))]
11094 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11095 "btc{q}\t{%1, %0|%0, %1}"
11096 [(set_attr "type" "alu1")
11097 (set_attr "prefix_0f" "1")
11098 (set_attr "mode" "DI")])
11100 ;; Allow Nocona to avoid these instructions if a register is available.
11103 [(match_scratch:DI 2 "r")
11104 (parallel [(set (zero_extract:DI
11105 (match_operand:DI 0 "register_operand" "")
11107 (match_operand:DI 1 "const_0_to_63_operand" ""))
11109 (clobber (reg:CC FLAGS_REG))])]
11110 "TARGET_64BIT && !TARGET_USE_BT"
11113 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
11116 if (HOST_BITS_PER_WIDE_INT >= 64)
11117 lo = (HOST_WIDE_INT)1 << i, hi = 0;
11118 else if (i < HOST_BITS_PER_WIDE_INT)
11119 lo = (HOST_WIDE_INT)1 << i, hi = 0;
11121 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
11123 op1 = immed_double_const (lo, hi, DImode);
11126 emit_move_insn (operands[2], op1);
11130 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
11135 [(match_scratch:DI 2 "r")
11136 (parallel [(set (zero_extract:DI
11137 (match_operand:DI 0 "register_operand" "")
11139 (match_operand:DI 1 "const_0_to_63_operand" ""))
11141 (clobber (reg:CC FLAGS_REG))])]
11142 "TARGET_64BIT && !TARGET_USE_BT"
11145 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
11148 if (HOST_BITS_PER_WIDE_INT >= 64)
11149 lo = (HOST_WIDE_INT)1 << i, hi = 0;
11150 else if (i < HOST_BITS_PER_WIDE_INT)
11151 lo = (HOST_WIDE_INT)1 << i, hi = 0;
11153 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
11155 op1 = immed_double_const (~lo, ~hi, DImode);
11158 emit_move_insn (operands[2], op1);
11162 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
11167 [(match_scratch:DI 2 "r")
11168 (parallel [(set (zero_extract:DI
11169 (match_operand:DI 0 "register_operand" "")
11171 (match_operand:DI 1 "const_0_to_63_operand" ""))
11172 (not:DI (zero_extract:DI
11173 (match_dup 0) (const_int 1) (match_dup 1))))
11174 (clobber (reg:CC FLAGS_REG))])]
11175 "TARGET_64BIT && !TARGET_USE_BT"
11178 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
11181 if (HOST_BITS_PER_WIDE_INT >= 64)
11182 lo = (HOST_WIDE_INT)1 << i, hi = 0;
11183 else if (i < HOST_BITS_PER_WIDE_INT)
11184 lo = (HOST_WIDE_INT)1 << i, hi = 0;
11186 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
11188 op1 = immed_double_const (lo, hi, DImode);
11191 emit_move_insn (operands[2], op1);
11195 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
11199 (define_insn "*btdi_rex64"
11200 [(set (reg:CCC FLAGS_REG)
11203 (match_operand:DI 0 "register_operand" "r")
11205 (match_operand:DI 1 "nonmemory_operand" "rN"))
11207 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
11208 "bt{q}\t{%1, %0|%0, %1}"
11209 [(set_attr "type" "alu1")
11210 (set_attr "prefix_0f" "1")
11211 (set_attr "mode" "DI")])
11213 (define_insn "*btsi"
11214 [(set (reg:CCC FLAGS_REG)
11217 (match_operand:SI 0 "register_operand" "r")
11219 (match_operand:SI 1 "nonmemory_operand" "rN"))
11221 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11222 "bt{l}\t{%1, %0|%0, %1}"
11223 [(set_attr "type" "alu1")
11224 (set_attr "prefix_0f" "1")
11225 (set_attr "mode" "SI")])
11227 ;; Store-flag instructions.
11229 ;; For all sCOND expanders, also expand the compare or test insn that
11230 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
11232 (define_insn_and_split "*setcc_di_1"
11233 [(set (match_operand:DI 0 "register_operand" "=q")
11234 (match_operator:DI 1 "ix86_comparison_operator"
11235 [(reg FLAGS_REG) (const_int 0)]))]
11236 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11238 "&& reload_completed"
11239 [(set (match_dup 2) (match_dup 1))
11240 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11242 PUT_MODE (operands[1], QImode);
11243 operands[2] = gen_lowpart (QImode, operands[0]);
11246 (define_insn_and_split "*setcc_si_1_and"
11247 [(set (match_operand:SI 0 "register_operand" "=q")
11248 (match_operator:SI 1 "ix86_comparison_operator"
11249 [(reg FLAGS_REG) (const_int 0)]))
11250 (clobber (reg:CC FLAGS_REG))]
11251 "!TARGET_PARTIAL_REG_STALL
11252 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11254 "&& reload_completed"
11255 [(set (match_dup 2) (match_dup 1))
11256 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11257 (clobber (reg:CC FLAGS_REG))])]
11259 PUT_MODE (operands[1], QImode);
11260 operands[2] = gen_lowpart (QImode, operands[0]);
11263 (define_insn_and_split "*setcc_si_1_movzbl"
11264 [(set (match_operand:SI 0 "register_operand" "=q")
11265 (match_operator:SI 1 "ix86_comparison_operator"
11266 [(reg FLAGS_REG) (const_int 0)]))]
11267 "!TARGET_PARTIAL_REG_STALL
11268 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11270 "&& reload_completed"
11271 [(set (match_dup 2) (match_dup 1))
11272 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11274 PUT_MODE (operands[1], QImode);
11275 operands[2] = gen_lowpart (QImode, operands[0]);
11278 (define_insn "*setcc_qi"
11279 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11280 (match_operator:QI 1 "ix86_comparison_operator"
11281 [(reg FLAGS_REG) (const_int 0)]))]
11284 [(set_attr "type" "setcc")
11285 (set_attr "mode" "QI")])
11287 (define_insn "*setcc_qi_slp"
11288 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11289 (match_operator:QI 1 "ix86_comparison_operator"
11290 [(reg FLAGS_REG) (const_int 0)]))]
11293 [(set_attr "type" "setcc")
11294 (set_attr "mode" "QI")])
11296 ;; In general it is not safe to assume too much about CCmode registers,
11297 ;; so simplify-rtx stops when it sees a second one. Under certain
11298 ;; conditions this is safe on x86, so help combine not create
11305 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11306 (ne:QI (match_operator 1 "ix86_comparison_operator"
11307 [(reg FLAGS_REG) (const_int 0)])
11310 [(set (match_dup 0) (match_dup 1))]
11312 PUT_MODE (operands[1], QImode);
11316 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11317 (ne:QI (match_operator 1 "ix86_comparison_operator"
11318 [(reg FLAGS_REG) (const_int 0)])
11321 [(set (match_dup 0) (match_dup 1))]
11323 PUT_MODE (operands[1], QImode);
11327 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11328 (eq:QI (match_operator 1 "ix86_comparison_operator"
11329 [(reg FLAGS_REG) (const_int 0)])
11332 [(set (match_dup 0) (match_dup 1))]
11334 rtx new_op1 = copy_rtx (operands[1]);
11335 operands[1] = new_op1;
11336 PUT_MODE (new_op1, QImode);
11337 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11338 GET_MODE (XEXP (new_op1, 0))));
11340 /* Make sure that (a) the CCmode we have for the flags is strong
11341 enough for the reversed compare or (b) we have a valid FP compare. */
11342 if (! ix86_comparison_operator (new_op1, VOIDmode))
11347 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11348 (eq:QI (match_operator 1 "ix86_comparison_operator"
11349 [(reg FLAGS_REG) (const_int 0)])
11352 [(set (match_dup 0) (match_dup 1))]
11354 rtx new_op1 = copy_rtx (operands[1]);
11355 operands[1] = new_op1;
11356 PUT_MODE (new_op1, QImode);
11357 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11358 GET_MODE (XEXP (new_op1, 0))));
11360 /* Make sure that (a) the CCmode we have for the flags is strong
11361 enough for the reversed compare or (b) we have a valid FP compare. */
11362 if (! ix86_comparison_operator (new_op1, VOIDmode))
11366 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11367 ;; subsequent logical operations are used to imitate conditional moves.
11368 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11371 (define_insn "*avx_setcc<mode>"
11372 [(set (match_operand:MODEF 0 "register_operand" "=x")
11373 (match_operator:MODEF 1 "avx_comparison_float_operator"
11374 [(match_operand:MODEF 2 "register_operand" "x")
11375 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11377 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
11378 [(set_attr "type" "ssecmp")
11379 (set_attr "prefix" "vex")
11380 (set_attr "length_immediate" "1")
11381 (set_attr "mode" "<MODE>")])
11383 (define_insn "*sse_setcc<mode>"
11384 [(set (match_operand:MODEF 0 "register_operand" "=x")
11385 (match_operator:MODEF 1 "sse_comparison_operator"
11386 [(match_operand:MODEF 2 "register_operand" "0")
11387 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11388 "SSE_FLOAT_MODE_P (<MODE>mode)"
11389 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
11390 [(set_attr "type" "ssecmp")
11391 (set_attr "length_immediate" "1")
11392 (set_attr "mode" "<MODE>")])
11394 ;; Basic conditional jump instructions.
11395 ;; We ignore the overflow flag for signed branch instructions.
11397 (define_insn "*jcc_1"
11399 (if_then_else (match_operator 1 "ix86_comparison_operator"
11400 [(reg FLAGS_REG) (const_int 0)])
11401 (label_ref (match_operand 0 "" ""))
11405 [(set_attr "type" "ibr")
11406 (set_attr "modrm" "0")
11407 (set (attr "length")
11408 (if_then_else (and (ge (minus (match_dup 0) (pc))
11410 (lt (minus (match_dup 0) (pc))
11415 (define_insn "*jcc_2"
11417 (if_then_else (match_operator 1 "ix86_comparison_operator"
11418 [(reg FLAGS_REG) (const_int 0)])
11420 (label_ref (match_operand 0 "" ""))))]
11423 [(set_attr "type" "ibr")
11424 (set_attr "modrm" "0")
11425 (set (attr "length")
11426 (if_then_else (and (ge (minus (match_dup 0) (pc))
11428 (lt (minus (match_dup 0) (pc))
11433 ;; In general it is not safe to assume too much about CCmode registers,
11434 ;; so simplify-rtx stops when it sees a second one. Under certain
11435 ;; conditions this is safe on x86, so help combine not create
11443 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11444 [(reg FLAGS_REG) (const_int 0)])
11446 (label_ref (match_operand 1 "" ""))
11450 (if_then_else (match_dup 0)
11451 (label_ref (match_dup 1))
11454 PUT_MODE (operands[0], VOIDmode);
11459 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11460 [(reg FLAGS_REG) (const_int 0)])
11462 (label_ref (match_operand 1 "" ""))
11466 (if_then_else (match_dup 0)
11467 (label_ref (match_dup 1))
11470 rtx new_op0 = copy_rtx (operands[0]);
11471 operands[0] = new_op0;
11472 PUT_MODE (new_op0, VOIDmode);
11473 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11474 GET_MODE (XEXP (new_op0, 0))));
11476 /* Make sure that (a) the CCmode we have for the flags is strong
11477 enough for the reversed compare or (b) we have a valid FP compare. */
11478 if (! ix86_comparison_operator (new_op0, VOIDmode))
11482 ;; zero_extend in SImode is correct, since this is what combine pass
11483 ;; generates from shift insn with QImode operand. Actually, the mode of
11484 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
11485 ;; appropriate modulo of the bit offset value.
11487 (define_insn_and_split "*jcc_btdi_rex64"
11489 (if_then_else (match_operator 0 "bt_comparison_operator"
11491 (match_operand:DI 1 "register_operand" "r")
11494 (match_operand:QI 2 "register_operand" "r")))
11496 (label_ref (match_operand 3 "" ""))
11498 (clobber (reg:CC FLAGS_REG))]
11499 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
11502 [(set (reg:CCC FLAGS_REG)
11510 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11511 (label_ref (match_dup 3))
11514 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
11516 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11519 ;; avoid useless masking of bit offset operand
11520 (define_insn_and_split "*jcc_btdi_mask_rex64"
11522 (if_then_else (match_operator 0 "bt_comparison_operator"
11524 (match_operand:DI 1 "register_operand" "r")
11527 (match_operand:SI 2 "register_operand" "r")
11528 (match_operand:SI 3 "const_int_operand" "n")))])
11529 (label_ref (match_operand 4 "" ""))
11531 (clobber (reg:CC FLAGS_REG))]
11532 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
11533 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
11536 [(set (reg:CCC FLAGS_REG)
11544 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11545 (label_ref (match_dup 4))
11548 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
11550 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11553 (define_insn_and_split "*jcc_btsi"
11555 (if_then_else (match_operator 0 "bt_comparison_operator"
11557 (match_operand:SI 1 "register_operand" "r")
11560 (match_operand:QI 2 "register_operand" "r")))
11562 (label_ref (match_operand 3 "" ""))
11564 (clobber (reg:CC FLAGS_REG))]
11565 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11568 [(set (reg:CCC FLAGS_REG)
11576 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11577 (label_ref (match_dup 3))
11580 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11582 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11585 ;; avoid useless masking of bit offset operand
11586 (define_insn_and_split "*jcc_btsi_mask"
11588 (if_then_else (match_operator 0 "bt_comparison_operator"
11590 (match_operand:SI 1 "register_operand" "r")
11593 (match_operand:SI 2 "register_operand" "r")
11594 (match_operand:SI 3 "const_int_operand" "n")))])
11595 (label_ref (match_operand 4 "" ""))
11597 (clobber (reg:CC FLAGS_REG))]
11598 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11599 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11602 [(set (reg:CCC FLAGS_REG)
11610 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11611 (label_ref (match_dup 4))
11613 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11615 (define_insn_and_split "*jcc_btsi_1"
11617 (if_then_else (match_operator 0 "bt_comparison_operator"
11620 (match_operand:SI 1 "register_operand" "r")
11621 (match_operand:QI 2 "register_operand" "r"))
11624 (label_ref (match_operand 3 "" ""))
11626 (clobber (reg:CC FLAGS_REG))]
11627 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11630 [(set (reg:CCC FLAGS_REG)
11638 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11639 (label_ref (match_dup 3))
11642 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11644 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11647 ;; avoid useless masking of bit offset operand
11648 (define_insn_and_split "*jcc_btsi_mask_1"
11651 (match_operator 0 "bt_comparison_operator"
11654 (match_operand:SI 1 "register_operand" "r")
11657 (match_operand:SI 2 "register_operand" "r")
11658 (match_operand:SI 3 "const_int_operand" "n")) 0))
11661 (label_ref (match_operand 4 "" ""))
11663 (clobber (reg:CC FLAGS_REG))]
11664 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11665 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11668 [(set (reg:CCC FLAGS_REG)
11676 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11677 (label_ref (match_dup 4))
11679 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11681 ;; Define combination compare-and-branch fp compare instructions to help
11684 (define_insn "*fp_jcc_3_387"
11686 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11687 [(match_operand 1 "register_operand" "f")
11688 (match_operand 2 "nonimmediate_operand" "fm")])
11689 (label_ref (match_operand 3 "" ""))
11691 (clobber (reg:CCFP FPSR_REG))
11692 (clobber (reg:CCFP FLAGS_REG))
11693 (clobber (match_scratch:HI 4 "=a"))]
11695 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11696 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11697 && SELECT_CC_MODE (GET_CODE (operands[0]),
11698 operands[1], operands[2]) == CCFPmode
11702 (define_insn "*fp_jcc_4_387"
11704 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11705 [(match_operand 1 "register_operand" "f")
11706 (match_operand 2 "nonimmediate_operand" "fm")])
11708 (label_ref (match_operand 3 "" ""))))
11709 (clobber (reg:CCFP FPSR_REG))
11710 (clobber (reg:CCFP FLAGS_REG))
11711 (clobber (match_scratch:HI 4 "=a"))]
11713 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11714 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11715 && SELECT_CC_MODE (GET_CODE (operands[0]),
11716 operands[1], operands[2]) == CCFPmode
11720 (define_insn "*fp_jcc_5_387"
11722 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11723 [(match_operand 1 "register_operand" "f")
11724 (match_operand 2 "register_operand" "f")])
11725 (label_ref (match_operand 3 "" ""))
11727 (clobber (reg:CCFP FPSR_REG))
11728 (clobber (reg:CCFP FLAGS_REG))
11729 (clobber (match_scratch:HI 4 "=a"))]
11730 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11731 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11735 (define_insn "*fp_jcc_6_387"
11737 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11738 [(match_operand 1 "register_operand" "f")
11739 (match_operand 2 "register_operand" "f")])
11741 (label_ref (match_operand 3 "" ""))))
11742 (clobber (reg:CCFP FPSR_REG))
11743 (clobber (reg:CCFP FLAGS_REG))
11744 (clobber (match_scratch:HI 4 "=a"))]
11745 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11746 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11750 (define_insn "*fp_jcc_7_387"
11752 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11753 [(match_operand 1 "register_operand" "f")
11754 (match_operand 2 "const0_operand" "")])
11755 (label_ref (match_operand 3 "" ""))
11757 (clobber (reg:CCFP FPSR_REG))
11758 (clobber (reg:CCFP FLAGS_REG))
11759 (clobber (match_scratch:HI 4 "=a"))]
11760 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11761 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11762 && SELECT_CC_MODE (GET_CODE (operands[0]),
11763 operands[1], operands[2]) == CCFPmode
11767 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
11768 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11769 ;; with a precedence over other operators and is always put in the first
11770 ;; place. Swap condition and operands to match ficom instruction.
11772 (define_insn "*fp_jcc_8<mode>_387"
11774 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11775 [(match_operator 1 "float_operator"
11776 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11777 (match_operand 3 "register_operand" "f,f")])
11778 (label_ref (match_operand 4 "" ""))
11780 (clobber (reg:CCFP FPSR_REG))
11781 (clobber (reg:CCFP FLAGS_REG))
11782 (clobber (match_scratch:HI 5 "=a,a"))]
11783 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11784 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11785 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11786 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11792 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11793 [(match_operand 1 "register_operand" "")
11794 (match_operand 2 "nonimmediate_operand" "")])
11795 (match_operand 3 "" "")
11796 (match_operand 4 "" "")))
11797 (clobber (reg:CCFP FPSR_REG))
11798 (clobber (reg:CCFP FLAGS_REG))]
11802 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11803 operands[3], operands[4], NULL_RTX, NULL_RTX);
11809 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11810 [(match_operand 1 "register_operand" "")
11811 (match_operand 2 "general_operand" "")])
11812 (match_operand 3 "" "")
11813 (match_operand 4 "" "")))
11814 (clobber (reg:CCFP FPSR_REG))
11815 (clobber (reg:CCFP FLAGS_REG))
11816 (clobber (match_scratch:HI 5 "=a"))]
11820 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11821 operands[3], operands[4], operands[5], NULL_RTX);
11827 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11828 [(match_operator 1 "float_operator"
11829 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11830 (match_operand 3 "register_operand" "")])
11831 (match_operand 4 "" "")
11832 (match_operand 5 "" "")))
11833 (clobber (reg:CCFP FPSR_REG))
11834 (clobber (reg:CCFP FLAGS_REG))
11835 (clobber (match_scratch:HI 6 "=a"))]
11839 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11840 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11841 operands[3], operands[7],
11842 operands[4], operands[5], operands[6], NULL_RTX);
11846 ;; %%% Kill this when reload knows how to do it.
11849 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11850 [(match_operator 1 "float_operator"
11851 [(match_operand:X87MODEI12 2 "register_operand" "")])
11852 (match_operand 3 "register_operand" "")])
11853 (match_operand 4 "" "")
11854 (match_operand 5 "" "")))
11855 (clobber (reg:CCFP FPSR_REG))
11856 (clobber (reg:CCFP FLAGS_REG))
11857 (clobber (match_scratch:HI 6 "=a"))]
11861 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11862 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11863 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11864 operands[3], operands[7],
11865 operands[4], operands[5], operands[6], operands[2]);
11869 ;; Unconditional and other jump instructions
11871 (define_insn "jump"
11873 (label_ref (match_operand 0 "" "")))]
11876 [(set_attr "type" "ibr")
11877 (set (attr "length")
11878 (if_then_else (and (ge (minus (match_dup 0) (pc))
11880 (lt (minus (match_dup 0) (pc))
11884 (set_attr "modrm" "0")])
11886 (define_expand "indirect_jump"
11887 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11891 (define_insn "*indirect_jump"
11892 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11895 [(set_attr "type" "ibr")
11896 (set_attr "length_immediate" "0")])
11898 (define_expand "tablejump"
11899 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11900 (use (label_ref (match_operand 1 "" "")))])]
11903 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11904 relative. Convert the relative address to an absolute address. */
11908 enum rtx_code code;
11910 /* We can't use @GOTOFF for text labels on VxWorks;
11911 see gotoff_operand. */
11912 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11916 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11918 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11922 op1 = pic_offset_table_rtx;
11927 op0 = pic_offset_table_rtx;
11931 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11936 (define_insn "*tablejump_1"
11937 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11938 (use (label_ref (match_operand 1 "" "")))]
11941 [(set_attr "type" "ibr")
11942 (set_attr "length_immediate" "0")])
11944 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11947 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11948 (set (match_operand:QI 1 "register_operand" "")
11949 (match_operator:QI 2 "ix86_comparison_operator"
11950 [(reg FLAGS_REG) (const_int 0)]))
11951 (set (match_operand 3 "q_regs_operand" "")
11952 (zero_extend (match_dup 1)))]
11953 "(peep2_reg_dead_p (3, operands[1])
11954 || operands_match_p (operands[1], operands[3]))
11955 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11956 [(set (match_dup 4) (match_dup 0))
11957 (set (strict_low_part (match_dup 5))
11960 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11961 operands[5] = gen_lowpart (QImode, operands[3]);
11962 ix86_expand_clear (operands[3]);
11965 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11968 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11969 (set (match_operand:QI 1 "register_operand" "")
11970 (match_operator:QI 2 "ix86_comparison_operator"
11971 [(reg FLAGS_REG) (const_int 0)]))
11972 (parallel [(set (match_operand 3 "q_regs_operand" "")
11973 (zero_extend (match_dup 1)))
11974 (clobber (reg:CC FLAGS_REG))])]
11975 "(peep2_reg_dead_p (3, operands[1])
11976 || operands_match_p (operands[1], operands[3]))
11977 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11978 [(set (match_dup 4) (match_dup 0))
11979 (set (strict_low_part (match_dup 5))
11982 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11983 operands[5] = gen_lowpart (QImode, operands[3]);
11984 ix86_expand_clear (operands[3]);
11987 ;; Call instructions.
11989 ;; The predicates normally associated with named expanders are not properly
11990 ;; checked for calls. This is a bug in the generic code, but it isn't that
11991 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11993 ;; P6 processors will jump to the address after the decrement when %esp
11994 ;; is used as a call operand, so they will execute return address as a code.
11995 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11997 ;; Call subroutine returning no value.
11999 (define_expand "call_pop"
12000 [(parallel [(call (match_operand:QI 0 "" "")
12001 (match_operand:SI 1 "" ""))
12002 (set (reg:SI SP_REG)
12003 (plus:SI (reg:SI SP_REG)
12004 (match_operand:SI 3 "" "")))])]
12007 ix86_expand_call (NULL, operands[0], operands[1],
12008 operands[2], operands[3], 0);
12012 (define_insn "*call_pop_0"
12013 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
12014 (match_operand:SI 1 "" ""))
12015 (set (reg:SI SP_REG)
12016 (plus:SI (reg:SI SP_REG)
12017 (match_operand:SI 2 "immediate_operand" "")))]
12020 if (SIBLING_CALL_P (insn))
12023 return "call\t%P0";
12025 [(set_attr "type" "call")])
12027 (define_insn "*call_pop_1"
12028 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
12029 (match_operand:SI 1 "" ""))
12030 (set (reg:SI SP_REG)
12031 (plus:SI (reg:SI SP_REG)
12032 (match_operand:SI 2 "immediate_operand" "i")))]
12033 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12035 if (constant_call_address_operand (operands[0], Pmode))
12036 return "call\t%P0";
12037 return "call\t%A0";
12039 [(set_attr "type" "call")])
12041 (define_insn "*sibcall_pop_1"
12042 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
12043 (match_operand:SI 1 "" ""))
12044 (set (reg:SI SP_REG)
12045 (plus:SI (reg:SI SP_REG)
12046 (match_operand:SI 2 "immediate_operand" "i,i")))]
12047 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12051 [(set_attr "type" "call")])
12053 (define_expand "call"
12054 [(call (match_operand:QI 0 "" "")
12055 (match_operand 1 "" ""))
12056 (use (match_operand 2 "" ""))]
12059 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
12063 (define_expand "sibcall"
12064 [(call (match_operand:QI 0 "" "")
12065 (match_operand 1 "" ""))
12066 (use (match_operand 2 "" ""))]
12069 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
12073 (define_insn "*call_0"
12074 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
12075 (match_operand 1 "" ""))]
12078 if (SIBLING_CALL_P (insn))
12081 return "call\t%P0";
12083 [(set_attr "type" "call")])
12085 (define_insn "*call_1"
12086 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
12087 (match_operand 1 "" ""))]
12088 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12090 if (constant_call_address_operand (operands[0], Pmode))
12091 return "call\t%P0";
12092 return "call\t%A0";
12094 [(set_attr "type" "call")])
12096 (define_insn "*sibcall_1"
12097 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
12098 (match_operand 1 "" ""))]
12099 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12103 [(set_attr "type" "call")])
12105 (define_insn "*call_1_rex64"
12106 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
12107 (match_operand 1 "" ""))]
12108 "TARGET_64BIT && !SIBLING_CALL_P (insn)
12109 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
12111 if (constant_call_address_operand (operands[0], Pmode))
12112 return "call\t%P0";
12113 return "call\t%A0";
12115 [(set_attr "type" "call")])
12117 (define_insn "*call_1_rex64_ms_sysv"
12118 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
12119 (match_operand 1 "" ""))
12120 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
12121 (clobber (reg:TI XMM6_REG))
12122 (clobber (reg:TI XMM7_REG))
12123 (clobber (reg:TI XMM8_REG))
12124 (clobber (reg:TI XMM9_REG))
12125 (clobber (reg:TI XMM10_REG))
12126 (clobber (reg:TI XMM11_REG))
12127 (clobber (reg:TI XMM12_REG))
12128 (clobber (reg:TI XMM13_REG))
12129 (clobber (reg:TI XMM14_REG))
12130 (clobber (reg:TI XMM15_REG))
12131 (clobber (reg:DI SI_REG))
12132 (clobber (reg:DI DI_REG))]
12133 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
12135 if (constant_call_address_operand (operands[0], Pmode))
12136 return "call\t%P0";
12137 return "call\t%A0";
12139 [(set_attr "type" "call")])
12141 (define_insn "*call_1_rex64_large"
12142 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
12143 (match_operand 1 "" ""))]
12144 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
12146 [(set_attr "type" "call")])
12148 (define_insn "*sibcall_1_rex64"
12149 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
12150 (match_operand 1 "" ""))]
12151 "TARGET_64BIT && SIBLING_CALL_P (insn)"
12155 [(set_attr "type" "call")])
12157 ;; Call subroutine, returning value in operand 0
12158 (define_expand "call_value_pop"
12159 [(parallel [(set (match_operand 0 "" "")
12160 (call (match_operand:QI 1 "" "")
12161 (match_operand:SI 2 "" "")))
12162 (set (reg:SI SP_REG)
12163 (plus:SI (reg:SI SP_REG)
12164 (match_operand:SI 4 "" "")))])]
12167 ix86_expand_call (operands[0], operands[1], operands[2],
12168 operands[3], operands[4], 0);
12172 (define_expand "call_value"
12173 [(set (match_operand 0 "" "")
12174 (call (match_operand:QI 1 "" "")
12175 (match_operand:SI 2 "" "")))
12176 (use (match_operand:SI 3 "" ""))]
12177 ;; Operand 3 is not used on the i386.
12180 ix86_expand_call (operands[0], operands[1], operands[2],
12181 operands[3], NULL, 0);
12185 (define_expand "sibcall_value"
12186 [(set (match_operand 0 "" "")
12187 (call (match_operand:QI 1 "" "")
12188 (match_operand:SI 2 "" "")))
12189 (use (match_operand:SI 3 "" ""))]
12190 ;; Operand 3 is not used on the i386.
12193 ix86_expand_call (operands[0], operands[1], operands[2],
12194 operands[3], NULL, 1);
12198 ;; Call subroutine returning any type.
12200 (define_expand "untyped_call"
12201 [(parallel [(call (match_operand 0 "" "")
12203 (match_operand 1 "" "")
12204 (match_operand 2 "" "")])]
12209 /* In order to give reg-stack an easier job in validating two
12210 coprocessor registers as containing a possible return value,
12211 simply pretend the untyped call returns a complex long double
12214 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12215 and should have the default ABI. */
12217 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12218 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12219 operands[0], const0_rtx,
12220 GEN_INT ((TARGET_64BIT
12221 ? (ix86_abi == SYSV_ABI
12222 ? X86_64_SSE_REGPARM_MAX
12223 : X86_64_MS_SSE_REGPARM_MAX)
12224 : X86_32_SSE_REGPARM_MAX)
12228 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12230 rtx set = XVECEXP (operands[2], 0, i);
12231 emit_move_insn (SET_DEST (set), SET_SRC (set));
12234 /* The optimizer does not know that the call sets the function value
12235 registers we stored in the result block. We avoid problems by
12236 claiming that all hard registers are used and clobbered at this
12238 emit_insn (gen_blockage ());
12243 ;; Prologue and epilogue instructions
12245 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12246 ;; all of memory. This blocks insns from being moved across this point.
12248 (define_insn "blockage"
12249 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12252 [(set_attr "length" "0")])
12254 ;; Do not schedule instructions accessing memory across this point.
12256 (define_expand "memory_blockage"
12257 [(set (match_dup 0)
12258 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12261 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12262 MEM_VOLATILE_P (operands[0]) = 1;
12265 (define_insn "*memory_blockage"
12266 [(set (match_operand:BLK 0 "" "")
12267 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12270 [(set_attr "length" "0")])
12272 ;; As USE insns aren't meaningful after reload, this is used instead
12273 ;; to prevent deleting instructions setting registers for PIC code
12274 (define_insn "prologue_use"
12275 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
12278 [(set_attr "length" "0")])
12280 ;; Insn emitted into the body of a function to return from a function.
12281 ;; This is only done if the function's epilogue is known to be simple.
12282 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12284 (define_expand "return"
12286 "ix86_can_use_return_insn_p ()"
12288 if (crtl->args.pops_args)
12290 rtx popc = GEN_INT (crtl->args.pops_args);
12291 emit_jump_insn (gen_return_pop_internal (popc));
12296 (define_insn "return_internal"
12300 [(set_attr "length" "1")
12301 (set_attr "atom_unit" "jeu")
12302 (set_attr "length_immediate" "0")
12303 (set_attr "modrm" "0")])
12305 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12306 ;; instruction Athlon and K8 have.
12308 (define_insn "return_internal_long"
12310 (unspec [(const_int 0)] UNSPEC_REP)]
12313 [(set_attr "length" "2")
12314 (set_attr "atom_unit" "jeu")
12315 (set_attr "length_immediate" "0")
12316 (set_attr "prefix_rep" "1")
12317 (set_attr "modrm" "0")])
12319 (define_insn "return_pop_internal"
12321 (use (match_operand:SI 0 "const_int_operand" ""))]
12324 [(set_attr "length" "3")
12325 (set_attr "atom_unit" "jeu")
12326 (set_attr "length_immediate" "2")
12327 (set_attr "modrm" "0")])
12329 (define_insn "return_indirect_internal"
12331 (use (match_operand:SI 0 "register_operand" "r"))]
12334 [(set_attr "type" "ibr")
12335 (set_attr "length_immediate" "0")])
12341 [(set_attr "length" "1")
12342 (set_attr "length_immediate" "0")
12343 (set_attr "modrm" "0")])
12345 (define_insn "vswapmov"
12346 [(set (match_operand:SI 0 "register_operand" "=r")
12347 (match_operand:SI 1 "register_operand" "r"))
12348 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
12350 "movl.s\t{%1, %0|%0, %1}"
12351 [(set_attr "length" "2")
12352 (set_attr "length_immediate" "0")
12353 (set_attr "modrm" "0")])
12355 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12356 ;; branch prediction penalty for the third jump in a 16-byte
12360 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
12363 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12364 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12366 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12367 The align insn is used to avoid 3 jump instructions in the row to improve
12368 branch prediction and the benefits hardly outweigh the cost of extra 8
12369 nops on the average inserted by full alignment pseudo operation. */
12373 [(set_attr "length" "16")])
12375 (define_expand "prologue"
12378 "ix86_expand_prologue (); DONE;")
12380 (define_insn "set_got"
12381 [(set (match_operand:SI 0 "register_operand" "=r")
12382 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12383 (clobber (reg:CC FLAGS_REG))]
12385 { return output_set_got (operands[0], NULL_RTX); }
12386 [(set_attr "type" "multi")
12387 (set_attr "length" "12")])
12389 (define_insn "set_got_labelled"
12390 [(set (match_operand:SI 0 "register_operand" "=r")
12391 (unspec:SI [(label_ref (match_operand 1 "" ""))]
12393 (clobber (reg:CC FLAGS_REG))]
12395 { return output_set_got (operands[0], operands[1]); }
12396 [(set_attr "type" "multi")
12397 (set_attr "length" "12")])
12399 (define_insn "set_got_rex64"
12400 [(set (match_operand:DI 0 "register_operand" "=r")
12401 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12403 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12404 [(set_attr "type" "lea")
12405 (set_attr "length_address" "4")
12406 (set_attr "mode" "DI")])
12408 (define_insn "set_rip_rex64"
12409 [(set (match_operand:DI 0 "register_operand" "=r")
12410 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
12412 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12413 [(set_attr "type" "lea")
12414 (set_attr "length_address" "4")
12415 (set_attr "mode" "DI")])
12417 (define_insn "set_got_offset_rex64"
12418 [(set (match_operand:DI 0 "register_operand" "=r")
12420 [(label_ref (match_operand 1 "" ""))]
12421 UNSPEC_SET_GOT_OFFSET))]
12423 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12424 [(set_attr "type" "imov")
12425 (set_attr "length_immediate" "0")
12426 (set_attr "length_address" "8")
12427 (set_attr "mode" "DI")])
12429 (define_expand "epilogue"
12432 "ix86_expand_epilogue (1); DONE;")
12434 (define_expand "sibcall_epilogue"
12437 "ix86_expand_epilogue (0); DONE;")
12439 (define_expand "eh_return"
12440 [(use (match_operand 0 "register_operand" ""))]
12443 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12445 /* Tricky bit: we write the address of the handler to which we will
12446 be returning into someone else's stack frame, one word below the
12447 stack address we wish to restore. */
12448 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12449 tmp = plus_constant (tmp, -UNITS_PER_WORD);
12450 tmp = gen_rtx_MEM (Pmode, tmp);
12451 emit_move_insn (tmp, ra);
12453 emit_jump_insn (gen_eh_return_internal ());
12458 (define_insn_and_split "eh_return_internal"
12462 "epilogue_completed"
12464 "ix86_expand_epilogue (2); DONE;")
12466 (define_insn "leave"
12467 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12468 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12469 (clobber (mem:BLK (scratch)))]
12472 [(set_attr "type" "leave")])
12474 (define_insn "leave_rex64"
12475 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12476 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12477 (clobber (mem:BLK (scratch)))]
12480 [(set_attr "type" "leave")])
12482 (define_expand "ffssi2"
12484 [(set (match_operand:SI 0 "register_operand" "")
12485 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
12486 (clobber (match_scratch:SI 2 ""))
12487 (clobber (reg:CC FLAGS_REG))])]
12492 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
12497 (define_expand "ffs_cmove"
12498 [(set (match_dup 2) (const_int -1))
12499 (parallel [(set (reg:CCZ FLAGS_REG)
12500 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
12502 (set (match_operand:SI 0 "register_operand" "")
12503 (ctz:SI (match_dup 1)))])
12504 (set (match_dup 0) (if_then_else:SI
12505 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12508 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12509 (clobber (reg:CC FLAGS_REG))])]
12511 "operands[2] = gen_reg_rtx (SImode);")
12513 (define_insn_and_split "*ffs_no_cmove"
12514 [(set (match_operand:SI 0 "register_operand" "=r")
12515 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12516 (clobber (match_scratch:SI 2 "=&q"))
12517 (clobber (reg:CC FLAGS_REG))]
12520 "&& reload_completed"
12521 [(parallel [(set (reg:CCZ FLAGS_REG)
12522 (compare:CCZ (match_dup 1) (const_int 0)))
12523 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12524 (set (strict_low_part (match_dup 3))
12525 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12526 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12527 (clobber (reg:CC FLAGS_REG))])
12528 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12529 (clobber (reg:CC FLAGS_REG))])
12530 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12531 (clobber (reg:CC FLAGS_REG))])]
12533 operands[3] = gen_lowpart (QImode, operands[2]);
12534 ix86_expand_clear (operands[2]);
12537 (define_insn "*ffssi_1"
12538 [(set (reg:CCZ FLAGS_REG)
12539 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
12541 (set (match_operand:SI 0 "register_operand" "=r")
12542 (ctz:SI (match_dup 1)))]
12544 "bsf{l}\t{%1, %0|%0, %1}"
12545 [(set_attr "type" "alu1")
12546 (set_attr "prefix_0f" "1")
12547 (set_attr "mode" "SI")])
12549 (define_expand "ffsdi2"
12550 [(set (match_dup 2) (const_int -1))
12551 (parallel [(set (reg:CCZ FLAGS_REG)
12552 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
12554 (set (match_operand:DI 0 "register_operand" "")
12555 (ctz:DI (match_dup 1)))])
12556 (set (match_dup 0) (if_then_else:DI
12557 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12560 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
12561 (clobber (reg:CC FLAGS_REG))])]
12563 "operands[2] = gen_reg_rtx (DImode);")
12565 (define_insn "*ffsdi_1"
12566 [(set (reg:CCZ FLAGS_REG)
12567 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
12569 (set (match_operand:DI 0 "register_operand" "=r")
12570 (ctz:DI (match_dup 1)))]
12572 "bsf{q}\t{%1, %0|%0, %1}"
12573 [(set_attr "type" "alu1")
12574 (set_attr "prefix_0f" "1")
12575 (set_attr "mode" "DI")])
12577 (define_insn "ctzsi2"
12578 [(set (match_operand:SI 0 "register_operand" "=r")
12579 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12580 (clobber (reg:CC FLAGS_REG))]
12582 "bsf{l}\t{%1, %0|%0, %1}"
12583 [(set_attr "type" "alu1")
12584 (set_attr "prefix_0f" "1")
12585 (set_attr "mode" "SI")])
12587 (define_insn "ctzdi2"
12588 [(set (match_operand:DI 0 "register_operand" "=r")
12589 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
12590 (clobber (reg:CC FLAGS_REG))]
12592 "bsf{q}\t{%1, %0|%0, %1}"
12593 [(set_attr "type" "alu1")
12594 (set_attr "prefix_0f" "1")
12595 (set_attr "mode" "DI")])
12597 (define_expand "clzsi2"
12599 [(set (match_operand:SI 0 "register_operand" "")
12600 (minus:SI (const_int 31)
12601 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
12602 (clobber (reg:CC FLAGS_REG))])
12604 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
12605 (clobber (reg:CC FLAGS_REG))])]
12610 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
12615 (define_insn "clzsi2_abm"
12616 [(set (match_operand:SI 0 "register_operand" "=r")
12617 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12618 (clobber (reg:CC FLAGS_REG))]
12620 "lzcnt{l}\t{%1, %0|%0, %1}"
12621 [(set_attr "prefix_rep" "1")
12622 (set_attr "type" "bitmanip")
12623 (set_attr "mode" "SI")])
12626 [(set (match_operand:SI 0 "register_operand" "=r")
12627 (minus:SI (const_int 31)
12628 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12629 (clobber (reg:CC FLAGS_REG))]
12631 "bsr{l}\t{%1, %0|%0, %1}"
12632 [(set_attr "type" "alu1")
12633 (set_attr "prefix_0f" "1")
12634 (set_attr "mode" "SI")])
12636 (define_insn "popcount<mode>2"
12637 [(set (match_operand:SWI248 0 "register_operand" "=r")
12639 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12640 (clobber (reg:CC FLAGS_REG))]
12644 return "popcnt\t{%1, %0|%0, %1}";
12646 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12649 [(set_attr "prefix_rep" "1")
12650 (set_attr "type" "bitmanip")
12651 (set_attr "mode" "<MODE>")])
12653 (define_insn "*popcount<mode>2_cmp"
12654 [(set (reg FLAGS_REG)
12657 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12659 (set (match_operand:SWI248 0 "register_operand" "=r")
12660 (popcount:SWI248 (match_dup 1)))]
12661 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12664 return "popcnt\t{%1, %0|%0, %1}";
12666 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12669 [(set_attr "prefix_rep" "1")
12670 (set_attr "type" "bitmanip")
12671 (set_attr "mode" "<MODE>")])
12673 (define_insn "*popcountsi2_cmp_zext"
12674 [(set (reg FLAGS_REG)
12676 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12678 (set (match_operand:DI 0 "register_operand" "=r")
12679 (zero_extend:DI(popcount:SI (match_dup 1))))]
12680 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12683 return "popcnt\t{%1, %0|%0, %1}";
12685 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12688 [(set_attr "prefix_rep" "1")
12689 (set_attr "type" "bitmanip")
12690 (set_attr "mode" "SI")])
12692 (define_expand "bswapsi2"
12693 [(set (match_operand:SI 0 "register_operand" "")
12694 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
12697 if (!(TARGET_BSWAP || TARGET_MOVBE))
12699 rtx x = operands[0];
12701 emit_move_insn (x, operands[1]);
12702 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12703 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12704 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12709 (define_insn "*bswapsi_movbe"
12710 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
12711 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
12712 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12715 movbe\t{%1, %0|%0, %1}
12716 movbe\t{%1, %0|%0, %1}"
12717 [(set_attr "type" "*,imov,imov")
12718 (set_attr "modrm" "*,1,1")
12719 (set_attr "prefix_0f" "1")
12720 (set_attr "prefix_extra" "*,1,1")
12721 (set_attr "length" "2,*,*")
12722 (set_attr "mode" "SI")])
12724 (define_insn "*bswapsi_1"
12725 [(set (match_operand:SI 0 "register_operand" "=r")
12726 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
12729 [(set_attr "prefix_0f" "1")
12730 (set_attr "length" "2")])
12732 (define_insn "*bswaphi_lowpart_1"
12733 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12734 (bswap:HI (match_dup 0)))
12735 (clobber (reg:CC FLAGS_REG))]
12736 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12738 xchg{b}\t{%h0, %b0|%b0, %h0}
12739 rol{w}\t{$8, %0|%0, 8}"
12740 [(set_attr "length" "2,4")
12741 (set_attr "mode" "QI,HI")])
12743 (define_insn "bswaphi_lowpart"
12744 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12745 (bswap:HI (match_dup 0)))
12746 (clobber (reg:CC FLAGS_REG))]
12748 "rol{w}\t{$8, %0|%0, 8}"
12749 [(set_attr "length" "4")
12750 (set_attr "mode" "HI")])
12752 (define_expand "bswapdi2"
12753 [(set (match_operand:DI 0 "register_operand" "")
12754 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
12758 (define_insn "*bswapdi_movbe"
12759 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12760 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12761 "TARGET_64BIT && TARGET_MOVBE
12762 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12765 movbe\t{%1, %0|%0, %1}
12766 movbe\t{%1, %0|%0, %1}"
12767 [(set_attr "type" "*,imov,imov")
12768 (set_attr "modrm" "*,1,1")
12769 (set_attr "prefix_0f" "1")
12770 (set_attr "prefix_extra" "*,1,1")
12771 (set_attr "length" "3,*,*")
12772 (set_attr "mode" "DI")])
12774 (define_insn "*bswapdi_1"
12775 [(set (match_operand:DI 0 "register_operand" "=r")
12776 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
12779 [(set_attr "prefix_0f" "1")
12780 (set_attr "length" "3")])
12782 (define_expand "clzdi2"
12784 [(set (match_operand:DI 0 "register_operand" "")
12785 (minus:DI (const_int 63)
12786 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
12787 (clobber (reg:CC FLAGS_REG))])
12789 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
12790 (clobber (reg:CC FLAGS_REG))])]
12795 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
12800 (define_insn "clzdi2_abm"
12801 [(set (match_operand:DI 0 "register_operand" "=r")
12802 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
12803 (clobber (reg:CC FLAGS_REG))]
12804 "TARGET_64BIT && TARGET_ABM"
12805 "lzcnt{q}\t{%1, %0|%0, %1}"
12806 [(set_attr "prefix_rep" "1")
12807 (set_attr "type" "bitmanip")
12808 (set_attr "mode" "DI")])
12810 (define_insn "bsr_rex64"
12811 [(set (match_operand:DI 0 "register_operand" "=r")
12812 (minus:DI (const_int 63)
12813 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12814 (clobber (reg:CC FLAGS_REG))]
12816 "bsr{q}\t{%1, %0|%0, %1}"
12817 [(set_attr "type" "alu1")
12818 (set_attr "prefix_0f" "1")
12819 (set_attr "mode" "DI")])
12821 (define_expand "clzhi2"
12823 [(set (match_operand:HI 0 "register_operand" "")
12824 (minus:HI (const_int 15)
12825 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
12826 (clobber (reg:CC FLAGS_REG))])
12828 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
12829 (clobber (reg:CC FLAGS_REG))])]
12834 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
12839 (define_insn "clzhi2_abm"
12840 [(set (match_operand:HI 0 "register_operand" "=r")
12841 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
12842 (clobber (reg:CC FLAGS_REG))]
12844 "lzcnt{w}\t{%1, %0|%0, %1}"
12845 [(set_attr "prefix_rep" "1")
12846 (set_attr "type" "bitmanip")
12847 (set_attr "mode" "HI")])
12849 (define_insn "*bsrhi"
12850 [(set (match_operand:HI 0 "register_operand" "=r")
12851 (minus:HI (const_int 15)
12852 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12853 (clobber (reg:CC FLAGS_REG))]
12855 "bsr{w}\t{%1, %0|%0, %1}"
12856 [(set_attr "type" "alu1")
12857 (set_attr "prefix_0f" "1")
12858 (set_attr "mode" "HI")])
12860 (define_expand "paritydi2"
12861 [(set (match_operand:DI 0 "register_operand" "")
12862 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12865 rtx scratch = gen_reg_rtx (QImode);
12868 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12869 NULL_RTX, operands[1]));
12871 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12872 gen_rtx_REG (CCmode, FLAGS_REG),
12874 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12877 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12880 rtx tmp = gen_reg_rtx (SImode);
12882 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12883 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12888 (define_insn_and_split "paritydi2_cmp"
12889 [(set (reg:CC FLAGS_REG)
12890 (parity:CC (match_operand:DI 3 "register_operand" "0")))
12891 (clobber (match_scratch:DI 0 "=r"))
12892 (clobber (match_scratch:SI 1 "=&r"))
12893 (clobber (match_scratch:HI 2 "=Q"))]
12896 "&& reload_completed"
12898 [(set (match_dup 1)
12899 (xor:SI (match_dup 1) (match_dup 4)))
12900 (clobber (reg:CC FLAGS_REG))])
12902 [(set (reg:CC FLAGS_REG)
12903 (parity:CC (match_dup 1)))
12904 (clobber (match_dup 1))
12905 (clobber (match_dup 2))])]
12907 operands[4] = gen_lowpart (SImode, operands[3]);
12911 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12912 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12915 operands[1] = gen_highpart (SImode, operands[3]);
12918 (define_expand "paritysi2"
12919 [(set (match_operand:SI 0 "register_operand" "")
12920 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12923 rtx scratch = gen_reg_rtx (QImode);
12926 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12928 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12929 gen_rtx_REG (CCmode, FLAGS_REG),
12931 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12933 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12937 (define_insn_and_split "paritysi2_cmp"
12938 [(set (reg:CC FLAGS_REG)
12939 (parity:CC (match_operand:SI 2 "register_operand" "0")))
12940 (clobber (match_scratch:SI 0 "=r"))
12941 (clobber (match_scratch:HI 1 "=&Q"))]
12944 "&& reload_completed"
12946 [(set (match_dup 1)
12947 (xor:HI (match_dup 1) (match_dup 3)))
12948 (clobber (reg:CC FLAGS_REG))])
12950 [(set (reg:CC FLAGS_REG)
12951 (parity:CC (match_dup 1)))
12952 (clobber (match_dup 1))])]
12954 operands[3] = gen_lowpart (HImode, operands[2]);
12956 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12957 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12960 (define_insn "*parityhi2_cmp"
12961 [(set (reg:CC FLAGS_REG)
12962 (parity:CC (match_operand:HI 1 "register_operand" "0")))
12963 (clobber (match_scratch:HI 0 "=Q"))]
12965 "xor{b}\t{%h0, %b0|%b0, %h0}"
12966 [(set_attr "length" "2")
12967 (set_attr "mode" "HI")])
12969 (define_insn "*parityqi2_cmp"
12970 [(set (reg:CC FLAGS_REG)
12971 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
12974 [(set_attr "length" "2")
12975 (set_attr "mode" "QI")])
12977 ;; Thread-local storage patterns for ELF.
12979 ;; Note that these code sequences must appear exactly as shown
12980 ;; in order to allow linker relaxation.
12982 (define_insn "*tls_global_dynamic_32_gnu"
12983 [(set (match_operand:SI 0 "register_operand" "=a")
12984 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12985 (match_operand:SI 2 "tls_symbolic_operand" "")
12986 (match_operand:SI 3 "call_insn_operand" "")]
12988 (clobber (match_scratch:SI 4 "=d"))
12989 (clobber (match_scratch:SI 5 "=c"))
12990 (clobber (reg:CC FLAGS_REG))]
12991 "!TARGET_64BIT && TARGET_GNU_TLS"
12992 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12993 [(set_attr "type" "multi")
12994 (set_attr "length" "12")])
12996 (define_expand "tls_global_dynamic_32"
12997 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13000 (match_operand:SI 1 "tls_symbolic_operand" "")
13003 (clobber (match_scratch:SI 4 ""))
13004 (clobber (match_scratch:SI 5 ""))
13005 (clobber (reg:CC FLAGS_REG))])]
13009 operands[2] = pic_offset_table_rtx;
13012 operands[2] = gen_reg_rtx (Pmode);
13013 emit_insn (gen_set_got (operands[2]));
13015 if (TARGET_GNU2_TLS)
13017 emit_insn (gen_tls_dynamic_gnu2_32
13018 (operands[0], operands[1], operands[2]));
13021 operands[3] = ix86_tls_get_addr ();
13024 (define_insn "*tls_global_dynamic_64"
13025 [(set (match_operand:DI 0 "register_operand" "=a")
13026 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13027 (match_operand:DI 3 "" "")))
13028 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13031 { 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"; }
13032 [(set_attr "type" "multi")
13033 (set_attr "length" "16")])
13035 (define_expand "tls_global_dynamic_64"
13036 [(parallel [(set (match_operand:DI 0 "register_operand" "")
13037 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
13038 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13042 if (TARGET_GNU2_TLS)
13044 emit_insn (gen_tls_dynamic_gnu2_64
13045 (operands[0], operands[1]));
13048 operands[2] = ix86_tls_get_addr ();
13051 (define_insn "*tls_local_dynamic_base_32_gnu"
13052 [(set (match_operand:SI 0 "register_operand" "=a")
13053 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13054 (match_operand:SI 2 "call_insn_operand" "")]
13055 UNSPEC_TLS_LD_BASE))
13056 (clobber (match_scratch:SI 3 "=d"))
13057 (clobber (match_scratch:SI 4 "=c"))
13058 (clobber (reg:CC FLAGS_REG))]
13059 "!TARGET_64BIT && TARGET_GNU_TLS"
13060 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
13061 [(set_attr "type" "multi")
13062 (set_attr "length" "11")])
13064 (define_expand "tls_local_dynamic_base_32"
13065 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13066 (unspec:SI [(match_dup 1) (match_dup 2)]
13067 UNSPEC_TLS_LD_BASE))
13068 (clobber (match_scratch:SI 3 ""))
13069 (clobber (match_scratch:SI 4 ""))
13070 (clobber (reg:CC FLAGS_REG))])]
13074 operands[1] = pic_offset_table_rtx;
13077 operands[1] = gen_reg_rtx (Pmode);
13078 emit_insn (gen_set_got (operands[1]));
13080 if (TARGET_GNU2_TLS)
13082 emit_insn (gen_tls_dynamic_gnu2_32
13083 (operands[0], ix86_tls_module_base (), operands[1]));
13086 operands[2] = ix86_tls_get_addr ();
13089 (define_insn "*tls_local_dynamic_base_64"
13090 [(set (match_operand:DI 0 "register_operand" "=a")
13091 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13092 (match_operand:DI 2 "" "")))
13093 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13095 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
13096 [(set_attr "type" "multi")
13097 (set_attr "length" "12")])
13099 (define_expand "tls_local_dynamic_base_64"
13100 [(parallel [(set (match_operand:DI 0 "register_operand" "")
13101 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
13102 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13105 if (TARGET_GNU2_TLS)
13107 emit_insn (gen_tls_dynamic_gnu2_64
13108 (operands[0], ix86_tls_module_base ()));
13111 operands[1] = ix86_tls_get_addr ();
13114 ;; Local dynamic of a single variable is a lose. Show combine how
13115 ;; to convert that back to global dynamic.
13117 (define_insn_and_split "*tls_local_dynamic_32_once"
13118 [(set (match_operand:SI 0 "register_operand" "=a")
13119 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13120 (match_operand:SI 2 "call_insn_operand" "")]
13121 UNSPEC_TLS_LD_BASE)
13122 (const:SI (unspec:SI
13123 [(match_operand:SI 3 "tls_symbolic_operand" "")]
13125 (clobber (match_scratch:SI 4 "=d"))
13126 (clobber (match_scratch:SI 5 "=c"))
13127 (clobber (reg:CC FLAGS_REG))]
13131 [(parallel [(set (match_dup 0)
13132 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13134 (clobber (match_dup 4))
13135 (clobber (match_dup 5))
13136 (clobber (reg:CC FLAGS_REG))])]
13139 ;; Load and add the thread base pointer from %gs:0.
13141 (define_insn "*load_tp_si"
13142 [(set (match_operand:SI 0 "register_operand" "=r")
13143 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13145 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
13146 [(set_attr "type" "imov")
13147 (set_attr "modrm" "0")
13148 (set_attr "length" "7")
13149 (set_attr "memory" "load")
13150 (set_attr "imm_disp" "false")])
13152 (define_insn "*add_tp_si"
13153 [(set (match_operand:SI 0 "register_operand" "=r")
13154 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13155 (match_operand:SI 1 "register_operand" "0")))
13156 (clobber (reg:CC FLAGS_REG))]
13158 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
13159 [(set_attr "type" "alu")
13160 (set_attr "modrm" "0")
13161 (set_attr "length" "7")
13162 (set_attr "memory" "load")
13163 (set_attr "imm_disp" "false")])
13165 (define_insn "*load_tp_di"
13166 [(set (match_operand:DI 0 "register_operand" "=r")
13167 (unspec:DI [(const_int 0)] UNSPEC_TP))]
13169 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
13170 [(set_attr "type" "imov")
13171 (set_attr "modrm" "0")
13172 (set_attr "length" "7")
13173 (set_attr "memory" "load")
13174 (set_attr "imm_disp" "false")])
13176 (define_insn "*add_tp_di"
13177 [(set (match_operand:DI 0 "register_operand" "=r")
13178 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
13179 (match_operand:DI 1 "register_operand" "0")))
13180 (clobber (reg:CC FLAGS_REG))]
13182 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
13183 [(set_attr "type" "alu")
13184 (set_attr "modrm" "0")
13185 (set_attr "length" "7")
13186 (set_attr "memory" "load")
13187 (set_attr "imm_disp" "false")])
13189 ;; GNU2 TLS patterns can be split.
13191 (define_expand "tls_dynamic_gnu2_32"
13192 [(set (match_dup 3)
13193 (plus:SI (match_operand:SI 2 "register_operand" "")
13195 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
13198 [(set (match_operand:SI 0 "register_operand" "")
13199 (unspec:SI [(match_dup 1) (match_dup 3)
13200 (match_dup 2) (reg:SI SP_REG)]
13202 (clobber (reg:CC FLAGS_REG))])]
13203 "!TARGET_64BIT && TARGET_GNU2_TLS"
13205 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13206 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13209 (define_insn "*tls_dynamic_lea_32"
13210 [(set (match_operand:SI 0 "register_operand" "=r")
13211 (plus:SI (match_operand:SI 1 "register_operand" "b")
13213 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
13214 UNSPEC_TLSDESC))))]
13215 "!TARGET_64BIT && TARGET_GNU2_TLS"
13216 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
13217 [(set_attr "type" "lea")
13218 (set_attr "mode" "SI")
13219 (set_attr "length" "6")
13220 (set_attr "length_address" "4")])
13222 (define_insn "*tls_dynamic_call_32"
13223 [(set (match_operand:SI 0 "register_operand" "=a")
13224 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
13225 (match_operand:SI 2 "register_operand" "0")
13226 ;; we have to make sure %ebx still points to the GOT
13227 (match_operand:SI 3 "register_operand" "b")
13230 (clobber (reg:CC FLAGS_REG))]
13231 "!TARGET_64BIT && TARGET_GNU2_TLS"
13232 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13233 [(set_attr "type" "call")
13234 (set_attr "length" "2")
13235 (set_attr "length_address" "0")])
13237 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13238 [(set (match_operand:SI 0 "register_operand" "=&a")
13240 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
13241 (match_operand:SI 4 "" "")
13242 (match_operand:SI 2 "register_operand" "b")
13245 (const:SI (unspec:SI
13246 [(match_operand:SI 1 "tls_symbolic_operand" "")]
13248 (clobber (reg:CC FLAGS_REG))]
13249 "!TARGET_64BIT && TARGET_GNU2_TLS"
13252 [(set (match_dup 0) (match_dup 5))]
13254 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13255 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13258 (define_expand "tls_dynamic_gnu2_64"
13259 [(set (match_dup 2)
13260 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13263 [(set (match_operand:DI 0 "register_operand" "")
13264 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13266 (clobber (reg:CC FLAGS_REG))])]
13267 "TARGET_64BIT && TARGET_GNU2_TLS"
13269 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13270 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13273 (define_insn "*tls_dynamic_lea_64"
13274 [(set (match_operand:DI 0 "register_operand" "=r")
13275 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13277 "TARGET_64BIT && TARGET_GNU2_TLS"
13278 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
13279 [(set_attr "type" "lea")
13280 (set_attr "mode" "DI")
13281 (set_attr "length" "7")
13282 (set_attr "length_address" "4")])
13284 (define_insn "*tls_dynamic_call_64"
13285 [(set (match_operand:DI 0 "register_operand" "=a")
13286 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
13287 (match_operand:DI 2 "register_operand" "0")
13290 (clobber (reg:CC FLAGS_REG))]
13291 "TARGET_64BIT && TARGET_GNU2_TLS"
13292 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13293 [(set_attr "type" "call")
13294 (set_attr "length" "2")
13295 (set_attr "length_address" "0")])
13297 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13298 [(set (match_operand:DI 0 "register_operand" "=&a")
13300 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
13301 (match_operand:DI 3 "" "")
13304 (const:DI (unspec:DI
13305 [(match_operand:DI 1 "tls_symbolic_operand" "")]
13307 (clobber (reg:CC FLAGS_REG))]
13308 "TARGET_64BIT && TARGET_GNU2_TLS"
13311 [(set (match_dup 0) (match_dup 4))]
13313 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13314 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13319 ;; These patterns match the binary 387 instructions for addM3, subM3,
13320 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13321 ;; SFmode. The first is the normal insn, the second the same insn but
13322 ;; with one operand a conversion, and the third the same insn but with
13323 ;; the other operand a conversion. The conversion may be SFmode or
13324 ;; SImode if the target mode DFmode, but only SImode if the target mode
13327 ;; Gcc is slightly more smart about handling normal two address instructions
13328 ;; so use special patterns for add and mull.
13330 (define_insn "*fop_<mode>_comm_mixed_avx"
13331 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
13332 (match_operator:MODEF 3 "binary_fp_operator"
13333 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13334 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
13335 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13336 && COMMUTATIVE_ARITH_P (operands[3])
13337 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13338 "* return output_387_binary_op (insn, operands);"
13339 [(set (attr "type")
13340 (if_then_else (eq_attr "alternative" "1")
13341 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13342 (const_string "ssemul")
13343 (const_string "sseadd"))
13344 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13345 (const_string "fmul")
13346 (const_string "fop"))))
13347 (set_attr "prefix" "orig,maybe_vex")
13348 (set_attr "mode" "<MODE>")])
13350 (define_insn "*fop_<mode>_comm_mixed"
13351 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
13352 (match_operator:MODEF 3 "binary_fp_operator"
13353 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
13354 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
13355 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13356 && COMMUTATIVE_ARITH_P (operands[3])
13357 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13358 "* return output_387_binary_op (insn, operands);"
13359 [(set (attr "type")
13360 (if_then_else (eq_attr "alternative" "1")
13361 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13362 (const_string "ssemul")
13363 (const_string "sseadd"))
13364 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13365 (const_string "fmul")
13366 (const_string "fop"))))
13367 (set_attr "mode" "<MODE>")])
13369 (define_insn "*fop_<mode>_comm_avx"
13370 [(set (match_operand:MODEF 0 "register_operand" "=x")
13371 (match_operator:MODEF 3 "binary_fp_operator"
13372 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
13373 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13374 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13375 && COMMUTATIVE_ARITH_P (operands[3])
13376 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13377 "* return output_387_binary_op (insn, operands);"
13378 [(set (attr "type")
13379 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13380 (const_string "ssemul")
13381 (const_string "sseadd")))
13382 (set_attr "prefix" "vex")
13383 (set_attr "mode" "<MODE>")])
13385 (define_insn "*fop_<mode>_comm_sse"
13386 [(set (match_operand:MODEF 0 "register_operand" "=x")
13387 (match_operator:MODEF 3 "binary_fp_operator"
13388 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13389 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13390 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13391 && COMMUTATIVE_ARITH_P (operands[3])
13392 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13393 "* return output_387_binary_op (insn, operands);"
13394 [(set (attr "type")
13395 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13396 (const_string "ssemul")
13397 (const_string "sseadd")))
13398 (set_attr "mode" "<MODE>")])
13400 (define_insn "*fop_<mode>_comm_i387"
13401 [(set (match_operand:MODEF 0 "register_operand" "=f")
13402 (match_operator:MODEF 3 "binary_fp_operator"
13403 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13404 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13405 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13406 && COMMUTATIVE_ARITH_P (operands[3])
13407 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13408 "* return output_387_binary_op (insn, operands);"
13409 [(set (attr "type")
13410 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13411 (const_string "fmul")
13412 (const_string "fop")))
13413 (set_attr "mode" "<MODE>")])
13415 (define_insn "*fop_<mode>_1_mixed_avx"
13416 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13417 (match_operator:MODEF 3 "binary_fp_operator"
13418 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
13419 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13420 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13421 && !COMMUTATIVE_ARITH_P (operands[3])
13422 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13423 "* return output_387_binary_op (insn, operands);"
13424 [(set (attr "type")
13425 (cond [(and (eq_attr "alternative" "2")
13426 (match_operand:MODEF 3 "mult_operator" ""))
13427 (const_string "ssemul")
13428 (and (eq_attr "alternative" "2")
13429 (match_operand:MODEF 3 "div_operator" ""))
13430 (const_string "ssediv")
13431 (eq_attr "alternative" "2")
13432 (const_string "sseadd")
13433 (match_operand:MODEF 3 "mult_operator" "")
13434 (const_string "fmul")
13435 (match_operand:MODEF 3 "div_operator" "")
13436 (const_string "fdiv")
13438 (const_string "fop")))
13439 (set_attr "prefix" "orig,orig,maybe_vex")
13440 (set_attr "mode" "<MODE>")])
13442 (define_insn "*fop_<mode>_1_mixed"
13443 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13444 (match_operator:MODEF 3 "binary_fp_operator"
13445 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
13446 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13447 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13448 && !COMMUTATIVE_ARITH_P (operands[3])
13449 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13450 "* return output_387_binary_op (insn, operands);"
13451 [(set (attr "type")
13452 (cond [(and (eq_attr "alternative" "2")
13453 (match_operand:MODEF 3 "mult_operator" ""))
13454 (const_string "ssemul")
13455 (and (eq_attr "alternative" "2")
13456 (match_operand:MODEF 3 "div_operator" ""))
13457 (const_string "ssediv")
13458 (eq_attr "alternative" "2")
13459 (const_string "sseadd")
13460 (match_operand:MODEF 3 "mult_operator" "")
13461 (const_string "fmul")
13462 (match_operand:MODEF 3 "div_operator" "")
13463 (const_string "fdiv")
13465 (const_string "fop")))
13466 (set_attr "mode" "<MODE>")])
13468 (define_insn "*rcpsf2_sse"
13469 [(set (match_operand:SF 0 "register_operand" "=x")
13470 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13473 "%vrcpss\t{%1, %d0|%d0, %1}"
13474 [(set_attr "type" "sse")
13475 (set_attr "atom_sse_attr" "rcp")
13476 (set_attr "prefix" "maybe_vex")
13477 (set_attr "mode" "SF")])
13479 (define_insn "*fop_<mode>_1_avx"
13480 [(set (match_operand:MODEF 0 "register_operand" "=x")
13481 (match_operator:MODEF 3 "binary_fp_operator"
13482 [(match_operand:MODEF 1 "register_operand" "x")
13483 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13484 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13485 && !COMMUTATIVE_ARITH_P (operands[3])"
13486 "* return output_387_binary_op (insn, operands);"
13487 [(set (attr "type")
13488 (cond [(match_operand:MODEF 3 "mult_operator" "")
13489 (const_string "ssemul")
13490 (match_operand:MODEF 3 "div_operator" "")
13491 (const_string "ssediv")
13493 (const_string "sseadd")))
13494 (set_attr "prefix" "vex")
13495 (set_attr "mode" "<MODE>")])
13497 (define_insn "*fop_<mode>_1_sse"
13498 [(set (match_operand:MODEF 0 "register_operand" "=x")
13499 (match_operator:MODEF 3 "binary_fp_operator"
13500 [(match_operand:MODEF 1 "register_operand" "0")
13501 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13502 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13503 && !COMMUTATIVE_ARITH_P (operands[3])"
13504 "* return output_387_binary_op (insn, operands);"
13505 [(set (attr "type")
13506 (cond [(match_operand:MODEF 3 "mult_operator" "")
13507 (const_string "ssemul")
13508 (match_operand:MODEF 3 "div_operator" "")
13509 (const_string "ssediv")
13511 (const_string "sseadd")))
13512 (set_attr "mode" "<MODE>")])
13514 ;; This pattern is not fully shadowed by the pattern above.
13515 (define_insn "*fop_<mode>_1_i387"
13516 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13517 (match_operator:MODEF 3 "binary_fp_operator"
13518 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13519 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13520 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13521 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13522 && !COMMUTATIVE_ARITH_P (operands[3])
13523 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13524 "* return output_387_binary_op (insn, operands);"
13525 [(set (attr "type")
13526 (cond [(match_operand:MODEF 3 "mult_operator" "")
13527 (const_string "fmul")
13528 (match_operand:MODEF 3 "div_operator" "")
13529 (const_string "fdiv")
13531 (const_string "fop")))
13532 (set_attr "mode" "<MODE>")])
13534 ;; ??? Add SSE splitters for these!
13535 (define_insn "*fop_<MODEF:mode>_2_i387"
13536 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13537 (match_operator:MODEF 3 "binary_fp_operator"
13539 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13540 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13541 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13542 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13543 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13544 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13545 [(set (attr "type")
13546 (cond [(match_operand:MODEF 3 "mult_operator" "")
13547 (const_string "fmul")
13548 (match_operand:MODEF 3 "div_operator" "")
13549 (const_string "fdiv")
13551 (const_string "fop")))
13552 (set_attr "fp_int_src" "true")
13553 (set_attr "mode" "<X87MODEI12:MODE>")])
13555 (define_insn "*fop_<MODEF:mode>_3_i387"
13556 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13557 (match_operator:MODEF 3 "binary_fp_operator"
13558 [(match_operand:MODEF 1 "register_operand" "0,0")
13560 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13561 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13562 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13563 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13564 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13565 [(set (attr "type")
13566 (cond [(match_operand:MODEF 3 "mult_operator" "")
13567 (const_string "fmul")
13568 (match_operand:MODEF 3 "div_operator" "")
13569 (const_string "fdiv")
13571 (const_string "fop")))
13572 (set_attr "fp_int_src" "true")
13573 (set_attr "mode" "<MODE>")])
13575 (define_insn "*fop_df_4_i387"
13576 [(set (match_operand:DF 0 "register_operand" "=f,f")
13577 (match_operator:DF 3 "binary_fp_operator"
13579 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13580 (match_operand:DF 2 "register_operand" "0,f")]))]
13581 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13582 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13583 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13584 "* return output_387_binary_op (insn, operands);"
13585 [(set (attr "type")
13586 (cond [(match_operand:DF 3 "mult_operator" "")
13587 (const_string "fmul")
13588 (match_operand:DF 3 "div_operator" "")
13589 (const_string "fdiv")
13591 (const_string "fop")))
13592 (set_attr "mode" "SF")])
13594 (define_insn "*fop_df_5_i387"
13595 [(set (match_operand:DF 0 "register_operand" "=f,f")
13596 (match_operator:DF 3 "binary_fp_operator"
13597 [(match_operand:DF 1 "register_operand" "0,f")
13599 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13600 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13601 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13602 "* return output_387_binary_op (insn, operands);"
13603 [(set (attr "type")
13604 (cond [(match_operand:DF 3 "mult_operator" "")
13605 (const_string "fmul")
13606 (match_operand:DF 3 "div_operator" "")
13607 (const_string "fdiv")
13609 (const_string "fop")))
13610 (set_attr "mode" "SF")])
13612 (define_insn "*fop_df_6_i387"
13613 [(set (match_operand:DF 0 "register_operand" "=f,f")
13614 (match_operator:DF 3 "binary_fp_operator"
13616 (match_operand:SF 1 "register_operand" "0,f"))
13618 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13619 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13620 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13621 "* return output_387_binary_op (insn, operands);"
13622 [(set (attr "type")
13623 (cond [(match_operand:DF 3 "mult_operator" "")
13624 (const_string "fmul")
13625 (match_operand:DF 3 "div_operator" "")
13626 (const_string "fdiv")
13628 (const_string "fop")))
13629 (set_attr "mode" "SF")])
13631 (define_insn "*fop_xf_comm_i387"
13632 [(set (match_operand:XF 0 "register_operand" "=f")
13633 (match_operator:XF 3 "binary_fp_operator"
13634 [(match_operand:XF 1 "register_operand" "%0")
13635 (match_operand:XF 2 "register_operand" "f")]))]
13637 && COMMUTATIVE_ARITH_P (operands[3])"
13638 "* return output_387_binary_op (insn, operands);"
13639 [(set (attr "type")
13640 (if_then_else (match_operand:XF 3 "mult_operator" "")
13641 (const_string "fmul")
13642 (const_string "fop")))
13643 (set_attr "mode" "XF")])
13645 (define_insn "*fop_xf_1_i387"
13646 [(set (match_operand:XF 0 "register_operand" "=f,f")
13647 (match_operator:XF 3 "binary_fp_operator"
13648 [(match_operand:XF 1 "register_operand" "0,f")
13649 (match_operand:XF 2 "register_operand" "f,0")]))]
13651 && !COMMUTATIVE_ARITH_P (operands[3])"
13652 "* return output_387_binary_op (insn, operands);"
13653 [(set (attr "type")
13654 (cond [(match_operand:XF 3 "mult_operator" "")
13655 (const_string "fmul")
13656 (match_operand:XF 3 "div_operator" "")
13657 (const_string "fdiv")
13659 (const_string "fop")))
13660 (set_attr "mode" "XF")])
13662 (define_insn "*fop_xf_2_i387"
13663 [(set (match_operand:XF 0 "register_operand" "=f,f")
13664 (match_operator:XF 3 "binary_fp_operator"
13666 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13667 (match_operand:XF 2 "register_operand" "0,0")]))]
13668 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13669 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13670 [(set (attr "type")
13671 (cond [(match_operand:XF 3 "mult_operator" "")
13672 (const_string "fmul")
13673 (match_operand:XF 3 "div_operator" "")
13674 (const_string "fdiv")
13676 (const_string "fop")))
13677 (set_attr "fp_int_src" "true")
13678 (set_attr "mode" "<MODE>")])
13680 (define_insn "*fop_xf_3_i387"
13681 [(set (match_operand:XF 0 "register_operand" "=f,f")
13682 (match_operator:XF 3 "binary_fp_operator"
13683 [(match_operand:XF 1 "register_operand" "0,0")
13685 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13686 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13687 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13688 [(set (attr "type")
13689 (cond [(match_operand:XF 3 "mult_operator" "")
13690 (const_string "fmul")
13691 (match_operand:XF 3 "div_operator" "")
13692 (const_string "fdiv")
13694 (const_string "fop")))
13695 (set_attr "fp_int_src" "true")
13696 (set_attr "mode" "<MODE>")])
13698 (define_insn "*fop_xf_4_i387"
13699 [(set (match_operand:XF 0 "register_operand" "=f,f")
13700 (match_operator:XF 3 "binary_fp_operator"
13702 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13703 (match_operand:XF 2 "register_operand" "0,f")]))]
13705 "* return output_387_binary_op (insn, operands);"
13706 [(set (attr "type")
13707 (cond [(match_operand:XF 3 "mult_operator" "")
13708 (const_string "fmul")
13709 (match_operand:XF 3 "div_operator" "")
13710 (const_string "fdiv")
13712 (const_string "fop")))
13713 (set_attr "mode" "<MODE>")])
13715 (define_insn "*fop_xf_5_i387"
13716 [(set (match_operand:XF 0 "register_operand" "=f,f")
13717 (match_operator:XF 3 "binary_fp_operator"
13718 [(match_operand:XF 1 "register_operand" "0,f")
13720 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13722 "* return output_387_binary_op (insn, operands);"
13723 [(set (attr "type")
13724 (cond [(match_operand:XF 3 "mult_operator" "")
13725 (const_string "fmul")
13726 (match_operand:XF 3 "div_operator" "")
13727 (const_string "fdiv")
13729 (const_string "fop")))
13730 (set_attr "mode" "<MODE>")])
13732 (define_insn "*fop_xf_6_i387"
13733 [(set (match_operand:XF 0 "register_operand" "=f,f")
13734 (match_operator:XF 3 "binary_fp_operator"
13736 (match_operand:MODEF 1 "register_operand" "0,f"))
13738 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13740 "* return output_387_binary_op (insn, operands);"
13741 [(set (attr "type")
13742 (cond [(match_operand:XF 3 "mult_operator" "")
13743 (const_string "fmul")
13744 (match_operand:XF 3 "div_operator" "")
13745 (const_string "fdiv")
13747 (const_string "fop")))
13748 (set_attr "mode" "<MODE>")])
13751 [(set (match_operand 0 "register_operand" "")
13752 (match_operator 3 "binary_fp_operator"
13753 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13754 (match_operand 2 "register_operand" "")]))]
13756 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13757 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13760 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13761 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13762 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13763 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13764 GET_MODE (operands[3]),
13767 ix86_free_from_memory (GET_MODE (operands[1]));
13772 [(set (match_operand 0 "register_operand" "")
13773 (match_operator 3 "binary_fp_operator"
13774 [(match_operand 1 "register_operand" "")
13775 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13777 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13778 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13781 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13782 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13783 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13784 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13785 GET_MODE (operands[3]),
13788 ix86_free_from_memory (GET_MODE (operands[2]));
13792 ;; FPU special functions.
13794 ;; This pattern implements a no-op XFmode truncation for
13795 ;; all fancy i386 XFmode math functions.
13797 (define_insn "truncxf<mode>2_i387_noop_unspec"
13798 [(set (match_operand:MODEF 0 "register_operand" "=f")
13799 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13800 UNSPEC_TRUNC_NOOP))]
13801 "TARGET_USE_FANCY_MATH_387"
13802 "* return output_387_reg_move (insn, operands);"
13803 [(set_attr "type" "fmov")
13804 (set_attr "mode" "<MODE>")])
13806 (define_insn "sqrtxf2"
13807 [(set (match_operand:XF 0 "register_operand" "=f")
13808 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13809 "TARGET_USE_FANCY_MATH_387"
13811 [(set_attr "type" "fpspc")
13812 (set_attr "mode" "XF")
13813 (set_attr "athlon_decode" "direct")
13814 (set_attr "amdfam10_decode" "direct")])
13816 (define_insn "sqrt_extend<mode>xf2_i387"
13817 [(set (match_operand:XF 0 "register_operand" "=f")
13820 (match_operand:MODEF 1 "register_operand" "0"))))]
13821 "TARGET_USE_FANCY_MATH_387"
13823 [(set_attr "type" "fpspc")
13824 (set_attr "mode" "XF")
13825 (set_attr "athlon_decode" "direct")
13826 (set_attr "amdfam10_decode" "direct")])
13828 (define_insn "*rsqrtsf2_sse"
13829 [(set (match_operand:SF 0 "register_operand" "=x")
13830 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13833 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13834 [(set_attr "type" "sse")
13835 (set_attr "atom_sse_attr" "rcp")
13836 (set_attr "prefix" "maybe_vex")
13837 (set_attr "mode" "SF")])
13839 (define_expand "rsqrtsf2"
13840 [(set (match_operand:SF 0 "register_operand" "")
13841 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13845 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13849 (define_insn "*sqrt<mode>2_sse"
13850 [(set (match_operand:MODEF 0 "register_operand" "=x")
13852 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13853 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13854 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13855 [(set_attr "type" "sse")
13856 (set_attr "atom_sse_attr" "sqrt")
13857 (set_attr "prefix" "maybe_vex")
13858 (set_attr "mode" "<MODE>")
13859 (set_attr "athlon_decode" "*")
13860 (set_attr "amdfam10_decode" "*")])
13862 (define_expand "sqrt<mode>2"
13863 [(set (match_operand:MODEF 0 "register_operand" "")
13865 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13866 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13867 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13869 if (<MODE>mode == SFmode
13870 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13871 && flag_finite_math_only && !flag_trapping_math
13872 && flag_unsafe_math_optimizations)
13874 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13878 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13880 rtx op0 = gen_reg_rtx (XFmode);
13881 rtx op1 = force_reg (<MODE>mode, operands[1]);
13883 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13884 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13889 (define_insn "fpremxf4_i387"
13890 [(set (match_operand:XF 0 "register_operand" "=f")
13891 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13892 (match_operand:XF 3 "register_operand" "1")]
13894 (set (match_operand:XF 1 "register_operand" "=u")
13895 (unspec:XF [(match_dup 2) (match_dup 3)]
13897 (set (reg:CCFP FPSR_REG)
13898 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13900 "TARGET_USE_FANCY_MATH_387"
13902 [(set_attr "type" "fpspc")
13903 (set_attr "mode" "XF")])
13905 (define_expand "fmodxf3"
13906 [(use (match_operand:XF 0 "register_operand" ""))
13907 (use (match_operand:XF 1 "general_operand" ""))
13908 (use (match_operand:XF 2 "general_operand" ""))]
13909 "TARGET_USE_FANCY_MATH_387"
13911 rtx label = gen_label_rtx ();
13913 rtx op1 = gen_reg_rtx (XFmode);
13914 rtx op2 = gen_reg_rtx (XFmode);
13916 emit_move_insn (op2, operands[2]);
13917 emit_move_insn (op1, operands[1]);
13919 emit_label (label);
13920 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13921 ix86_emit_fp_unordered_jump (label);
13922 LABEL_NUSES (label) = 1;
13924 emit_move_insn (operands[0], op1);
13928 (define_expand "fmod<mode>3"
13929 [(use (match_operand:MODEF 0 "register_operand" ""))
13930 (use (match_operand:MODEF 1 "general_operand" ""))
13931 (use (match_operand:MODEF 2 "general_operand" ""))]
13932 "TARGET_USE_FANCY_MATH_387"
13934 rtx label = gen_label_rtx ();
13936 rtx op1 = gen_reg_rtx (XFmode);
13937 rtx op2 = gen_reg_rtx (XFmode);
13939 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13940 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13942 emit_label (label);
13943 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13944 ix86_emit_fp_unordered_jump (label);
13945 LABEL_NUSES (label) = 1;
13947 /* Truncate the result properly for strict SSE math. */
13948 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13949 && !TARGET_MIX_SSE_I387)
13950 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13952 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13957 (define_insn "fprem1xf4_i387"
13958 [(set (match_operand:XF 0 "register_operand" "=f")
13959 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13960 (match_operand:XF 3 "register_operand" "1")]
13962 (set (match_operand:XF 1 "register_operand" "=u")
13963 (unspec:XF [(match_dup 2) (match_dup 3)]
13965 (set (reg:CCFP FPSR_REG)
13966 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13968 "TARGET_USE_FANCY_MATH_387"
13970 [(set_attr "type" "fpspc")
13971 (set_attr "mode" "XF")])
13973 (define_expand "remainderxf3"
13974 [(use (match_operand:XF 0 "register_operand" ""))
13975 (use (match_operand:XF 1 "general_operand" ""))
13976 (use (match_operand:XF 2 "general_operand" ""))]
13977 "TARGET_USE_FANCY_MATH_387"
13979 rtx label = gen_label_rtx ();
13981 rtx op1 = gen_reg_rtx (XFmode);
13982 rtx op2 = gen_reg_rtx (XFmode);
13984 emit_move_insn (op2, operands[2]);
13985 emit_move_insn (op1, operands[1]);
13987 emit_label (label);
13988 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13989 ix86_emit_fp_unordered_jump (label);
13990 LABEL_NUSES (label) = 1;
13992 emit_move_insn (operands[0], op1);
13996 (define_expand "remainder<mode>3"
13997 [(use (match_operand:MODEF 0 "register_operand" ""))
13998 (use (match_operand:MODEF 1 "general_operand" ""))
13999 (use (match_operand:MODEF 2 "general_operand" ""))]
14000 "TARGET_USE_FANCY_MATH_387"
14002 rtx label = gen_label_rtx ();
14004 rtx op1 = gen_reg_rtx (XFmode);
14005 rtx op2 = gen_reg_rtx (XFmode);
14007 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14008 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14010 emit_label (label);
14012 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14013 ix86_emit_fp_unordered_jump (label);
14014 LABEL_NUSES (label) = 1;
14016 /* Truncate the result properly for strict SSE math. */
14017 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14018 && !TARGET_MIX_SSE_I387)
14019 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
14021 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
14026 (define_insn "*sinxf2_i387"
14027 [(set (match_operand:XF 0 "register_operand" "=f")
14028 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14029 "TARGET_USE_FANCY_MATH_387
14030 && flag_unsafe_math_optimizations"
14032 [(set_attr "type" "fpspc")
14033 (set_attr "mode" "XF")])
14035 (define_insn "*sin_extend<mode>xf2_i387"
14036 [(set (match_operand:XF 0 "register_operand" "=f")
14037 (unspec:XF [(float_extend:XF
14038 (match_operand:MODEF 1 "register_operand" "0"))]
14040 "TARGET_USE_FANCY_MATH_387
14041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14042 || TARGET_MIX_SSE_I387)
14043 && flag_unsafe_math_optimizations"
14045 [(set_attr "type" "fpspc")
14046 (set_attr "mode" "XF")])
14048 (define_insn "*cosxf2_i387"
14049 [(set (match_operand:XF 0 "register_operand" "=f")
14050 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14051 "TARGET_USE_FANCY_MATH_387
14052 && flag_unsafe_math_optimizations"
14054 [(set_attr "type" "fpspc")
14055 (set_attr "mode" "XF")])
14057 (define_insn "*cos_extend<mode>xf2_i387"
14058 [(set (match_operand:XF 0 "register_operand" "=f")
14059 (unspec:XF [(float_extend:XF
14060 (match_operand:MODEF 1 "register_operand" "0"))]
14062 "TARGET_USE_FANCY_MATH_387
14063 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14064 || TARGET_MIX_SSE_I387)
14065 && flag_unsafe_math_optimizations"
14067 [(set_attr "type" "fpspc")
14068 (set_attr "mode" "XF")])
14070 ;; When sincos pattern is defined, sin and cos builtin functions will be
14071 ;; expanded to sincos pattern with one of its outputs left unused.
14072 ;; CSE pass will figure out if two sincos patterns can be combined,
14073 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14074 ;; depending on the unused output.
14076 (define_insn "sincosxf3"
14077 [(set (match_operand:XF 0 "register_operand" "=f")
14078 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14079 UNSPEC_SINCOS_COS))
14080 (set (match_operand:XF 1 "register_operand" "=u")
14081 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14082 "TARGET_USE_FANCY_MATH_387
14083 && flag_unsafe_math_optimizations"
14085 [(set_attr "type" "fpspc")
14086 (set_attr "mode" "XF")])
14089 [(set (match_operand:XF 0 "register_operand" "")
14090 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14091 UNSPEC_SINCOS_COS))
14092 (set (match_operand:XF 1 "register_operand" "")
14093 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14094 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14095 && !(reload_completed || reload_in_progress)"
14096 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
14100 [(set (match_operand:XF 0 "register_operand" "")
14101 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14102 UNSPEC_SINCOS_COS))
14103 (set (match_operand:XF 1 "register_operand" "")
14104 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14105 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14106 && !(reload_completed || reload_in_progress)"
14107 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
14110 (define_insn "sincos_extend<mode>xf3_i387"
14111 [(set (match_operand:XF 0 "register_operand" "=f")
14112 (unspec:XF [(float_extend:XF
14113 (match_operand:MODEF 2 "register_operand" "0"))]
14114 UNSPEC_SINCOS_COS))
14115 (set (match_operand:XF 1 "register_operand" "=u")
14116 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14117 "TARGET_USE_FANCY_MATH_387
14118 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14119 || TARGET_MIX_SSE_I387)
14120 && flag_unsafe_math_optimizations"
14122 [(set_attr "type" "fpspc")
14123 (set_attr "mode" "XF")])
14126 [(set (match_operand:XF 0 "register_operand" "")
14127 (unspec:XF [(float_extend:XF
14128 (match_operand:MODEF 2 "register_operand" ""))]
14129 UNSPEC_SINCOS_COS))
14130 (set (match_operand:XF 1 "register_operand" "")
14131 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14132 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14133 && !(reload_completed || reload_in_progress)"
14134 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
14138 [(set (match_operand:XF 0 "register_operand" "")
14139 (unspec:XF [(float_extend:XF
14140 (match_operand:MODEF 2 "register_operand" ""))]
14141 UNSPEC_SINCOS_COS))
14142 (set (match_operand:XF 1 "register_operand" "")
14143 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14144 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14145 && !(reload_completed || reload_in_progress)"
14146 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
14149 (define_expand "sincos<mode>3"
14150 [(use (match_operand:MODEF 0 "register_operand" ""))
14151 (use (match_operand:MODEF 1 "register_operand" ""))
14152 (use (match_operand:MODEF 2 "register_operand" ""))]
14153 "TARGET_USE_FANCY_MATH_387
14154 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14155 || TARGET_MIX_SSE_I387)
14156 && flag_unsafe_math_optimizations"
14158 rtx op0 = gen_reg_rtx (XFmode);
14159 rtx op1 = gen_reg_rtx (XFmode);
14161 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14162 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14163 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14167 (define_insn "fptanxf4_i387"
14168 [(set (match_operand:XF 0 "register_operand" "=f")
14169 (match_operand:XF 3 "const_double_operand" "F"))
14170 (set (match_operand:XF 1 "register_operand" "=u")
14171 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14173 "TARGET_USE_FANCY_MATH_387
14174 && flag_unsafe_math_optimizations
14175 && standard_80387_constant_p (operands[3]) == 2"
14177 [(set_attr "type" "fpspc")
14178 (set_attr "mode" "XF")])
14180 (define_insn "fptan_extend<mode>xf4_i387"
14181 [(set (match_operand:MODEF 0 "register_operand" "=f")
14182 (match_operand:MODEF 3 "const_double_operand" "F"))
14183 (set (match_operand:XF 1 "register_operand" "=u")
14184 (unspec:XF [(float_extend:XF
14185 (match_operand:MODEF 2 "register_operand" "0"))]
14187 "TARGET_USE_FANCY_MATH_387
14188 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14189 || TARGET_MIX_SSE_I387)
14190 && flag_unsafe_math_optimizations
14191 && standard_80387_constant_p (operands[3]) == 2"
14193 [(set_attr "type" "fpspc")
14194 (set_attr "mode" "XF")])
14196 (define_expand "tanxf2"
14197 [(use (match_operand:XF 0 "register_operand" ""))
14198 (use (match_operand:XF 1 "register_operand" ""))]
14199 "TARGET_USE_FANCY_MATH_387
14200 && flag_unsafe_math_optimizations"
14202 rtx one = gen_reg_rtx (XFmode);
14203 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14205 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14209 (define_expand "tan<mode>2"
14210 [(use (match_operand:MODEF 0 "register_operand" ""))
14211 (use (match_operand:MODEF 1 "register_operand" ""))]
14212 "TARGET_USE_FANCY_MATH_387
14213 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14214 || TARGET_MIX_SSE_I387)
14215 && flag_unsafe_math_optimizations"
14217 rtx op0 = gen_reg_rtx (XFmode);
14219 rtx one = gen_reg_rtx (<MODE>mode);
14220 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14222 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14223 operands[1], op2));
14224 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14228 (define_insn "*fpatanxf3_i387"
14229 [(set (match_operand:XF 0 "register_operand" "=f")
14230 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14231 (match_operand:XF 2 "register_operand" "u")]
14233 (clobber (match_scratch:XF 3 "=2"))]
14234 "TARGET_USE_FANCY_MATH_387
14235 && flag_unsafe_math_optimizations"
14237 [(set_attr "type" "fpspc")
14238 (set_attr "mode" "XF")])
14240 (define_insn "fpatan_extend<mode>xf3_i387"
14241 [(set (match_operand:XF 0 "register_operand" "=f")
14242 (unspec:XF [(float_extend:XF
14243 (match_operand:MODEF 1 "register_operand" "0"))
14245 (match_operand:MODEF 2 "register_operand" "u"))]
14247 (clobber (match_scratch:XF 3 "=2"))]
14248 "TARGET_USE_FANCY_MATH_387
14249 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14250 || TARGET_MIX_SSE_I387)
14251 && flag_unsafe_math_optimizations"
14253 [(set_attr "type" "fpspc")
14254 (set_attr "mode" "XF")])
14256 (define_expand "atan2xf3"
14257 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14258 (unspec:XF [(match_operand:XF 2 "register_operand" "")
14259 (match_operand:XF 1 "register_operand" "")]
14261 (clobber (match_scratch:XF 3 ""))])]
14262 "TARGET_USE_FANCY_MATH_387
14263 && flag_unsafe_math_optimizations"
14266 (define_expand "atan2<mode>3"
14267 [(use (match_operand:MODEF 0 "register_operand" ""))
14268 (use (match_operand:MODEF 1 "register_operand" ""))
14269 (use (match_operand:MODEF 2 "register_operand" ""))]
14270 "TARGET_USE_FANCY_MATH_387
14271 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14272 || TARGET_MIX_SSE_I387)
14273 && flag_unsafe_math_optimizations"
14275 rtx op0 = gen_reg_rtx (XFmode);
14277 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14278 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14282 (define_expand "atanxf2"
14283 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14284 (unspec:XF [(match_dup 2)
14285 (match_operand:XF 1 "register_operand" "")]
14287 (clobber (match_scratch:XF 3 ""))])]
14288 "TARGET_USE_FANCY_MATH_387
14289 && flag_unsafe_math_optimizations"
14291 operands[2] = gen_reg_rtx (XFmode);
14292 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14295 (define_expand "atan<mode>2"
14296 [(use (match_operand:MODEF 0 "register_operand" ""))
14297 (use (match_operand:MODEF 1 "register_operand" ""))]
14298 "TARGET_USE_FANCY_MATH_387
14299 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14300 || TARGET_MIX_SSE_I387)
14301 && flag_unsafe_math_optimizations"
14303 rtx op0 = gen_reg_rtx (XFmode);
14305 rtx op2 = gen_reg_rtx (<MODE>mode);
14306 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14308 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14309 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14313 (define_expand "asinxf2"
14314 [(set (match_dup 2)
14315 (mult:XF (match_operand:XF 1 "register_operand" "")
14317 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14318 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14319 (parallel [(set (match_operand:XF 0 "register_operand" "")
14320 (unspec:XF [(match_dup 5) (match_dup 1)]
14322 (clobber (match_scratch:XF 6 ""))])]
14323 "TARGET_USE_FANCY_MATH_387
14324 && flag_unsafe_math_optimizations"
14328 if (optimize_insn_for_size_p ())
14331 for (i = 2; i < 6; i++)
14332 operands[i] = gen_reg_rtx (XFmode);
14334 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14337 (define_expand "asin<mode>2"
14338 [(use (match_operand:MODEF 0 "register_operand" ""))
14339 (use (match_operand:MODEF 1 "general_operand" ""))]
14340 "TARGET_USE_FANCY_MATH_387
14341 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14342 || TARGET_MIX_SSE_I387)
14343 && flag_unsafe_math_optimizations"
14345 rtx op0 = gen_reg_rtx (XFmode);
14346 rtx op1 = gen_reg_rtx (XFmode);
14348 if (optimize_insn_for_size_p ())
14351 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14352 emit_insn (gen_asinxf2 (op0, op1));
14353 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14357 (define_expand "acosxf2"
14358 [(set (match_dup 2)
14359 (mult:XF (match_operand:XF 1 "register_operand" "")
14361 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14362 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14363 (parallel [(set (match_operand:XF 0 "register_operand" "")
14364 (unspec:XF [(match_dup 1) (match_dup 5)]
14366 (clobber (match_scratch:XF 6 ""))])]
14367 "TARGET_USE_FANCY_MATH_387
14368 && flag_unsafe_math_optimizations"
14372 if (optimize_insn_for_size_p ())
14375 for (i = 2; i < 6; i++)
14376 operands[i] = gen_reg_rtx (XFmode);
14378 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14381 (define_expand "acos<mode>2"
14382 [(use (match_operand:MODEF 0 "register_operand" ""))
14383 (use (match_operand:MODEF 1 "general_operand" ""))]
14384 "TARGET_USE_FANCY_MATH_387
14385 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14386 || TARGET_MIX_SSE_I387)
14387 && flag_unsafe_math_optimizations"
14389 rtx op0 = gen_reg_rtx (XFmode);
14390 rtx op1 = gen_reg_rtx (XFmode);
14392 if (optimize_insn_for_size_p ())
14395 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14396 emit_insn (gen_acosxf2 (op0, op1));
14397 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14401 (define_insn "fyl2xxf3_i387"
14402 [(set (match_operand:XF 0 "register_operand" "=f")
14403 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14404 (match_operand:XF 2 "register_operand" "u")]
14406 (clobber (match_scratch:XF 3 "=2"))]
14407 "TARGET_USE_FANCY_MATH_387
14408 && flag_unsafe_math_optimizations"
14410 [(set_attr "type" "fpspc")
14411 (set_attr "mode" "XF")])
14413 (define_insn "fyl2x_extend<mode>xf3_i387"
14414 [(set (match_operand:XF 0 "register_operand" "=f")
14415 (unspec:XF [(float_extend:XF
14416 (match_operand:MODEF 1 "register_operand" "0"))
14417 (match_operand:XF 2 "register_operand" "u")]
14419 (clobber (match_scratch:XF 3 "=2"))]
14420 "TARGET_USE_FANCY_MATH_387
14421 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14422 || TARGET_MIX_SSE_I387)
14423 && flag_unsafe_math_optimizations"
14425 [(set_attr "type" "fpspc")
14426 (set_attr "mode" "XF")])
14428 (define_expand "logxf2"
14429 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14430 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14431 (match_dup 2)] UNSPEC_FYL2X))
14432 (clobber (match_scratch:XF 3 ""))])]
14433 "TARGET_USE_FANCY_MATH_387
14434 && flag_unsafe_math_optimizations"
14436 operands[2] = gen_reg_rtx (XFmode);
14437 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14440 (define_expand "log<mode>2"
14441 [(use (match_operand:MODEF 0 "register_operand" ""))
14442 (use (match_operand:MODEF 1 "register_operand" ""))]
14443 "TARGET_USE_FANCY_MATH_387
14444 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14445 || TARGET_MIX_SSE_I387)
14446 && flag_unsafe_math_optimizations"
14448 rtx op0 = gen_reg_rtx (XFmode);
14450 rtx op2 = gen_reg_rtx (XFmode);
14451 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14453 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14454 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14458 (define_expand "log10xf2"
14459 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14460 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14461 (match_dup 2)] UNSPEC_FYL2X))
14462 (clobber (match_scratch:XF 3 ""))])]
14463 "TARGET_USE_FANCY_MATH_387
14464 && flag_unsafe_math_optimizations"
14466 operands[2] = gen_reg_rtx (XFmode);
14467 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14470 (define_expand "log10<mode>2"
14471 [(use (match_operand:MODEF 0 "register_operand" ""))
14472 (use (match_operand:MODEF 1 "register_operand" ""))]
14473 "TARGET_USE_FANCY_MATH_387
14474 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14475 || TARGET_MIX_SSE_I387)
14476 && flag_unsafe_math_optimizations"
14478 rtx op0 = gen_reg_rtx (XFmode);
14480 rtx op2 = gen_reg_rtx (XFmode);
14481 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14483 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14484 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14488 (define_expand "log2xf2"
14489 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14490 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14491 (match_dup 2)] UNSPEC_FYL2X))
14492 (clobber (match_scratch:XF 3 ""))])]
14493 "TARGET_USE_FANCY_MATH_387
14494 && flag_unsafe_math_optimizations"
14496 operands[2] = gen_reg_rtx (XFmode);
14497 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14500 (define_expand "log2<mode>2"
14501 [(use (match_operand:MODEF 0 "register_operand" ""))
14502 (use (match_operand:MODEF 1 "register_operand" ""))]
14503 "TARGET_USE_FANCY_MATH_387
14504 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14505 || TARGET_MIX_SSE_I387)
14506 && flag_unsafe_math_optimizations"
14508 rtx op0 = gen_reg_rtx (XFmode);
14510 rtx op2 = gen_reg_rtx (XFmode);
14511 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14513 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14514 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14518 (define_insn "fyl2xp1xf3_i387"
14519 [(set (match_operand:XF 0 "register_operand" "=f")
14520 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14521 (match_operand:XF 2 "register_operand" "u")]
14523 (clobber (match_scratch:XF 3 "=2"))]
14524 "TARGET_USE_FANCY_MATH_387
14525 && flag_unsafe_math_optimizations"
14527 [(set_attr "type" "fpspc")
14528 (set_attr "mode" "XF")])
14530 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14531 [(set (match_operand:XF 0 "register_operand" "=f")
14532 (unspec:XF [(float_extend:XF
14533 (match_operand:MODEF 1 "register_operand" "0"))
14534 (match_operand:XF 2 "register_operand" "u")]
14536 (clobber (match_scratch:XF 3 "=2"))]
14537 "TARGET_USE_FANCY_MATH_387
14538 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14539 || TARGET_MIX_SSE_I387)
14540 && flag_unsafe_math_optimizations"
14542 [(set_attr "type" "fpspc")
14543 (set_attr "mode" "XF")])
14545 (define_expand "log1pxf2"
14546 [(use (match_operand:XF 0 "register_operand" ""))
14547 (use (match_operand:XF 1 "register_operand" ""))]
14548 "TARGET_USE_FANCY_MATH_387
14549 && flag_unsafe_math_optimizations"
14551 if (optimize_insn_for_size_p ())
14554 ix86_emit_i387_log1p (operands[0], operands[1]);
14558 (define_expand "log1p<mode>2"
14559 [(use (match_operand:MODEF 0 "register_operand" ""))
14560 (use (match_operand:MODEF 1 "register_operand" ""))]
14561 "TARGET_USE_FANCY_MATH_387
14562 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14563 || TARGET_MIX_SSE_I387)
14564 && flag_unsafe_math_optimizations"
14568 if (optimize_insn_for_size_p ())
14571 op0 = gen_reg_rtx (XFmode);
14573 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14575 ix86_emit_i387_log1p (op0, operands[1]);
14576 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14580 (define_insn "fxtractxf3_i387"
14581 [(set (match_operand:XF 0 "register_operand" "=f")
14582 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14583 UNSPEC_XTRACT_FRACT))
14584 (set (match_operand:XF 1 "register_operand" "=u")
14585 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14586 "TARGET_USE_FANCY_MATH_387
14587 && flag_unsafe_math_optimizations"
14589 [(set_attr "type" "fpspc")
14590 (set_attr "mode" "XF")])
14592 (define_insn "fxtract_extend<mode>xf3_i387"
14593 [(set (match_operand:XF 0 "register_operand" "=f")
14594 (unspec:XF [(float_extend:XF
14595 (match_operand:MODEF 2 "register_operand" "0"))]
14596 UNSPEC_XTRACT_FRACT))
14597 (set (match_operand:XF 1 "register_operand" "=u")
14598 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14599 "TARGET_USE_FANCY_MATH_387
14600 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14601 || TARGET_MIX_SSE_I387)
14602 && flag_unsafe_math_optimizations"
14604 [(set_attr "type" "fpspc")
14605 (set_attr "mode" "XF")])
14607 (define_expand "logbxf2"
14608 [(parallel [(set (match_dup 2)
14609 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14610 UNSPEC_XTRACT_FRACT))
14611 (set (match_operand:XF 0 "register_operand" "")
14612 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14613 "TARGET_USE_FANCY_MATH_387
14614 && flag_unsafe_math_optimizations"
14616 operands[2] = gen_reg_rtx (XFmode);
14619 (define_expand "logb<mode>2"
14620 [(use (match_operand:MODEF 0 "register_operand" ""))
14621 (use (match_operand:MODEF 1 "register_operand" ""))]
14622 "TARGET_USE_FANCY_MATH_387
14623 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14624 || TARGET_MIX_SSE_I387)
14625 && flag_unsafe_math_optimizations"
14627 rtx op0 = gen_reg_rtx (XFmode);
14628 rtx op1 = gen_reg_rtx (XFmode);
14630 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14631 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14635 (define_expand "ilogbxf2"
14636 [(use (match_operand:SI 0 "register_operand" ""))
14637 (use (match_operand:XF 1 "register_operand" ""))]
14638 "TARGET_USE_FANCY_MATH_387
14639 && flag_unsafe_math_optimizations"
14643 if (optimize_insn_for_size_p ())
14646 op0 = gen_reg_rtx (XFmode);
14647 op1 = gen_reg_rtx (XFmode);
14649 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14650 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14654 (define_expand "ilogb<mode>2"
14655 [(use (match_operand:SI 0 "register_operand" ""))
14656 (use (match_operand:MODEF 1 "register_operand" ""))]
14657 "TARGET_USE_FANCY_MATH_387
14658 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14659 || TARGET_MIX_SSE_I387)
14660 && flag_unsafe_math_optimizations"
14664 if (optimize_insn_for_size_p ())
14667 op0 = gen_reg_rtx (XFmode);
14668 op1 = gen_reg_rtx (XFmode);
14670 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14671 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14675 (define_insn "*f2xm1xf2_i387"
14676 [(set (match_operand:XF 0 "register_operand" "=f")
14677 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14679 "TARGET_USE_FANCY_MATH_387
14680 && flag_unsafe_math_optimizations"
14682 [(set_attr "type" "fpspc")
14683 (set_attr "mode" "XF")])
14685 (define_insn "*fscalexf4_i387"
14686 [(set (match_operand:XF 0 "register_operand" "=f")
14687 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14688 (match_operand:XF 3 "register_operand" "1")]
14689 UNSPEC_FSCALE_FRACT))
14690 (set (match_operand:XF 1 "register_operand" "=u")
14691 (unspec:XF [(match_dup 2) (match_dup 3)]
14692 UNSPEC_FSCALE_EXP))]
14693 "TARGET_USE_FANCY_MATH_387
14694 && flag_unsafe_math_optimizations"
14696 [(set_attr "type" "fpspc")
14697 (set_attr "mode" "XF")])
14699 (define_expand "expNcorexf3"
14700 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14701 (match_operand:XF 2 "register_operand" "")))
14702 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14703 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14704 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14705 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14706 (parallel [(set (match_operand:XF 0 "register_operand" "")
14707 (unspec:XF [(match_dup 8) (match_dup 4)]
14708 UNSPEC_FSCALE_FRACT))
14710 (unspec:XF [(match_dup 8) (match_dup 4)]
14711 UNSPEC_FSCALE_EXP))])]
14712 "TARGET_USE_FANCY_MATH_387
14713 && flag_unsafe_math_optimizations"
14717 if (optimize_insn_for_size_p ())
14720 for (i = 3; i < 10; i++)
14721 operands[i] = gen_reg_rtx (XFmode);
14723 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14726 (define_expand "expxf2"
14727 [(use (match_operand:XF 0 "register_operand" ""))
14728 (use (match_operand:XF 1 "register_operand" ""))]
14729 "TARGET_USE_FANCY_MATH_387
14730 && flag_unsafe_math_optimizations"
14734 if (optimize_insn_for_size_p ())
14737 op2 = gen_reg_rtx (XFmode);
14738 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14740 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14744 (define_expand "exp<mode>2"
14745 [(use (match_operand:MODEF 0 "register_operand" ""))
14746 (use (match_operand:MODEF 1 "general_operand" ""))]
14747 "TARGET_USE_FANCY_MATH_387
14748 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14749 || TARGET_MIX_SSE_I387)
14750 && flag_unsafe_math_optimizations"
14754 if (optimize_insn_for_size_p ())
14757 op0 = gen_reg_rtx (XFmode);
14758 op1 = gen_reg_rtx (XFmode);
14760 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14761 emit_insn (gen_expxf2 (op0, op1));
14762 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14766 (define_expand "exp10xf2"
14767 [(use (match_operand:XF 0 "register_operand" ""))
14768 (use (match_operand:XF 1 "register_operand" ""))]
14769 "TARGET_USE_FANCY_MATH_387
14770 && flag_unsafe_math_optimizations"
14774 if (optimize_insn_for_size_p ())
14777 op2 = gen_reg_rtx (XFmode);
14778 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14780 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14784 (define_expand "exp10<mode>2"
14785 [(use (match_operand:MODEF 0 "register_operand" ""))
14786 (use (match_operand:MODEF 1 "general_operand" ""))]
14787 "TARGET_USE_FANCY_MATH_387
14788 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14789 || TARGET_MIX_SSE_I387)
14790 && flag_unsafe_math_optimizations"
14794 if (optimize_insn_for_size_p ())
14797 op0 = gen_reg_rtx (XFmode);
14798 op1 = gen_reg_rtx (XFmode);
14800 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14801 emit_insn (gen_exp10xf2 (op0, op1));
14802 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14806 (define_expand "exp2xf2"
14807 [(use (match_operand:XF 0 "register_operand" ""))
14808 (use (match_operand:XF 1 "register_operand" ""))]
14809 "TARGET_USE_FANCY_MATH_387
14810 && flag_unsafe_math_optimizations"
14814 if (optimize_insn_for_size_p ())
14817 op2 = gen_reg_rtx (XFmode);
14818 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14820 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14824 (define_expand "exp2<mode>2"
14825 [(use (match_operand:MODEF 0 "register_operand" ""))
14826 (use (match_operand:MODEF 1 "general_operand" ""))]
14827 "TARGET_USE_FANCY_MATH_387
14828 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14829 || TARGET_MIX_SSE_I387)
14830 && flag_unsafe_math_optimizations"
14834 if (optimize_insn_for_size_p ())
14837 op0 = gen_reg_rtx (XFmode);
14838 op1 = gen_reg_rtx (XFmode);
14840 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14841 emit_insn (gen_exp2xf2 (op0, op1));
14842 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14846 (define_expand "expm1xf2"
14847 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14849 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14850 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14851 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14852 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14853 (parallel [(set (match_dup 7)
14854 (unspec:XF [(match_dup 6) (match_dup 4)]
14855 UNSPEC_FSCALE_FRACT))
14857 (unspec:XF [(match_dup 6) (match_dup 4)]
14858 UNSPEC_FSCALE_EXP))])
14859 (parallel [(set (match_dup 10)
14860 (unspec:XF [(match_dup 9) (match_dup 8)]
14861 UNSPEC_FSCALE_FRACT))
14862 (set (match_dup 11)
14863 (unspec:XF [(match_dup 9) (match_dup 8)]
14864 UNSPEC_FSCALE_EXP))])
14865 (set (match_dup 12) (minus:XF (match_dup 10)
14866 (float_extend:XF (match_dup 13))))
14867 (set (match_operand:XF 0 "register_operand" "")
14868 (plus:XF (match_dup 12) (match_dup 7)))]
14869 "TARGET_USE_FANCY_MATH_387
14870 && flag_unsafe_math_optimizations"
14874 if (optimize_insn_for_size_p ())
14877 for (i = 2; i < 13; i++)
14878 operands[i] = gen_reg_rtx (XFmode);
14881 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14883 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14886 (define_expand "expm1<mode>2"
14887 [(use (match_operand:MODEF 0 "register_operand" ""))
14888 (use (match_operand:MODEF 1 "general_operand" ""))]
14889 "TARGET_USE_FANCY_MATH_387
14890 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14891 || TARGET_MIX_SSE_I387)
14892 && flag_unsafe_math_optimizations"
14896 if (optimize_insn_for_size_p ())
14899 op0 = gen_reg_rtx (XFmode);
14900 op1 = gen_reg_rtx (XFmode);
14902 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14903 emit_insn (gen_expm1xf2 (op0, op1));
14904 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14908 (define_expand "ldexpxf3"
14909 [(set (match_dup 3)
14910 (float:XF (match_operand:SI 2 "register_operand" "")))
14911 (parallel [(set (match_operand:XF 0 " register_operand" "")
14912 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14914 UNSPEC_FSCALE_FRACT))
14916 (unspec:XF [(match_dup 1) (match_dup 3)]
14917 UNSPEC_FSCALE_EXP))])]
14918 "TARGET_USE_FANCY_MATH_387
14919 && flag_unsafe_math_optimizations"
14921 if (optimize_insn_for_size_p ())
14924 operands[3] = gen_reg_rtx (XFmode);
14925 operands[4] = gen_reg_rtx (XFmode);
14928 (define_expand "ldexp<mode>3"
14929 [(use (match_operand:MODEF 0 "register_operand" ""))
14930 (use (match_operand:MODEF 1 "general_operand" ""))
14931 (use (match_operand:SI 2 "register_operand" ""))]
14932 "TARGET_USE_FANCY_MATH_387
14933 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14934 || TARGET_MIX_SSE_I387)
14935 && flag_unsafe_math_optimizations"
14939 if (optimize_insn_for_size_p ())
14942 op0 = gen_reg_rtx (XFmode);
14943 op1 = gen_reg_rtx (XFmode);
14945 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14946 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14947 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14951 (define_expand "scalbxf3"
14952 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14953 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14954 (match_operand:XF 2 "register_operand" "")]
14955 UNSPEC_FSCALE_FRACT))
14957 (unspec:XF [(match_dup 1) (match_dup 2)]
14958 UNSPEC_FSCALE_EXP))])]
14959 "TARGET_USE_FANCY_MATH_387
14960 && flag_unsafe_math_optimizations"
14962 if (optimize_insn_for_size_p ())
14965 operands[3] = gen_reg_rtx (XFmode);
14968 (define_expand "scalb<mode>3"
14969 [(use (match_operand:MODEF 0 "register_operand" ""))
14970 (use (match_operand:MODEF 1 "general_operand" ""))
14971 (use (match_operand:MODEF 2 "general_operand" ""))]
14972 "TARGET_USE_FANCY_MATH_387
14973 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14974 || TARGET_MIX_SSE_I387)
14975 && flag_unsafe_math_optimizations"
14979 if (optimize_insn_for_size_p ())
14982 op0 = gen_reg_rtx (XFmode);
14983 op1 = gen_reg_rtx (XFmode);
14984 op2 = gen_reg_rtx (XFmode);
14986 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14987 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14988 emit_insn (gen_scalbxf3 (op0, op1, op2));
14989 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14993 (define_expand "significandxf2"
14994 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14995 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14996 UNSPEC_XTRACT_FRACT))
14998 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14999 "TARGET_USE_FANCY_MATH_387
15000 && flag_unsafe_math_optimizations"
15002 operands[2] = gen_reg_rtx (XFmode);
15005 (define_expand "significand<mode>2"
15006 [(use (match_operand:MODEF 0 "register_operand" ""))
15007 (use (match_operand:MODEF 1 "register_operand" ""))]
15008 "TARGET_USE_FANCY_MATH_387
15009 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15010 || TARGET_MIX_SSE_I387)
15011 && flag_unsafe_math_optimizations"
15013 rtx op0 = gen_reg_rtx (XFmode);
15014 rtx op1 = gen_reg_rtx (XFmode);
15016 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15017 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15022 (define_insn "sse4_1_round<mode>2"
15023 [(set (match_operand:MODEF 0 "register_operand" "=x")
15024 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15025 (match_operand:SI 2 "const_0_to_15_operand" "n")]
15028 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15029 [(set_attr "type" "ssecvt")
15030 (set_attr "prefix_extra" "1")
15031 (set_attr "prefix" "maybe_vex")
15032 (set_attr "mode" "<MODE>")])
15034 (define_insn "rintxf2"
15035 [(set (match_operand:XF 0 "register_operand" "=f")
15036 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15038 "TARGET_USE_FANCY_MATH_387
15039 && flag_unsafe_math_optimizations"
15041 [(set_attr "type" "fpspc")
15042 (set_attr "mode" "XF")])
15044 (define_expand "rint<mode>2"
15045 [(use (match_operand:MODEF 0 "register_operand" ""))
15046 (use (match_operand:MODEF 1 "register_operand" ""))]
15047 "(TARGET_USE_FANCY_MATH_387
15048 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15049 || TARGET_MIX_SSE_I387)
15050 && flag_unsafe_math_optimizations)
15051 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15052 && !flag_trapping_math)"
15054 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15055 && !flag_trapping_math)
15057 if (!TARGET_ROUND && optimize_insn_for_size_p ())
15060 emit_insn (gen_sse4_1_round<mode>2
15061 (operands[0], operands[1], GEN_INT (0x04)));
15063 ix86_expand_rint (operand0, operand1);
15067 rtx op0 = gen_reg_rtx (XFmode);
15068 rtx op1 = gen_reg_rtx (XFmode);
15070 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15071 emit_insn (gen_rintxf2 (op0, op1));
15073 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15078 (define_expand "round<mode>2"
15079 [(match_operand:MODEF 0 "register_operand" "")
15080 (match_operand:MODEF 1 "nonimmediate_operand" "")]
15081 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15082 && !flag_trapping_math && !flag_rounding_math"
15084 if (optimize_insn_for_size_p ())
15086 if (TARGET_64BIT || (<MODE>mode != DFmode))
15087 ix86_expand_round (operand0, operand1);
15089 ix86_expand_rounddf_32 (operand0, operand1);
15093 (define_insn_and_split "*fistdi2_1"
15094 [(set (match_operand:DI 0 "nonimmediate_operand" "")
15095 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15097 "TARGET_USE_FANCY_MATH_387
15098 && can_create_pseudo_p ()"
15103 if (memory_operand (operands[0], VOIDmode))
15104 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15107 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15108 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15113 [(set_attr "type" "fpspc")
15114 (set_attr "mode" "DI")])
15116 (define_insn "fistdi2"
15117 [(set (match_operand:DI 0 "memory_operand" "=m")
15118 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15120 (clobber (match_scratch:XF 2 "=&1f"))]
15121 "TARGET_USE_FANCY_MATH_387"
15122 "* return output_fix_trunc (insn, operands, 0);"
15123 [(set_attr "type" "fpspc")
15124 (set_attr "mode" "DI")])
15126 (define_insn "fistdi2_with_temp"
15127 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15128 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15130 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15131 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15132 "TARGET_USE_FANCY_MATH_387"
15134 [(set_attr "type" "fpspc")
15135 (set_attr "mode" "DI")])
15138 [(set (match_operand:DI 0 "register_operand" "")
15139 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15141 (clobber (match_operand:DI 2 "memory_operand" ""))
15142 (clobber (match_scratch 3 ""))]
15144 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15145 (clobber (match_dup 3))])
15146 (set (match_dup 0) (match_dup 2))]
15150 [(set (match_operand:DI 0 "memory_operand" "")
15151 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15153 (clobber (match_operand:DI 2 "memory_operand" ""))
15154 (clobber (match_scratch 3 ""))]
15156 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15157 (clobber (match_dup 3))])]
15160 (define_insn_and_split "*fist<mode>2_1"
15161 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15162 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15164 "TARGET_USE_FANCY_MATH_387
15165 && can_create_pseudo_p ()"
15170 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15171 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15175 [(set_attr "type" "fpspc")
15176 (set_attr "mode" "<MODE>")])
15178 (define_insn "fist<mode>2"
15179 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15180 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15182 "TARGET_USE_FANCY_MATH_387"
15183 "* return output_fix_trunc (insn, operands, 0);"
15184 [(set_attr "type" "fpspc")
15185 (set_attr "mode" "<MODE>")])
15187 (define_insn "fist<mode>2_with_temp"
15188 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
15189 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15191 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
15192 "TARGET_USE_FANCY_MATH_387"
15194 [(set_attr "type" "fpspc")
15195 (set_attr "mode" "<MODE>")])
15198 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15199 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15201 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
15203 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
15204 (set (match_dup 0) (match_dup 2))]
15208 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15209 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15211 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
15213 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
15216 (define_expand "lrintxf<mode>2"
15217 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15218 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15220 "TARGET_USE_FANCY_MATH_387"
15223 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
15224 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
15225 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
15226 UNSPEC_FIX_NOTRUNC))]
15227 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15228 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
15231 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
15232 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
15233 (match_operand:MODEF 1 "register_operand" "")]
15234 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15235 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
15236 && !flag_trapping_math && !flag_rounding_math"
15238 if (optimize_insn_for_size_p ())
15240 ix86_expand_lround (operand0, operand1);
15244 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15245 (define_insn_and_split "frndintxf2_floor"
15246 [(set (match_operand:XF 0 "register_operand" "")
15247 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15248 UNSPEC_FRNDINT_FLOOR))
15249 (clobber (reg:CC FLAGS_REG))]
15250 "TARGET_USE_FANCY_MATH_387
15251 && flag_unsafe_math_optimizations
15252 && can_create_pseudo_p ()"
15257 ix86_optimize_mode_switching[I387_FLOOR] = 1;
15259 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15260 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
15262 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
15263 operands[2], operands[3]));
15266 [(set_attr "type" "frndint")
15267 (set_attr "i387_cw" "floor")
15268 (set_attr "mode" "XF")])
15270 (define_insn "frndintxf2_floor_i387"
15271 [(set (match_operand:XF 0 "register_operand" "=f")
15272 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15273 UNSPEC_FRNDINT_FLOOR))
15274 (use (match_operand:HI 2 "memory_operand" "m"))
15275 (use (match_operand:HI 3 "memory_operand" "m"))]
15276 "TARGET_USE_FANCY_MATH_387
15277 && flag_unsafe_math_optimizations"
15278 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15279 [(set_attr "type" "frndint")
15280 (set_attr "i387_cw" "floor")
15281 (set_attr "mode" "XF")])
15283 (define_expand "floorxf2"
15284 [(use (match_operand:XF 0 "register_operand" ""))
15285 (use (match_operand:XF 1 "register_operand" ""))]
15286 "TARGET_USE_FANCY_MATH_387
15287 && flag_unsafe_math_optimizations"
15289 if (optimize_insn_for_size_p ())
15291 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
15295 (define_expand "floor<mode>2"
15296 [(use (match_operand:MODEF 0 "register_operand" ""))
15297 (use (match_operand:MODEF 1 "register_operand" ""))]
15298 "(TARGET_USE_FANCY_MATH_387
15299 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15300 || TARGET_MIX_SSE_I387)
15301 && flag_unsafe_math_optimizations)
15302 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15303 && !flag_trapping_math)"
15305 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15306 && !flag_trapping_math
15307 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15309 if (!TARGET_ROUND && optimize_insn_for_size_p ())
15312 emit_insn (gen_sse4_1_round<mode>2
15313 (operands[0], operands[1], GEN_INT (0x01)));
15314 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15315 ix86_expand_floorceil (operand0, operand1, true);
15317 ix86_expand_floorceildf_32 (operand0, operand1, true);
15323 if (optimize_insn_for_size_p ())
15326 op0 = gen_reg_rtx (XFmode);
15327 op1 = gen_reg_rtx (XFmode);
15328 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15329 emit_insn (gen_frndintxf2_floor (op0, op1));
15331 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15336 (define_insn_and_split "*fist<mode>2_floor_1"
15337 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15338 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15339 UNSPEC_FIST_FLOOR))
15340 (clobber (reg:CC FLAGS_REG))]
15341 "TARGET_USE_FANCY_MATH_387
15342 && flag_unsafe_math_optimizations
15343 && can_create_pseudo_p ()"
15348 ix86_optimize_mode_switching[I387_FLOOR] = 1;
15350 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15351 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
15352 if (memory_operand (operands[0], VOIDmode))
15353 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
15354 operands[2], operands[3]));
15357 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15358 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
15359 operands[2], operands[3],
15364 [(set_attr "type" "fistp")
15365 (set_attr "i387_cw" "floor")
15366 (set_attr "mode" "<MODE>")])
15368 (define_insn "fistdi2_floor"
15369 [(set (match_operand:DI 0 "memory_operand" "=m")
15370 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15371 UNSPEC_FIST_FLOOR))
15372 (use (match_operand:HI 2 "memory_operand" "m"))
15373 (use (match_operand:HI 3 "memory_operand" "m"))
15374 (clobber (match_scratch:XF 4 "=&1f"))]
15375 "TARGET_USE_FANCY_MATH_387
15376 && flag_unsafe_math_optimizations"
15377 "* return output_fix_trunc (insn, operands, 0);"
15378 [(set_attr "type" "fistp")
15379 (set_attr "i387_cw" "floor")
15380 (set_attr "mode" "DI")])
15382 (define_insn "fistdi2_floor_with_temp"
15383 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15384 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15385 UNSPEC_FIST_FLOOR))
15386 (use (match_operand:HI 2 "memory_operand" "m,m"))
15387 (use (match_operand:HI 3 "memory_operand" "m,m"))
15388 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15389 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15390 "TARGET_USE_FANCY_MATH_387
15391 && flag_unsafe_math_optimizations"
15393 [(set_attr "type" "fistp")
15394 (set_attr "i387_cw" "floor")
15395 (set_attr "mode" "DI")])
15398 [(set (match_operand:DI 0 "register_operand" "")
15399 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15400 UNSPEC_FIST_FLOOR))
15401 (use (match_operand:HI 2 "memory_operand" ""))
15402 (use (match_operand:HI 3 "memory_operand" ""))
15403 (clobber (match_operand:DI 4 "memory_operand" ""))
15404 (clobber (match_scratch 5 ""))]
15406 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15407 (use (match_dup 2))
15408 (use (match_dup 3))
15409 (clobber (match_dup 5))])
15410 (set (match_dup 0) (match_dup 4))]
15414 [(set (match_operand:DI 0 "memory_operand" "")
15415 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15416 UNSPEC_FIST_FLOOR))
15417 (use (match_operand:HI 2 "memory_operand" ""))
15418 (use (match_operand:HI 3 "memory_operand" ""))
15419 (clobber (match_operand:DI 4 "memory_operand" ""))
15420 (clobber (match_scratch 5 ""))]
15422 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15423 (use (match_dup 2))
15424 (use (match_dup 3))
15425 (clobber (match_dup 5))])]
15428 (define_insn "fist<mode>2_floor"
15429 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15430 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15431 UNSPEC_FIST_FLOOR))
15432 (use (match_operand:HI 2 "memory_operand" "m"))
15433 (use (match_operand:HI 3 "memory_operand" "m"))]
15434 "TARGET_USE_FANCY_MATH_387
15435 && flag_unsafe_math_optimizations"
15436 "* return output_fix_trunc (insn, operands, 0);"
15437 [(set_attr "type" "fistp")
15438 (set_attr "i387_cw" "floor")
15439 (set_attr "mode" "<MODE>")])
15441 (define_insn "fist<mode>2_floor_with_temp"
15442 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15443 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15444 UNSPEC_FIST_FLOOR))
15445 (use (match_operand:HI 2 "memory_operand" "m,m"))
15446 (use (match_operand:HI 3 "memory_operand" "m,m"))
15447 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15448 "TARGET_USE_FANCY_MATH_387
15449 && flag_unsafe_math_optimizations"
15451 [(set_attr "type" "fistp")
15452 (set_attr "i387_cw" "floor")
15453 (set_attr "mode" "<MODE>")])
15456 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15457 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15458 UNSPEC_FIST_FLOOR))
15459 (use (match_operand:HI 2 "memory_operand" ""))
15460 (use (match_operand:HI 3 "memory_operand" ""))
15461 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15463 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15464 UNSPEC_FIST_FLOOR))
15465 (use (match_dup 2))
15466 (use (match_dup 3))])
15467 (set (match_dup 0) (match_dup 4))]
15471 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15472 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15473 UNSPEC_FIST_FLOOR))
15474 (use (match_operand:HI 2 "memory_operand" ""))
15475 (use (match_operand:HI 3 "memory_operand" ""))
15476 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15478 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15479 UNSPEC_FIST_FLOOR))
15480 (use (match_dup 2))
15481 (use (match_dup 3))])]
15484 (define_expand "lfloorxf<mode>2"
15485 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15486 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15487 UNSPEC_FIST_FLOOR))
15488 (clobber (reg:CC FLAGS_REG))])]
15489 "TARGET_USE_FANCY_MATH_387
15490 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15491 && flag_unsafe_math_optimizations"
15494 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15495 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15496 (match_operand:MODEF 1 "register_operand" "")]
15497 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15498 && !flag_trapping_math"
15500 if (TARGET_64BIT && optimize_insn_for_size_p ())
15502 ix86_expand_lfloorceil (operand0, operand1, true);
15506 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15507 (define_insn_and_split "frndintxf2_ceil"
15508 [(set (match_operand:XF 0 "register_operand" "")
15509 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15510 UNSPEC_FRNDINT_CEIL))
15511 (clobber (reg:CC FLAGS_REG))]
15512 "TARGET_USE_FANCY_MATH_387
15513 && flag_unsafe_math_optimizations
15514 && can_create_pseudo_p ()"
15519 ix86_optimize_mode_switching[I387_CEIL] = 1;
15521 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15522 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15524 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15525 operands[2], operands[3]));
15528 [(set_attr "type" "frndint")
15529 (set_attr "i387_cw" "ceil")
15530 (set_attr "mode" "XF")])
15532 (define_insn "frndintxf2_ceil_i387"
15533 [(set (match_operand:XF 0 "register_operand" "=f")
15534 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15535 UNSPEC_FRNDINT_CEIL))
15536 (use (match_operand:HI 2 "memory_operand" "m"))
15537 (use (match_operand:HI 3 "memory_operand" "m"))]
15538 "TARGET_USE_FANCY_MATH_387
15539 && flag_unsafe_math_optimizations"
15540 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15541 [(set_attr "type" "frndint")
15542 (set_attr "i387_cw" "ceil")
15543 (set_attr "mode" "XF")])
15545 (define_expand "ceilxf2"
15546 [(use (match_operand:XF 0 "register_operand" ""))
15547 (use (match_operand:XF 1 "register_operand" ""))]
15548 "TARGET_USE_FANCY_MATH_387
15549 && flag_unsafe_math_optimizations"
15551 if (optimize_insn_for_size_p ())
15553 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15557 (define_expand "ceil<mode>2"
15558 [(use (match_operand:MODEF 0 "register_operand" ""))
15559 (use (match_operand:MODEF 1 "register_operand" ""))]
15560 "(TARGET_USE_FANCY_MATH_387
15561 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15562 || TARGET_MIX_SSE_I387)
15563 && flag_unsafe_math_optimizations)
15564 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15565 && !flag_trapping_math)"
15567 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15568 && !flag_trapping_math
15569 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15572 emit_insn (gen_sse4_1_round<mode>2
15573 (operands[0], operands[1], GEN_INT (0x02)));
15574 else if (optimize_insn_for_size_p ())
15576 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15577 ix86_expand_floorceil (operand0, operand1, false);
15579 ix86_expand_floorceildf_32 (operand0, operand1, false);
15585 if (optimize_insn_for_size_p ())
15588 op0 = gen_reg_rtx (XFmode);
15589 op1 = gen_reg_rtx (XFmode);
15590 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15591 emit_insn (gen_frndintxf2_ceil (op0, op1));
15593 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15598 (define_insn_and_split "*fist<mode>2_ceil_1"
15599 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15600 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15602 (clobber (reg:CC FLAGS_REG))]
15603 "TARGET_USE_FANCY_MATH_387
15604 && flag_unsafe_math_optimizations
15605 && can_create_pseudo_p ()"
15610 ix86_optimize_mode_switching[I387_CEIL] = 1;
15612 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15613 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15614 if (memory_operand (operands[0], VOIDmode))
15615 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15616 operands[2], operands[3]));
15619 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15620 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15621 operands[2], operands[3],
15626 [(set_attr "type" "fistp")
15627 (set_attr "i387_cw" "ceil")
15628 (set_attr "mode" "<MODE>")])
15630 (define_insn "fistdi2_ceil"
15631 [(set (match_operand:DI 0 "memory_operand" "=m")
15632 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15634 (use (match_operand:HI 2 "memory_operand" "m"))
15635 (use (match_operand:HI 3 "memory_operand" "m"))
15636 (clobber (match_scratch:XF 4 "=&1f"))]
15637 "TARGET_USE_FANCY_MATH_387
15638 && flag_unsafe_math_optimizations"
15639 "* return output_fix_trunc (insn, operands, 0);"
15640 [(set_attr "type" "fistp")
15641 (set_attr "i387_cw" "ceil")
15642 (set_attr "mode" "DI")])
15644 (define_insn "fistdi2_ceil_with_temp"
15645 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15646 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15648 (use (match_operand:HI 2 "memory_operand" "m,m"))
15649 (use (match_operand:HI 3 "memory_operand" "m,m"))
15650 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15651 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15652 "TARGET_USE_FANCY_MATH_387
15653 && flag_unsafe_math_optimizations"
15655 [(set_attr "type" "fistp")
15656 (set_attr "i387_cw" "ceil")
15657 (set_attr "mode" "DI")])
15660 [(set (match_operand:DI 0 "register_operand" "")
15661 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15663 (use (match_operand:HI 2 "memory_operand" ""))
15664 (use (match_operand:HI 3 "memory_operand" ""))
15665 (clobber (match_operand:DI 4 "memory_operand" ""))
15666 (clobber (match_scratch 5 ""))]
15668 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15669 (use (match_dup 2))
15670 (use (match_dup 3))
15671 (clobber (match_dup 5))])
15672 (set (match_dup 0) (match_dup 4))]
15676 [(set (match_operand:DI 0 "memory_operand" "")
15677 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15679 (use (match_operand:HI 2 "memory_operand" ""))
15680 (use (match_operand:HI 3 "memory_operand" ""))
15681 (clobber (match_operand:DI 4 "memory_operand" ""))
15682 (clobber (match_scratch 5 ""))]
15684 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15685 (use (match_dup 2))
15686 (use (match_dup 3))
15687 (clobber (match_dup 5))])]
15690 (define_insn "fist<mode>2_ceil"
15691 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15692 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15694 (use (match_operand:HI 2 "memory_operand" "m"))
15695 (use (match_operand:HI 3 "memory_operand" "m"))]
15696 "TARGET_USE_FANCY_MATH_387
15697 && flag_unsafe_math_optimizations"
15698 "* return output_fix_trunc (insn, operands, 0);"
15699 [(set_attr "type" "fistp")
15700 (set_attr "i387_cw" "ceil")
15701 (set_attr "mode" "<MODE>")])
15703 (define_insn "fist<mode>2_ceil_with_temp"
15704 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15705 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15707 (use (match_operand:HI 2 "memory_operand" "m,m"))
15708 (use (match_operand:HI 3 "memory_operand" "m,m"))
15709 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15710 "TARGET_USE_FANCY_MATH_387
15711 && flag_unsafe_math_optimizations"
15713 [(set_attr "type" "fistp")
15714 (set_attr "i387_cw" "ceil")
15715 (set_attr "mode" "<MODE>")])
15718 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15719 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15721 (use (match_operand:HI 2 "memory_operand" ""))
15722 (use (match_operand:HI 3 "memory_operand" ""))
15723 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15725 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15727 (use (match_dup 2))
15728 (use (match_dup 3))])
15729 (set (match_dup 0) (match_dup 4))]
15733 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15734 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15736 (use (match_operand:HI 2 "memory_operand" ""))
15737 (use (match_operand:HI 3 "memory_operand" ""))
15738 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15740 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15742 (use (match_dup 2))
15743 (use (match_dup 3))])]
15746 (define_expand "lceilxf<mode>2"
15747 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15748 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15750 (clobber (reg:CC FLAGS_REG))])]
15751 "TARGET_USE_FANCY_MATH_387
15752 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15753 && flag_unsafe_math_optimizations"
15756 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15757 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15758 (match_operand:MODEF 1 "register_operand" "")]
15759 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15760 && !flag_trapping_math"
15762 ix86_expand_lfloorceil (operand0, operand1, false);
15766 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15767 (define_insn_and_split "frndintxf2_trunc"
15768 [(set (match_operand:XF 0 "register_operand" "")
15769 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15770 UNSPEC_FRNDINT_TRUNC))
15771 (clobber (reg:CC FLAGS_REG))]
15772 "TARGET_USE_FANCY_MATH_387
15773 && flag_unsafe_math_optimizations
15774 && can_create_pseudo_p ()"
15779 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15781 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15782 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15784 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15785 operands[2], operands[3]));
15788 [(set_attr "type" "frndint")
15789 (set_attr "i387_cw" "trunc")
15790 (set_attr "mode" "XF")])
15792 (define_insn "frndintxf2_trunc_i387"
15793 [(set (match_operand:XF 0 "register_operand" "=f")
15794 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15795 UNSPEC_FRNDINT_TRUNC))
15796 (use (match_operand:HI 2 "memory_operand" "m"))
15797 (use (match_operand:HI 3 "memory_operand" "m"))]
15798 "TARGET_USE_FANCY_MATH_387
15799 && flag_unsafe_math_optimizations"
15800 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15801 [(set_attr "type" "frndint")
15802 (set_attr "i387_cw" "trunc")
15803 (set_attr "mode" "XF")])
15805 (define_expand "btruncxf2"
15806 [(use (match_operand:XF 0 "register_operand" ""))
15807 (use (match_operand:XF 1 "register_operand" ""))]
15808 "TARGET_USE_FANCY_MATH_387
15809 && flag_unsafe_math_optimizations"
15811 if (optimize_insn_for_size_p ())
15813 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15817 (define_expand "btrunc<mode>2"
15818 [(use (match_operand:MODEF 0 "register_operand" ""))
15819 (use (match_operand:MODEF 1 "register_operand" ""))]
15820 "(TARGET_USE_FANCY_MATH_387
15821 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15822 || TARGET_MIX_SSE_I387)
15823 && flag_unsafe_math_optimizations)
15824 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15825 && !flag_trapping_math)"
15827 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15828 && !flag_trapping_math
15829 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15832 emit_insn (gen_sse4_1_round<mode>2
15833 (operands[0], operands[1], GEN_INT (0x03)));
15834 else if (optimize_insn_for_size_p ())
15836 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15837 ix86_expand_trunc (operand0, operand1);
15839 ix86_expand_truncdf_32 (operand0, operand1);
15845 if (optimize_insn_for_size_p ())
15848 op0 = gen_reg_rtx (XFmode);
15849 op1 = gen_reg_rtx (XFmode);
15850 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15851 emit_insn (gen_frndintxf2_trunc (op0, op1));
15853 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15858 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15859 (define_insn_and_split "frndintxf2_mask_pm"
15860 [(set (match_operand:XF 0 "register_operand" "")
15861 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15862 UNSPEC_FRNDINT_MASK_PM))
15863 (clobber (reg:CC FLAGS_REG))]
15864 "TARGET_USE_FANCY_MATH_387
15865 && flag_unsafe_math_optimizations
15866 && can_create_pseudo_p ()"
15871 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15873 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15874 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15876 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15877 operands[2], operands[3]));
15880 [(set_attr "type" "frndint")
15881 (set_attr "i387_cw" "mask_pm")
15882 (set_attr "mode" "XF")])
15884 (define_insn "frndintxf2_mask_pm_i387"
15885 [(set (match_operand:XF 0 "register_operand" "=f")
15886 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15887 UNSPEC_FRNDINT_MASK_PM))
15888 (use (match_operand:HI 2 "memory_operand" "m"))
15889 (use (match_operand:HI 3 "memory_operand" "m"))]
15890 "TARGET_USE_FANCY_MATH_387
15891 && flag_unsafe_math_optimizations"
15892 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15893 [(set_attr "type" "frndint")
15894 (set_attr "i387_cw" "mask_pm")
15895 (set_attr "mode" "XF")])
15897 (define_expand "nearbyintxf2"
15898 [(use (match_operand:XF 0 "register_operand" ""))
15899 (use (match_operand:XF 1 "register_operand" ""))]
15900 "TARGET_USE_FANCY_MATH_387
15901 && flag_unsafe_math_optimizations"
15903 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15908 (define_expand "nearbyint<mode>2"
15909 [(use (match_operand:MODEF 0 "register_operand" ""))
15910 (use (match_operand:MODEF 1 "register_operand" ""))]
15911 "TARGET_USE_FANCY_MATH_387
15912 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15913 || TARGET_MIX_SSE_I387)
15914 && flag_unsafe_math_optimizations"
15916 rtx op0 = gen_reg_rtx (XFmode);
15917 rtx op1 = gen_reg_rtx (XFmode);
15919 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15920 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15922 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15926 (define_insn "fxam<mode>2_i387"
15927 [(set (match_operand:HI 0 "register_operand" "=a")
15929 [(match_operand:X87MODEF 1 "register_operand" "f")]
15931 "TARGET_USE_FANCY_MATH_387"
15932 "fxam\n\tfnstsw\t%0"
15933 [(set_attr "type" "multi")
15934 (set_attr "length" "4")
15935 (set_attr "unit" "i387")
15936 (set_attr "mode" "<MODE>")])
15938 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15939 [(set (match_operand:HI 0 "register_operand" "")
15941 [(match_operand:MODEF 1 "memory_operand" "")]
15943 "TARGET_USE_FANCY_MATH_387
15944 && can_create_pseudo_p ()"
15947 [(set (match_dup 2)(match_dup 1))
15949 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15951 operands[2] = gen_reg_rtx (<MODE>mode);
15953 MEM_VOLATILE_P (operands[1]) = 1;
15955 [(set_attr "type" "multi")
15956 (set_attr "unit" "i387")
15957 (set_attr "mode" "<MODE>")])
15959 (define_expand "isinfxf2"
15960 [(use (match_operand:SI 0 "register_operand" ""))
15961 (use (match_operand:XF 1 "register_operand" ""))]
15962 "TARGET_USE_FANCY_MATH_387
15963 && TARGET_C99_FUNCTIONS"
15965 rtx mask = GEN_INT (0x45);
15966 rtx val = GEN_INT (0x05);
15970 rtx scratch = gen_reg_rtx (HImode);
15971 rtx res = gen_reg_rtx (QImode);
15973 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15975 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15976 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15977 cond = gen_rtx_fmt_ee (EQ, QImode,
15978 gen_rtx_REG (CCmode, FLAGS_REG),
15980 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15981 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15985 (define_expand "isinf<mode>2"
15986 [(use (match_operand:SI 0 "register_operand" ""))
15987 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15988 "TARGET_USE_FANCY_MATH_387
15989 && TARGET_C99_FUNCTIONS
15990 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15992 rtx mask = GEN_INT (0x45);
15993 rtx val = GEN_INT (0x05);
15997 rtx scratch = gen_reg_rtx (HImode);
15998 rtx res = gen_reg_rtx (QImode);
16000 /* Remove excess precision by forcing value through memory. */
16001 if (memory_operand (operands[1], VOIDmode))
16002 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16005 enum ix86_stack_slot slot = (virtuals_instantiated
16008 rtx temp = assign_386_stack_local (<MODE>mode, slot);
16010 emit_move_insn (temp, operands[1]);
16011 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16014 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16015 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16016 cond = gen_rtx_fmt_ee (EQ, QImode,
16017 gen_rtx_REG (CCmode, FLAGS_REG),
16019 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
16020 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16024 (define_expand "signbit<mode>2"
16025 [(use (match_operand:SI 0 "register_operand" ""))
16026 (use (match_operand:X87MODEF 1 "register_operand" ""))]
16027 "TARGET_USE_FANCY_MATH_387
16028 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16030 rtx mask = GEN_INT (0x0200);
16032 rtx scratch = gen_reg_rtx (HImode);
16034 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
16035 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
16039 ;; Block operation instructions
16042 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16045 [(set_attr "length" "1")
16046 (set_attr "length_immediate" "0")
16047 (set_attr "modrm" "0")])
16049 (define_expand "movmemsi"
16050 [(use (match_operand:BLK 0 "memory_operand" ""))
16051 (use (match_operand:BLK 1 "memory_operand" ""))
16052 (use (match_operand:SI 2 "nonmemory_operand" ""))
16053 (use (match_operand:SI 3 "const_int_operand" ""))
16054 (use (match_operand:SI 4 "const_int_operand" ""))
16055 (use (match_operand:SI 5 "const_int_operand" ""))]
16058 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
16059 operands[4], operands[5]))
16065 (define_expand "movmemdi"
16066 [(use (match_operand:BLK 0 "memory_operand" ""))
16067 (use (match_operand:BLK 1 "memory_operand" ""))
16068 (use (match_operand:DI 2 "nonmemory_operand" ""))
16069 (use (match_operand:DI 3 "const_int_operand" ""))
16070 (use (match_operand:SI 4 "const_int_operand" ""))
16071 (use (match_operand:SI 5 "const_int_operand" ""))]
16074 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
16075 operands[4], operands[5]))
16081 ;; Most CPUs don't like single string operations
16082 ;; Handle this case here to simplify previous expander.
16084 (define_expand "strmov"
16085 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16086 (set (match_operand 1 "memory_operand" "") (match_dup 4))
16087 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16088 (clobber (reg:CC FLAGS_REG))])
16089 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16090 (clobber (reg:CC FLAGS_REG))])]
16093 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16095 /* If .md ever supports :P for Pmode, these can be directly
16096 in the pattern above. */
16097 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16098 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16100 /* Can't use this if the user has appropriated esi or edi. */
16101 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16102 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16104 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16105 operands[2], operands[3],
16106 operands[5], operands[6]));
16110 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16113 (define_expand "strmov_singleop"
16114 [(parallel [(set (match_operand 1 "memory_operand" "")
16115 (match_operand 3 "memory_operand" ""))
16116 (set (match_operand 0 "register_operand" "")
16117 (match_operand 4 "" ""))
16118 (set (match_operand 2 "register_operand" "")
16119 (match_operand 5 "" ""))])]
16121 "ix86_current_function_needs_cld = 1;")
16123 (define_insn "*strmovdi_rex_1"
16124 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16125 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16126 (set (match_operand:DI 0 "register_operand" "=D")
16127 (plus:DI (match_dup 2)
16129 (set (match_operand:DI 1 "register_operand" "=S")
16130 (plus:DI (match_dup 3)
16134 [(set_attr "type" "str")
16135 (set_attr "mode" "DI")
16136 (set_attr "memory" "both")])
16138 (define_insn "*strmovsi_1"
16139 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16140 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16141 (set (match_operand:SI 0 "register_operand" "=D")
16142 (plus:SI (match_dup 2)
16144 (set (match_operand:SI 1 "register_operand" "=S")
16145 (plus:SI (match_dup 3)
16149 [(set_attr "type" "str")
16150 (set_attr "mode" "SI")
16151 (set_attr "memory" "both")])
16153 (define_insn "*strmovsi_rex_1"
16154 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16155 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16156 (set (match_operand:DI 0 "register_operand" "=D")
16157 (plus:DI (match_dup 2)
16159 (set (match_operand:DI 1 "register_operand" "=S")
16160 (plus:DI (match_dup 3)
16164 [(set_attr "type" "str")
16165 (set_attr "mode" "SI")
16166 (set_attr "memory" "both")])
16168 (define_insn "*strmovhi_1"
16169 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16170 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16171 (set (match_operand:SI 0 "register_operand" "=D")
16172 (plus:SI (match_dup 2)
16174 (set (match_operand:SI 1 "register_operand" "=S")
16175 (plus:SI (match_dup 3)
16179 [(set_attr "type" "str")
16180 (set_attr "memory" "both")
16181 (set_attr "mode" "HI")])
16183 (define_insn "*strmovhi_rex_1"
16184 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16185 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16186 (set (match_operand:DI 0 "register_operand" "=D")
16187 (plus:DI (match_dup 2)
16189 (set (match_operand:DI 1 "register_operand" "=S")
16190 (plus:DI (match_dup 3)
16194 [(set_attr "type" "str")
16195 (set_attr "memory" "both")
16196 (set_attr "mode" "HI")])
16198 (define_insn "*strmovqi_1"
16199 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16200 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16201 (set (match_operand:SI 0 "register_operand" "=D")
16202 (plus:SI (match_dup 2)
16204 (set (match_operand:SI 1 "register_operand" "=S")
16205 (plus:SI (match_dup 3)
16209 [(set_attr "type" "str")
16210 (set_attr "memory" "both")
16211 (set_attr "mode" "QI")])
16213 (define_insn "*strmovqi_rex_1"
16214 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16215 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16216 (set (match_operand:DI 0 "register_operand" "=D")
16217 (plus:DI (match_dup 2)
16219 (set (match_operand:DI 1 "register_operand" "=S")
16220 (plus:DI (match_dup 3)
16224 [(set_attr "type" "str")
16225 (set_attr "memory" "both")
16226 (set_attr "prefix_rex" "0")
16227 (set_attr "mode" "QI")])
16229 (define_expand "rep_mov"
16230 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16231 (set (match_operand 0 "register_operand" "")
16232 (match_operand 5 "" ""))
16233 (set (match_operand 2 "register_operand" "")
16234 (match_operand 6 "" ""))
16235 (set (match_operand 1 "memory_operand" "")
16236 (match_operand 3 "memory_operand" ""))
16237 (use (match_dup 4))])]
16239 "ix86_current_function_needs_cld = 1;")
16241 (define_insn "*rep_movdi_rex64"
16242 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16243 (set (match_operand:DI 0 "register_operand" "=D")
16244 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16246 (match_operand:DI 3 "register_operand" "0")))
16247 (set (match_operand:DI 1 "register_operand" "=S")
16248 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16249 (match_operand:DI 4 "register_operand" "1")))
16250 (set (mem:BLK (match_dup 3))
16251 (mem:BLK (match_dup 4)))
16252 (use (match_dup 5))]
16255 [(set_attr "type" "str")
16256 (set_attr "prefix_rep" "1")
16257 (set_attr "memory" "both")
16258 (set_attr "mode" "DI")])
16260 (define_insn "*rep_movsi"
16261 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16262 (set (match_operand:SI 0 "register_operand" "=D")
16263 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16265 (match_operand:SI 3 "register_operand" "0")))
16266 (set (match_operand:SI 1 "register_operand" "=S")
16267 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16268 (match_operand:SI 4 "register_operand" "1")))
16269 (set (mem:BLK (match_dup 3))
16270 (mem:BLK (match_dup 4)))
16271 (use (match_dup 5))]
16274 [(set_attr "type" "str")
16275 (set_attr "prefix_rep" "1")
16276 (set_attr "memory" "both")
16277 (set_attr "mode" "SI")])
16279 (define_insn "*rep_movsi_rex64"
16280 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16281 (set (match_operand:DI 0 "register_operand" "=D")
16282 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16284 (match_operand:DI 3 "register_operand" "0")))
16285 (set (match_operand:DI 1 "register_operand" "=S")
16286 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16287 (match_operand:DI 4 "register_operand" "1")))
16288 (set (mem:BLK (match_dup 3))
16289 (mem:BLK (match_dup 4)))
16290 (use (match_dup 5))]
16293 [(set_attr "type" "str")
16294 (set_attr "prefix_rep" "1")
16295 (set_attr "memory" "both")
16296 (set_attr "mode" "SI")])
16298 (define_insn "*rep_movqi"
16299 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16300 (set (match_operand:SI 0 "register_operand" "=D")
16301 (plus:SI (match_operand:SI 3 "register_operand" "0")
16302 (match_operand:SI 5 "register_operand" "2")))
16303 (set (match_operand:SI 1 "register_operand" "=S")
16304 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16305 (set (mem:BLK (match_dup 3))
16306 (mem:BLK (match_dup 4)))
16307 (use (match_dup 5))]
16310 [(set_attr "type" "str")
16311 (set_attr "prefix_rep" "1")
16312 (set_attr "memory" "both")
16313 (set_attr "mode" "SI")])
16315 (define_insn "*rep_movqi_rex64"
16316 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16317 (set (match_operand:DI 0 "register_operand" "=D")
16318 (plus:DI (match_operand:DI 3 "register_operand" "0")
16319 (match_operand:DI 5 "register_operand" "2")))
16320 (set (match_operand:DI 1 "register_operand" "=S")
16321 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16322 (set (mem:BLK (match_dup 3))
16323 (mem:BLK (match_dup 4)))
16324 (use (match_dup 5))]
16327 [(set_attr "type" "str")
16328 (set_attr "prefix_rep" "1")
16329 (set_attr "memory" "both")
16330 (set_attr "mode" "SI")])
16332 (define_expand "setmemsi"
16333 [(use (match_operand:BLK 0 "memory_operand" ""))
16334 (use (match_operand:SI 1 "nonmemory_operand" ""))
16335 (use (match_operand 2 "const_int_operand" ""))
16336 (use (match_operand 3 "const_int_operand" ""))
16337 (use (match_operand:SI 4 "const_int_operand" ""))
16338 (use (match_operand:SI 5 "const_int_operand" ""))]
16341 if (ix86_expand_setmem (operands[0], operands[1],
16342 operands[2], operands[3],
16343 operands[4], operands[5]))
16349 (define_expand "setmemdi"
16350 [(use (match_operand:BLK 0 "memory_operand" ""))
16351 (use (match_operand:DI 1 "nonmemory_operand" ""))
16352 (use (match_operand 2 "const_int_operand" ""))
16353 (use (match_operand 3 "const_int_operand" ""))
16354 (use (match_operand 4 "const_int_operand" ""))
16355 (use (match_operand 5 "const_int_operand" ""))]
16358 if (ix86_expand_setmem (operands[0], operands[1],
16359 operands[2], operands[3],
16360 operands[4], operands[5]))
16366 ;; Most CPUs don't like single string operations
16367 ;; Handle this case here to simplify previous expander.
16369 (define_expand "strset"
16370 [(set (match_operand 1 "memory_operand" "")
16371 (match_operand 2 "register_operand" ""))
16372 (parallel [(set (match_operand 0 "register_operand" "")
16374 (clobber (reg:CC FLAGS_REG))])]
16377 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16378 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16380 /* If .md ever supports :P for Pmode, this can be directly
16381 in the pattern above. */
16382 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16383 GEN_INT (GET_MODE_SIZE (GET_MODE
16385 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16387 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16393 (define_expand "strset_singleop"
16394 [(parallel [(set (match_operand 1 "memory_operand" "")
16395 (match_operand 2 "register_operand" ""))
16396 (set (match_operand 0 "register_operand" "")
16397 (match_operand 3 "" ""))])]
16399 "ix86_current_function_needs_cld = 1;")
16401 (define_insn "*strsetdi_rex_1"
16402 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16403 (match_operand:DI 2 "register_operand" "a"))
16404 (set (match_operand:DI 0 "register_operand" "=D")
16405 (plus:DI (match_dup 1)
16409 [(set_attr "type" "str")
16410 (set_attr "memory" "store")
16411 (set_attr "mode" "DI")])
16413 (define_insn "*strsetsi_1"
16414 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16415 (match_operand:SI 2 "register_operand" "a"))
16416 (set (match_operand:SI 0 "register_operand" "=D")
16417 (plus:SI (match_dup 1)
16421 [(set_attr "type" "str")
16422 (set_attr "memory" "store")
16423 (set_attr "mode" "SI")])
16425 (define_insn "*strsetsi_rex_1"
16426 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16427 (match_operand:SI 2 "register_operand" "a"))
16428 (set (match_operand:DI 0 "register_operand" "=D")
16429 (plus:DI (match_dup 1)
16433 [(set_attr "type" "str")
16434 (set_attr "memory" "store")
16435 (set_attr "mode" "SI")])
16437 (define_insn "*strsethi_1"
16438 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16439 (match_operand:HI 2 "register_operand" "a"))
16440 (set (match_operand:SI 0 "register_operand" "=D")
16441 (plus:SI (match_dup 1)
16445 [(set_attr "type" "str")
16446 (set_attr "memory" "store")
16447 (set_attr "mode" "HI")])
16449 (define_insn "*strsethi_rex_1"
16450 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16451 (match_operand:HI 2 "register_operand" "a"))
16452 (set (match_operand:DI 0 "register_operand" "=D")
16453 (plus:DI (match_dup 1)
16457 [(set_attr "type" "str")
16458 (set_attr "memory" "store")
16459 (set_attr "mode" "HI")])
16461 (define_insn "*strsetqi_1"
16462 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16463 (match_operand:QI 2 "register_operand" "a"))
16464 (set (match_operand:SI 0 "register_operand" "=D")
16465 (plus:SI (match_dup 1)
16469 [(set_attr "type" "str")
16470 (set_attr "memory" "store")
16471 (set_attr "mode" "QI")])
16473 (define_insn "*strsetqi_rex_1"
16474 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16475 (match_operand:QI 2 "register_operand" "a"))
16476 (set (match_operand:DI 0 "register_operand" "=D")
16477 (plus:DI (match_dup 1)
16481 [(set_attr "type" "str")
16482 (set_attr "memory" "store")
16483 (set_attr "prefix_rex" "0")
16484 (set_attr "mode" "QI")])
16486 (define_expand "rep_stos"
16487 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16488 (set (match_operand 0 "register_operand" "")
16489 (match_operand 4 "" ""))
16490 (set (match_operand 2 "memory_operand" "") (const_int 0))
16491 (use (match_operand 3 "register_operand" ""))
16492 (use (match_dup 1))])]
16494 "ix86_current_function_needs_cld = 1;")
16496 (define_insn "*rep_stosdi_rex64"
16497 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16498 (set (match_operand:DI 0 "register_operand" "=D")
16499 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16501 (match_operand:DI 3 "register_operand" "0")))
16502 (set (mem:BLK (match_dup 3))
16504 (use (match_operand:DI 2 "register_operand" "a"))
16505 (use (match_dup 4))]
16508 [(set_attr "type" "str")
16509 (set_attr "prefix_rep" "1")
16510 (set_attr "memory" "store")
16511 (set_attr "mode" "DI")])
16513 (define_insn "*rep_stossi"
16514 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16515 (set (match_operand:SI 0 "register_operand" "=D")
16516 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16518 (match_operand:SI 3 "register_operand" "0")))
16519 (set (mem:BLK (match_dup 3))
16521 (use (match_operand:SI 2 "register_operand" "a"))
16522 (use (match_dup 4))]
16525 [(set_attr "type" "str")
16526 (set_attr "prefix_rep" "1")
16527 (set_attr "memory" "store")
16528 (set_attr "mode" "SI")])
16530 (define_insn "*rep_stossi_rex64"
16531 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16532 (set (match_operand:DI 0 "register_operand" "=D")
16533 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16535 (match_operand:DI 3 "register_operand" "0")))
16536 (set (mem:BLK (match_dup 3))
16538 (use (match_operand:SI 2 "register_operand" "a"))
16539 (use (match_dup 4))]
16542 [(set_attr "type" "str")
16543 (set_attr "prefix_rep" "1")
16544 (set_attr "memory" "store")
16545 (set_attr "mode" "SI")])
16547 (define_insn "*rep_stosqi"
16548 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16549 (set (match_operand:SI 0 "register_operand" "=D")
16550 (plus:SI (match_operand:SI 3 "register_operand" "0")
16551 (match_operand:SI 4 "register_operand" "1")))
16552 (set (mem:BLK (match_dup 3))
16554 (use (match_operand:QI 2 "register_operand" "a"))
16555 (use (match_dup 4))]
16558 [(set_attr "type" "str")
16559 (set_attr "prefix_rep" "1")
16560 (set_attr "memory" "store")
16561 (set_attr "mode" "QI")])
16563 (define_insn "*rep_stosqi_rex64"
16564 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16565 (set (match_operand:DI 0 "register_operand" "=D")
16566 (plus:DI (match_operand:DI 3 "register_operand" "0")
16567 (match_operand:DI 4 "register_operand" "1")))
16568 (set (mem:BLK (match_dup 3))
16570 (use (match_operand:QI 2 "register_operand" "a"))
16571 (use (match_dup 4))]
16574 [(set_attr "type" "str")
16575 (set_attr "prefix_rep" "1")
16576 (set_attr "memory" "store")
16577 (set_attr "prefix_rex" "0")
16578 (set_attr "mode" "QI")])
16580 (define_expand "cmpstrnsi"
16581 [(set (match_operand:SI 0 "register_operand" "")
16582 (compare:SI (match_operand:BLK 1 "general_operand" "")
16583 (match_operand:BLK 2 "general_operand" "")))
16584 (use (match_operand 3 "general_operand" ""))
16585 (use (match_operand 4 "immediate_operand" ""))]
16588 rtx addr1, addr2, out, outlow, count, countreg, align;
16590 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16593 /* Can't use this if the user has appropriated esi or edi. */
16594 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
16599 out = gen_reg_rtx (SImode);
16601 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16602 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16603 if (addr1 != XEXP (operands[1], 0))
16604 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16605 if (addr2 != XEXP (operands[2], 0))
16606 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16608 count = operands[3];
16609 countreg = ix86_zero_extend_to_Pmode (count);
16611 /* %%% Iff we are testing strict equality, we can use known alignment
16612 to good advantage. This may be possible with combine, particularly
16613 once cc0 is dead. */
16614 align = operands[4];
16616 if (CONST_INT_P (count))
16618 if (INTVAL (count) == 0)
16620 emit_move_insn (operands[0], const0_rtx);
16623 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16624 operands[1], operands[2]));
16628 rtx (*cmp_insn)(rtx, rtx);
16631 cmp_insn = gen_cmpdi_1;
16633 cmp_insn = gen_cmpsi_1;
16634 emit_insn (cmp_insn (countreg, countreg));
16635 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16636 operands[1], operands[2]));
16639 outlow = gen_lowpart (QImode, out);
16640 emit_insn (gen_cmpintqi (outlow));
16641 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16643 if (operands[0] != out)
16644 emit_move_insn (operands[0], out);
16649 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16651 (define_expand "cmpintqi"
16652 [(set (match_dup 1)
16653 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16655 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16656 (parallel [(set (match_operand:QI 0 "register_operand" "")
16657 (minus:QI (match_dup 1)
16659 (clobber (reg:CC FLAGS_REG))])]
16661 "operands[1] = gen_reg_rtx (QImode);
16662 operands[2] = gen_reg_rtx (QImode);")
16664 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16665 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16667 (define_expand "cmpstrnqi_nz_1"
16668 [(parallel [(set (reg:CC FLAGS_REG)
16669 (compare:CC (match_operand 4 "memory_operand" "")
16670 (match_operand 5 "memory_operand" "")))
16671 (use (match_operand 2 "register_operand" ""))
16672 (use (match_operand:SI 3 "immediate_operand" ""))
16673 (clobber (match_operand 0 "register_operand" ""))
16674 (clobber (match_operand 1 "register_operand" ""))
16675 (clobber (match_dup 2))])]
16677 "ix86_current_function_needs_cld = 1;")
16679 (define_insn "*cmpstrnqi_nz_1"
16680 [(set (reg:CC FLAGS_REG)
16681 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16682 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16683 (use (match_operand:SI 6 "register_operand" "2"))
16684 (use (match_operand:SI 3 "immediate_operand" "i"))
16685 (clobber (match_operand:SI 0 "register_operand" "=S"))
16686 (clobber (match_operand:SI 1 "register_operand" "=D"))
16687 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16690 [(set_attr "type" "str")
16691 (set_attr "mode" "QI")
16692 (set_attr "prefix_rep" "1")])
16694 (define_insn "*cmpstrnqi_nz_rex_1"
16695 [(set (reg:CC FLAGS_REG)
16696 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16697 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16698 (use (match_operand:DI 6 "register_operand" "2"))
16699 (use (match_operand:SI 3 "immediate_operand" "i"))
16700 (clobber (match_operand:DI 0 "register_operand" "=S"))
16701 (clobber (match_operand:DI 1 "register_operand" "=D"))
16702 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16705 [(set_attr "type" "str")
16706 (set_attr "mode" "QI")
16707 (set_attr "prefix_rex" "0")
16708 (set_attr "prefix_rep" "1")])
16710 ;; The same, but the count is not known to not be zero.
16712 (define_expand "cmpstrnqi_1"
16713 [(parallel [(set (reg:CC FLAGS_REG)
16714 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16716 (compare:CC (match_operand 4 "memory_operand" "")
16717 (match_operand 5 "memory_operand" ""))
16719 (use (match_operand:SI 3 "immediate_operand" ""))
16720 (use (reg:CC FLAGS_REG))
16721 (clobber (match_operand 0 "register_operand" ""))
16722 (clobber (match_operand 1 "register_operand" ""))
16723 (clobber (match_dup 2))])]
16725 "ix86_current_function_needs_cld = 1;")
16727 (define_insn "*cmpstrnqi_1"
16728 [(set (reg:CC FLAGS_REG)
16729 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16731 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16732 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16734 (use (match_operand:SI 3 "immediate_operand" "i"))
16735 (use (reg:CC FLAGS_REG))
16736 (clobber (match_operand:SI 0 "register_operand" "=S"))
16737 (clobber (match_operand:SI 1 "register_operand" "=D"))
16738 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16741 [(set_attr "type" "str")
16742 (set_attr "mode" "QI")
16743 (set_attr "prefix_rep" "1")])
16745 (define_insn "*cmpstrnqi_rex_1"
16746 [(set (reg:CC FLAGS_REG)
16747 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16749 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16750 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16752 (use (match_operand:SI 3 "immediate_operand" "i"))
16753 (use (reg:CC FLAGS_REG))
16754 (clobber (match_operand:DI 0 "register_operand" "=S"))
16755 (clobber (match_operand:DI 1 "register_operand" "=D"))
16756 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16759 [(set_attr "type" "str")
16760 (set_attr "mode" "QI")
16761 (set_attr "prefix_rex" "0")
16762 (set_attr "prefix_rep" "1")])
16764 (define_expand "strlensi"
16765 [(set (match_operand:SI 0 "register_operand" "")
16766 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16767 (match_operand:QI 2 "immediate_operand" "")
16768 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16771 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16777 (define_expand "strlendi"
16778 [(set (match_operand:DI 0 "register_operand" "")
16779 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16780 (match_operand:QI 2 "immediate_operand" "")
16781 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16784 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16790 (define_expand "strlenqi_1"
16791 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16792 (clobber (match_operand 1 "register_operand" ""))
16793 (clobber (reg:CC FLAGS_REG))])]
16795 "ix86_current_function_needs_cld = 1;")
16797 (define_insn "*strlenqi_1"
16798 [(set (match_operand:SI 0 "register_operand" "=&c")
16799 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16800 (match_operand:QI 2 "register_operand" "a")
16801 (match_operand:SI 3 "immediate_operand" "i")
16802 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16803 (clobber (match_operand:SI 1 "register_operand" "=D"))
16804 (clobber (reg:CC FLAGS_REG))]
16807 [(set_attr "type" "str")
16808 (set_attr "mode" "QI")
16809 (set_attr "prefix_rep" "1")])
16811 (define_insn "*strlenqi_rex_1"
16812 [(set (match_operand:DI 0 "register_operand" "=&c")
16813 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16814 (match_operand:QI 2 "register_operand" "a")
16815 (match_operand:DI 3 "immediate_operand" "i")
16816 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16817 (clobber (match_operand:DI 1 "register_operand" "=D"))
16818 (clobber (reg:CC FLAGS_REG))]
16821 [(set_attr "type" "str")
16822 (set_attr "mode" "QI")
16823 (set_attr "prefix_rex" "0")
16824 (set_attr "prefix_rep" "1")])
16826 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16827 ;; handled in combine, but it is not currently up to the task.
16828 ;; When used for their truth value, the cmpstrn* expanders generate
16837 ;; The intermediate three instructions are unnecessary.
16839 ;; This one handles cmpstrn*_nz_1...
16842 (set (reg:CC FLAGS_REG)
16843 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16844 (mem:BLK (match_operand 5 "register_operand" ""))))
16845 (use (match_operand 6 "register_operand" ""))
16846 (use (match_operand:SI 3 "immediate_operand" ""))
16847 (clobber (match_operand 0 "register_operand" ""))
16848 (clobber (match_operand 1 "register_operand" ""))
16849 (clobber (match_operand 2 "register_operand" ""))])
16850 (set (match_operand:QI 7 "register_operand" "")
16851 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16852 (set (match_operand:QI 8 "register_operand" "")
16853 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16854 (set (reg FLAGS_REG)
16855 (compare (match_dup 7) (match_dup 8)))
16857 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16859 (set (reg:CC FLAGS_REG)
16860 (compare:CC (mem:BLK (match_dup 4))
16861 (mem:BLK (match_dup 5))))
16862 (use (match_dup 6))
16863 (use (match_dup 3))
16864 (clobber (match_dup 0))
16865 (clobber (match_dup 1))
16866 (clobber (match_dup 2))])]
16869 ;; ...and this one handles cmpstrn*_1.
16872 (set (reg:CC FLAGS_REG)
16873 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16875 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16876 (mem:BLK (match_operand 5 "register_operand" "")))
16878 (use (match_operand:SI 3 "immediate_operand" ""))
16879 (use (reg:CC FLAGS_REG))
16880 (clobber (match_operand 0 "register_operand" ""))
16881 (clobber (match_operand 1 "register_operand" ""))
16882 (clobber (match_operand 2 "register_operand" ""))])
16883 (set (match_operand:QI 7 "register_operand" "")
16884 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16885 (set (match_operand:QI 8 "register_operand" "")
16886 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16887 (set (reg FLAGS_REG)
16888 (compare (match_dup 7) (match_dup 8)))
16890 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16892 (set (reg:CC FLAGS_REG)
16893 (if_then_else:CC (ne (match_dup 6)
16895 (compare:CC (mem:BLK (match_dup 4))
16896 (mem:BLK (match_dup 5)))
16898 (use (match_dup 3))
16899 (use (reg:CC FLAGS_REG))
16900 (clobber (match_dup 0))
16901 (clobber (match_dup 1))
16902 (clobber (match_dup 2))])]
16907 ;; Conditional move instructions.
16909 (define_expand "mov<mode>cc"
16910 [(set (match_operand:SWIM 0 "register_operand" "")
16911 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16912 (match_operand:SWIM 2 "general_operand" "")
16913 (match_operand:SWIM 3 "general_operand" "")))]
16915 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16917 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16918 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16919 ;; So just document what we're doing explicitly.
16921 (define_expand "x86_mov<mode>cc_0_m1"
16923 [(set (match_operand:SWI48 0 "register_operand" "")
16924 (if_then_else:SWI48
16925 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16926 [(match_operand 1 "flags_reg_operand" "")
16930 (clobber (reg:CC FLAGS_REG))])]
16934 (define_insn "*x86_mov<mode>cc_0_m1"
16935 [(set (match_operand:SWI48 0 "register_operand" "=r")
16936 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16937 [(reg FLAGS_REG) (const_int 0)])
16940 (clobber (reg:CC FLAGS_REG))]
16942 "sbb{<imodesuffix>}\t%0, %0"
16943 ; Since we don't have the proper number of operands for an alu insn,
16944 ; fill in all the blanks.
16945 [(set_attr "type" "alu")
16946 (set_attr "use_carry" "1")
16947 (set_attr "pent_pair" "pu")
16948 (set_attr "memory" "none")
16949 (set_attr "imm_disp" "false")
16950 (set_attr "mode" "<MODE>")
16951 (set_attr "length_immediate" "0")])
16953 (define_insn "*x86_mov<mode>cc_0_m1_se"
16954 [(set (match_operand:SWI48 0 "register_operand" "=r")
16955 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16956 [(reg FLAGS_REG) (const_int 0)])
16959 (clobber (reg:CC FLAGS_REG))]
16961 "sbb{<imodesuffix>}\t%0, %0"
16962 [(set_attr "type" "alu")
16963 (set_attr "use_carry" "1")
16964 (set_attr "pent_pair" "pu")
16965 (set_attr "memory" "none")
16966 (set_attr "imm_disp" "false")
16967 (set_attr "mode" "<MODE>")
16968 (set_attr "length_immediate" "0")])
16970 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16971 [(set (match_operand:SWI48 0 "register_operand" "=r")
16972 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16973 [(reg FLAGS_REG) (const_int 0)])))]
16975 "sbb{<imodesuffix>}\t%0, %0"
16976 [(set_attr "type" "alu")
16977 (set_attr "use_carry" "1")
16978 (set_attr "pent_pair" "pu")
16979 (set_attr "memory" "none")
16980 (set_attr "imm_disp" "false")
16981 (set_attr "mode" "<MODE>")
16982 (set_attr "length_immediate" "0")])
16984 (define_insn "*mov<mode>cc_noc"
16985 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16986 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16987 [(reg FLAGS_REG) (const_int 0)])
16988 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16989 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16990 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16992 cmov%O2%C1\t{%2, %0|%0, %2}
16993 cmov%O2%c1\t{%3, %0|%0, %3}"
16994 [(set_attr "type" "icmov")
16995 (set_attr "mode" "<MODE>")])
16997 (define_insn_and_split "*movqicc_noc"
16998 [(set (match_operand:QI 0 "register_operand" "=r,r")
16999 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17000 [(match_operand 4 "flags_reg_operand" "")
17002 (match_operand:QI 2 "register_operand" "r,0")
17003 (match_operand:QI 3 "register_operand" "0,r")))]
17004 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17006 "&& reload_completed"
17007 [(set (match_dup 0)
17008 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17011 "operands[0] = gen_lowpart (SImode, operands[0]);
17012 operands[2] = gen_lowpart (SImode, operands[2]);
17013 operands[3] = gen_lowpart (SImode, operands[3]);"
17014 [(set_attr "type" "icmov")
17015 (set_attr "mode" "SI")])
17017 (define_expand "mov<mode>cc"
17018 [(set (match_operand:X87MODEF 0 "register_operand" "")
17019 (if_then_else:X87MODEF
17020 (match_operand 1 "ix86_fp_comparison_operator" "")
17021 (match_operand:X87MODEF 2 "register_operand" "")
17022 (match_operand:X87MODEF 3 "register_operand" "")))]
17023 "(TARGET_80387 && TARGET_CMOVE)
17024 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17025 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17027 (define_insn "*movsfcc_1_387"
17028 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17029 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17030 [(reg FLAGS_REG) (const_int 0)])
17031 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17032 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17033 "TARGET_80387 && TARGET_CMOVE
17034 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17036 fcmov%F1\t{%2, %0|%0, %2}
17037 fcmov%f1\t{%3, %0|%0, %3}
17038 cmov%O2%C1\t{%2, %0|%0, %2}
17039 cmov%O2%c1\t{%3, %0|%0, %3}"
17040 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17041 (set_attr "mode" "SF,SF,SI,SI")])
17043 (define_insn "*movdfcc_1"
17044 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
17045 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17046 [(reg FLAGS_REG) (const_int 0)])
17047 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
17048 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
17049 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17050 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17052 fcmov%F1\t{%2, %0|%0, %2}
17053 fcmov%f1\t{%3, %0|%0, %3}
17056 [(set_attr "type" "fcmov,fcmov,multi,multi")
17057 (set_attr "mode" "DF")])
17059 (define_insn "*movdfcc_1_rex64"
17060 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
17061 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17062 [(reg FLAGS_REG) (const_int 0)])
17063 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
17064 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
17065 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17066 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17068 fcmov%F1\t{%2, %0|%0, %2}
17069 fcmov%f1\t{%3, %0|%0, %3}
17070 cmov%O2%C1\t{%2, %0|%0, %2}
17071 cmov%O2%c1\t{%3, %0|%0, %3}"
17072 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17073 (set_attr "mode" "DF")])
17076 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17077 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17078 [(match_operand 4 "flags_reg_operand" "")
17080 (match_operand:DF 2 "nonimmediate_operand" "")
17081 (match_operand:DF 3 "nonimmediate_operand" "")))]
17082 "!TARGET_64BIT && reload_completed"
17083 [(set (match_dup 2)
17084 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17088 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17091 "split_di (&operands[2], 2, &operands[5], &operands[7]);
17092 split_di (&operands[0], 1, &operands[2], &operands[3]);")
17094 (define_insn "*movxfcc_1"
17095 [(set (match_operand:XF 0 "register_operand" "=f,f")
17096 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17097 [(reg FLAGS_REG) (const_int 0)])
17098 (match_operand:XF 2 "register_operand" "f,0")
17099 (match_operand:XF 3 "register_operand" "0,f")))]
17100 "TARGET_80387 && TARGET_CMOVE"
17102 fcmov%F1\t{%2, %0|%0, %2}
17103 fcmov%f1\t{%3, %0|%0, %3}"
17104 [(set_attr "type" "fcmov")
17105 (set_attr "mode" "XF")])
17107 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17108 ;; the scalar versions to have only XMM registers as operands.
17110 ;; XOP conditional move
17111 (define_insn "*xop_pcmov_<mode>"
17112 [(set (match_operand:MODEF 0 "register_operand" "=x")
17113 (if_then_else:MODEF
17114 (match_operand:MODEF 1 "register_operand" "x")
17115 (match_operand:MODEF 2 "register_operand" "x")
17116 (match_operand:MODEF 3 "register_operand" "x")))]
17118 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17119 [(set_attr "type" "sse4arg")])
17121 ;; These versions of the min/max patterns are intentionally ignorant of
17122 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17123 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17124 ;; are undefined in this condition, we're certain this is correct.
17126 (define_insn "*avx_<code><mode>3"
17127 [(set (match_operand:MODEF 0 "register_operand" "=x")
17129 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
17130 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
17131 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17132 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17133 [(set_attr "type" "sseadd")
17134 (set_attr "prefix" "vex")
17135 (set_attr "mode" "<MODE>")])
17137 (define_insn "<code><mode>3"
17138 [(set (match_operand:MODEF 0 "register_operand" "=x")
17140 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
17141 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
17142 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17143 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
17144 [(set_attr "type" "sseadd")
17145 (set_attr "mode" "<MODE>")])
17147 ;; These versions of the min/max patterns implement exactly the operations
17148 ;; min = (op1 < op2 ? op1 : op2)
17149 ;; max = (!(op1 < op2) ? op1 : op2)
17150 ;; Their operands are not commutative, and thus they may be used in the
17151 ;; presence of -0.0 and NaN.
17153 (define_insn "*avx_ieee_smin<mode>3"
17154 [(set (match_operand:MODEF 0 "register_operand" "=x")
17156 [(match_operand:MODEF 1 "register_operand" "x")
17157 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
17159 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17160 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17161 [(set_attr "type" "sseadd")
17162 (set_attr "prefix" "vex")
17163 (set_attr "mode" "<MODE>")])
17165 (define_insn "*ieee_smin<mode>3"
17166 [(set (match_operand:MODEF 0 "register_operand" "=x")
17168 [(match_operand:MODEF 1 "register_operand" "0")
17169 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
17171 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17172 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
17173 [(set_attr "type" "sseadd")
17174 (set_attr "mode" "<MODE>")])
17176 (define_insn "*avx_ieee_smax<mode>3"
17177 [(set (match_operand:MODEF 0 "register_operand" "=x")
17179 [(match_operand:MODEF 1 "register_operand" "0")
17180 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
17182 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17183 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17184 [(set_attr "type" "sseadd")
17185 (set_attr "prefix" "vex")
17186 (set_attr "mode" "<MODE>")])
17188 (define_insn "*ieee_smax<mode>3"
17189 [(set (match_operand:MODEF 0 "register_operand" "=x")
17191 [(match_operand:MODEF 1 "register_operand" "0")
17192 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
17194 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17195 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
17196 [(set_attr "type" "sseadd")
17197 (set_attr "mode" "<MODE>")])
17199 ;; Make two stack loads independent:
17201 ;; fld %st(0) -> fld bb
17202 ;; fmul bb fmul %st(1), %st
17204 ;; Actually we only match the last two instructions for simplicity.
17206 [(set (match_operand 0 "fp_register_operand" "")
17207 (match_operand 1 "fp_register_operand" ""))
17209 (match_operator 2 "binary_fp_operator"
17211 (match_operand 3 "memory_operand" "")]))]
17212 "REGNO (operands[0]) != REGNO (operands[1])"
17213 [(set (match_dup 0) (match_dup 3))
17214 (set (match_dup 0) (match_dup 4))]
17216 ;; The % modifier is not operational anymore in peephole2's, so we have to
17217 ;; swap the operands manually in the case of addition and multiplication.
17218 "if (COMMUTATIVE_ARITH_P (operands[2]))
17219 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
17220 operands[0], operands[1]);
17222 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
17223 operands[1], operands[0]);")
17225 ;; Conditional addition patterns
17226 (define_expand "add<mode>cc"
17227 [(match_operand:SWI 0 "register_operand" "")
17228 (match_operand 1 "comparison_operator" "")
17229 (match_operand:SWI 2 "register_operand" "")
17230 (match_operand:SWI 3 "const_int_operand" "")]
17232 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17235 ;; Misc patterns (?)
17237 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17238 ;; Otherwise there will be nothing to keep
17240 ;; [(set (reg ebp) (reg esp))]
17241 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17242 ;; (clobber (eflags)]
17243 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17245 ;; in proper program order.
17246 (define_insn "pro_epilogue_adjust_stack_1"
17247 [(set (match_operand:SI 0 "register_operand" "=r,r")
17248 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17249 (match_operand:SI 2 "immediate_operand" "i,i")))
17250 (clobber (reg:CC FLAGS_REG))
17251 (clobber (mem:BLK (scratch)))]
17254 switch (get_attr_type (insn))
17257 return "mov{l}\t{%1, %0|%0, %1}";
17260 if (CONST_INT_P (operands[2])
17261 && (INTVAL (operands[2]) == 128
17262 || (INTVAL (operands[2]) < 0
17263 && INTVAL (operands[2]) != -128)))
17265 operands[2] = GEN_INT (-INTVAL (operands[2]));
17266 return "sub{l}\t{%2, %0|%0, %2}";
17268 return "add{l}\t{%2, %0|%0, %2}";
17271 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17272 return "lea{l}\t{%a2, %0|%0, %a2}";
17275 gcc_unreachable ();
17278 [(set (attr "type")
17279 (cond [(and (eq_attr "alternative" "0")
17280 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
17281 (const_string "alu")
17282 (match_operand:SI 2 "const0_operand" "")
17283 (const_string "imov")
17285 (const_string "lea")))
17286 (set (attr "length_immediate")
17287 (cond [(eq_attr "type" "imov")
17289 (and (eq_attr "type" "alu")
17290 (match_operand 2 "const128_operand" ""))
17293 (const_string "*")))
17294 (set_attr "mode" "SI")])
17296 (define_insn "pro_epilogue_adjust_stack_rex64"
17297 [(set (match_operand:DI 0 "register_operand" "=r,r")
17298 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17299 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17300 (clobber (reg:CC FLAGS_REG))
17301 (clobber (mem:BLK (scratch)))]
17304 switch (get_attr_type (insn))
17307 return "mov{q}\t{%1, %0|%0, %1}";
17310 if (CONST_INT_P (operands[2])
17311 /* Avoid overflows. */
17312 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17313 && (INTVAL (operands[2]) == 128
17314 || (INTVAL (operands[2]) < 0
17315 && INTVAL (operands[2]) != -128)))
17317 operands[2] = GEN_INT (-INTVAL (operands[2]));
17318 return "sub{q}\t{%2, %0|%0, %2}";
17320 return "add{q}\t{%2, %0|%0, %2}";
17323 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17324 return "lea{q}\t{%a2, %0|%0, %a2}";
17327 gcc_unreachable ();
17330 [(set (attr "type")
17331 (cond [(and (eq_attr "alternative" "0")
17332 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
17333 (const_string "alu")
17334 (match_operand:DI 2 "const0_operand" "")
17335 (const_string "imov")
17337 (const_string "lea")))
17338 (set (attr "length_immediate")
17339 (cond [(eq_attr "type" "imov")
17341 (and (eq_attr "type" "alu")
17342 (match_operand 2 "const128_operand" ""))
17345 (const_string "*")))
17346 (set_attr "mode" "DI")])
17348 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17349 [(set (match_operand:DI 0 "register_operand" "=r,r")
17350 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17351 (match_operand:DI 3 "immediate_operand" "i,i")))
17352 (use (match_operand:DI 2 "register_operand" "r,r"))
17353 (clobber (reg:CC FLAGS_REG))
17354 (clobber (mem:BLK (scratch)))]
17357 switch (get_attr_type (insn))
17360 return "add{q}\t{%2, %0|%0, %2}";
17363 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17364 return "lea{q}\t{%a2, %0|%0, %a2}";
17367 gcc_unreachable ();
17370 [(set_attr "type" "alu,lea")
17371 (set_attr "mode" "DI")])
17373 (define_insn "allocate_stack_worker_32"
17374 [(set (match_operand:SI 0 "register_operand" "=a")
17375 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
17376 UNSPECV_STACK_PROBE))
17377 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
17378 (clobber (reg:CC FLAGS_REG))]
17379 "!TARGET_64BIT && TARGET_STACK_PROBE"
17381 [(set_attr "type" "multi")
17382 (set_attr "length" "5")])
17384 (define_insn "allocate_stack_worker_64"
17385 [(set (match_operand:DI 0 "register_operand" "=a")
17386 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
17387 UNSPECV_STACK_PROBE))
17388 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
17389 (clobber (reg:DI R10_REG))
17390 (clobber (reg:DI R11_REG))
17391 (clobber (reg:CC FLAGS_REG))]
17392 "TARGET_64BIT && TARGET_STACK_PROBE"
17394 [(set_attr "type" "multi")
17395 (set_attr "length" "5")])
17397 (define_expand "allocate_stack"
17398 [(match_operand 0 "register_operand" "")
17399 (match_operand 1 "general_operand" "")]
17400 "TARGET_STACK_PROBE"
17404 #ifndef CHECK_STACK_LIMIT
17405 #define CHECK_STACK_LIMIT 0
17408 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17409 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17411 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
17412 stack_pointer_rtx, 0, OPTAB_DIRECT);
17413 if (x != stack_pointer_rtx)
17414 emit_move_insn (stack_pointer_rtx, x);
17418 x = copy_to_mode_reg (Pmode, operands[1]);
17420 x = gen_allocate_stack_worker_64 (x, x);
17422 x = gen_allocate_stack_worker_32 (x, x);
17426 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17430 ;; Use IOR for stack probes, this is shorter.
17431 (define_expand "probe_stack"
17432 [(match_operand 0 "memory_operand" "")]
17435 if (GET_MODE (operands[0]) == DImode)
17436 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
17438 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
17442 (define_expand "builtin_setjmp_receiver"
17443 [(label_ref (match_operand 0 "" ""))]
17444 "!TARGET_64BIT && flag_pic"
17450 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
17451 rtx label_rtx = gen_label_rtx ();
17452 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17453 xops[0] = xops[1] = picreg;
17454 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17455 ix86_expand_binary_operator (MINUS, SImode, xops);
17459 emit_insn (gen_set_got (pic_offset_table_rtx));
17463 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17466 [(set (match_operand 0 "register_operand" "")
17467 (match_operator 3 "promotable_binary_operator"
17468 [(match_operand 1 "register_operand" "")
17469 (match_operand 2 "aligned_operand" "")]))
17470 (clobber (reg:CC FLAGS_REG))]
17471 "! TARGET_PARTIAL_REG_STALL && reload_completed
17472 && ((GET_MODE (operands[0]) == HImode
17473 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17474 /* ??? next two lines just !satisfies_constraint_K (...) */
17475 || !CONST_INT_P (operands[2])
17476 || satisfies_constraint_K (operands[2])))
17477 || (GET_MODE (operands[0]) == QImode
17478 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17479 [(parallel [(set (match_dup 0)
17480 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17481 (clobber (reg:CC FLAGS_REG))])]
17482 "operands[0] = gen_lowpart (SImode, operands[0]);
17483 operands[1] = gen_lowpart (SImode, operands[1]);
17484 if (GET_CODE (operands[3]) != ASHIFT)
17485 operands[2] = gen_lowpart (SImode, operands[2]);
17486 PUT_MODE (operands[3], SImode);")
17488 ; Promote the QImode tests, as i386 has encoding of the AND
17489 ; instruction with 32-bit sign-extended immediate and thus the
17490 ; instruction size is unchanged, except in the %eax case for
17491 ; which it is increased by one byte, hence the ! optimize_size.
17493 [(set (match_operand 0 "flags_reg_operand" "")
17494 (match_operator 2 "compare_operator"
17495 [(and (match_operand 3 "aligned_operand" "")
17496 (match_operand 4 "const_int_operand" ""))
17498 (set (match_operand 1 "register_operand" "")
17499 (and (match_dup 3) (match_dup 4)))]
17500 "! TARGET_PARTIAL_REG_STALL && reload_completed
17501 && optimize_insn_for_speed_p ()
17502 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17503 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17504 /* Ensure that the operand will remain sign-extended immediate. */
17505 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17506 [(parallel [(set (match_dup 0)
17507 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17510 (and:SI (match_dup 3) (match_dup 4)))])]
17513 = gen_int_mode (INTVAL (operands[4])
17514 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17515 operands[1] = gen_lowpart (SImode, operands[1]);
17516 operands[3] = gen_lowpart (SImode, operands[3]);
17519 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17520 ; the TEST instruction with 32-bit sign-extended immediate and thus
17521 ; the instruction size would at least double, which is not what we
17522 ; want even with ! optimize_size.
17524 [(set (match_operand 0 "flags_reg_operand" "")
17525 (match_operator 1 "compare_operator"
17526 [(and (match_operand:HI 2 "aligned_operand" "")
17527 (match_operand:HI 3 "const_int_operand" ""))
17529 "! TARGET_PARTIAL_REG_STALL && reload_completed
17530 && ! TARGET_FAST_PREFIX
17531 && optimize_insn_for_speed_p ()
17532 /* Ensure that the operand will remain sign-extended immediate. */
17533 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17534 [(set (match_dup 0)
17535 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17539 = gen_int_mode (INTVAL (operands[3])
17540 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17541 operands[2] = gen_lowpart (SImode, operands[2]);
17545 [(set (match_operand 0 "register_operand" "")
17546 (neg (match_operand 1 "register_operand" "")))
17547 (clobber (reg:CC FLAGS_REG))]
17548 "! TARGET_PARTIAL_REG_STALL && reload_completed
17549 && (GET_MODE (operands[0]) == HImode
17550 || (GET_MODE (operands[0]) == QImode
17551 && (TARGET_PROMOTE_QImode
17552 || optimize_insn_for_size_p ())))"
17553 [(parallel [(set (match_dup 0)
17554 (neg:SI (match_dup 1)))
17555 (clobber (reg:CC FLAGS_REG))])]
17556 "operands[0] = gen_lowpart (SImode, operands[0]);
17557 operands[1] = gen_lowpart (SImode, operands[1]);")
17560 [(set (match_operand 0 "register_operand" "")
17561 (not (match_operand 1 "register_operand" "")))]
17562 "! TARGET_PARTIAL_REG_STALL && reload_completed
17563 && (GET_MODE (operands[0]) == HImode
17564 || (GET_MODE (operands[0]) == QImode
17565 && (TARGET_PROMOTE_QImode
17566 || optimize_insn_for_size_p ())))"
17567 [(set (match_dup 0)
17568 (not:SI (match_dup 1)))]
17569 "operands[0] = gen_lowpart (SImode, operands[0]);
17570 operands[1] = gen_lowpart (SImode, operands[1]);")
17573 [(set (match_operand 0 "register_operand" "")
17574 (if_then_else (match_operator 1 "comparison_operator"
17575 [(reg FLAGS_REG) (const_int 0)])
17576 (match_operand 2 "register_operand" "")
17577 (match_operand 3 "register_operand" "")))]
17578 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17579 && (GET_MODE (operands[0]) == HImode
17580 || (GET_MODE (operands[0]) == QImode
17581 && (TARGET_PROMOTE_QImode
17582 || optimize_insn_for_size_p ())))"
17583 [(set (match_dup 0)
17584 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17585 "operands[0] = gen_lowpart (SImode, operands[0]);
17586 operands[2] = gen_lowpart (SImode, operands[2]);
17587 operands[3] = gen_lowpart (SImode, operands[3]);")
17590 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17591 ;; transform a complex memory operation into two memory to register operations.
17593 ;; Don't push memory operands
17595 [(set (match_operand:SI 0 "push_operand" "")
17596 (match_operand:SI 1 "memory_operand" ""))
17597 (match_scratch:SI 2 "r")]
17598 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17599 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17600 [(set (match_dup 2) (match_dup 1))
17601 (set (match_dup 0) (match_dup 2))]
17605 [(set (match_operand:DI 0 "push_operand" "")
17606 (match_operand:DI 1 "memory_operand" ""))
17607 (match_scratch:DI 2 "r")]
17608 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17609 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17610 [(set (match_dup 2) (match_dup 1))
17611 (set (match_dup 0) (match_dup 2))]
17614 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17617 [(set (match_operand:SF 0 "push_operand" "")
17618 (match_operand:SF 1 "memory_operand" ""))
17619 (match_scratch:SF 2 "r")]
17620 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17621 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17622 [(set (match_dup 2) (match_dup 1))
17623 (set (match_dup 0) (match_dup 2))]
17627 [(set (match_operand:HI 0 "push_operand" "")
17628 (match_operand:HI 1 "memory_operand" ""))
17629 (match_scratch:HI 2 "r")]
17630 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17631 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17632 [(set (match_dup 2) (match_dup 1))
17633 (set (match_dup 0) (match_dup 2))]
17637 [(set (match_operand:QI 0 "push_operand" "")
17638 (match_operand:QI 1 "memory_operand" ""))
17639 (match_scratch:QI 2 "q")]
17640 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17641 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17642 [(set (match_dup 2) (match_dup 1))
17643 (set (match_dup 0) (match_dup 2))]
17646 ;; Don't move an immediate directly to memory when the instruction
17649 [(match_scratch:SI 1 "r")
17650 (set (match_operand:SI 0 "memory_operand" "")
17652 "optimize_insn_for_speed_p ()
17653 && ! TARGET_USE_MOV0
17654 && TARGET_SPLIT_LONG_MOVES
17655 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17656 && peep2_regno_dead_p (0, FLAGS_REG)"
17657 [(parallel [(set (match_dup 1) (const_int 0))
17658 (clobber (reg:CC FLAGS_REG))])
17659 (set (match_dup 0) (match_dup 1))]
17663 [(match_scratch:HI 1 "r")
17664 (set (match_operand:HI 0 "memory_operand" "")
17666 "optimize_insn_for_speed_p ()
17667 && ! TARGET_USE_MOV0
17668 && TARGET_SPLIT_LONG_MOVES
17669 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17670 && peep2_regno_dead_p (0, FLAGS_REG)"
17671 [(parallel [(set (match_dup 2) (const_int 0))
17672 (clobber (reg:CC FLAGS_REG))])
17673 (set (match_dup 0) (match_dup 1))]
17674 "operands[2] = gen_lowpart (SImode, operands[1]);")
17677 [(match_scratch:QI 1 "q")
17678 (set (match_operand:QI 0 "memory_operand" "")
17680 "optimize_insn_for_speed_p ()
17681 && ! TARGET_USE_MOV0
17682 && TARGET_SPLIT_LONG_MOVES
17683 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17684 && peep2_regno_dead_p (0, FLAGS_REG)"
17685 [(parallel [(set (match_dup 2) (const_int 0))
17686 (clobber (reg:CC FLAGS_REG))])
17687 (set (match_dup 0) (match_dup 1))]
17688 "operands[2] = gen_lowpart (SImode, operands[1]);")
17691 [(match_scratch:SI 2 "r")
17692 (set (match_operand:SI 0 "memory_operand" "")
17693 (match_operand:SI 1 "immediate_operand" ""))]
17694 "optimize_insn_for_speed_p ()
17695 && TARGET_SPLIT_LONG_MOVES
17696 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17697 [(set (match_dup 2) (match_dup 1))
17698 (set (match_dup 0) (match_dup 2))]
17702 [(match_scratch:HI 2 "r")
17703 (set (match_operand:HI 0 "memory_operand" "")
17704 (match_operand:HI 1 "immediate_operand" ""))]
17705 "optimize_insn_for_speed_p ()
17706 && TARGET_SPLIT_LONG_MOVES
17707 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17708 [(set (match_dup 2) (match_dup 1))
17709 (set (match_dup 0) (match_dup 2))]
17713 [(match_scratch:QI 2 "q")
17714 (set (match_operand:QI 0 "memory_operand" "")
17715 (match_operand:QI 1 "immediate_operand" ""))]
17716 "optimize_insn_for_speed_p ()
17717 && TARGET_SPLIT_LONG_MOVES
17718 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17719 [(set (match_dup 2) (match_dup 1))
17720 (set (match_dup 0) (match_dup 2))]
17723 ;; Don't compare memory with zero, load and use a test instead.
17725 [(set (match_operand 0 "flags_reg_operand" "")
17726 (match_operator 1 "compare_operator"
17727 [(match_operand:SI 2 "memory_operand" "")
17729 (match_scratch:SI 3 "r")]
17730 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17731 [(set (match_dup 3) (match_dup 2))
17732 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17735 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17736 ;; Don't split NOTs with a displacement operand, because resulting XOR
17737 ;; will not be pairable anyway.
17739 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17740 ;; represented using a modRM byte. The XOR replacement is long decoded,
17741 ;; so this split helps here as well.
17743 ;; Note: Can't do this as a regular split because we can't get proper
17744 ;; lifetime information then.
17747 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17748 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17749 "optimize_insn_for_speed_p ()
17750 && ((TARGET_NOT_UNPAIRABLE
17751 && (!MEM_P (operands[0])
17752 || !memory_displacement_operand (operands[0], SImode)))
17753 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
17754 && peep2_regno_dead_p (0, FLAGS_REG)"
17755 [(parallel [(set (match_dup 0)
17756 (xor:SI (match_dup 1) (const_int -1)))
17757 (clobber (reg:CC FLAGS_REG))])]
17761 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17762 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17763 "optimize_insn_for_speed_p ()
17764 && ((TARGET_NOT_UNPAIRABLE
17765 && (!MEM_P (operands[0])
17766 || !memory_displacement_operand (operands[0], HImode)))
17767 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
17768 && peep2_regno_dead_p (0, FLAGS_REG)"
17769 [(parallel [(set (match_dup 0)
17770 (xor:HI (match_dup 1) (const_int -1)))
17771 (clobber (reg:CC FLAGS_REG))])]
17775 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17776 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17777 "optimize_insn_for_speed_p ()
17778 && ((TARGET_NOT_UNPAIRABLE
17779 && (!MEM_P (operands[0])
17780 || !memory_displacement_operand (operands[0], QImode)))
17781 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
17782 && peep2_regno_dead_p (0, FLAGS_REG)"
17783 [(parallel [(set (match_dup 0)
17784 (xor:QI (match_dup 1) (const_int -1)))
17785 (clobber (reg:CC FLAGS_REG))])]
17788 ;; Non pairable "test imm, reg" instructions can be translated to
17789 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17790 ;; byte opcode instead of two, have a short form for byte operands),
17791 ;; so do it for other CPUs as well. Given that the value was dead,
17792 ;; this should not create any new dependencies. Pass on the sub-word
17793 ;; versions if we're concerned about partial register stalls.
17796 [(set (match_operand 0 "flags_reg_operand" "")
17797 (match_operator 1 "compare_operator"
17798 [(and:SI (match_operand:SI 2 "register_operand" "")
17799 (match_operand:SI 3 "immediate_operand" ""))
17801 "ix86_match_ccmode (insn, CCNOmode)
17802 && (true_regnum (operands[2]) != AX_REG
17803 || satisfies_constraint_K (operands[3]))
17804 && peep2_reg_dead_p (1, operands[2])"
17806 [(set (match_dup 0)
17807 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17810 (and:SI (match_dup 2) (match_dup 3)))])]
17813 ;; We don't need to handle HImode case, because it will be promoted to SImode
17814 ;; on ! TARGET_PARTIAL_REG_STALL
17817 [(set (match_operand 0 "flags_reg_operand" "")
17818 (match_operator 1 "compare_operator"
17819 [(and:QI (match_operand:QI 2 "register_operand" "")
17820 (match_operand:QI 3 "immediate_operand" ""))
17822 "! TARGET_PARTIAL_REG_STALL
17823 && ix86_match_ccmode (insn, CCNOmode)
17824 && true_regnum (operands[2]) != AX_REG
17825 && peep2_reg_dead_p (1, operands[2])"
17827 [(set (match_dup 0)
17828 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17831 (and:QI (match_dup 2) (match_dup 3)))])]
17835 [(set (match_operand 0 "flags_reg_operand" "")
17836 (match_operator 1 "compare_operator"
17839 (match_operand 2 "ext_register_operand" "")
17842 (match_operand 3 "const_int_operand" ""))
17844 "! TARGET_PARTIAL_REG_STALL
17845 && ix86_match_ccmode (insn, CCNOmode)
17846 && true_regnum (operands[2]) != AX_REG
17847 && peep2_reg_dead_p (1, operands[2])"
17848 [(parallel [(set (match_dup 0)
17857 (set (zero_extract:SI (match_dup 2)
17868 ;; Don't do logical operations with memory inputs.
17870 [(match_scratch:SI 2 "r")
17871 (parallel [(set (match_operand:SI 0 "register_operand" "")
17872 (match_operator:SI 3 "arith_or_logical_operator"
17874 (match_operand:SI 1 "memory_operand" "")]))
17875 (clobber (reg:CC FLAGS_REG))])]
17876 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17877 [(set (match_dup 2) (match_dup 1))
17878 (parallel [(set (match_dup 0)
17879 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17880 (clobber (reg:CC FLAGS_REG))])]
17884 [(match_scratch:SI 2 "r")
17885 (parallel [(set (match_operand:SI 0 "register_operand" "")
17886 (match_operator:SI 3 "arith_or_logical_operator"
17887 [(match_operand:SI 1 "memory_operand" "")
17889 (clobber (reg:CC FLAGS_REG))])]
17890 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17891 [(set (match_dup 2) (match_dup 1))
17892 (parallel [(set (match_dup 0)
17893 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17894 (clobber (reg:CC FLAGS_REG))])]
17897 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17898 ;; refers to the destination of the load!
17901 [(set (match_operand:SI 0 "register_operand" "")
17902 (match_operand:SI 1 "register_operand" ""))
17903 (parallel [(set (match_dup 0)
17904 (match_operator:SI 3 "commutative_operator"
17906 (match_operand:SI 2 "memory_operand" "")]))
17907 (clobber (reg:CC FLAGS_REG))])]
17908 "REGNO (operands[0]) != REGNO (operands[1])
17909 && GENERAL_REGNO_P (REGNO (operands[0]))
17910 && GENERAL_REGNO_P (REGNO (operands[1]))"
17911 [(set (match_dup 0) (match_dup 4))
17912 (parallel [(set (match_dup 0)
17913 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17914 (clobber (reg:CC FLAGS_REG))])]
17915 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17918 [(set (match_operand 0 "register_operand" "")
17919 (match_operand 1 "register_operand" ""))
17921 (match_operator 3 "commutative_operator"
17923 (match_operand 2 "memory_operand" "")]))]
17924 "REGNO (operands[0]) != REGNO (operands[1])
17925 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17926 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17927 [(set (match_dup 0) (match_dup 2))
17929 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17932 ; Don't do logical operations with memory outputs
17934 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17935 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17936 ; the same decoder scheduling characteristics as the original.
17939 [(match_scratch:SI 2 "r")
17940 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17941 (match_operator:SI 3 "arith_or_logical_operator"
17943 (match_operand:SI 1 "nonmemory_operand" "")]))
17944 (clobber (reg:CC FLAGS_REG))])]
17945 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17946 /* Do not split stack checking probes. */
17947 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17948 [(set (match_dup 2) (match_dup 0))
17949 (parallel [(set (match_dup 2)
17950 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17951 (clobber (reg:CC FLAGS_REG))])
17952 (set (match_dup 0) (match_dup 2))]
17956 [(match_scratch:SI 2 "r")
17957 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17958 (match_operator:SI 3 "arith_or_logical_operator"
17959 [(match_operand:SI 1 "nonmemory_operand" "")
17961 (clobber (reg:CC FLAGS_REG))])]
17962 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17963 /* Do not split stack checking probes. */
17964 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17965 [(set (match_dup 2) (match_dup 0))
17966 (parallel [(set (match_dup 2)
17967 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17968 (clobber (reg:CC FLAGS_REG))])
17969 (set (match_dup 0) (match_dup 2))]
17972 ;; Attempt to always use XOR for zeroing registers.
17974 [(set (match_operand 0 "register_operand" "")
17975 (match_operand 1 "const0_operand" ""))]
17976 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17977 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17978 && GENERAL_REG_P (operands[0])
17979 && peep2_regno_dead_p (0, FLAGS_REG)"
17980 [(parallel [(set (match_dup 0) (const_int 0))
17981 (clobber (reg:CC FLAGS_REG))])]
17983 operands[0] = gen_lowpart (word_mode, operands[0]);
17987 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17989 "(GET_MODE (operands[0]) == QImode
17990 || GET_MODE (operands[0]) == HImode)
17991 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17992 && peep2_regno_dead_p (0, FLAGS_REG)"
17993 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17994 (clobber (reg:CC FLAGS_REG))])])
17996 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17998 [(set (match_operand 0 "register_operand" "")
18000 "(GET_MODE (operands[0]) == HImode
18001 || GET_MODE (operands[0]) == SImode
18002 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18003 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
18004 && peep2_regno_dead_p (0, FLAGS_REG)"
18005 [(parallel [(set (match_dup 0) (const_int -1))
18006 (clobber (reg:CC FLAGS_REG))])]
18007 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18010 ;; Attempt to convert simple leas to adds. These can be created by
18013 [(set (match_operand:SI 0 "register_operand" "")
18014 (plus:SI (match_dup 0)
18015 (match_operand:SI 1 "nonmemory_operand" "")))]
18016 "peep2_regno_dead_p (0, FLAGS_REG)"
18017 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18018 (clobber (reg:CC FLAGS_REG))])]
18022 [(set (match_operand:SI 0 "register_operand" "")
18023 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18024 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18025 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18026 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18027 (clobber (reg:CC FLAGS_REG))])]
18028 "operands[2] = gen_lowpart (SImode, operands[2]);")
18031 [(set (match_operand:DI 0 "register_operand" "")
18032 (plus:DI (match_dup 0)
18033 (match_operand:DI 1 "x86_64_general_operand" "")))]
18034 "peep2_regno_dead_p (0, FLAGS_REG)"
18035 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18036 (clobber (reg:CC FLAGS_REG))])]
18040 [(set (match_operand:SI 0 "register_operand" "")
18041 (mult:SI (match_dup 0)
18042 (match_operand:SI 1 "const_int_operand" "")))]
18043 "exact_log2 (INTVAL (operands[1])) >= 0
18044 && peep2_regno_dead_p (0, FLAGS_REG)"
18045 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18046 (clobber (reg:CC FLAGS_REG))])]
18047 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18050 [(set (match_operand:DI 0 "register_operand" "")
18051 (mult:DI (match_dup 0)
18052 (match_operand:DI 1 "const_int_operand" "")))]
18053 "exact_log2 (INTVAL (operands[1])) >= 0
18054 && peep2_regno_dead_p (0, FLAGS_REG)"
18055 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18056 (clobber (reg:CC FLAGS_REG))])]
18057 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18060 [(set (match_operand:SI 0 "register_operand" "")
18061 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18062 (match_operand:DI 2 "const_int_operand" "")) 0))]
18063 "exact_log2 (INTVAL (operands[2])) >= 0
18064 && REGNO (operands[0]) == REGNO (operands[1])
18065 && peep2_regno_dead_p (0, FLAGS_REG)"
18066 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18067 (clobber (reg:CC FLAGS_REG))])]
18068 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18070 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18071 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18072 ;; many CPUs it is also faster, since special hardware to avoid esp
18073 ;; dependencies is present.
18075 ;; While some of these conversions may be done using splitters, we use peepholes
18076 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18078 ;; Convert prologue esp subtractions to push.
18079 ;; We need register to push. In order to keep verify_flow_info happy we have
18081 ;; - use scratch and clobber it in order to avoid dependencies
18082 ;; - use already live register
18083 ;; We can't use the second way right now, since there is no reliable way how to
18084 ;; verify that given register is live. First choice will also most likely in
18085 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18086 ;; call clobbered registers are dead. We may want to use base pointer as an
18087 ;; alternative when no register is available later.
18090 [(match_scratch:SI 0 "r")
18091 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18092 (clobber (reg:CC FLAGS_REG))
18093 (clobber (mem:BLK (scratch)))])]
18094 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
18095 [(clobber (match_dup 0))
18096 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18097 (clobber (mem:BLK (scratch)))])])
18100 [(match_scratch:SI 0 "r")
18101 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18102 (clobber (reg:CC FLAGS_REG))
18103 (clobber (mem:BLK (scratch)))])]
18104 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
18105 [(clobber (match_dup 0))
18106 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18107 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18108 (clobber (mem:BLK (scratch)))])])
18110 ;; Convert esp subtractions to push.
18112 [(match_scratch:SI 0 "r")
18113 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18114 (clobber (reg:CC FLAGS_REG))])]
18115 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
18116 [(clobber (match_dup 0))
18117 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18120 [(match_scratch:SI 0 "r")
18121 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18122 (clobber (reg:CC FLAGS_REG))])]
18123 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
18124 [(clobber (match_dup 0))
18125 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18126 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18128 ;; Convert epilogue deallocator to pop.
18130 [(match_scratch:SI 0 "r")
18131 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18132 (clobber (reg:CC FLAGS_REG))
18133 (clobber (mem:BLK (scratch)))])]
18134 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
18135 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18136 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18137 (clobber (mem:BLK (scratch)))])]
18140 ;; Two pops case is tricky, since pop causes dependency on destination register.
18141 ;; We use two registers if available.
18143 [(match_scratch:SI 0 "r")
18144 (match_scratch:SI 1 "r")
18145 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18146 (clobber (reg:CC FLAGS_REG))
18147 (clobber (mem:BLK (scratch)))])]
18148 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
18149 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18150 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18151 (clobber (mem:BLK (scratch)))])
18152 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18153 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18157 [(match_scratch:SI 0 "r")
18158 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18159 (clobber (reg:CC FLAGS_REG))
18160 (clobber (mem:BLK (scratch)))])]
18161 "optimize_insn_for_size_p ()"
18162 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18163 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18164 (clobber (mem:BLK (scratch)))])
18165 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18166 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18169 ;; Convert esp additions to pop.
18171 [(match_scratch:SI 0 "r")
18172 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18173 (clobber (reg:CC FLAGS_REG))])]
18175 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18176 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18179 ;; Two pops case is tricky, since pop causes dependency on destination register.
18180 ;; We use two registers if available.
18182 [(match_scratch:SI 0 "r")
18183 (match_scratch:SI 1 "r")
18184 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18185 (clobber (reg:CC FLAGS_REG))])]
18187 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18188 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18189 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18190 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18194 [(match_scratch:SI 0 "r")
18195 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18196 (clobber (reg:CC FLAGS_REG))])]
18197 "optimize_insn_for_size_p ()"
18198 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18199 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18200 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18201 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18204 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18205 ;; required and register dies. Similarly for 128 to -128.
18207 [(set (match_operand 0 "flags_reg_operand" "")
18208 (match_operator 1 "compare_operator"
18209 [(match_operand 2 "register_operand" "")
18210 (match_operand 3 "const_int_operand" "")]))]
18211 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18212 && incdec_operand (operands[3], GET_MODE (operands[3])))
18213 || (!TARGET_FUSE_CMP_AND_BRANCH
18214 && INTVAL (operands[3]) == 128))
18215 && ix86_match_ccmode (insn, CCGCmode)
18216 && peep2_reg_dead_p (1, operands[2])"
18217 [(parallel [(set (match_dup 0)
18218 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18219 (clobber (match_dup 2))])]
18223 [(match_scratch:DI 0 "r")
18224 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18225 (clobber (reg:CC FLAGS_REG))
18226 (clobber (mem:BLK (scratch)))])]
18227 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
18228 [(clobber (match_dup 0))
18229 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18230 (clobber (mem:BLK (scratch)))])])
18233 [(match_scratch:DI 0 "r")
18234 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18235 (clobber (reg:CC FLAGS_REG))
18236 (clobber (mem:BLK (scratch)))])]
18237 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
18238 [(clobber (match_dup 0))
18239 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18240 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18241 (clobber (mem:BLK (scratch)))])])
18243 ;; Convert esp subtractions to push.
18245 [(match_scratch:DI 0 "r")
18246 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18247 (clobber (reg:CC FLAGS_REG))])]
18248 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
18249 [(clobber (match_dup 0))
18250 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18253 [(match_scratch:DI 0 "r")
18254 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18255 (clobber (reg:CC FLAGS_REG))])]
18256 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
18257 [(clobber (match_dup 0))
18258 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18259 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18261 ;; Convert epilogue deallocator to pop.
18263 [(match_scratch:DI 0 "r")
18264 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18265 (clobber (reg:CC FLAGS_REG))
18266 (clobber (mem:BLK (scratch)))])]
18267 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
18268 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18269 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18270 (clobber (mem:BLK (scratch)))])]
18273 ;; Two pops case is tricky, since pop causes dependency on destination register.
18274 ;; We use two registers if available.
18276 [(match_scratch:DI 0 "r")
18277 (match_scratch:DI 1 "r")
18278 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18279 (clobber (reg:CC FLAGS_REG))
18280 (clobber (mem:BLK (scratch)))])]
18281 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
18282 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18283 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18284 (clobber (mem:BLK (scratch)))])
18285 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18286 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18290 [(match_scratch:DI 0 "r")
18291 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18292 (clobber (reg:CC FLAGS_REG))
18293 (clobber (mem:BLK (scratch)))])]
18294 "optimize_insn_for_size_p ()"
18295 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18296 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18297 (clobber (mem:BLK (scratch)))])
18298 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18299 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18302 ;; Convert esp additions to pop.
18304 [(match_scratch:DI 0 "r")
18305 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18306 (clobber (reg:CC FLAGS_REG))])]
18308 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18309 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18312 ;; Two pops case is tricky, since pop causes dependency on destination register.
18313 ;; We use two registers if available.
18315 [(match_scratch:DI 0 "r")
18316 (match_scratch:DI 1 "r")
18317 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18318 (clobber (reg:CC FLAGS_REG))])]
18320 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18321 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18322 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18323 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18327 [(match_scratch:DI 0 "r")
18328 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18329 (clobber (reg:CC FLAGS_REG))])]
18330 "optimize_insn_for_size_p ()"
18331 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18332 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18333 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18334 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18337 ;; Convert imul by three, five and nine into lea
18340 [(set (match_operand:SI 0 "register_operand" "")
18341 (mult:SI (match_operand:SI 1 "register_operand" "")
18342 (match_operand:SI 2 "const_int_operand" "")))
18343 (clobber (reg:CC FLAGS_REG))])]
18344 "INTVAL (operands[2]) == 3
18345 || INTVAL (operands[2]) == 5
18346 || INTVAL (operands[2]) == 9"
18347 [(set (match_dup 0)
18348 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
18350 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18354 [(set (match_operand:SI 0 "register_operand" "")
18355 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18356 (match_operand:SI 2 "const_int_operand" "")))
18357 (clobber (reg:CC FLAGS_REG))])]
18358 "optimize_insn_for_speed_p ()
18359 && (INTVAL (operands[2]) == 3
18360 || INTVAL (operands[2]) == 5
18361 || INTVAL (operands[2]) == 9)"
18362 [(set (match_dup 0) (match_dup 1))
18364 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
18366 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18370 [(set (match_operand:DI 0 "register_operand" "")
18371 (mult:DI (match_operand:DI 1 "register_operand" "")
18372 (match_operand:DI 2 "const_int_operand" "")))
18373 (clobber (reg:CC FLAGS_REG))])]
18375 && (INTVAL (operands[2]) == 3
18376 || INTVAL (operands[2]) == 5
18377 || INTVAL (operands[2]) == 9)"
18378 [(set (match_dup 0)
18379 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
18381 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18385 [(set (match_operand:DI 0 "register_operand" "")
18386 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18387 (match_operand:DI 2 "const_int_operand" "")))
18388 (clobber (reg:CC FLAGS_REG))])]
18390 && optimize_insn_for_speed_p ()
18391 && (INTVAL (operands[2]) == 3
18392 || INTVAL (operands[2]) == 5
18393 || INTVAL (operands[2]) == 9)"
18394 [(set (match_dup 0) (match_dup 1))
18396 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18398 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18400 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18401 ;; imul $32bit_imm, reg, reg is direct decoded.
18403 [(match_scratch:DI 3 "r")
18404 (parallel [(set (match_operand:DI 0 "register_operand" "")
18405 (mult:DI (match_operand:DI 1 "memory_operand" "")
18406 (match_operand:DI 2 "immediate_operand" "")))
18407 (clobber (reg:CC FLAGS_REG))])]
18408 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18409 && !satisfies_constraint_K (operands[2])"
18410 [(set (match_dup 3) (match_dup 1))
18411 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18412 (clobber (reg:CC FLAGS_REG))])]
18416 [(match_scratch:SI 3 "r")
18417 (parallel [(set (match_operand:SI 0 "register_operand" "")
18418 (mult:SI (match_operand:SI 1 "memory_operand" "")
18419 (match_operand:SI 2 "immediate_operand" "")))
18420 (clobber (reg:CC FLAGS_REG))])]
18421 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18422 && !satisfies_constraint_K (operands[2])"
18423 [(set (match_dup 3) (match_dup 1))
18424 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18425 (clobber (reg:CC FLAGS_REG))])]
18429 [(match_scratch:SI 3 "r")
18430 (parallel [(set (match_operand:DI 0 "register_operand" "")
18432 (mult:SI (match_operand:SI 1 "memory_operand" "")
18433 (match_operand:SI 2 "immediate_operand" ""))))
18434 (clobber (reg:CC FLAGS_REG))])]
18435 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18436 && !satisfies_constraint_K (operands[2])"
18437 [(set (match_dup 3) (match_dup 1))
18438 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18439 (clobber (reg:CC FLAGS_REG))])]
18442 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18443 ;; Convert it into imul reg, reg
18444 ;; It would be better to force assembler to encode instruction using long
18445 ;; immediate, but there is apparently no way to do so.
18447 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18448 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18449 (match_operand:DI 2 "const_int_operand" "")))
18450 (clobber (reg:CC FLAGS_REG))])
18451 (match_scratch:DI 3 "r")]
18452 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18453 && satisfies_constraint_K (operands[2])"
18454 [(set (match_dup 3) (match_dup 2))
18455 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18456 (clobber (reg:CC FLAGS_REG))])]
18458 if (!rtx_equal_p (operands[0], operands[1]))
18459 emit_move_insn (operands[0], operands[1]);
18463 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18464 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18465 (match_operand:SI 2 "const_int_operand" "")))
18466 (clobber (reg:CC FLAGS_REG))])
18467 (match_scratch:SI 3 "r")]
18468 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18469 && satisfies_constraint_K (operands[2])"
18470 [(set (match_dup 3) (match_dup 2))
18471 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18472 (clobber (reg:CC FLAGS_REG))])]
18474 if (!rtx_equal_p (operands[0], operands[1]))
18475 emit_move_insn (operands[0], operands[1]);
18479 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18480 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18481 (match_operand:HI 2 "immediate_operand" "")))
18482 (clobber (reg:CC FLAGS_REG))])
18483 (match_scratch:HI 3 "r")]
18484 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
18485 [(set (match_dup 3) (match_dup 2))
18486 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18487 (clobber (reg:CC FLAGS_REG))])]
18489 if (!rtx_equal_p (operands[0], operands[1]))
18490 emit_move_insn (operands[0], operands[1]);
18493 ;; After splitting up read-modify operations, array accesses with memory
18494 ;; operands might end up in form:
18496 ;; movl 4(%esp), %edx
18498 ;; instead of pre-splitting:
18500 ;; addl 4(%esp), %eax
18502 ;; movl 4(%esp), %edx
18503 ;; leal (%edx,%eax,4), %eax
18506 [(parallel [(set (match_operand 0 "register_operand" "")
18507 (ashift (match_operand 1 "register_operand" "")
18508 (match_operand 2 "const_int_operand" "")))
18509 (clobber (reg:CC FLAGS_REG))])
18510 (set (match_operand 3 "register_operand")
18511 (match_operand 4 "x86_64_general_operand" ""))
18512 (parallel [(set (match_operand 5 "register_operand" "")
18513 (plus (match_operand 6 "register_operand" "")
18514 (match_operand 7 "register_operand" "")))
18515 (clobber (reg:CC FLAGS_REG))])]
18516 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
18517 /* Validate MODE for lea. */
18518 && ((!TARGET_PARTIAL_REG_STALL
18519 && (GET_MODE (operands[0]) == QImode
18520 || GET_MODE (operands[0]) == HImode))
18521 || GET_MODE (operands[0]) == SImode
18522 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18523 /* We reorder load and the shift. */
18524 && !rtx_equal_p (operands[1], operands[3])
18525 && !reg_overlap_mentioned_p (operands[0], operands[4])
18526 /* Last PLUS must consist of operand 0 and 3. */
18527 && !rtx_equal_p (operands[0], operands[3])
18528 && (rtx_equal_p (operands[3], operands[6])
18529 || rtx_equal_p (operands[3], operands[7]))
18530 && (rtx_equal_p (operands[0], operands[6])
18531 || rtx_equal_p (operands[0], operands[7]))
18532 /* The intermediate operand 0 must die or be same as output. */
18533 && (rtx_equal_p (operands[0], operands[5])
18534 || peep2_reg_dead_p (3, operands[0]))"
18535 [(set (match_dup 3) (match_dup 4))
18536 (set (match_dup 0) (match_dup 1))]
18538 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
18539 int scale = 1 << INTVAL (operands[2]);
18540 rtx index = gen_lowpart (Pmode, operands[1]);
18541 rtx base = gen_lowpart (Pmode, operands[3]);
18542 rtx dest = gen_lowpart (mode, operands[5]);
18544 operands[1] = gen_rtx_PLUS (Pmode, base,
18545 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
18547 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18548 operands[0] = dest;
18551 ;; Call-value patterns last so that the wildcard operand does not
18552 ;; disrupt insn-recog's switch tables.
18554 (define_insn "*call_value_pop_0"
18555 [(set (match_operand 0 "" "")
18556 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18557 (match_operand:SI 2 "" "")))
18558 (set (reg:SI SP_REG)
18559 (plus:SI (reg:SI SP_REG)
18560 (match_operand:SI 3 "immediate_operand" "")))]
18563 if (SIBLING_CALL_P (insn))
18566 return "call\t%P1";
18568 [(set_attr "type" "callv")])
18570 (define_insn "*call_value_pop_1"
18571 [(set (match_operand 0 "" "")
18572 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18573 (match_operand:SI 2 "" "")))
18574 (set (reg:SI SP_REG)
18575 (plus:SI (reg:SI SP_REG)
18576 (match_operand:SI 3 "immediate_operand" "i")))]
18577 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18579 if (constant_call_address_operand (operands[1], Pmode))
18580 return "call\t%P1";
18581 return "call\t%A1";
18583 [(set_attr "type" "callv")])
18585 (define_insn "*sibcall_value_pop_1"
18586 [(set (match_operand 0 "" "")
18587 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18588 (match_operand:SI 2 "" "")))
18589 (set (reg:SI SP_REG)
18590 (plus:SI (reg:SI SP_REG)
18591 (match_operand:SI 3 "immediate_operand" "i,i")))]
18592 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18596 [(set_attr "type" "callv")])
18598 (define_insn "*call_value_0"
18599 [(set (match_operand 0 "" "")
18600 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18601 (match_operand:SI 2 "" "")))]
18604 if (SIBLING_CALL_P (insn))
18607 return "call\t%P1";
18609 [(set_attr "type" "callv")])
18611 (define_insn "*call_value_0_rex64"
18612 [(set (match_operand 0 "" "")
18613 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18614 (match_operand:DI 2 "const_int_operand" "")))]
18617 if (SIBLING_CALL_P (insn))
18620 return "call\t%P1";
18622 [(set_attr "type" "callv")])
18624 (define_insn "*call_value_0_rex64_ms_sysv"
18625 [(set (match_operand 0 "" "")
18626 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18627 (match_operand:DI 2 "const_int_operand" "")))
18628 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18629 (clobber (reg:TI XMM6_REG))
18630 (clobber (reg:TI XMM7_REG))
18631 (clobber (reg:TI XMM8_REG))
18632 (clobber (reg:TI XMM9_REG))
18633 (clobber (reg:TI XMM10_REG))
18634 (clobber (reg:TI XMM11_REG))
18635 (clobber (reg:TI XMM12_REG))
18636 (clobber (reg:TI XMM13_REG))
18637 (clobber (reg:TI XMM14_REG))
18638 (clobber (reg:TI XMM15_REG))
18639 (clobber (reg:DI SI_REG))
18640 (clobber (reg:DI DI_REG))]
18641 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18643 if (SIBLING_CALL_P (insn))
18646 return "call\t%P1";
18648 [(set_attr "type" "callv")])
18650 (define_insn "*call_value_1"
18651 [(set (match_operand 0 "" "")
18652 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18653 (match_operand:SI 2 "" "")))]
18654 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18656 if (constant_call_address_operand (operands[1], Pmode))
18657 return "call\t%P1";
18658 return "call\t%A1";
18660 [(set_attr "type" "callv")])
18662 (define_insn "*sibcall_value_1"
18663 [(set (match_operand 0 "" "")
18664 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18665 (match_operand:SI 2 "" "")))]
18666 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18670 [(set_attr "type" "callv")])
18672 (define_insn "*call_value_1_rex64"
18673 [(set (match_operand 0 "" "")
18674 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18675 (match_operand:DI 2 "" "")))]
18676 "TARGET_64BIT && !SIBLING_CALL_P (insn)
18677 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
18679 if (constant_call_address_operand (operands[1], Pmode))
18680 return "call\t%P1";
18681 return "call\t%A1";
18683 [(set_attr "type" "callv")])
18685 (define_insn "*call_value_1_rex64_ms_sysv"
18686 [(set (match_operand 0 "" "")
18687 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18688 (match_operand:DI 2 "" "")))
18689 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18690 (clobber (reg:TI XMM6_REG))
18691 (clobber (reg:TI XMM7_REG))
18692 (clobber (reg:TI XMM8_REG))
18693 (clobber (reg:TI XMM9_REG))
18694 (clobber (reg:TI XMM10_REG))
18695 (clobber (reg:TI XMM11_REG))
18696 (clobber (reg:TI XMM12_REG))
18697 (clobber (reg:TI XMM13_REG))
18698 (clobber (reg:TI XMM14_REG))
18699 (clobber (reg:TI XMM15_REG))
18700 (clobber (reg:DI SI_REG))
18701 (clobber (reg:DI DI_REG))]
18702 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18704 if (constant_call_address_operand (operands[1], Pmode))
18705 return "call\t%P1";
18706 return "call\t%A1";
18708 [(set_attr "type" "callv")])
18710 (define_insn "*call_value_1_rex64_large"
18711 [(set (match_operand 0 "" "")
18712 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
18713 (match_operand:DI 2 "" "")))]
18714 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18716 [(set_attr "type" "callv")])
18718 (define_insn "*sibcall_value_1_rex64"
18719 [(set (match_operand 0 "" "")
18720 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
18721 (match_operand:DI 2 "" "")))]
18722 "TARGET_64BIT && SIBLING_CALL_P (insn)"
18726 [(set_attr "type" "callv")])
18728 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18729 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18730 ;; caught for use by garbage collectors and the like. Using an insn that
18731 ;; maps to SIGILL makes it more likely the program will rightfully die.
18732 ;; Keeping with tradition, "6" is in honor of #UD.
18733 (define_insn "trap"
18734 [(trap_if (const_int 1) (const_int 6))]
18736 { return ASM_SHORT "0x0b0f"; }
18737 [(set_attr "length" "2")])
18739 (define_expand "sse_prologue_save"
18740 [(parallel [(set (match_operand:BLK 0 "" "")
18741 (unspec:BLK [(reg:DI XMM0_REG)
18748 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18749 (use (match_operand:DI 1 "register_operand" ""))
18750 (use (match_operand:DI 2 "immediate_operand" ""))
18751 (use (label_ref:DI (match_operand 3 "" "")))])]
18755 (define_insn "*sse_prologue_save_insn"
18756 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18757 (match_operand:DI 4 "const_int_operand" "n")))
18758 (unspec:BLK [(reg:DI XMM0_REG)
18765 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18766 (use (match_operand:DI 1 "register_operand" "r"))
18767 (use (match_operand:DI 2 "const_int_operand" "i"))
18768 (use (label_ref:DI (match_operand 3 "" "X")))]
18770 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18771 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
18774 operands[0] = gen_rtx_MEM (Pmode,
18775 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
18776 /* VEX instruction with a REX prefix will #UD. */
18777 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
18778 gcc_unreachable ();
18780 output_asm_insn ("jmp\t%A1", operands);
18781 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
18783 operands[4] = adjust_address (operands[0], DImode, i*16);
18784 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
18785 PUT_MODE (operands[4], TImode);
18786 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
18787 output_asm_insn ("rex", operands);
18788 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
18790 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18791 CODE_LABEL_NUMBER (operands[3]));
18794 [(set_attr "type" "other")
18795 (set_attr "length_immediate" "0")
18796 (set_attr "length_address" "0")
18797 (set (attr "length")
18799 (eq (symbol_ref "TARGET_AVX") (const_int 0))
18800 (const_string "34")
18801 (const_string "42")))
18802 (set_attr "memory" "store")
18803 (set_attr "modrm" "0")
18804 (set_attr "prefix" "maybe_vex")
18805 (set_attr "mode" "DI")])
18807 (define_expand "prefetch"
18808 [(prefetch (match_operand 0 "address_operand" "")
18809 (match_operand:SI 1 "const_int_operand" "")
18810 (match_operand:SI 2 "const_int_operand" ""))]
18811 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
18813 int rw = INTVAL (operands[1]);
18814 int locality = INTVAL (operands[2]);
18816 gcc_assert (rw == 0 || rw == 1);
18817 gcc_assert (locality >= 0 && locality <= 3);
18818 gcc_assert (GET_MODE (operands[0]) == Pmode
18819 || GET_MODE (operands[0]) == VOIDmode);
18821 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18822 supported by SSE counterpart or the SSE prefetch is not available
18823 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18825 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
18826 operands[2] = GEN_INT (3);
18828 operands[1] = const0_rtx;
18831 (define_insn "*prefetch_sse"
18832 [(prefetch (match_operand:SI 0 "address_operand" "p")
18834 (match_operand:SI 1 "const_int_operand" ""))]
18835 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
18837 static const char * const patterns[4] = {
18838 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18841 int locality = INTVAL (operands[1]);
18842 gcc_assert (locality >= 0 && locality <= 3);
18844 return patterns[locality];
18846 [(set_attr "type" "sse")
18847 (set_attr "atom_sse_attr" "prefetch")
18848 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18849 (set_attr "memory" "none")])
18851 (define_insn "*prefetch_sse_rex"
18852 [(prefetch (match_operand:DI 0 "address_operand" "p")
18854 (match_operand:SI 1 "const_int_operand" ""))]
18855 "TARGET_PREFETCH_SSE && TARGET_64BIT"
18857 static const char * const patterns[4] = {
18858 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18861 int locality = INTVAL (operands[1]);
18862 gcc_assert (locality >= 0 && locality <= 3);
18864 return patterns[locality];
18866 [(set_attr "type" "sse")
18867 (set_attr "atom_sse_attr" "prefetch")
18868 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18869 (set_attr "memory" "none")])
18871 (define_insn "*prefetch_3dnow"
18872 [(prefetch (match_operand:SI 0 "address_operand" "p")
18873 (match_operand:SI 1 "const_int_operand" "n")
18875 "TARGET_3DNOW && !TARGET_64BIT"
18877 if (INTVAL (operands[1]) == 0)
18878 return "prefetch\t%a0";
18880 return "prefetchw\t%a0";
18882 [(set_attr "type" "mmx")
18883 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18884 (set_attr "memory" "none")])
18886 (define_insn "*prefetch_3dnow_rex"
18887 [(prefetch (match_operand:DI 0 "address_operand" "p")
18888 (match_operand:SI 1 "const_int_operand" "n")
18890 "TARGET_3DNOW && TARGET_64BIT"
18892 if (INTVAL (operands[1]) == 0)
18893 return "prefetch\t%a0";
18895 return "prefetchw\t%a0";
18897 [(set_attr "type" "mmx")
18898 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18899 (set_attr "memory" "none")])
18901 (define_expand "stack_protect_set"
18902 [(match_operand 0 "memory_operand" "")
18903 (match_operand 1 "memory_operand" "")]
18906 #ifdef TARGET_THREAD_SSP_OFFSET
18908 emit_insn (gen_stack_tls_protect_set_di (operands[0],
18909 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18911 emit_insn (gen_stack_tls_protect_set_si (operands[0],
18912 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18915 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18917 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18922 (define_insn "stack_protect_set_si"
18923 [(set (match_operand:SI 0 "memory_operand" "=m")
18924 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18925 (set (match_scratch:SI 2 "=&r") (const_int 0))
18926 (clobber (reg:CC FLAGS_REG))]
18928 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18929 [(set_attr "type" "multi")])
18931 (define_insn "stack_protect_set_di"
18932 [(set (match_operand:DI 0 "memory_operand" "=m")
18933 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18934 (set (match_scratch:DI 2 "=&r") (const_int 0))
18935 (clobber (reg:CC FLAGS_REG))]
18937 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18938 [(set_attr "type" "multi")])
18940 (define_insn "stack_tls_protect_set_si"
18941 [(set (match_operand:SI 0 "memory_operand" "=m")
18942 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18943 (set (match_scratch:SI 2 "=&r") (const_int 0))
18944 (clobber (reg:CC FLAGS_REG))]
18946 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18947 [(set_attr "type" "multi")])
18949 (define_insn "stack_tls_protect_set_di"
18950 [(set (match_operand:DI 0 "memory_operand" "=m")
18951 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18952 (set (match_scratch:DI 2 "=&r") (const_int 0))
18953 (clobber (reg:CC FLAGS_REG))]
18956 /* The kernel uses a different segment register for performance reasons; a
18957 system call would not have to trash the userspace segment register,
18958 which would be expensive */
18959 if (ix86_cmodel != CM_KERNEL)
18960 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18962 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18964 [(set_attr "type" "multi")])
18966 (define_expand "stack_protect_test"
18967 [(match_operand 0 "memory_operand" "")
18968 (match_operand 1 "memory_operand" "")
18969 (match_operand 2 "" "")]
18972 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18974 #ifdef TARGET_THREAD_SSP_OFFSET
18976 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18977 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18979 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18980 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18983 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18985 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18988 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18989 flags, const0_rtx, operands[2]));
18993 (define_insn "stack_protect_test_si"
18994 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18995 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18996 (match_operand:SI 2 "memory_operand" "m")]
18998 (clobber (match_scratch:SI 3 "=&r"))]
19000 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
19001 [(set_attr "type" "multi")])
19003 (define_insn "stack_protect_test_di"
19004 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19005 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
19006 (match_operand:DI 2 "memory_operand" "m")]
19008 (clobber (match_scratch:DI 3 "=&r"))]
19010 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
19011 [(set_attr "type" "multi")])
19013 (define_insn "stack_tls_protect_test_si"
19014 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19015 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
19016 (match_operand:SI 2 "const_int_operand" "i")]
19017 UNSPEC_SP_TLS_TEST))
19018 (clobber (match_scratch:SI 3 "=r"))]
19020 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
19021 [(set_attr "type" "multi")])
19023 (define_insn "stack_tls_protect_test_di"
19024 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19025 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
19026 (match_operand:DI 2 "const_int_operand" "i")]
19027 UNSPEC_SP_TLS_TEST))
19028 (clobber (match_scratch:DI 3 "=r"))]
19031 /* The kernel uses a different segment register for performance reasons; a
19032 system call would not have to trash the userspace segment register,
19033 which would be expensive */
19034 if (ix86_cmodel != CM_KERNEL)
19035 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
19037 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
19039 [(set_attr "type" "multi")])
19041 (define_insn "sse4_2_crc32<mode>"
19042 [(set (match_operand:SI 0 "register_operand" "=r")
19044 [(match_operand:SI 1 "register_operand" "0")
19045 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19047 "TARGET_SSE4_2 || TARGET_CRC32"
19048 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19049 [(set_attr "type" "sselog1")
19050 (set_attr "prefix_rep" "1")
19051 (set_attr "prefix_extra" "1")
19052 (set (attr "prefix_data16")
19053 (if_then_else (match_operand:HI 2 "" "")
19055 (const_string "*")))
19056 (set (attr "prefix_rex")
19057 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
19059 (const_string "*")))
19060 (set_attr "mode" "SI")])
19062 (define_insn "sse4_2_crc32di"
19063 [(set (match_operand:DI 0 "register_operand" "=r")
19065 [(match_operand:DI 1 "register_operand" "0")
19066 (match_operand:DI 2 "nonimmediate_operand" "rm")]
19068 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19069 "crc32{q}\t{%2, %0|%0, %2}"
19070 [(set_attr "type" "sselog1")
19071 (set_attr "prefix_rep" "1")
19072 (set_attr "prefix_extra" "1")
19073 (set_attr "mode" "DI")])
19075 (define_expand "rdpmc"
19076 [(match_operand:DI 0 "register_operand" "")
19077 (match_operand:SI 1 "register_operand" "")]
19080 rtx reg = gen_reg_rtx (DImode);
19083 /* Force operand 1 into ECX. */
19084 rtx ecx = gen_rtx_REG (SImode, CX_REG);
19085 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
19086 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
19091 rtvec vec = rtvec_alloc (2);
19092 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
19093 rtx upper = gen_reg_rtx (DImode);
19094 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
19095 gen_rtvec (1, const0_rtx),
19097 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
19098 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
19100 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
19101 NULL, 1, OPTAB_DIRECT);
19102 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
19106 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
19107 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
19111 (define_insn "*rdpmc"
19112 [(set (match_operand:DI 0 "register_operand" "=A")
19113 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19117 [(set_attr "type" "other")
19118 (set_attr "length" "2")])
19120 (define_insn "*rdpmc_rex64"
19121 [(set (match_operand:DI 0 "register_operand" "=a")
19122 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19124 (set (match_operand:DI 1 "register_operand" "=d")
19125 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
19128 [(set_attr "type" "other")
19129 (set_attr "length" "2")])
19131 (define_expand "rdtsc"
19132 [(set (match_operand:DI 0 "register_operand" "")
19133 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19138 rtvec vec = rtvec_alloc (2);
19139 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
19140 rtx upper = gen_reg_rtx (DImode);
19141 rtx lower = gen_reg_rtx (DImode);
19142 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
19143 gen_rtvec (1, const0_rtx),
19145 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
19146 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
19148 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
19149 NULL, 1, OPTAB_DIRECT);
19150 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
19152 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
19157 (define_insn "*rdtsc"
19158 [(set (match_operand:DI 0 "register_operand" "=A")
19159 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19162 [(set_attr "type" "other")
19163 (set_attr "length" "2")])
19165 (define_insn "*rdtsc_rex64"
19166 [(set (match_operand:DI 0 "register_operand" "=a")
19167 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19168 (set (match_operand:DI 1 "register_operand" "=d")
19169 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19172 [(set_attr "type" "other")
19173 (set_attr "length" "2")])
19175 (define_expand "rdtscp"
19176 [(match_operand:DI 0 "register_operand" "")
19177 (match_operand:SI 1 "memory_operand" "")]
19180 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
19181 gen_rtvec (1, const0_rtx),
19183 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
19184 gen_rtvec (1, const0_rtx),
19186 rtx reg = gen_reg_rtx (DImode);
19187 rtx tmp = gen_reg_rtx (SImode);
19191 rtvec vec = rtvec_alloc (3);
19192 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
19193 rtx upper = gen_reg_rtx (DImode);
19194 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
19195 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
19196 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
19198 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
19199 NULL, 1, OPTAB_DIRECT);
19200 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
19205 rtvec vec = rtvec_alloc (2);
19206 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
19207 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
19208 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
19211 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
19212 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
19216 (define_insn "*rdtscp"
19217 [(set (match_operand:DI 0 "register_operand" "=A")
19218 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19219 (set (match_operand:SI 1 "register_operand" "=c")
19220 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19223 [(set_attr "type" "other")
19224 (set_attr "length" "3")])
19226 (define_insn "*rdtscp_rex64"
19227 [(set (match_operand:DI 0 "register_operand" "=a")
19228 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19229 (set (match_operand:DI 1 "register_operand" "=d")
19230 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19231 (set (match_operand:SI 2 "register_operand" "=c")
19232 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19235 [(set_attr "type" "other")
19236 (set_attr "length" "3")])
19238 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19240 ;; LWP instructions
19242 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19244 (define_expand "lwp_llwpcb"
19245 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
19246 UNSPECV_LLWP_INTRINSIC)]
19250 (define_insn "*lwp_llwpcb<mode>1"
19251 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19252 UNSPECV_LLWP_INTRINSIC)]
19255 [(set_attr "type" "lwp")
19256 (set_attr "mode" "<MODE>")
19257 (set_attr "length" "5")])
19259 (define_expand "lwp_slwpcb"
19260 [(set (match_operand 0 "register_operand" "=r")
19261 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19265 emit_insn (gen_lwp_slwpcbdi (operands[0]));
19267 emit_insn (gen_lwp_slwpcbsi (operands[0]));
19271 (define_insn "lwp_slwpcb<mode>"
19272 [(set (match_operand:P 0 "register_operand" "=r")
19273 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19276 [(set_attr "type" "lwp")
19277 (set_attr "mode" "<MODE>")
19278 (set_attr "length" "5")])
19280 (define_expand "lwp_lwpval<mode>3"
19281 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
19282 (match_operand:SI 2 "nonimmediate_operand" "rm")
19283 (match_operand:SI 3 "const_int_operand" "i")]
19284 UNSPECV_LWPVAL_INTRINSIC)]
19286 "/* Avoid unused variable warning. */
19289 (define_insn "*lwp_lwpval<mode>3_1"
19290 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19291 (match_operand:SI 1 "nonimmediate_operand" "rm")
19292 (match_operand:SI 2 "const_int_operand" "i")]
19293 UNSPECV_LWPVAL_INTRINSIC)]
19295 "lwpval\t{%2, %1, %0|%0, %1, %2}"
19296 [(set_attr "type" "lwp")
19297 (set_attr "mode" "<MODE>")
19298 (set (attr "length")
19299 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19301 (define_expand "lwp_lwpins<mode>3"
19302 [(set (reg:CCC FLAGS_REG)
19303 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
19304 (match_operand:SI 2 "nonimmediate_operand" "rm")
19305 (match_operand:SI 3 "const_int_operand" "i")]
19306 UNSPECV_LWPINS_INTRINSIC))
19307 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
19308 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19312 (define_insn "*lwp_lwpins<mode>3_1"
19313 [(set (reg:CCC FLAGS_REG)
19314 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19315 (match_operand:SI 1 "nonimmediate_operand" "rm")
19316 (match_operand:SI 2 "const_int_operand" "i")]
19317 UNSPECV_LWPINS_INTRINSIC))]
19319 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19320 [(set_attr "type" "lwp")
19321 (set_attr "mode" "<MODE>")
19322 (set (attr "length")
19323 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19327 (include "sync.md")