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 abs neg operators
728 (define_code_iterator absneg [abs neg])
730 ;; Base name for x87 insn mnemonic.
731 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
733 ;; Used in signed and unsigned widening multiplications.
734 (define_code_iterator any_extend [sign_extend zero_extend])
736 ;; Various insn prefixes for signed and unsigned operations.
737 (define_code_attr u [(sign_extend "") (zero_extend "u")
738 (div "") (udiv "u")])
739 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
741 ;; Used in signed and unsigned divisions.
742 (define_code_iterator any_div [div udiv])
744 ;; Instruction prefix for signed and unsigned operations.
745 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
746 (div "i") (udiv "")])
748 ;; All single word integer modes.
749 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
751 ;; Single word integer modes without DImode.
752 (define_mode_iterator SWI124 [QI HI SI])
754 ;; Single word integer modes without QImode.
755 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
757 ;; Single word integer modes without QImode and HImode.
758 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
760 ;; All math-dependant single and double word integer modes.
761 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
762 (HI "TARGET_HIMODE_MATH")
763 SI DI (TI "TARGET_64BIT")])
765 ;; Math-dependant single word integer modes.
766 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
767 (HI "TARGET_HIMODE_MATH")
768 SI (DI "TARGET_64BIT")])
770 ;; Math-dependant single word integer modes without QImode.
771 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
772 SI (DI "TARGET_64BIT")])
774 ;; Double word integer modes.
775 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
776 (TI "TARGET_64BIT")])
778 ;; Double word integer modes as mode attribute.
779 (define_mode_attr DWI [(SI "DI") (DI "TI")])
780 (define_mode_attr dwi [(SI "di") (DI "ti")])
782 ;; Half mode for double word integer modes.
783 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
784 (DI "TARGET_64BIT")])
786 ;; Instruction suffix for integer modes.
787 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
789 ;; Register class for integer modes.
790 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
792 ;; Immediate operand constraint for integer modes.
793 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
795 ;; General operand constraint for word modes.
796 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
798 ;; Immediate operand constraint for double integer modes.
799 (define_mode_attr di [(SI "iF") (DI "e")])
801 ;; Immediate operand constraint for shifts.
802 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
804 ;; General operand predicate for integer modes.
805 (define_mode_attr general_operand
806 [(QI "general_operand")
807 (HI "general_operand")
808 (SI "general_operand")
809 (DI "x86_64_general_operand")
810 (TI "x86_64_general_operand")])
812 ;; General sign/zero extend operand predicate for integer modes.
813 (define_mode_attr general_szext_operand
814 [(QI "general_operand")
815 (HI "general_operand")
816 (SI "general_operand")
817 (DI "x86_64_szext_general_operand")])
819 ;; Operand predicate for shifts.
820 (define_mode_attr shift_operand
821 [(QI "nonimmediate_operand")
822 (HI "nonimmediate_operand")
823 (SI "nonimmediate_operand")
824 (DI "shiftdi_operand")
825 (TI "register_operand")])
827 ;; Operand predicate for shift argument.
828 (define_mode_attr shift_immediate_operand
829 [(QI "const_1_to_31_operand")
830 (HI "const_1_to_31_operand")
831 (SI "const_1_to_31_operand")
832 (DI "const_1_to_63_operand")])
834 ;; Input operand predicate for arithmetic left shifts.
835 (define_mode_attr ashl_input_operand
836 [(QI "nonimmediate_operand")
837 (HI "nonimmediate_operand")
838 (SI "nonimmediate_operand")
839 (DI "ashldi_input_operand")
840 (TI "reg_or_pm1_operand")])
842 ;; SSE and x87 SFmode and DFmode floating point modes
843 (define_mode_iterator MODEF [SF DF])
845 ;; All x87 floating point modes
846 (define_mode_iterator X87MODEF [SF DF XF])
848 ;; All integer modes handled by x87 fisttp operator.
849 (define_mode_iterator X87MODEI [HI SI DI])
851 ;; All integer modes handled by integer x87 operators.
852 (define_mode_iterator X87MODEI12 [HI SI])
854 ;; All integer modes handled by SSE cvtts?2si* operators.
855 (define_mode_iterator SSEMODEI24 [SI DI])
857 ;; SSE asm suffix for floating point modes
858 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
860 ;; SSE vector mode corresponding to a scalar mode
861 (define_mode_attr ssevecmode
862 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
864 ;; Instruction suffix for REX 64bit operators.
865 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
867 ;; This mode iterator allows :P to be used for patterns that operate on
868 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
869 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
871 ;; Scheduling descriptions
873 (include "pentium.md")
876 (include "athlon.md")
881 ;; Operand and operator predicates and constraints
883 (include "predicates.md")
884 (include "constraints.md")
887 ;; Compare and branch/compare and store instructions.
889 (define_expand "cbranch<mode>4"
890 [(set (reg:CC FLAGS_REG)
891 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
892 (match_operand:SDWIM 2 "<general_operand>" "")))
893 (set (pc) (if_then_else
894 (match_operator 0 "comparison_operator"
895 [(reg:CC FLAGS_REG) (const_int 0)])
896 (label_ref (match_operand 3 "" ""))
900 if (MEM_P (operands[1]) && MEM_P (operands[2]))
901 operands[1] = force_reg (<MODE>mode, operands[1]);
902 ix86_compare_op0 = operands[1];
903 ix86_compare_op1 = operands[2];
904 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
908 (define_expand "cstore<mode>4"
909 [(set (reg:CC FLAGS_REG)
910 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
911 (match_operand:SWIM 3 "<general_operand>" "")))
912 (set (match_operand:QI 0 "register_operand" "")
913 (match_operator 1 "comparison_operator"
914 [(reg:CC FLAGS_REG) (const_int 0)]))]
917 if (MEM_P (operands[2]) && MEM_P (operands[3]))
918 operands[2] = force_reg (<MODE>mode, operands[2]);
919 ix86_compare_op0 = operands[2];
920 ix86_compare_op1 = operands[3];
921 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
925 (define_expand "cmp<mode>_1"
926 [(set (reg:CC FLAGS_REG)
927 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
928 (match_operand:SWI48 1 "<general_operand>" "")))]
932 (define_insn "*cmp<mode>_ccno_1"
933 [(set (reg FLAGS_REG)
934 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
935 (match_operand:SWI 1 "const0_operand" "")))]
936 "ix86_match_ccmode (insn, CCNOmode)"
938 test{<imodesuffix>}\t%0, %0
939 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
940 [(set_attr "type" "test,icmp")
941 (set_attr "length_immediate" "0,1")
942 (set_attr "mode" "<MODE>")])
944 (define_insn "*cmp<mode>_1"
945 [(set (reg FLAGS_REG)
946 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
947 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
948 "ix86_match_ccmode (insn, CCmode)"
949 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
950 [(set_attr "type" "icmp")
951 (set_attr "mode" "<MODE>")])
953 (define_insn "*cmp<mode>_minus_1"
954 [(set (reg FLAGS_REG)
956 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
957 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
959 "ix86_match_ccmode (insn, CCGOCmode)"
960 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
961 [(set_attr "type" "icmp")
962 (set_attr "mode" "<MODE>")])
964 (define_insn "*cmpqi_ext_1"
965 [(set (reg FLAGS_REG)
967 (match_operand:QI 0 "general_operand" "Qm")
970 (match_operand 1 "ext_register_operand" "Q")
973 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
974 "cmp{b}\t{%h1, %0|%0, %h1}"
975 [(set_attr "type" "icmp")
976 (set_attr "mode" "QI")])
978 (define_insn "*cmpqi_ext_1_rex64"
979 [(set (reg FLAGS_REG)
981 (match_operand:QI 0 "register_operand" "Q")
984 (match_operand 1 "ext_register_operand" "Q")
987 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
988 "cmp{b}\t{%h1, %0|%0, %h1}"
989 [(set_attr "type" "icmp")
990 (set_attr "mode" "QI")])
992 (define_insn "*cmpqi_ext_2"
993 [(set (reg FLAGS_REG)
997 (match_operand 0 "ext_register_operand" "Q")
1000 (match_operand:QI 1 "const0_operand" "")))]
1001 "ix86_match_ccmode (insn, CCNOmode)"
1003 [(set_attr "type" "test")
1004 (set_attr "length_immediate" "0")
1005 (set_attr "mode" "QI")])
1007 (define_expand "cmpqi_ext_3"
1008 [(set (reg:CC FLAGS_REG)
1012 (match_operand 0 "ext_register_operand" "")
1015 (match_operand:QI 1 "immediate_operand" "")))]
1019 (define_insn "*cmpqi_ext_3_insn"
1020 [(set (reg FLAGS_REG)
1024 (match_operand 0 "ext_register_operand" "Q")
1027 (match_operand:QI 1 "general_operand" "Qmn")))]
1028 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1029 "cmp{b}\t{%1, %h0|%h0, %1}"
1030 [(set_attr "type" "icmp")
1031 (set_attr "modrm" "1")
1032 (set_attr "mode" "QI")])
1034 (define_insn "*cmpqi_ext_3_insn_rex64"
1035 [(set (reg FLAGS_REG)
1039 (match_operand 0 "ext_register_operand" "Q")
1042 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1043 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1044 "cmp{b}\t{%1, %h0|%h0, %1}"
1045 [(set_attr "type" "icmp")
1046 (set_attr "modrm" "1")
1047 (set_attr "mode" "QI")])
1049 (define_insn "*cmpqi_ext_4"
1050 [(set (reg FLAGS_REG)
1054 (match_operand 0 "ext_register_operand" "Q")
1059 (match_operand 1 "ext_register_operand" "Q")
1061 (const_int 8)) 0)))]
1062 "ix86_match_ccmode (insn, CCmode)"
1063 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1064 [(set_attr "type" "icmp")
1065 (set_attr "mode" "QI")])
1067 ;; These implement float point compares.
1068 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1069 ;; which would allow mix and match FP modes on the compares. Which is what
1070 ;; the old patterns did, but with many more of them.
1072 (define_expand "cbranchxf4"
1073 [(set (reg:CC FLAGS_REG)
1074 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1075 (match_operand:XF 2 "nonmemory_operand" "")))
1076 (set (pc) (if_then_else
1077 (match_operator 0 "ix86_fp_comparison_operator"
1080 (label_ref (match_operand 3 "" ""))
1084 ix86_compare_op0 = operands[1];
1085 ix86_compare_op1 = operands[2];
1086 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1090 (define_expand "cstorexf4"
1091 [(set (reg:CC FLAGS_REG)
1092 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1093 (match_operand:XF 3 "nonmemory_operand" "")))
1094 (set (match_operand:QI 0 "register_operand" "")
1095 (match_operator 1 "ix86_fp_comparison_operator"
1100 ix86_compare_op0 = operands[2];
1101 ix86_compare_op1 = operands[3];
1102 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1106 (define_expand "cbranch<mode>4"
1107 [(set (reg:CC FLAGS_REG)
1108 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1109 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1110 (set (pc) (if_then_else
1111 (match_operator 0 "ix86_fp_comparison_operator"
1114 (label_ref (match_operand 3 "" ""))
1116 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1118 ix86_compare_op0 = operands[1];
1119 ix86_compare_op1 = operands[2];
1120 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1124 (define_expand "cstore<mode>4"
1125 [(set (reg:CC FLAGS_REG)
1126 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1127 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1128 (set (match_operand:QI 0 "register_operand" "")
1129 (match_operator 1 "ix86_fp_comparison_operator"
1132 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1134 ix86_compare_op0 = operands[2];
1135 ix86_compare_op1 = operands[3];
1136 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1140 (define_expand "cbranchcc4"
1141 [(set (pc) (if_then_else
1142 (match_operator 0 "comparison_operator"
1143 [(match_operand 1 "flags_reg_operand" "")
1144 (match_operand 2 "const0_operand" "")])
1145 (label_ref (match_operand 3 "" ""))
1149 ix86_compare_op0 = operands[1];
1150 ix86_compare_op1 = operands[2];
1151 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1155 (define_expand "cstorecc4"
1156 [(set (match_operand:QI 0 "register_operand" "")
1157 (match_operator 1 "comparison_operator"
1158 [(match_operand 2 "flags_reg_operand" "")
1159 (match_operand 3 "const0_operand" "")]))]
1162 ix86_compare_op0 = operands[2];
1163 ix86_compare_op1 = operands[3];
1164 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1169 ;; FP compares, step 1:
1170 ;; Set the FP condition codes.
1172 ;; CCFPmode compare with exceptions
1173 ;; CCFPUmode compare with no exceptions
1175 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1176 ;; used to manage the reg stack popping would not be preserved.
1178 (define_insn "*cmpfp_0"
1179 [(set (match_operand:HI 0 "register_operand" "=a")
1182 (match_operand 1 "register_operand" "f")
1183 (match_operand 2 "const0_operand" ""))]
1185 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1186 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1187 "* return output_fp_compare (insn, operands, 0, 0);"
1188 [(set_attr "type" "multi")
1189 (set_attr "unit" "i387")
1191 (cond [(match_operand:SF 1 "" "")
1193 (match_operand:DF 1 "" "")
1196 (const_string "XF")))])
1198 (define_insn_and_split "*cmpfp_0_cc"
1199 [(set (reg:CCFP FLAGS_REG)
1201 (match_operand 1 "register_operand" "f")
1202 (match_operand 2 "const0_operand" "")))
1203 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1204 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1205 && TARGET_SAHF && !TARGET_CMOVE
1206 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1208 "&& reload_completed"
1211 [(compare:CCFP (match_dup 1)(match_dup 2))]
1213 (set (reg:CC FLAGS_REG)
1214 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1216 [(set_attr "type" "multi")
1217 (set_attr "unit" "i387")
1219 (cond [(match_operand:SF 1 "" "")
1221 (match_operand:DF 1 "" "")
1224 (const_string "XF")))])
1226 (define_insn "*cmpfp_xf"
1227 [(set (match_operand:HI 0 "register_operand" "=a")
1230 (match_operand:XF 1 "register_operand" "f")
1231 (match_operand:XF 2 "register_operand" "f"))]
1234 "* return output_fp_compare (insn, operands, 0, 0);"
1235 [(set_attr "type" "multi")
1236 (set_attr "unit" "i387")
1237 (set_attr "mode" "XF")])
1239 (define_insn_and_split "*cmpfp_xf_cc"
1240 [(set (reg:CCFP FLAGS_REG)
1242 (match_operand:XF 1 "register_operand" "f")
1243 (match_operand:XF 2 "register_operand" "f")))
1244 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1246 && TARGET_SAHF && !TARGET_CMOVE"
1248 "&& reload_completed"
1251 [(compare:CCFP (match_dup 1)(match_dup 2))]
1253 (set (reg:CC FLAGS_REG)
1254 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1256 [(set_attr "type" "multi")
1257 (set_attr "unit" "i387")
1258 (set_attr "mode" "XF")])
1260 (define_insn "*cmpfp_<mode>"
1261 [(set (match_operand:HI 0 "register_operand" "=a")
1264 (match_operand:MODEF 1 "register_operand" "f")
1265 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1268 "* return output_fp_compare (insn, operands, 0, 0);"
1269 [(set_attr "type" "multi")
1270 (set_attr "unit" "i387")
1271 (set_attr "mode" "<MODE>")])
1273 (define_insn_and_split "*cmpfp_<mode>_cc"
1274 [(set (reg:CCFP FLAGS_REG)
1276 (match_operand:MODEF 1 "register_operand" "f")
1277 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1278 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1280 && TARGET_SAHF && !TARGET_CMOVE"
1282 "&& reload_completed"
1285 [(compare:CCFP (match_dup 1)(match_dup 2))]
1287 (set (reg:CC FLAGS_REG)
1288 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1290 [(set_attr "type" "multi")
1291 (set_attr "unit" "i387")
1292 (set_attr "mode" "<MODE>")])
1294 (define_insn "*cmpfp_u"
1295 [(set (match_operand:HI 0 "register_operand" "=a")
1298 (match_operand 1 "register_operand" "f")
1299 (match_operand 2 "register_operand" "f"))]
1301 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1302 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1303 "* return output_fp_compare (insn, operands, 0, 1);"
1304 [(set_attr "type" "multi")
1305 (set_attr "unit" "i387")
1307 (cond [(match_operand:SF 1 "" "")
1309 (match_operand:DF 1 "" "")
1312 (const_string "XF")))])
1314 (define_insn_and_split "*cmpfp_u_cc"
1315 [(set (reg:CCFPU FLAGS_REG)
1317 (match_operand 1 "register_operand" "f")
1318 (match_operand 2 "register_operand" "f")))
1319 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1320 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1321 && TARGET_SAHF && !TARGET_CMOVE
1322 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1324 "&& reload_completed"
1327 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1329 (set (reg:CC FLAGS_REG)
1330 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1332 [(set_attr "type" "multi")
1333 (set_attr "unit" "i387")
1335 (cond [(match_operand:SF 1 "" "")
1337 (match_operand:DF 1 "" "")
1340 (const_string "XF")))])
1342 (define_insn "*cmpfp_<mode>"
1343 [(set (match_operand:HI 0 "register_operand" "=a")
1346 (match_operand 1 "register_operand" "f")
1347 (match_operator 3 "float_operator"
1348 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1350 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1351 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1352 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1353 "* return output_fp_compare (insn, operands, 0, 0);"
1354 [(set_attr "type" "multi")
1355 (set_attr "unit" "i387")
1356 (set_attr "fp_int_src" "true")
1357 (set_attr "mode" "<MODE>")])
1359 (define_insn_and_split "*cmpfp_<mode>_cc"
1360 [(set (reg:CCFP FLAGS_REG)
1362 (match_operand 1 "register_operand" "f")
1363 (match_operator 3 "float_operator"
1364 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1365 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1366 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1367 && TARGET_SAHF && !TARGET_CMOVE
1368 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1369 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1371 "&& reload_completed"
1376 (match_op_dup 3 [(match_dup 2)]))]
1378 (set (reg:CC FLAGS_REG)
1379 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1381 [(set_attr "type" "multi")
1382 (set_attr "unit" "i387")
1383 (set_attr "fp_int_src" "true")
1384 (set_attr "mode" "<MODE>")])
1386 ;; FP compares, step 2
1387 ;; Move the fpsw to ax.
1389 (define_insn "x86_fnstsw_1"
1390 [(set (match_operand:HI 0 "register_operand" "=a")
1391 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1394 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1395 (set_attr "mode" "SI")
1396 (set_attr "unit" "i387")])
1398 ;; FP compares, step 3
1399 ;; Get ax into flags, general case.
1401 (define_insn "x86_sahf_1"
1402 [(set (reg:CC FLAGS_REG)
1403 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1407 #ifdef HAVE_AS_IX86_SAHF
1410 return ASM_BYTE "0x9e";
1413 [(set_attr "length" "1")
1414 (set_attr "athlon_decode" "vector")
1415 (set_attr "amdfam10_decode" "direct")
1416 (set_attr "mode" "SI")])
1418 ;; Pentium Pro can do steps 1 through 3 in one go.
1419 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1420 (define_insn "*cmpfp_i_mixed"
1421 [(set (reg:CCFP FLAGS_REG)
1422 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1423 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1424 "TARGET_MIX_SSE_I387
1425 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1426 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1427 "* return output_fp_compare (insn, operands, 1, 0);"
1428 [(set_attr "type" "fcmp,ssecomi")
1429 (set_attr "prefix" "orig,maybe_vex")
1431 (if_then_else (match_operand:SF 1 "" "")
1433 (const_string "DF")))
1434 (set (attr "prefix_rep")
1435 (if_then_else (eq_attr "type" "ssecomi")
1437 (const_string "*")))
1438 (set (attr "prefix_data16")
1439 (cond [(eq_attr "type" "fcmp")
1441 (eq_attr "mode" "DF")
1444 (const_string "0")))
1445 (set_attr "athlon_decode" "vector")
1446 (set_attr "amdfam10_decode" "direct")])
1448 (define_insn "*cmpfp_i_sse"
1449 [(set (reg:CCFP FLAGS_REG)
1450 (compare:CCFP (match_operand 0 "register_operand" "x")
1451 (match_operand 1 "nonimmediate_operand" "xm")))]
1453 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1454 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1455 "* return output_fp_compare (insn, operands, 1, 0);"
1456 [(set_attr "type" "ssecomi")
1457 (set_attr "prefix" "maybe_vex")
1459 (if_then_else (match_operand:SF 1 "" "")
1461 (const_string "DF")))
1462 (set_attr "prefix_rep" "0")
1463 (set (attr "prefix_data16")
1464 (if_then_else (eq_attr "mode" "DF")
1466 (const_string "0")))
1467 (set_attr "athlon_decode" "vector")
1468 (set_attr "amdfam10_decode" "direct")])
1470 (define_insn "*cmpfp_i_i387"
1471 [(set (reg:CCFP FLAGS_REG)
1472 (compare:CCFP (match_operand 0 "register_operand" "f")
1473 (match_operand 1 "register_operand" "f")))]
1474 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1476 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1477 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1478 "* return output_fp_compare (insn, operands, 1, 0);"
1479 [(set_attr "type" "fcmp")
1481 (cond [(match_operand:SF 1 "" "")
1483 (match_operand:DF 1 "" "")
1486 (const_string "XF")))
1487 (set_attr "athlon_decode" "vector")
1488 (set_attr "amdfam10_decode" "direct")])
1490 (define_insn "*cmpfp_iu_mixed"
1491 [(set (reg:CCFPU FLAGS_REG)
1492 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1493 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1494 "TARGET_MIX_SSE_I387
1495 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1496 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1497 "* return output_fp_compare (insn, operands, 1, 1);"
1498 [(set_attr "type" "fcmp,ssecomi")
1499 (set_attr "prefix" "orig,maybe_vex")
1501 (if_then_else (match_operand:SF 1 "" "")
1503 (const_string "DF")))
1504 (set (attr "prefix_rep")
1505 (if_then_else (eq_attr "type" "ssecomi")
1507 (const_string "*")))
1508 (set (attr "prefix_data16")
1509 (cond [(eq_attr "type" "fcmp")
1511 (eq_attr "mode" "DF")
1514 (const_string "0")))
1515 (set_attr "athlon_decode" "vector")
1516 (set_attr "amdfam10_decode" "direct")])
1518 (define_insn "*cmpfp_iu_sse"
1519 [(set (reg:CCFPU FLAGS_REG)
1520 (compare:CCFPU (match_operand 0 "register_operand" "x")
1521 (match_operand 1 "nonimmediate_operand" "xm")))]
1523 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1524 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1525 "* return output_fp_compare (insn, operands, 1, 1);"
1526 [(set_attr "type" "ssecomi")
1527 (set_attr "prefix" "maybe_vex")
1529 (if_then_else (match_operand:SF 1 "" "")
1531 (const_string "DF")))
1532 (set_attr "prefix_rep" "0")
1533 (set (attr "prefix_data16")
1534 (if_then_else (eq_attr "mode" "DF")
1536 (const_string "0")))
1537 (set_attr "athlon_decode" "vector")
1538 (set_attr "amdfam10_decode" "direct")])
1540 (define_insn "*cmpfp_iu_387"
1541 [(set (reg:CCFPU FLAGS_REG)
1542 (compare:CCFPU (match_operand 0 "register_operand" "f")
1543 (match_operand 1 "register_operand" "f")))]
1544 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1546 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1547 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1548 "* return output_fp_compare (insn, operands, 1, 1);"
1549 [(set_attr "type" "fcmp")
1551 (cond [(match_operand:SF 1 "" "")
1553 (match_operand:DF 1 "" "")
1556 (const_string "XF")))
1557 (set_attr "athlon_decode" "vector")
1558 (set_attr "amdfam10_decode" "direct")])
1560 ;; Move instructions.
1562 ;; General case of fullword move.
1564 (define_expand "movsi"
1565 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1566 (match_operand:SI 1 "general_operand" ""))]
1568 "ix86_expand_move (SImode, operands); DONE;")
1570 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1573 ;; %%% We don't use a post-inc memory reference because x86 is not a
1574 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1575 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1576 ;; targets without our curiosities, and it is just as easy to represent
1577 ;; this differently.
1579 (define_insn "*pushsi2"
1580 [(set (match_operand:SI 0 "push_operand" "=<")
1581 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1584 [(set_attr "type" "push")
1585 (set_attr "mode" "SI")])
1587 ;; For 64BIT abi we always round up to 8 bytes.
1588 (define_insn "*pushsi2_rex64"
1589 [(set (match_operand:SI 0 "push_operand" "=X")
1590 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1593 [(set_attr "type" "push")
1594 (set_attr "mode" "SI")])
1596 (define_insn "*pushsi2_prologue"
1597 [(set (match_operand:SI 0 "push_operand" "=<")
1598 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1599 (clobber (mem:BLK (scratch)))]
1602 [(set_attr "type" "push")
1603 (set_attr "mode" "SI")])
1605 (define_insn "*popsi1_epilogue"
1606 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1607 (mem:SI (reg:SI SP_REG)))
1608 (set (reg:SI SP_REG)
1609 (plus:SI (reg:SI SP_REG) (const_int 4)))
1610 (clobber (mem:BLK (scratch)))]
1613 [(set_attr "type" "pop")
1614 (set_attr "mode" "SI")])
1616 (define_insn "popsi1"
1617 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1618 (mem:SI (reg:SI SP_REG)))
1619 (set (reg:SI SP_REG)
1620 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1623 [(set_attr "type" "pop")
1624 (set_attr "mode" "SI")])
1626 (define_insn "*movsi_xor"
1627 [(set (match_operand:SI 0 "register_operand" "=r")
1628 (match_operand:SI 1 "const0_operand" ""))
1629 (clobber (reg:CC FLAGS_REG))]
1632 [(set_attr "type" "alu1")
1633 (set_attr "mode" "SI")
1634 (set_attr "length_immediate" "0")])
1636 (define_insn "*movsi_or"
1637 [(set (match_operand:SI 0 "register_operand" "=r")
1638 (match_operand:SI 1 "immediate_operand" "i"))
1639 (clobber (reg:CC FLAGS_REG))]
1641 && operands[1] == constm1_rtx"
1643 operands[1] = constm1_rtx;
1644 return "or{l}\t{%1, %0|%0, %1}";
1646 [(set_attr "type" "alu1")
1647 (set_attr "mode" "SI")
1648 (set_attr "length_immediate" "1")])
1650 (define_insn "*movsi_1"
1651 [(set (match_operand:SI 0 "nonimmediate_operand"
1652 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1653 (match_operand:SI 1 "general_operand"
1654 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1655 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1657 switch (get_attr_type (insn))
1660 if (get_attr_mode (insn) == MODE_TI)
1661 return "%vpxor\t%0, %d0";
1662 return "%vxorps\t%0, %d0";
1665 switch (get_attr_mode (insn))
1668 return "%vmovdqa\t{%1, %0|%0, %1}";
1670 return "%vmovaps\t{%1, %0|%0, %1}";
1672 return "%vmovd\t{%1, %0|%0, %1}";
1674 return "%vmovss\t{%1, %0|%0, %1}";
1680 return "pxor\t%0, %0";
1683 if (get_attr_mode (insn) == MODE_DI)
1684 return "movq\t{%1, %0|%0, %1}";
1685 return "movd\t{%1, %0|%0, %1}";
1688 return "lea{l}\t{%1, %0|%0, %1}";
1691 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1692 return "mov{l}\t{%1, %0|%0, %1}";
1696 (cond [(eq_attr "alternative" "2")
1697 (const_string "mmx")
1698 (eq_attr "alternative" "3,4,5")
1699 (const_string "mmxmov")
1700 (eq_attr "alternative" "6")
1701 (const_string "sselog1")
1702 (eq_attr "alternative" "7,8,9,10,11")
1703 (const_string "ssemov")
1704 (match_operand:DI 1 "pic_32bit_operand" "")
1705 (const_string "lea")
1707 (const_string "imov")))
1708 (set (attr "prefix")
1709 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1710 (const_string "orig")
1711 (const_string "maybe_vex")))
1712 (set (attr "prefix_data16")
1713 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1715 (const_string "*")))
1717 (cond [(eq_attr "alternative" "2,3")
1719 (eq_attr "alternative" "6,7")
1721 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1722 (const_string "V4SF")
1723 (const_string "TI"))
1724 (and (eq_attr "alternative" "8,9,10,11")
1725 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1728 (const_string "SI")))])
1730 ;; Stores and loads of ax to arbitrary constant address.
1731 ;; We fake an second form of instruction to force reload to load address
1732 ;; into register when rax is not available
1733 (define_insn "*movabssi_1_rex64"
1734 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1735 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1736 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1738 movabs{l}\t{%1, %P0|%P0, %1}
1739 mov{l}\t{%1, %a0|%a0, %1}"
1740 [(set_attr "type" "imov")
1741 (set_attr "modrm" "0,*")
1742 (set_attr "length_address" "8,0")
1743 (set_attr "length_immediate" "0,*")
1744 (set_attr "memory" "store")
1745 (set_attr "mode" "SI")])
1747 (define_insn "*movabssi_2_rex64"
1748 [(set (match_operand:SI 0 "register_operand" "=a,r")
1749 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1750 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1752 movabs{l}\t{%P1, %0|%0, %P1}
1753 mov{l}\t{%a1, %0|%0, %a1}"
1754 [(set_attr "type" "imov")
1755 (set_attr "modrm" "0,*")
1756 (set_attr "length_address" "8,0")
1757 (set_attr "length_immediate" "0")
1758 (set_attr "memory" "load")
1759 (set_attr "mode" "SI")])
1761 (define_insn "*swapsi"
1762 [(set (match_operand:SI 0 "register_operand" "+r")
1763 (match_operand:SI 1 "register_operand" "+r"))
1768 [(set_attr "type" "imov")
1769 (set_attr "mode" "SI")
1770 (set_attr "pent_pair" "np")
1771 (set_attr "athlon_decode" "vector")
1772 (set_attr "amdfam10_decode" "double")])
1774 (define_expand "movhi"
1775 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1776 (match_operand:HI 1 "general_operand" ""))]
1778 "ix86_expand_move (HImode, operands); DONE;")
1780 (define_insn "*pushhi2"
1781 [(set (match_operand:HI 0 "push_operand" "=X")
1782 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1785 [(set_attr "type" "push")
1786 (set_attr "mode" "SI")])
1788 ;; For 64BIT abi we always round up to 8 bytes.
1789 (define_insn "*pushhi2_rex64"
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" "DI")])
1797 (define_insn "*movhi_1"
1798 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1799 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1800 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1802 switch (get_attr_type (insn))
1805 /* movzwl is faster than movw on p2 due to partial word stalls,
1806 though not as fast as an aligned movl. */
1807 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1809 if (get_attr_mode (insn) == MODE_SI)
1810 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1812 return "mov{w}\t{%1, %0|%0, %1}";
1816 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1817 (const_string "imov")
1818 (and (eq_attr "alternative" "0")
1819 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1821 (eq (symbol_ref "TARGET_HIMODE_MATH")
1823 (const_string "imov")
1824 (and (eq_attr "alternative" "1,2")
1825 (match_operand:HI 1 "aligned_operand" ""))
1826 (const_string "imov")
1827 (and (ne (symbol_ref "TARGET_MOVX")
1829 (eq_attr "alternative" "0,2"))
1830 (const_string "imovx")
1832 (const_string "imov")))
1834 (cond [(eq_attr "type" "imovx")
1836 (and (eq_attr "alternative" "1,2")
1837 (match_operand:HI 1 "aligned_operand" ""))
1839 (and (eq_attr "alternative" "0")
1840 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1842 (eq (symbol_ref "TARGET_HIMODE_MATH")
1846 (const_string "HI")))])
1848 ;; Stores and loads of ax to arbitrary constant address.
1849 ;; We fake an second form of instruction to force reload to load address
1850 ;; into register when rax is not available
1851 (define_insn "*movabshi_1_rex64"
1852 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1853 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1854 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1856 movabs{w}\t{%1, %P0|%P0, %1}
1857 mov{w}\t{%1, %a0|%a0, %1}"
1858 [(set_attr "type" "imov")
1859 (set_attr "modrm" "0,*")
1860 (set_attr "length_address" "8,0")
1861 (set_attr "length_immediate" "0,*")
1862 (set_attr "memory" "store")
1863 (set_attr "mode" "HI")])
1865 (define_insn "*movabshi_2_rex64"
1866 [(set (match_operand:HI 0 "register_operand" "=a,r")
1867 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1868 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1870 movabs{w}\t{%P1, %0|%0, %P1}
1871 mov{w}\t{%a1, %0|%0, %a1}"
1872 [(set_attr "type" "imov")
1873 (set_attr "modrm" "0,*")
1874 (set_attr "length_address" "8,0")
1875 (set_attr "length_immediate" "0")
1876 (set_attr "memory" "load")
1877 (set_attr "mode" "HI")])
1879 (define_insn "*swaphi_1"
1880 [(set (match_operand:HI 0 "register_operand" "+r")
1881 (match_operand:HI 1 "register_operand" "+r"))
1884 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1886 [(set_attr "type" "imov")
1887 (set_attr "mode" "SI")
1888 (set_attr "pent_pair" "np")
1889 (set_attr "athlon_decode" "vector")
1890 (set_attr "amdfam10_decode" "double")])
1892 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1893 (define_insn "*swaphi_2"
1894 [(set (match_operand:HI 0 "register_operand" "+r")
1895 (match_operand:HI 1 "register_operand" "+r"))
1898 "TARGET_PARTIAL_REG_STALL"
1900 [(set_attr "type" "imov")
1901 (set_attr "mode" "HI")
1902 (set_attr "pent_pair" "np")
1903 (set_attr "athlon_decode" "vector")])
1905 (define_expand "movstricthi"
1906 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1907 (match_operand:HI 1 "general_operand" ""))]
1910 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1912 /* Don't generate memory->memory moves, go through a register */
1913 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1914 operands[1] = force_reg (HImode, operands[1]);
1917 (define_insn "*movstricthi_1"
1918 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1919 (match_operand:HI 1 "general_operand" "rn,m"))]
1920 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1921 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1922 "mov{w}\t{%1, %0|%0, %1}"
1923 [(set_attr "type" "imov")
1924 (set_attr "mode" "HI")])
1926 (define_insn "*movstricthi_xor"
1927 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1928 (match_operand:HI 1 "const0_operand" ""))
1929 (clobber (reg:CC FLAGS_REG))]
1932 [(set_attr "type" "alu1")
1933 (set_attr "mode" "HI")
1934 (set_attr "length_immediate" "0")])
1936 (define_expand "movqi"
1937 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1938 (match_operand:QI 1 "general_operand" ""))]
1940 "ix86_expand_move (QImode, operands); DONE;")
1942 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1943 ;; "push a byte". But actually we use pushl, which has the effect
1944 ;; of rounding the amount pushed up to a word.
1946 (define_insn "*pushqi2"
1947 [(set (match_operand:QI 0 "push_operand" "=X")
1948 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1951 [(set_attr "type" "push")
1952 (set_attr "mode" "SI")])
1954 ;; For 64BIT abi we always round up to 8 bytes.
1955 (define_insn "*pushqi2_rex64"
1956 [(set (match_operand:QI 0 "push_operand" "=X")
1957 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1960 [(set_attr "type" "push")
1961 (set_attr "mode" "DI")])
1963 ;; Situation is quite tricky about when to choose full sized (SImode) move
1964 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1965 ;; partial register dependency machines (such as AMD Athlon), where QImode
1966 ;; moves issue extra dependency and for partial register stalls machines
1967 ;; that don't use QImode patterns (and QImode move cause stall on the next
1970 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1971 ;; register stall machines with, where we use QImode instructions, since
1972 ;; partial register stall can be caused there. Then we use movzx.
1973 (define_insn "*movqi_1"
1974 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1975 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1976 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1978 switch (get_attr_type (insn))
1981 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1982 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1984 if (get_attr_mode (insn) == MODE_SI)
1985 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1987 return "mov{b}\t{%1, %0|%0, %1}";
1991 (cond [(and (eq_attr "alternative" "5")
1992 (not (match_operand:QI 1 "aligned_operand" "")))
1993 (const_string "imovx")
1994 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1995 (const_string "imov")
1996 (and (eq_attr "alternative" "3")
1997 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1999 (eq (symbol_ref "TARGET_QIMODE_MATH")
2001 (const_string "imov")
2002 (eq_attr "alternative" "3,5")
2003 (const_string "imovx")
2004 (and (ne (symbol_ref "TARGET_MOVX")
2006 (eq_attr "alternative" "2"))
2007 (const_string "imovx")
2009 (const_string "imov")))
2011 (cond [(eq_attr "alternative" "3,4,5")
2013 (eq_attr "alternative" "6")
2015 (eq_attr "type" "imovx")
2017 (and (eq_attr "type" "imov")
2018 (and (eq_attr "alternative" "0,1")
2019 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2021 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2023 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2026 ;; Avoid partial register stalls when not using QImode arithmetic
2027 (and (eq_attr "type" "imov")
2028 (and (eq_attr "alternative" "0,1")
2029 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2031 (eq (symbol_ref "TARGET_QIMODE_MATH")
2035 (const_string "QI")))])
2037 (define_insn "*swapqi_1"
2038 [(set (match_operand:QI 0 "register_operand" "+r")
2039 (match_operand:QI 1 "register_operand" "+r"))
2042 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2044 [(set_attr "type" "imov")
2045 (set_attr "mode" "SI")
2046 (set_attr "pent_pair" "np")
2047 (set_attr "athlon_decode" "vector")
2048 (set_attr "amdfam10_decode" "vector")])
2050 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2051 (define_insn "*swapqi_2"
2052 [(set (match_operand:QI 0 "register_operand" "+q")
2053 (match_operand:QI 1 "register_operand" "+q"))
2056 "TARGET_PARTIAL_REG_STALL"
2058 [(set_attr "type" "imov")
2059 (set_attr "mode" "QI")
2060 (set_attr "pent_pair" "np")
2061 (set_attr "athlon_decode" "vector")])
2063 (define_expand "movstrictqi"
2064 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2065 (match_operand:QI 1 "general_operand" ""))]
2068 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2070 /* Don't generate memory->memory moves, go through a register. */
2071 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2072 operands[1] = force_reg (QImode, operands[1]);
2075 (define_insn "*movstrictqi_1"
2076 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2077 (match_operand:QI 1 "general_operand" "*qn,m"))]
2078 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2079 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2080 "mov{b}\t{%1, %0|%0, %1}"
2081 [(set_attr "type" "imov")
2082 (set_attr "mode" "QI")])
2084 (define_insn "*movstrictqi_xor"
2085 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2086 (match_operand:QI 1 "const0_operand" ""))
2087 (clobber (reg:CC FLAGS_REG))]
2090 [(set_attr "type" "alu1")
2091 (set_attr "mode" "QI")
2092 (set_attr "length_immediate" "0")])
2094 (define_insn "*movsi_extv_1"
2095 [(set (match_operand:SI 0 "register_operand" "=R")
2096 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2100 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2101 [(set_attr "type" "imovx")
2102 (set_attr "mode" "SI")])
2104 (define_insn "*movhi_extv_1"
2105 [(set (match_operand:HI 0 "register_operand" "=R")
2106 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2110 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2111 [(set_attr "type" "imovx")
2112 (set_attr "mode" "SI")])
2114 (define_insn "*movqi_extv_1"
2115 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2116 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2121 switch (get_attr_type (insn))
2124 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2126 return "mov{b}\t{%h1, %0|%0, %h1}";
2130 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2131 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2132 (ne (symbol_ref "TARGET_MOVX")
2134 (const_string "imovx")
2135 (const_string "imov")))
2137 (if_then_else (eq_attr "type" "imovx")
2139 (const_string "QI")))])
2141 (define_insn "*movqi_extv_1_rex64"
2142 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2143 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2148 switch (get_attr_type (insn))
2151 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2153 return "mov{b}\t{%h1, %0|%0, %h1}";
2157 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2158 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2159 (ne (symbol_ref "TARGET_MOVX")
2161 (const_string "imovx")
2162 (const_string "imov")))
2164 (if_then_else (eq_attr "type" "imovx")
2166 (const_string "QI")))])
2168 ;; Stores and loads of ax to arbitrary constant address.
2169 ;; We fake an second form of instruction to force reload to load address
2170 ;; into register when rax is not available
2171 (define_insn "*movabsqi_1_rex64"
2172 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2173 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2174 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2176 movabs{b}\t{%1, %P0|%P0, %1}
2177 mov{b}\t{%1, %a0|%a0, %1}"
2178 [(set_attr "type" "imov")
2179 (set_attr "modrm" "0,*")
2180 (set_attr "length_address" "8,0")
2181 (set_attr "length_immediate" "0,*")
2182 (set_attr "memory" "store")
2183 (set_attr "mode" "QI")])
2185 (define_insn "*movabsqi_2_rex64"
2186 [(set (match_operand:QI 0 "register_operand" "=a,r")
2187 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2188 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2190 movabs{b}\t{%P1, %0|%0, %P1}
2191 mov{b}\t{%a1, %0|%0, %a1}"
2192 [(set_attr "type" "imov")
2193 (set_attr "modrm" "0,*")
2194 (set_attr "length_address" "8,0")
2195 (set_attr "length_immediate" "0")
2196 (set_attr "memory" "load")
2197 (set_attr "mode" "QI")])
2199 (define_insn "*movdi_extzv_1"
2200 [(set (match_operand:DI 0 "register_operand" "=R")
2201 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2205 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2206 [(set_attr "type" "imovx")
2207 (set_attr "mode" "SI")])
2209 (define_insn "*movsi_extzv_1"
2210 [(set (match_operand:SI 0 "register_operand" "=R")
2211 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2215 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2216 [(set_attr "type" "imovx")
2217 (set_attr "mode" "SI")])
2219 (define_insn "*movqi_extzv_2"
2220 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2221 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2226 switch (get_attr_type (insn))
2229 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2231 return "mov{b}\t{%h1, %0|%0, %h1}";
2235 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2236 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2237 (ne (symbol_ref "TARGET_MOVX")
2239 (const_string "imovx")
2240 (const_string "imov")))
2242 (if_then_else (eq_attr "type" "imovx")
2244 (const_string "QI")))])
2246 (define_insn "*movqi_extzv_2_rex64"
2247 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2248 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2253 switch (get_attr_type (insn))
2256 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2258 return "mov{b}\t{%h1, %0|%0, %h1}";
2262 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2263 (ne (symbol_ref "TARGET_MOVX")
2265 (const_string "imovx")
2266 (const_string "imov")))
2268 (if_then_else (eq_attr "type" "imovx")
2270 (const_string "QI")))])
2272 (define_insn "movsi_insv_1"
2273 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2276 (match_operand:SI 1 "general_operand" "Qmn"))]
2278 "mov{b}\t{%b1, %h0|%h0, %b1}"
2279 [(set_attr "type" "imov")
2280 (set_attr "mode" "QI")])
2282 (define_insn "*movsi_insv_1_rex64"
2283 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2286 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2288 "mov{b}\t{%b1, %h0|%h0, %b1}"
2289 [(set_attr "type" "imov")
2290 (set_attr "mode" "QI")])
2292 (define_insn "movdi_insv_1_rex64"
2293 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2296 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2298 "mov{b}\t{%b1, %h0|%h0, %b1}"
2299 [(set_attr "type" "imov")
2300 (set_attr "mode" "QI")])
2302 (define_insn "*movqi_insv_2"
2303 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2306 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2309 "mov{b}\t{%h1, %h0|%h0, %h1}"
2310 [(set_attr "type" "imov")
2311 (set_attr "mode" "QI")])
2313 (define_expand "movdi"
2314 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2315 (match_operand:DI 1 "general_operand" ""))]
2317 "ix86_expand_move (DImode, operands); DONE;")
2319 (define_insn "*pushdi"
2320 [(set (match_operand:DI 0 "push_operand" "=<")
2321 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2325 (define_insn "*pushdi2_rex64"
2326 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2327 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2332 [(set_attr "type" "push,multi")
2333 (set_attr "mode" "DI")])
2335 ;; Convert impossible pushes of immediate to existing instructions.
2336 ;; First try to get scratch register and go through it. In case this
2337 ;; fails, push sign extended lower part first and then overwrite
2338 ;; upper part by 32bit move.
2340 [(match_scratch:DI 2 "r")
2341 (set (match_operand:DI 0 "push_operand" "")
2342 (match_operand:DI 1 "immediate_operand" ""))]
2343 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2344 && !x86_64_immediate_operand (operands[1], DImode)"
2345 [(set (match_dup 2) (match_dup 1))
2346 (set (match_dup 0) (match_dup 2))]
2349 ;; We need to define this as both peepholer and splitter for case
2350 ;; peephole2 pass is not run.
2351 ;; "&& 1" is needed to keep it from matching the previous pattern.
2353 [(set (match_operand:DI 0 "push_operand" "")
2354 (match_operand:DI 1 "immediate_operand" ""))]
2355 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2356 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2357 [(set (match_dup 0) (match_dup 1))
2358 (set (match_dup 2) (match_dup 3))]
2359 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2360 operands[1] = gen_lowpart (DImode, operands[2]);
2361 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2366 [(set (match_operand:DI 0 "push_operand" "")
2367 (match_operand:DI 1 "immediate_operand" ""))]
2368 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2369 ? epilogue_completed : reload_completed)
2370 && !symbolic_operand (operands[1], DImode)
2371 && !x86_64_immediate_operand (operands[1], DImode)"
2372 [(set (match_dup 0) (match_dup 1))
2373 (set (match_dup 2) (match_dup 3))]
2374 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2375 operands[1] = gen_lowpart (DImode, operands[2]);
2376 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2380 (define_insn "*pushdi2_prologue_rex64"
2381 [(set (match_operand:DI 0 "push_operand" "=<")
2382 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2383 (clobber (mem:BLK (scratch)))]
2386 [(set_attr "type" "push")
2387 (set_attr "mode" "DI")])
2389 (define_insn "*popdi1_epilogue_rex64"
2390 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2391 (mem:DI (reg:DI SP_REG)))
2392 (set (reg:DI SP_REG)
2393 (plus:DI (reg:DI SP_REG) (const_int 8)))
2394 (clobber (mem:BLK (scratch)))]
2397 [(set_attr "type" "pop")
2398 (set_attr "mode" "DI")])
2400 (define_insn "popdi1"
2401 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2402 (mem:DI (reg:DI SP_REG)))
2403 (set (reg:DI SP_REG)
2404 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2407 [(set_attr "type" "pop")
2408 (set_attr "mode" "DI")])
2410 (define_insn "*movdi_xor_rex64"
2411 [(set (match_operand:DI 0 "register_operand" "=r")
2412 (match_operand:DI 1 "const0_operand" ""))
2413 (clobber (reg:CC FLAGS_REG))]
2415 && reload_completed"
2417 [(set_attr "type" "alu1")
2418 (set_attr "mode" "SI")
2419 (set_attr "length_immediate" "0")])
2421 (define_insn "*movdi_or_rex64"
2422 [(set (match_operand:DI 0 "register_operand" "=r")
2423 (match_operand:DI 1 "const_int_operand" "i"))
2424 (clobber (reg:CC FLAGS_REG))]
2427 && operands[1] == constm1_rtx"
2429 operands[1] = constm1_rtx;
2430 return "or{q}\t{%1, %0|%0, %1}";
2432 [(set_attr "type" "alu1")
2433 (set_attr "mode" "DI")
2434 (set_attr "length_immediate" "1")])
2436 (define_insn "*movdi_2"
2437 [(set (match_operand:DI 0 "nonimmediate_operand"
2438 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2439 (match_operand:DI 1 "general_operand"
2440 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2441 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2446 movq\t{%1, %0|%0, %1}
2447 movq\t{%1, %0|%0, %1}
2449 %vmovq\t{%1, %0|%0, %1}
2450 %vmovdqa\t{%1, %0|%0, %1}
2451 %vmovq\t{%1, %0|%0, %1}
2453 movlps\t{%1, %0|%0, %1}
2454 movaps\t{%1, %0|%0, %1}
2455 movlps\t{%1, %0|%0, %1}"
2456 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2457 (set (attr "prefix")
2458 (if_then_else (eq_attr "alternative" "5,6,7,8")
2459 (const_string "vex")
2460 (const_string "orig")))
2461 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2464 [(set (match_operand:DI 0 "push_operand" "")
2465 (match_operand:DI 1 "general_operand" ""))]
2466 "!TARGET_64BIT && reload_completed
2467 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2469 "ix86_split_long_move (operands); DONE;")
2471 ;; %%% This multiword shite has got to go.
2473 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2474 (match_operand:DI 1 "general_operand" ""))]
2475 "!TARGET_64BIT && reload_completed
2476 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2477 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2479 "ix86_split_long_move (operands); DONE;")
2481 (define_insn "*movdi_1_rex64"
2482 [(set (match_operand:DI 0 "nonimmediate_operand"
2483 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2484 (match_operand:DI 1 "general_operand"
2485 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2486 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2488 switch (get_attr_type (insn))
2491 if (SSE_REG_P (operands[0]))
2492 return "movq2dq\t{%1, %0|%0, %1}";
2494 return "movdq2q\t{%1, %0|%0, %1}";
2499 if (get_attr_mode (insn) == MODE_TI)
2500 return "vmovdqa\t{%1, %0|%0, %1}";
2502 return "vmovq\t{%1, %0|%0, %1}";
2505 if (get_attr_mode (insn) == MODE_TI)
2506 return "movdqa\t{%1, %0|%0, %1}";
2510 /* Moves from and into integer register is done using movd
2511 opcode with REX prefix. */
2512 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2513 return "movd\t{%1, %0|%0, %1}";
2514 return "movq\t{%1, %0|%0, %1}";
2517 return "%vpxor\t%0, %d0";
2520 return "pxor\t%0, %0";
2526 return "lea{q}\t{%a1, %0|%0, %a1}";
2529 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2530 if (get_attr_mode (insn) == MODE_SI)
2531 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2532 else if (which_alternative == 2)
2533 return "movabs{q}\t{%1, %0|%0, %1}";
2535 return "mov{q}\t{%1, %0|%0, %1}";
2539 (cond [(eq_attr "alternative" "5")
2540 (const_string "mmx")
2541 (eq_attr "alternative" "6,7,8,9,10")
2542 (const_string "mmxmov")
2543 (eq_attr "alternative" "11")
2544 (const_string "sselog1")
2545 (eq_attr "alternative" "12,13,14,15,16")
2546 (const_string "ssemov")
2547 (eq_attr "alternative" "17,18")
2548 (const_string "ssecvt")
2549 (eq_attr "alternative" "4")
2550 (const_string "multi")
2551 (match_operand:DI 1 "pic_32bit_operand" "")
2552 (const_string "lea")
2554 (const_string "imov")))
2557 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2559 (const_string "*")))
2560 (set (attr "length_immediate")
2562 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2564 (const_string "*")))
2565 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2566 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2567 (set (attr "prefix")
2568 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2569 (const_string "maybe_vex")
2570 (const_string "orig")))
2571 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2573 ;; Stores and loads of ax to arbitrary constant address.
2574 ;; We fake an second form of instruction to force reload to load address
2575 ;; into register when rax is not available
2576 (define_insn "*movabsdi_1_rex64"
2577 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2578 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2579 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2581 movabs{q}\t{%1, %P0|%P0, %1}
2582 mov{q}\t{%1, %a0|%a0, %1}"
2583 [(set_attr "type" "imov")
2584 (set_attr "modrm" "0,*")
2585 (set_attr "length_address" "8,0")
2586 (set_attr "length_immediate" "0,*")
2587 (set_attr "memory" "store")
2588 (set_attr "mode" "DI")])
2590 (define_insn "*movabsdi_2_rex64"
2591 [(set (match_operand:DI 0 "register_operand" "=a,r")
2592 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2593 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2595 movabs{q}\t{%P1, %0|%0, %P1}
2596 mov{q}\t{%a1, %0|%0, %a1}"
2597 [(set_attr "type" "imov")
2598 (set_attr "modrm" "0,*")
2599 (set_attr "length_address" "8,0")
2600 (set_attr "length_immediate" "0")
2601 (set_attr "memory" "load")
2602 (set_attr "mode" "DI")])
2604 ;; Convert impossible stores of immediate to existing instructions.
2605 ;; First try to get scratch register and go through it. In case this
2606 ;; fails, move by 32bit parts.
2608 [(match_scratch:DI 2 "r")
2609 (set (match_operand:DI 0 "memory_operand" "")
2610 (match_operand:DI 1 "immediate_operand" ""))]
2611 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2612 && !x86_64_immediate_operand (operands[1], DImode)"
2613 [(set (match_dup 2) (match_dup 1))
2614 (set (match_dup 0) (match_dup 2))]
2617 ;; We need to define this as both peepholer and splitter for case
2618 ;; peephole2 pass is not run.
2619 ;; "&& 1" is needed to keep it from matching the previous pattern.
2621 [(set (match_operand:DI 0 "memory_operand" "")
2622 (match_operand:DI 1 "immediate_operand" ""))]
2623 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2624 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2625 [(set (match_dup 2) (match_dup 3))
2626 (set (match_dup 4) (match_dup 5))]
2627 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2630 [(set (match_operand:DI 0 "memory_operand" "")
2631 (match_operand:DI 1 "immediate_operand" ""))]
2632 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2633 ? epilogue_completed : reload_completed)
2634 && !symbolic_operand (operands[1], DImode)
2635 && !x86_64_immediate_operand (operands[1], DImode)"
2636 [(set (match_dup 2) (match_dup 3))
2637 (set (match_dup 4) (match_dup 5))]
2638 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2640 (define_insn "*swapdi_rex64"
2641 [(set (match_operand:DI 0 "register_operand" "+r")
2642 (match_operand:DI 1 "register_operand" "+r"))
2647 [(set_attr "type" "imov")
2648 (set_attr "mode" "DI")
2649 (set_attr "pent_pair" "np")
2650 (set_attr "athlon_decode" "vector")
2651 (set_attr "amdfam10_decode" "double")])
2653 (define_expand "movoi"
2654 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2655 (match_operand:OI 1 "general_operand" ""))]
2657 "ix86_expand_move (OImode, operands); DONE;")
2659 (define_insn "*movoi_internal"
2660 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2661 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2663 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2665 switch (which_alternative)
2668 return "vxorps\t%0, %0, %0";
2671 if (misaligned_operand (operands[0], OImode)
2672 || misaligned_operand (operands[1], OImode))
2673 return "vmovdqu\t{%1, %0|%0, %1}";
2675 return "vmovdqa\t{%1, %0|%0, %1}";
2680 [(set_attr "type" "sselog1,ssemov,ssemov")
2681 (set_attr "prefix" "vex")
2682 (set_attr "mode" "OI")])
2684 (define_expand "movti"
2685 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2686 (match_operand:TI 1 "nonimmediate_operand" ""))]
2687 "TARGET_SSE || TARGET_64BIT"
2690 ix86_expand_move (TImode, operands);
2691 else if (push_operand (operands[0], TImode))
2692 ix86_expand_push (TImode, operands[1]);
2694 ix86_expand_vector_move (TImode, operands);
2698 (define_insn "*movti_internal"
2699 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2700 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2701 "TARGET_SSE && !TARGET_64BIT
2702 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2704 switch (which_alternative)
2707 if (get_attr_mode (insn) == MODE_V4SF)
2708 return "%vxorps\t%0, %d0";
2710 return "%vpxor\t%0, %d0";
2713 /* TDmode values are passed as TImode on the stack. Moving them
2714 to stack may result in unaligned memory access. */
2715 if (misaligned_operand (operands[0], TImode)
2716 || misaligned_operand (operands[1], TImode))
2718 if (get_attr_mode (insn) == MODE_V4SF)
2719 return "%vmovups\t{%1, %0|%0, %1}";
2721 return "%vmovdqu\t{%1, %0|%0, %1}";
2725 if (get_attr_mode (insn) == MODE_V4SF)
2726 return "%vmovaps\t{%1, %0|%0, %1}";
2728 return "%vmovdqa\t{%1, %0|%0, %1}";
2734 [(set_attr "type" "sselog1,ssemov,ssemov")
2735 (set_attr "prefix" "maybe_vex")
2737 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2738 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2739 (const_string "V4SF")
2740 (and (eq_attr "alternative" "2")
2741 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2743 (const_string "V4SF")]
2744 (const_string "TI")))])
2746 (define_insn "*movti_rex64"
2747 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2748 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2750 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2752 switch (which_alternative)
2758 if (get_attr_mode (insn) == MODE_V4SF)
2759 return "%vxorps\t%0, %d0";
2761 return "%vpxor\t%0, %d0";
2764 /* TDmode values are passed as TImode on the stack. Moving them
2765 to stack may result in unaligned memory access. */
2766 if (misaligned_operand (operands[0], TImode)
2767 || misaligned_operand (operands[1], TImode))
2769 if (get_attr_mode (insn) == MODE_V4SF)
2770 return "%vmovups\t{%1, %0|%0, %1}";
2772 return "%vmovdqu\t{%1, %0|%0, %1}";
2776 if (get_attr_mode (insn) == MODE_V4SF)
2777 return "%vmovaps\t{%1, %0|%0, %1}";
2779 return "%vmovdqa\t{%1, %0|%0, %1}";
2785 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2786 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2788 (cond [(eq_attr "alternative" "2,3")
2790 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2792 (const_string "V4SF")
2793 (const_string "TI"))
2794 (eq_attr "alternative" "4")
2796 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2798 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2800 (const_string "V4SF")
2801 (const_string "TI"))]
2802 (const_string "DI")))])
2805 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2806 (match_operand:TI 1 "general_operand" ""))]
2807 "reload_completed && !SSE_REG_P (operands[0])
2808 && !SSE_REG_P (operands[1])"
2810 "ix86_split_long_move (operands); DONE;")
2812 ;; This expands to what emit_move_complex would generate if we didn't
2813 ;; have a movti pattern. Having this avoids problems with reload on
2814 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2815 ;; to have around all the time.
2816 (define_expand "movcdi"
2817 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2818 (match_operand:CDI 1 "general_operand" ""))]
2821 if (push_operand (operands[0], CDImode))
2822 emit_move_complex_push (CDImode, operands[0], operands[1]);
2824 emit_move_complex_parts (operands[0], operands[1]);
2828 (define_expand "movsf"
2829 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2830 (match_operand:SF 1 "general_operand" ""))]
2832 "ix86_expand_move (SFmode, operands); DONE;")
2834 (define_insn "*pushsf"
2835 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2836 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2839 /* Anything else should be already split before reg-stack. */
2840 gcc_assert (which_alternative == 1);
2841 return "push{l}\t%1";
2843 [(set_attr "type" "multi,push,multi")
2844 (set_attr "unit" "i387,*,*")
2845 (set_attr "mode" "SF,SI,SF")])
2847 (define_insn "*pushsf_rex64"
2848 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2849 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2852 /* Anything else should be already split before reg-stack. */
2853 gcc_assert (which_alternative == 1);
2854 return "push{q}\t%q1";
2856 [(set_attr "type" "multi,push,multi")
2857 (set_attr "unit" "i387,*,*")
2858 (set_attr "mode" "SF,DI,SF")])
2861 [(set (match_operand:SF 0 "push_operand" "")
2862 (match_operand:SF 1 "memory_operand" ""))]
2864 && MEM_P (operands[1])
2865 && (operands[2] = find_constant_src (insn))"
2869 ;; %%% Kill this when call knows how to work this out.
2871 [(set (match_operand:SF 0 "push_operand" "")
2872 (match_operand:SF 1 "any_fp_register_operand" ""))]
2874 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2875 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2878 [(set (match_operand:SF 0 "push_operand" "")
2879 (match_operand:SF 1 "any_fp_register_operand" ""))]
2881 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2882 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2884 (define_insn "*movsf_1"
2885 [(set (match_operand:SF 0 "nonimmediate_operand"
2886 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2887 (match_operand:SF 1 "general_operand"
2888 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2889 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2890 && (reload_in_progress || reload_completed
2891 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2892 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2893 && standard_80387_constant_p (operands[1]))
2894 || GET_CODE (operands[1]) != CONST_DOUBLE
2895 || memory_operand (operands[0], SFmode))"
2897 switch (which_alternative)
2901 return output_387_reg_move (insn, operands);
2904 return standard_80387_constant_opcode (operands[1]);
2908 return "mov{l}\t{%1, %0|%0, %1}";
2910 if (get_attr_mode (insn) == MODE_TI)
2911 return "%vpxor\t%0, %d0";
2913 return "%vxorps\t%0, %d0";
2915 if (get_attr_mode (insn) == MODE_V4SF)
2916 return "%vmovaps\t{%1, %0|%0, %1}";
2918 return "%vmovss\t{%1, %d0|%d0, %1}";
2921 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2922 : "vmovss\t{%1, %0|%0, %1}";
2924 return "movss\t{%1, %0|%0, %1}";
2926 return "%vmovss\t{%1, %0|%0, %1}";
2928 case 9: case 10: case 14: case 15:
2929 return "movd\t{%1, %0|%0, %1}";
2931 return "%vmovd\t{%1, %0|%0, %1}";
2934 return "movq\t{%1, %0|%0, %1}";
2940 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2941 (set (attr "prefix")
2942 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2943 (const_string "maybe_vex")
2944 (const_string "orig")))
2946 (cond [(eq_attr "alternative" "3,4,9,10")
2948 (eq_attr "alternative" "5")
2950 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2952 (ne (symbol_ref "TARGET_SSE2")
2954 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2957 (const_string "V4SF"))
2958 /* For architectures resolving dependencies on
2959 whole SSE registers use APS move to break dependency
2960 chains, otherwise use short move to avoid extra work.
2962 Do the same for architectures resolving dependencies on
2963 the parts. While in DF mode it is better to always handle
2964 just register parts, the SF mode is different due to lack
2965 of instructions to load just part of the register. It is
2966 better to maintain the whole registers in single format
2967 to avoid problems on using packed logical operations. */
2968 (eq_attr "alternative" "6")
2970 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2972 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2974 (const_string "V4SF")
2975 (const_string "SF"))
2976 (eq_attr "alternative" "11")
2977 (const_string "DI")]
2978 (const_string "SF")))])
2980 (define_insn "*swapsf"
2981 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2982 (match_operand:SF 1 "fp_register_operand" "+f"))
2985 "reload_completed || TARGET_80387"
2987 if (STACK_TOP_P (operands[0]))
2992 [(set_attr "type" "fxch")
2993 (set_attr "mode" "SF")])
2995 (define_expand "movdf"
2996 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2997 (match_operand:DF 1 "general_operand" ""))]
2999 "ix86_expand_move (DFmode, operands); DONE;")
3001 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3002 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3003 ;; On the average, pushdf using integers can be still shorter. Allow this
3004 ;; pattern for optimize_size too.
3006 (define_insn "*pushdf_nointeger"
3007 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3008 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3009 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3011 /* This insn should be already split before reg-stack. */
3014 [(set_attr "type" "multi")
3015 (set_attr "unit" "i387,*,*,*")
3016 (set_attr "mode" "DF,SI,SI,DF")])
3018 (define_insn "*pushdf_integer"
3019 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3020 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3021 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3023 /* This insn should be already split before reg-stack. */
3026 [(set_attr "type" "multi")
3027 (set_attr "unit" "i387,*,*")
3028 (set_attr "mode" "DF,SI,DF")])
3030 ;; %%% Kill this when call knows how to work this out.
3032 [(set (match_operand:DF 0 "push_operand" "")
3033 (match_operand:DF 1 "any_fp_register_operand" ""))]
3035 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3036 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3040 [(set (match_operand:DF 0 "push_operand" "")
3041 (match_operand:DF 1 "general_operand" ""))]
3044 "ix86_split_long_move (operands); DONE;")
3046 ;; Moving is usually shorter when only FP registers are used. This separate
3047 ;; movdf pattern avoids the use of integer registers for FP operations
3048 ;; when optimizing for size.
3050 (define_insn "*movdf_nointeger"
3051 [(set (match_operand:DF 0 "nonimmediate_operand"
3052 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3053 (match_operand:DF 1 "general_operand"
3054 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3055 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3056 && ((optimize_function_for_size_p (cfun)
3057 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3058 && (reload_in_progress || reload_completed
3059 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3060 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3061 && optimize_function_for_size_p (cfun)
3062 && !memory_operand (operands[0], DFmode)
3063 && standard_80387_constant_p (operands[1]))
3064 || GET_CODE (operands[1]) != CONST_DOUBLE
3065 || ((optimize_function_for_size_p (cfun)
3066 || !TARGET_MEMORY_MISMATCH_STALL
3067 || reload_in_progress || reload_completed)
3068 && memory_operand (operands[0], DFmode)))"
3070 switch (which_alternative)
3074 return output_387_reg_move (insn, operands);
3077 return standard_80387_constant_opcode (operands[1]);
3083 switch (get_attr_mode (insn))
3086 return "%vxorps\t%0, %d0";
3088 return "%vxorpd\t%0, %d0";
3090 return "%vpxor\t%0, %d0";
3097 switch (get_attr_mode (insn))
3100 return "%vmovaps\t{%1, %0|%0, %1}";
3102 return "%vmovapd\t{%1, %0|%0, %1}";
3104 return "%vmovdqa\t{%1, %0|%0, %1}";
3106 return "%vmovq\t{%1, %0|%0, %1}";
3110 if (REG_P (operands[0]) && REG_P (operands[1]))
3111 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3113 return "vmovsd\t{%1, %0|%0, %1}";
3116 return "movsd\t{%1, %0|%0, %1}";
3120 if (REG_P (operands[0]))
3121 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3123 return "vmovlpd\t{%1, %0|%0, %1}";
3126 return "movlpd\t{%1, %0|%0, %1}";
3130 if (REG_P (operands[0]))
3131 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3133 return "vmovlps\t{%1, %0|%0, %1}";
3136 return "movlps\t{%1, %0|%0, %1}";
3145 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3146 (set (attr "prefix")
3147 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3148 (const_string "orig")
3149 (const_string "maybe_vex")))
3150 (set (attr "prefix_data16")
3151 (if_then_else (eq_attr "mode" "V1DF")
3153 (const_string "*")))
3155 (cond [(eq_attr "alternative" "0,1,2")
3157 (eq_attr "alternative" "3,4")
3160 /* For SSE1, we have many fewer alternatives. */
3161 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3162 (cond [(eq_attr "alternative" "5,6")
3163 (const_string "V4SF")
3165 (const_string "V2SF"))
3167 /* xorps is one byte shorter. */
3168 (eq_attr "alternative" "5")
3169 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3171 (const_string "V4SF")
3172 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3176 (const_string "V2DF"))
3178 /* For architectures resolving dependencies on
3179 whole SSE registers use APD move to break dependency
3180 chains, otherwise use short move to avoid extra work.
3182 movaps encodes one byte shorter. */
3183 (eq_attr "alternative" "6")
3185 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3187 (const_string "V4SF")
3188 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3190 (const_string "V2DF")
3192 (const_string "DF"))
3193 /* For architectures resolving dependencies on register
3194 parts we may avoid extra work to zero out upper part
3196 (eq_attr "alternative" "7")
3198 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3200 (const_string "V1DF")
3201 (const_string "DF"))
3203 (const_string "DF")))])
3205 (define_insn "*movdf_integer_rex64"
3206 [(set (match_operand:DF 0 "nonimmediate_operand"
3207 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3208 (match_operand:DF 1 "general_operand"
3209 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3210 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3211 && (reload_in_progress || reload_completed
3212 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3213 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3214 && optimize_function_for_size_p (cfun)
3215 && standard_80387_constant_p (operands[1]))
3216 || GET_CODE (operands[1]) != CONST_DOUBLE
3217 || memory_operand (operands[0], DFmode))"
3219 switch (which_alternative)
3223 return output_387_reg_move (insn, operands);
3226 return standard_80387_constant_opcode (operands[1]);
3233 switch (get_attr_mode (insn))
3236 return "%vxorps\t%0, %d0";
3238 return "%vxorpd\t%0, %d0";
3240 return "%vpxor\t%0, %d0";
3247 switch (get_attr_mode (insn))
3250 return "%vmovaps\t{%1, %0|%0, %1}";
3252 return "%vmovapd\t{%1, %0|%0, %1}";
3254 return "%vmovdqa\t{%1, %0|%0, %1}";
3256 return "%vmovq\t{%1, %0|%0, %1}";
3260 if (REG_P (operands[0]) && REG_P (operands[1]))
3261 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3263 return "vmovsd\t{%1, %0|%0, %1}";
3266 return "movsd\t{%1, %0|%0, %1}";
3268 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3270 return "%vmovlps\t{%1, %d0|%d0, %1}";
3277 return "%vmovd\t{%1, %0|%0, %1}";
3283 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3284 (set (attr "prefix")
3285 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3286 (const_string "orig")
3287 (const_string "maybe_vex")))
3288 (set (attr "prefix_data16")
3289 (if_then_else (eq_attr "mode" "V1DF")
3291 (const_string "*")))
3293 (cond [(eq_attr "alternative" "0,1,2")
3295 (eq_attr "alternative" "3,4,9,10")
3298 /* For SSE1, we have many fewer alternatives. */
3299 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3300 (cond [(eq_attr "alternative" "5,6")
3301 (const_string "V4SF")
3303 (const_string "V2SF"))
3305 /* xorps is one byte shorter. */
3306 (eq_attr "alternative" "5")
3307 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3309 (const_string "V4SF")
3310 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3314 (const_string "V2DF"))
3316 /* For architectures resolving dependencies on
3317 whole SSE registers use APD move to break dependency
3318 chains, otherwise use short move to avoid extra work.
3320 movaps encodes one byte shorter. */
3321 (eq_attr "alternative" "6")
3323 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3325 (const_string "V4SF")
3326 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3328 (const_string "V2DF")
3330 (const_string "DF"))
3331 /* For architectures resolving dependencies on register
3332 parts we may avoid extra work to zero out upper part
3334 (eq_attr "alternative" "7")
3336 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3338 (const_string "V1DF")
3339 (const_string "DF"))
3341 (const_string "DF")))])
3343 (define_insn "*movdf_integer"
3344 [(set (match_operand:DF 0 "nonimmediate_operand"
3345 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3346 (match_operand:DF 1 "general_operand"
3347 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3348 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3349 && optimize_function_for_speed_p (cfun)
3350 && TARGET_INTEGER_DFMODE_MOVES
3351 && (reload_in_progress || reload_completed
3352 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3353 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3354 && optimize_function_for_size_p (cfun)
3355 && standard_80387_constant_p (operands[1]))
3356 || GET_CODE (operands[1]) != CONST_DOUBLE
3357 || memory_operand (operands[0], DFmode))"
3359 switch (which_alternative)
3363 return output_387_reg_move (insn, operands);
3366 return standard_80387_constant_opcode (operands[1]);
3373 switch (get_attr_mode (insn))
3376 return "xorps\t%0, %0";
3378 return "xorpd\t%0, %0";
3380 return "pxor\t%0, %0";
3387 switch (get_attr_mode (insn))
3390 return "movaps\t{%1, %0|%0, %1}";
3392 return "movapd\t{%1, %0|%0, %1}";
3394 return "movdqa\t{%1, %0|%0, %1}";
3396 return "movq\t{%1, %0|%0, %1}";
3398 return "movsd\t{%1, %0|%0, %1}";
3400 return "movlpd\t{%1, %0|%0, %1}";
3402 return "movlps\t{%1, %0|%0, %1}";
3411 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3412 (set (attr "prefix_data16")
3413 (if_then_else (eq_attr "mode" "V1DF")
3415 (const_string "*")))
3417 (cond [(eq_attr "alternative" "0,1,2")
3419 (eq_attr "alternative" "3,4")
3422 /* For SSE1, we have many fewer alternatives. */
3423 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3424 (cond [(eq_attr "alternative" "5,6")
3425 (const_string "V4SF")
3427 (const_string "V2SF"))
3429 /* xorps is one byte shorter. */
3430 (eq_attr "alternative" "5")
3431 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3433 (const_string "V4SF")
3434 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3438 (const_string "V2DF"))
3440 /* For architectures resolving dependencies on
3441 whole SSE registers use APD move to break dependency
3442 chains, otherwise use short move to avoid extra work.
3444 movaps encodes one byte shorter. */
3445 (eq_attr "alternative" "6")
3447 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3449 (const_string "V4SF")
3450 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3452 (const_string "V2DF")
3454 (const_string "DF"))
3455 /* For architectures resolving dependencies on register
3456 parts we may avoid extra work to zero out upper part
3458 (eq_attr "alternative" "7")
3460 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3462 (const_string "V1DF")
3463 (const_string "DF"))
3465 (const_string "DF")))])
3468 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3469 (match_operand:DF 1 "general_operand" ""))]
3471 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3472 && ! (ANY_FP_REG_P (operands[0]) ||
3473 (GET_CODE (operands[0]) == SUBREG
3474 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3475 && ! (ANY_FP_REG_P (operands[1]) ||
3476 (GET_CODE (operands[1]) == SUBREG
3477 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3479 "ix86_split_long_move (operands); DONE;")
3481 (define_insn "*swapdf"
3482 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3483 (match_operand:DF 1 "fp_register_operand" "+f"))
3486 "reload_completed || TARGET_80387"
3488 if (STACK_TOP_P (operands[0]))
3493 [(set_attr "type" "fxch")
3494 (set_attr "mode" "DF")])
3496 (define_expand "movxf"
3497 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3498 (match_operand:XF 1 "general_operand" ""))]
3500 "ix86_expand_move (XFmode, operands); DONE;")
3502 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3503 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3504 ;; Pushing using integer instructions is longer except for constants
3505 ;; and direct memory references.
3506 ;; (assuming that any given constant is pushed only once, but this ought to be
3507 ;; handled elsewhere).
3509 (define_insn "*pushxf_nointeger"
3510 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3511 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3512 "optimize_function_for_size_p (cfun)"
3514 /* This insn should be already split before reg-stack. */
3517 [(set_attr "type" "multi")
3518 (set_attr "unit" "i387,*,*")
3519 (set_attr "mode" "XF,SI,SI")])
3521 (define_insn "*pushxf_integer"
3522 [(set (match_operand:XF 0 "push_operand" "=<,<")
3523 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3524 "optimize_function_for_speed_p (cfun)"
3526 /* This insn should be already split before reg-stack. */
3529 [(set_attr "type" "multi")
3530 (set_attr "unit" "i387,*")
3531 (set_attr "mode" "XF,SI")])
3534 [(set (match_operand 0 "push_operand" "")
3535 (match_operand 1 "general_operand" ""))]
3537 && (GET_MODE (operands[0]) == XFmode
3538 || GET_MODE (operands[0]) == DFmode)
3539 && !ANY_FP_REG_P (operands[1])"
3541 "ix86_split_long_move (operands); DONE;")
3544 [(set (match_operand:XF 0 "push_operand" "")
3545 (match_operand:XF 1 "any_fp_register_operand" ""))]
3547 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3548 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3549 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3551 ;; Do not use integer registers when optimizing for size
3552 (define_insn "*movxf_nointeger"
3553 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3554 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3555 "optimize_function_for_size_p (cfun)
3556 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3557 && (reload_in_progress || reload_completed
3558 || standard_80387_constant_p (operands[1])
3559 || GET_CODE (operands[1]) != CONST_DOUBLE
3560 || memory_operand (operands[0], XFmode))"
3562 switch (which_alternative)
3566 return output_387_reg_move (insn, operands);
3569 return standard_80387_constant_opcode (operands[1]);
3577 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3578 (set_attr "mode" "XF,XF,XF,SI,SI")])
3580 (define_insn "*movxf_integer"
3581 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3582 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3583 "optimize_function_for_speed_p (cfun)
3584 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3585 && (reload_in_progress || reload_completed
3586 || GET_CODE (operands[1]) != CONST_DOUBLE
3587 || memory_operand (operands[0], XFmode))"
3589 switch (which_alternative)
3593 return output_387_reg_move (insn, operands);
3596 return standard_80387_constant_opcode (operands[1]);
3605 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3606 (set_attr "mode" "XF,XF,XF,SI,SI")])
3608 (define_expand "movtf"
3609 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3610 (match_operand:TF 1 "nonimmediate_operand" ""))]
3613 ix86_expand_move (TFmode, operands);
3617 (define_insn "*movtf_internal"
3618 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3619 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3621 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3623 switch (which_alternative)
3627 if (get_attr_mode (insn) == MODE_V4SF)
3628 return "%vmovaps\t{%1, %0|%0, %1}";
3630 return "%vmovdqa\t{%1, %0|%0, %1}";
3632 if (get_attr_mode (insn) == MODE_V4SF)
3633 return "%vxorps\t%0, %d0";
3635 return "%vpxor\t%0, %d0";
3643 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3644 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3646 (cond [(eq_attr "alternative" "0,2")
3648 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3650 (const_string "V4SF")
3651 (const_string "TI"))
3652 (eq_attr "alternative" "1")
3654 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3656 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3658 (const_string "V4SF")
3659 (const_string "TI"))]
3660 (const_string "DI")))])
3662 (define_insn "*pushtf_sse"
3663 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3664 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3667 /* This insn should be already split before reg-stack. */
3670 [(set_attr "type" "multi")
3671 (set_attr "unit" "sse,*,*")
3672 (set_attr "mode" "TF,SI,SI")])
3675 [(set (match_operand:TF 0 "push_operand" "")
3676 (match_operand:TF 1 "general_operand" ""))]
3677 "TARGET_SSE2 && reload_completed
3678 && !SSE_REG_P (operands[1])"
3680 "ix86_split_long_move (operands); DONE;")
3683 [(set (match_operand:TF 0 "push_operand" "")
3684 (match_operand:TF 1 "any_fp_register_operand" ""))]
3686 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3687 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3691 [(set (match_operand 0 "nonimmediate_operand" "")
3692 (match_operand 1 "general_operand" ""))]
3694 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3695 && GET_MODE (operands[0]) == XFmode
3696 && ! (ANY_FP_REG_P (operands[0]) ||
3697 (GET_CODE (operands[0]) == SUBREG
3698 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3699 && ! (ANY_FP_REG_P (operands[1]) ||
3700 (GET_CODE (operands[1]) == SUBREG
3701 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3703 "ix86_split_long_move (operands); DONE;")
3706 [(set (match_operand 0 "register_operand" "")
3707 (match_operand 1 "memory_operand" ""))]
3709 && MEM_P (operands[1])
3710 && (GET_MODE (operands[0]) == TFmode
3711 || GET_MODE (operands[0]) == XFmode
3712 || GET_MODE (operands[0]) == SFmode
3713 || GET_MODE (operands[0]) == DFmode)
3714 && (operands[2] = find_constant_src (insn))"
3715 [(set (match_dup 0) (match_dup 2))]
3717 rtx c = operands[2];
3718 rtx r = operands[0];
3720 if (GET_CODE (r) == SUBREG)
3725 if (!standard_sse_constant_p (c))
3728 else if (FP_REG_P (r))
3730 if (!standard_80387_constant_p (c))
3733 else if (MMX_REG_P (r))
3738 [(set (match_operand 0 "register_operand" "")
3739 (float_extend (match_operand 1 "memory_operand" "")))]
3741 && MEM_P (operands[1])
3742 && (GET_MODE (operands[0]) == TFmode
3743 || GET_MODE (operands[0]) == XFmode
3744 || GET_MODE (operands[0]) == SFmode
3745 || GET_MODE (operands[0]) == DFmode)
3746 && (operands[2] = find_constant_src (insn))"
3747 [(set (match_dup 0) (match_dup 2))]
3749 rtx c = operands[2];
3750 rtx r = operands[0];
3752 if (GET_CODE (r) == SUBREG)
3757 if (!standard_sse_constant_p (c))
3760 else if (FP_REG_P (r))
3762 if (!standard_80387_constant_p (c))
3765 else if (MMX_REG_P (r))
3769 (define_insn "swapxf"
3770 [(set (match_operand:XF 0 "register_operand" "+f")
3771 (match_operand:XF 1 "register_operand" "+f"))
3776 if (STACK_TOP_P (operands[0]))
3781 [(set_attr "type" "fxch")
3782 (set_attr "mode" "XF")])
3784 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3786 [(set (match_operand:X87MODEF 0 "register_operand" "")
3787 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3788 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3789 && (standard_80387_constant_p (operands[1]) == 8
3790 || standard_80387_constant_p (operands[1]) == 9)"
3791 [(set (match_dup 0)(match_dup 1))
3793 (neg:X87MODEF (match_dup 0)))]
3797 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3798 if (real_isnegzero (&r))
3799 operands[1] = CONST0_RTX (<MODE>mode);
3801 operands[1] = CONST1_RTX (<MODE>mode);
3805 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3806 (match_operand:TF 1 "general_operand" ""))]
3808 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3810 "ix86_split_long_move (operands); DONE;")
3812 ;; Zero extension instructions
3814 (define_expand "zero_extendhisi2"
3815 [(set (match_operand:SI 0 "register_operand" "")
3816 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3819 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3821 operands[1] = force_reg (HImode, operands[1]);
3822 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3827 (define_insn "zero_extendhisi2_and"
3828 [(set (match_operand:SI 0 "register_operand" "=r")
3829 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3830 (clobber (reg:CC FLAGS_REG))]
3831 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3833 [(set_attr "type" "alu1")
3834 (set_attr "mode" "SI")])
3837 [(set (match_operand:SI 0 "register_operand" "")
3838 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3839 (clobber (reg:CC FLAGS_REG))]
3840 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3841 && optimize_function_for_speed_p (cfun)"
3842 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3843 (clobber (reg:CC FLAGS_REG))])]
3846 (define_insn "*zero_extendhisi2_movzwl"
3847 [(set (match_operand:SI 0 "register_operand" "=r")
3848 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3849 "!TARGET_ZERO_EXTEND_WITH_AND
3850 || optimize_function_for_size_p (cfun)"
3851 "movz{wl|x}\t{%1, %0|%0, %1}"
3852 [(set_attr "type" "imovx")
3853 (set_attr "mode" "SI")])
3855 (define_expand "zero_extendqihi2"
3857 [(set (match_operand:HI 0 "register_operand" "")
3858 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3859 (clobber (reg:CC FLAGS_REG))])]
3863 (define_insn "*zero_extendqihi2_and"
3864 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3865 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3866 (clobber (reg:CC FLAGS_REG))]
3867 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3869 [(set_attr "type" "alu1")
3870 (set_attr "mode" "HI")])
3872 (define_insn "*zero_extendqihi2_movzbw_and"
3873 [(set (match_operand:HI 0 "register_operand" "=r,r")
3874 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3875 (clobber (reg:CC FLAGS_REG))]
3876 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3878 [(set_attr "type" "imovx,alu1")
3879 (set_attr "mode" "HI")])
3881 ; zero extend to SImode here to avoid partial register stalls
3882 (define_insn "*zero_extendqihi2_movzbl"
3883 [(set (match_operand:HI 0 "register_operand" "=r")
3884 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3885 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3886 && reload_completed"
3887 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3888 [(set_attr "type" "imovx")
3889 (set_attr "mode" "SI")])
3891 ;; For the movzbw case strip only the clobber
3893 [(set (match_operand:HI 0 "register_operand" "")
3894 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3895 (clobber (reg:CC FLAGS_REG))]
3897 && (!TARGET_ZERO_EXTEND_WITH_AND
3898 || optimize_function_for_size_p (cfun))
3899 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3900 [(set (match_operand:HI 0 "register_operand" "")
3901 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3903 ;; When source and destination does not overlap, clear destination
3904 ;; first and then do the movb
3906 [(set (match_operand:HI 0 "register_operand" "")
3907 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3908 (clobber (reg:CC FLAGS_REG))]
3910 && ANY_QI_REG_P (operands[0])
3911 && (TARGET_ZERO_EXTEND_WITH_AND
3912 && optimize_function_for_speed_p (cfun))
3913 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3914 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3916 operands[2] = gen_lowpart (QImode, operands[0]);
3917 ix86_expand_clear (operands[0]);
3920 ;; Rest is handled by single and.
3922 [(set (match_operand:HI 0 "register_operand" "")
3923 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3924 (clobber (reg:CC FLAGS_REG))]
3926 && true_regnum (operands[0]) == true_regnum (operands[1])"
3927 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3928 (clobber (reg:CC FLAGS_REG))])]
3931 (define_expand "zero_extendqisi2"
3933 [(set (match_operand:SI 0 "register_operand" "")
3934 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3935 (clobber (reg:CC FLAGS_REG))])]
3939 (define_insn "*zero_extendqisi2_and"
3940 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3941 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3942 (clobber (reg:CC FLAGS_REG))]
3943 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3945 [(set_attr "type" "alu1")
3946 (set_attr "mode" "SI")])
3948 (define_insn "*zero_extendqisi2_movzbl_and"
3949 [(set (match_operand:SI 0 "register_operand" "=r,r")
3950 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3951 (clobber (reg:CC FLAGS_REG))]
3952 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3954 [(set_attr "type" "imovx,alu1")
3955 (set_attr "mode" "SI")])
3957 (define_insn "*zero_extendqisi2_movzbl"
3958 [(set (match_operand:SI 0 "register_operand" "=r")
3959 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3960 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3961 && reload_completed"
3962 "movz{bl|x}\t{%1, %0|%0, %1}"
3963 [(set_attr "type" "imovx")
3964 (set_attr "mode" "SI")])
3966 ;; For the movzbl case strip only the clobber
3968 [(set (match_operand:SI 0 "register_operand" "")
3969 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3970 (clobber (reg:CC FLAGS_REG))]
3972 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3973 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3975 (zero_extend:SI (match_dup 1)))])
3977 ;; When source and destination does not overlap, clear destination
3978 ;; first and then do the movb
3980 [(set (match_operand:SI 0 "register_operand" "")
3981 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3982 (clobber (reg:CC FLAGS_REG))]
3984 && ANY_QI_REG_P (operands[0])
3985 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3986 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3987 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3988 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3990 operands[2] = gen_lowpart (QImode, operands[0]);
3991 ix86_expand_clear (operands[0]);
3994 ;; Rest is handled by single and.
3996 [(set (match_operand:SI 0 "register_operand" "")
3997 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3998 (clobber (reg:CC FLAGS_REG))]
4000 && true_regnum (operands[0]) == true_regnum (operands[1])"
4001 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4002 (clobber (reg:CC FLAGS_REG))])]
4005 ;; %%% Kill me once multi-word ops are sane.
4006 (define_expand "zero_extendsidi2"
4007 [(set (match_operand:DI 0 "register_operand" "")
4008 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4013 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4018 (define_insn "zero_extendsidi2_32"
4019 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4021 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
4022 (clobber (reg:CC FLAGS_REG))]
4028 movd\t{%1, %0|%0, %1}
4029 movd\t{%1, %0|%0, %1}
4030 %vmovd\t{%1, %0|%0, %1}
4031 %vmovd\t{%1, %0|%0, %1}"
4032 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4033 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4034 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4036 (define_insn "zero_extendsidi2_rex64"
4037 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4039 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4042 mov\t{%k1, %k0|%k0, %k1}
4044 movd\t{%1, %0|%0, %1}
4045 movd\t{%1, %0|%0, %1}
4046 %vmovd\t{%1, %0|%0, %1}
4047 %vmovd\t{%1, %0|%0, %1}"
4048 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4049 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4050 (set_attr "prefix_0f" "0,*,*,*,*,*")
4051 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4054 [(set (match_operand:DI 0 "memory_operand" "")
4055 (zero_extend:DI (match_dup 0)))]
4057 [(set (match_dup 4) (const_int 0))]
4058 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4061 [(set (match_operand:DI 0 "register_operand" "")
4062 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4063 (clobber (reg:CC FLAGS_REG))]
4064 "!TARGET_64BIT && reload_completed
4065 && true_regnum (operands[0]) == true_regnum (operands[1])"
4066 [(set (match_dup 4) (const_int 0))]
4067 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4070 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4071 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4072 (clobber (reg:CC FLAGS_REG))]
4073 "!TARGET_64BIT && reload_completed
4074 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4075 [(set (match_dup 3) (match_dup 1))
4076 (set (match_dup 4) (const_int 0))]
4077 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4079 (define_insn "zero_extendhidi2"
4080 [(set (match_operand:DI 0 "register_operand" "=r")
4081 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4083 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4084 [(set_attr "type" "imovx")
4085 (set_attr "mode" "SI")])
4087 (define_insn "zero_extendqidi2"
4088 [(set (match_operand:DI 0 "register_operand" "=r")
4089 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4091 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4092 [(set_attr "type" "imovx")
4093 (set_attr "mode" "SI")])
4095 ;; Sign extension instructions
4097 (define_expand "extendsidi2"
4098 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4099 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4100 (clobber (reg:CC FLAGS_REG))
4101 (clobber (match_scratch:SI 2 ""))])]
4106 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4111 (define_insn "*extendsidi2_1"
4112 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4113 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4114 (clobber (reg:CC FLAGS_REG))
4115 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4119 (define_insn "extendsidi2_rex64"
4120 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4121 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4125 movs{lq|x}\t{%1, %0|%0, %1}"
4126 [(set_attr "type" "imovx")
4127 (set_attr "mode" "DI")
4128 (set_attr "prefix_0f" "0")
4129 (set_attr "modrm" "0,1")])
4131 (define_insn "extendhidi2"
4132 [(set (match_operand:DI 0 "register_operand" "=r")
4133 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4135 "movs{wq|x}\t{%1, %0|%0, %1}"
4136 [(set_attr "type" "imovx")
4137 (set_attr "mode" "DI")])
4139 (define_insn "extendqidi2"
4140 [(set (match_operand:DI 0 "register_operand" "=r")
4141 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4143 "movs{bq|x}\t{%1, %0|%0, %1}"
4144 [(set_attr "type" "imovx")
4145 (set_attr "mode" "DI")])
4147 ;; Extend to memory case when source register does die.
4149 [(set (match_operand:DI 0 "memory_operand" "")
4150 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4151 (clobber (reg:CC FLAGS_REG))
4152 (clobber (match_operand:SI 2 "register_operand" ""))]
4154 && dead_or_set_p (insn, operands[1])
4155 && !reg_mentioned_p (operands[1], operands[0]))"
4156 [(set (match_dup 3) (match_dup 1))
4157 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4158 (clobber (reg:CC FLAGS_REG))])
4159 (set (match_dup 4) (match_dup 1))]
4160 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4162 ;; Extend to memory case when source register does not die.
4164 [(set (match_operand:DI 0 "memory_operand" "")
4165 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4166 (clobber (reg:CC FLAGS_REG))
4167 (clobber (match_operand:SI 2 "register_operand" ""))]
4171 split_di (&operands[0], 1, &operands[3], &operands[4]);
4173 emit_move_insn (operands[3], operands[1]);
4175 /* Generate a cltd if possible and doing so it profitable. */
4176 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4177 && true_regnum (operands[1]) == AX_REG
4178 && true_regnum (operands[2]) == DX_REG)
4180 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4184 emit_move_insn (operands[2], operands[1]);
4185 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4187 emit_move_insn (operands[4], operands[2]);
4191 ;; Extend to register case. Optimize case where source and destination
4192 ;; registers match and cases where we can use cltd.
4194 [(set (match_operand:DI 0 "register_operand" "")
4195 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4196 (clobber (reg:CC FLAGS_REG))
4197 (clobber (match_scratch:SI 2 ""))]
4201 split_di (&operands[0], 1, &operands[3], &operands[4]);
4203 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4204 emit_move_insn (operands[3], operands[1]);
4206 /* Generate a cltd if possible and doing so it profitable. */
4207 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4208 && true_regnum (operands[3]) == AX_REG)
4210 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4214 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4215 emit_move_insn (operands[4], operands[1]);
4217 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4221 (define_insn "extendhisi2"
4222 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4223 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4226 switch (get_attr_prefix_0f (insn))
4229 return "{cwtl|cwde}";
4231 return "movs{wl|x}\t{%1, %0|%0, %1}";
4234 [(set_attr "type" "imovx")
4235 (set_attr "mode" "SI")
4236 (set (attr "prefix_0f")
4237 ;; movsx is short decodable while cwtl is vector decoded.
4238 (if_then_else (and (eq_attr "cpu" "!k6")
4239 (eq_attr "alternative" "0"))
4241 (const_string "1")))
4243 (if_then_else (eq_attr "prefix_0f" "0")
4245 (const_string "1")))])
4247 (define_insn "*extendhisi2_zext"
4248 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4250 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4253 switch (get_attr_prefix_0f (insn))
4256 return "{cwtl|cwde}";
4258 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4261 [(set_attr "type" "imovx")
4262 (set_attr "mode" "SI")
4263 (set (attr "prefix_0f")
4264 ;; movsx is short decodable while cwtl is vector decoded.
4265 (if_then_else (and (eq_attr "cpu" "!k6")
4266 (eq_attr "alternative" "0"))
4268 (const_string "1")))
4270 (if_then_else (eq_attr "prefix_0f" "0")
4272 (const_string "1")))])
4274 (define_insn "extendqihi2"
4275 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4276 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4279 switch (get_attr_prefix_0f (insn))
4282 return "{cbtw|cbw}";
4284 return "movs{bw|x}\t{%1, %0|%0, %1}";
4287 [(set_attr "type" "imovx")
4288 (set_attr "mode" "HI")
4289 (set (attr "prefix_0f")
4290 ;; movsx is short decodable while cwtl is vector decoded.
4291 (if_then_else (and (eq_attr "cpu" "!k6")
4292 (eq_attr "alternative" "0"))
4294 (const_string "1")))
4296 (if_then_else (eq_attr "prefix_0f" "0")
4298 (const_string "1")))])
4300 (define_insn "extendqisi2"
4301 [(set (match_operand:SI 0 "register_operand" "=r")
4302 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4304 "movs{bl|x}\t{%1, %0|%0, %1}"
4305 [(set_attr "type" "imovx")
4306 (set_attr "mode" "SI")])
4308 (define_insn "*extendqisi2_zext"
4309 [(set (match_operand:DI 0 "register_operand" "=r")
4311 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4313 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4314 [(set_attr "type" "imovx")
4315 (set_attr "mode" "SI")])
4317 ;; Conversions between float and double.
4319 ;; These are all no-ops in the model used for the 80387. So just
4322 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4323 (define_insn "*dummy_extendsfdf2"
4324 [(set (match_operand:DF 0 "push_operand" "=<")
4325 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4330 [(set (match_operand:DF 0 "push_operand" "")
4331 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4333 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4334 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4336 (define_insn "*dummy_extendsfxf2"
4337 [(set (match_operand:XF 0 "push_operand" "=<")
4338 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4343 [(set (match_operand:XF 0 "push_operand" "")
4344 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4346 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4347 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4348 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4351 [(set (match_operand:XF 0 "push_operand" "")
4352 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4354 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4355 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4356 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4358 (define_expand "extendsfdf2"
4359 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4360 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4361 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4363 /* ??? Needed for compress_float_constant since all fp constants
4364 are LEGITIMATE_CONSTANT_P. */
4365 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4367 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4368 && standard_80387_constant_p (operands[1]) > 0)
4370 operands[1] = simplify_const_unary_operation
4371 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4372 emit_move_insn_1 (operands[0], operands[1]);
4375 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4379 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4381 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4383 We do the conversion post reload to avoid producing of 128bit spills
4384 that might lead to ICE on 32bit target. The sequence unlikely combine
4387 [(set (match_operand:DF 0 "register_operand" "")
4389 (match_operand:SF 1 "nonimmediate_operand" "")))]
4390 "TARGET_USE_VECTOR_FP_CONVERTS
4391 && optimize_insn_for_speed_p ()
4392 && reload_completed && SSE_REG_P (operands[0])"
4397 (parallel [(const_int 0) (const_int 1)]))))]
4399 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4400 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4401 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4402 Try to avoid move when unpacking can be done in source. */
4403 if (REG_P (operands[1]))
4405 /* If it is unsafe to overwrite upper half of source, we need
4406 to move to destination and unpack there. */
4407 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4408 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4409 && true_regnum (operands[0]) != true_regnum (operands[1]))
4411 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4412 emit_move_insn (tmp, operands[1]);
4415 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4416 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4420 emit_insn (gen_vec_setv4sf_0 (operands[3],
4421 CONST0_RTX (V4SFmode), operands[1]));
4424 (define_insn "*extendsfdf2_mixed"
4425 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4427 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4428 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4430 switch (which_alternative)
4434 return output_387_reg_move (insn, operands);
4437 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4443 [(set_attr "type" "fmov,fmov,ssecvt")
4444 (set_attr "prefix" "orig,orig,maybe_vex")
4445 (set_attr "mode" "SF,XF,DF")])
4447 (define_insn "*extendsfdf2_sse"
4448 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4449 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4450 "TARGET_SSE2 && TARGET_SSE_MATH"
4451 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4452 [(set_attr "type" "ssecvt")
4453 (set_attr "prefix" "maybe_vex")
4454 (set_attr "mode" "DF")])
4456 (define_insn "*extendsfdf2_i387"
4457 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4458 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4460 "* return output_387_reg_move (insn, operands);"
4461 [(set_attr "type" "fmov")
4462 (set_attr "mode" "SF,XF")])
4464 (define_expand "extend<mode>xf2"
4465 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4466 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4469 /* ??? Needed for compress_float_constant since all fp constants
4470 are LEGITIMATE_CONSTANT_P. */
4471 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4473 if (standard_80387_constant_p (operands[1]) > 0)
4475 operands[1] = simplify_const_unary_operation
4476 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4477 emit_move_insn_1 (operands[0], operands[1]);
4480 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4484 (define_insn "*extend<mode>xf2_i387"
4485 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4487 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4489 "* return output_387_reg_move (insn, operands);"
4490 [(set_attr "type" "fmov")
4491 (set_attr "mode" "<MODE>,XF")])
4493 ;; %%% This seems bad bad news.
4494 ;; This cannot output into an f-reg because there is no way to be sure
4495 ;; of truncating in that case. Otherwise this is just like a simple move
4496 ;; insn. So we pretend we can output to a reg in order to get better
4497 ;; register preferencing, but we really use a stack slot.
4499 ;; Conversion from DFmode to SFmode.
4501 (define_expand "truncdfsf2"
4502 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4504 (match_operand:DF 1 "nonimmediate_operand" "")))]
4505 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4507 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4509 else if (flag_unsafe_math_optimizations)
4513 enum ix86_stack_slot slot = (virtuals_instantiated
4516 rtx temp = assign_386_stack_local (SFmode, slot);
4517 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4522 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4524 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4526 We do the conversion post reload to avoid producing of 128bit spills
4527 that might lead to ICE on 32bit target. The sequence unlikely combine
4530 [(set (match_operand:SF 0 "register_operand" "")
4532 (match_operand:DF 1 "nonimmediate_operand" "")))]
4533 "TARGET_USE_VECTOR_FP_CONVERTS
4534 && optimize_insn_for_speed_p ()
4535 && reload_completed && SSE_REG_P (operands[0])"
4538 (float_truncate:V2SF
4542 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4543 operands[3] = CONST0_RTX (V2SFmode);
4544 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4545 /* Use movsd for loading from memory, unpcklpd for registers.
4546 Try to avoid move when unpacking can be done in source, or SSE3
4547 movddup is available. */
4548 if (REG_P (operands[1]))
4551 && true_regnum (operands[0]) != true_regnum (operands[1])
4552 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4553 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4555 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4556 emit_move_insn (tmp, operands[1]);
4559 else if (!TARGET_SSE3)
4560 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4561 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4564 emit_insn (gen_sse2_loadlpd (operands[4],
4565 CONST0_RTX (V2DFmode), operands[1]));
4568 (define_expand "truncdfsf2_with_temp"
4569 [(parallel [(set (match_operand:SF 0 "" "")
4570 (float_truncate:SF (match_operand:DF 1 "" "")))
4571 (clobber (match_operand:SF 2 "" ""))])]
4574 (define_insn "*truncdfsf_fast_mixed"
4575 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4577 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4578 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4580 switch (which_alternative)
4583 return output_387_reg_move (insn, operands);
4585 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4590 [(set_attr "type" "fmov,ssecvt")
4591 (set_attr "prefix" "orig,maybe_vex")
4592 (set_attr "mode" "SF")])
4594 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4595 ;; because nothing we do here is unsafe.
4596 (define_insn "*truncdfsf_fast_sse"
4597 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4599 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4600 "TARGET_SSE2 && TARGET_SSE_MATH"
4601 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4602 [(set_attr "type" "ssecvt")
4603 (set_attr "prefix" "maybe_vex")
4604 (set_attr "mode" "SF")])
4606 (define_insn "*truncdfsf_fast_i387"
4607 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4609 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4610 "TARGET_80387 && flag_unsafe_math_optimizations"
4611 "* return output_387_reg_move (insn, operands);"
4612 [(set_attr "type" "fmov")
4613 (set_attr "mode" "SF")])
4615 (define_insn "*truncdfsf_mixed"
4616 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4618 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4619 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4620 "TARGET_MIX_SSE_I387"
4622 switch (which_alternative)
4625 return output_387_reg_move (insn, operands);
4627 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4633 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4634 (set_attr "unit" "*,*,i387,i387,i387")
4635 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4636 (set_attr "mode" "SF")])
4638 (define_insn "*truncdfsf_i387"
4639 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4641 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4642 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4645 switch (which_alternative)
4648 return output_387_reg_move (insn, operands);
4654 [(set_attr "type" "fmov,multi,multi,multi")
4655 (set_attr "unit" "*,i387,i387,i387")
4656 (set_attr "mode" "SF")])
4658 (define_insn "*truncdfsf2_i387_1"
4659 [(set (match_operand:SF 0 "memory_operand" "=m")
4661 (match_operand:DF 1 "register_operand" "f")))]
4663 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4664 && !TARGET_MIX_SSE_I387"
4665 "* return output_387_reg_move (insn, operands);"
4666 [(set_attr "type" "fmov")
4667 (set_attr "mode" "SF")])
4670 [(set (match_operand:SF 0 "register_operand" "")
4672 (match_operand:DF 1 "fp_register_operand" "")))
4673 (clobber (match_operand 2 "" ""))]
4675 [(set (match_dup 2) (match_dup 1))
4676 (set (match_dup 0) (match_dup 2))]
4678 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4681 ;; Conversion from XFmode to {SF,DF}mode
4683 (define_expand "truncxf<mode>2"
4684 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4685 (float_truncate:MODEF
4686 (match_operand:XF 1 "register_operand" "")))
4687 (clobber (match_dup 2))])]
4690 if (flag_unsafe_math_optimizations)
4692 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4693 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4694 if (reg != operands[0])
4695 emit_move_insn (operands[0], reg);
4700 enum ix86_stack_slot slot = (virtuals_instantiated
4703 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4707 (define_insn "*truncxfsf2_mixed"
4708 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4710 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4711 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4714 gcc_assert (!which_alternative);
4715 return output_387_reg_move (insn, operands);
4717 [(set_attr "type" "fmov,multi,multi,multi")
4718 (set_attr "unit" "*,i387,i387,i387")
4719 (set_attr "mode" "SF")])
4721 (define_insn "*truncxfdf2_mixed"
4722 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4724 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4725 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4728 gcc_assert (!which_alternative);
4729 return output_387_reg_move (insn, operands);
4731 [(set_attr "type" "fmov,multi,multi,multi")
4732 (set_attr "unit" "*,i387,i387,i387")
4733 (set_attr "mode" "DF")])
4735 (define_insn "truncxf<mode>2_i387_noop"
4736 [(set (match_operand:MODEF 0 "register_operand" "=f")
4737 (float_truncate:MODEF
4738 (match_operand:XF 1 "register_operand" "f")))]
4739 "TARGET_80387 && flag_unsafe_math_optimizations"
4740 "* return output_387_reg_move (insn, operands);"
4741 [(set_attr "type" "fmov")
4742 (set_attr "mode" "<MODE>")])
4744 (define_insn "*truncxf<mode>2_i387"
4745 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4746 (float_truncate:MODEF
4747 (match_operand:XF 1 "register_operand" "f")))]
4749 "* return output_387_reg_move (insn, operands);"
4750 [(set_attr "type" "fmov")
4751 (set_attr "mode" "<MODE>")])
4754 [(set (match_operand:MODEF 0 "register_operand" "")
4755 (float_truncate:MODEF
4756 (match_operand:XF 1 "register_operand" "")))
4757 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4758 "TARGET_80387 && reload_completed"
4759 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4760 (set (match_dup 0) (match_dup 2))]
4764 [(set (match_operand:MODEF 0 "memory_operand" "")
4765 (float_truncate:MODEF
4766 (match_operand:XF 1 "register_operand" "")))
4767 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4769 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4772 ;; Signed conversion to DImode.
4774 (define_expand "fix_truncxfdi2"
4775 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4776 (fix:DI (match_operand:XF 1 "register_operand" "")))
4777 (clobber (reg:CC FLAGS_REG))])]
4782 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4787 (define_expand "fix_trunc<mode>di2"
4788 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4789 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4790 (clobber (reg:CC FLAGS_REG))])]
4791 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4794 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4796 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4799 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4801 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4802 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4803 if (out != operands[0])
4804 emit_move_insn (operands[0], out);
4809 ;; Signed conversion to SImode.
4811 (define_expand "fix_truncxfsi2"
4812 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4813 (fix:SI (match_operand:XF 1 "register_operand" "")))
4814 (clobber (reg:CC FLAGS_REG))])]
4819 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4824 (define_expand "fix_trunc<mode>si2"
4825 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4826 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4827 (clobber (reg:CC FLAGS_REG))])]
4828 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4831 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4833 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4836 if (SSE_FLOAT_MODE_P (<MODE>mode))
4838 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4839 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4840 if (out != operands[0])
4841 emit_move_insn (operands[0], out);
4846 ;; Signed conversion to HImode.
4848 (define_expand "fix_trunc<mode>hi2"
4849 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4850 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4851 (clobber (reg:CC FLAGS_REG))])]
4853 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4857 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4862 ;; Unsigned conversion to SImode.
4864 (define_expand "fixuns_trunc<mode>si2"
4866 [(set (match_operand:SI 0 "register_operand" "")
4868 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4870 (clobber (match_scratch:<ssevecmode> 3 ""))
4871 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4872 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4874 enum machine_mode mode = <MODE>mode;
4875 enum machine_mode vecmode = <ssevecmode>mode;
4876 REAL_VALUE_TYPE TWO31r;
4879 if (optimize_insn_for_size_p ())
4882 real_ldexp (&TWO31r, &dconst1, 31);
4883 two31 = const_double_from_real_value (TWO31r, mode);
4884 two31 = ix86_build_const_vector (mode, true, two31);
4885 operands[2] = force_reg (vecmode, two31);
4888 (define_insn_and_split "*fixuns_trunc<mode>_1"
4889 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4891 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4892 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4893 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4894 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4895 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4896 && optimize_function_for_speed_p (cfun)"
4898 "&& reload_completed"
4901 ix86_split_convert_uns_si_sse (operands);
4905 ;; Unsigned conversion to HImode.
4906 ;; Without these patterns, we'll try the unsigned SI conversion which
4907 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4909 (define_expand "fixuns_trunc<mode>hi2"
4911 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4912 (set (match_operand:HI 0 "nonimmediate_operand" "")
4913 (subreg:HI (match_dup 2) 0))]
4914 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4915 "operands[2] = gen_reg_rtx (SImode);")
4917 ;; When SSE is available, it is always faster to use it!
4918 (define_insn "fix_trunc<mode>di_sse"
4919 [(set (match_operand:DI 0 "register_operand" "=r,r")
4920 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4921 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4922 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4923 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4924 [(set_attr "type" "sseicvt")
4925 (set_attr "prefix" "maybe_vex")
4926 (set_attr "prefix_rex" "1")
4927 (set_attr "mode" "<MODE>")
4928 (set_attr "athlon_decode" "double,vector")
4929 (set_attr "amdfam10_decode" "double,double")])
4931 (define_insn "fix_trunc<mode>si_sse"
4932 [(set (match_operand:SI 0 "register_operand" "=r,r")
4933 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4934 "SSE_FLOAT_MODE_P (<MODE>mode)
4935 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4936 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4937 [(set_attr "type" "sseicvt")
4938 (set_attr "prefix" "maybe_vex")
4939 (set_attr "mode" "<MODE>")
4940 (set_attr "athlon_decode" "double,vector")
4941 (set_attr "amdfam10_decode" "double,double")])
4943 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4945 [(set (match_operand:MODEF 0 "register_operand" "")
4946 (match_operand:MODEF 1 "memory_operand" ""))
4947 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4948 (fix:SSEMODEI24 (match_dup 0)))]
4949 "TARGET_SHORTEN_X87_SSE
4950 && peep2_reg_dead_p (2, operands[0])"
4951 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4954 ;; Avoid vector decoded forms of the instruction.
4956 [(match_scratch:DF 2 "Y2")
4957 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4958 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4959 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4960 [(set (match_dup 2) (match_dup 1))
4961 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4965 [(match_scratch:SF 2 "x")
4966 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4967 (fix:SSEMODEI24 (match_operand:SF 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)))]
4973 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4974 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4975 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4976 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4978 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4979 && (TARGET_64BIT || <MODE>mode != DImode))
4981 && can_create_pseudo_p ()"
4986 if (memory_operand (operands[0], VOIDmode))
4987 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4990 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4991 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4997 [(set_attr "type" "fisttp")
4998 (set_attr "mode" "<MODE>")])
5000 (define_insn "fix_trunc<mode>_i387_fisttp"
5001 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5002 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5003 (clobber (match_scratch:XF 2 "=&1f"))]
5004 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5006 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5007 && (TARGET_64BIT || <MODE>mode != DImode))
5008 && TARGET_SSE_MATH)"
5009 "* return output_fix_trunc (insn, operands, 1);"
5010 [(set_attr "type" "fisttp")
5011 (set_attr "mode" "<MODE>")])
5013 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5014 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5015 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5016 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5017 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5018 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5020 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5021 && (TARGET_64BIT || <MODE>mode != DImode))
5022 && TARGET_SSE_MATH)"
5024 [(set_attr "type" "fisttp")
5025 (set_attr "mode" "<MODE>")])
5028 [(set (match_operand:X87MODEI 0 "register_operand" "")
5029 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5030 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5031 (clobber (match_scratch 3 ""))]
5033 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5034 (clobber (match_dup 3))])
5035 (set (match_dup 0) (match_dup 2))]
5039 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5040 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5041 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5042 (clobber (match_scratch 3 ""))]
5044 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5045 (clobber (match_dup 3))])]
5048 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5049 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5050 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5051 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5052 ;; function in i386.c.
5053 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5054 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5055 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5056 (clobber (reg:CC FLAGS_REG))]
5057 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5059 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5060 && (TARGET_64BIT || <MODE>mode != DImode))
5061 && can_create_pseudo_p ()"
5066 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5068 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5069 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5070 if (memory_operand (operands[0], VOIDmode))
5071 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5072 operands[2], operands[3]));
5075 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5076 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5077 operands[2], operands[3],
5082 [(set_attr "type" "fistp")
5083 (set_attr "i387_cw" "trunc")
5084 (set_attr "mode" "<MODE>")])
5086 (define_insn "fix_truncdi_i387"
5087 [(set (match_operand:DI 0 "memory_operand" "=m")
5088 (fix:DI (match_operand 1 "register_operand" "f")))
5089 (use (match_operand:HI 2 "memory_operand" "m"))
5090 (use (match_operand:HI 3 "memory_operand" "m"))
5091 (clobber (match_scratch:XF 4 "=&1f"))]
5092 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5094 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5095 "* return output_fix_trunc (insn, operands, 0);"
5096 [(set_attr "type" "fistp")
5097 (set_attr "i387_cw" "trunc")
5098 (set_attr "mode" "DI")])
5100 (define_insn "fix_truncdi_i387_with_temp"
5101 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5102 (fix:DI (match_operand 1 "register_operand" "f,f")))
5103 (use (match_operand:HI 2 "memory_operand" "m,m"))
5104 (use (match_operand:HI 3 "memory_operand" "m,m"))
5105 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5106 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5107 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5109 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5111 [(set_attr "type" "fistp")
5112 (set_attr "i387_cw" "trunc")
5113 (set_attr "mode" "DI")])
5116 [(set (match_operand:DI 0 "register_operand" "")
5117 (fix:DI (match_operand 1 "register_operand" "")))
5118 (use (match_operand:HI 2 "memory_operand" ""))
5119 (use (match_operand:HI 3 "memory_operand" ""))
5120 (clobber (match_operand:DI 4 "memory_operand" ""))
5121 (clobber (match_scratch 5 ""))]
5123 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5126 (clobber (match_dup 5))])
5127 (set (match_dup 0) (match_dup 4))]
5131 [(set (match_operand:DI 0 "memory_operand" "")
5132 (fix:DI (match_operand 1 "register_operand" "")))
5133 (use (match_operand:HI 2 "memory_operand" ""))
5134 (use (match_operand:HI 3 "memory_operand" ""))
5135 (clobber (match_operand:DI 4 "memory_operand" ""))
5136 (clobber (match_scratch 5 ""))]
5138 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5141 (clobber (match_dup 5))])]
5144 (define_insn "fix_trunc<mode>_i387"
5145 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5146 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5147 (use (match_operand:HI 2 "memory_operand" "m"))
5148 (use (match_operand:HI 3 "memory_operand" "m"))]
5149 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5151 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5152 "* return output_fix_trunc (insn, operands, 0);"
5153 [(set_attr "type" "fistp")
5154 (set_attr "i387_cw" "trunc")
5155 (set_attr "mode" "<MODE>")])
5157 (define_insn "fix_trunc<mode>_i387_with_temp"
5158 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5159 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5160 (use (match_operand:HI 2 "memory_operand" "m,m"))
5161 (use (match_operand:HI 3 "memory_operand" "m,m"))
5162 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5163 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5165 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5167 [(set_attr "type" "fistp")
5168 (set_attr "i387_cw" "trunc")
5169 (set_attr "mode" "<MODE>")])
5172 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5173 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5174 (use (match_operand:HI 2 "memory_operand" ""))
5175 (use (match_operand:HI 3 "memory_operand" ""))
5176 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5178 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5180 (use (match_dup 3))])
5181 (set (match_dup 0) (match_dup 4))]
5185 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5186 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5187 (use (match_operand:HI 2 "memory_operand" ""))
5188 (use (match_operand:HI 3 "memory_operand" ""))
5189 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5191 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5193 (use (match_dup 3))])]
5196 (define_insn "x86_fnstcw_1"
5197 [(set (match_operand:HI 0 "memory_operand" "=m")
5198 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5201 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5202 (set_attr "mode" "HI")
5203 (set_attr "unit" "i387")])
5205 (define_insn "x86_fldcw_1"
5206 [(set (reg:HI FPCR_REG)
5207 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5210 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5211 (set_attr "mode" "HI")
5212 (set_attr "unit" "i387")
5213 (set_attr "athlon_decode" "vector")
5214 (set_attr "amdfam10_decode" "vector")])
5216 ;; Conversion between fixed point and floating point.
5218 ;; Even though we only accept memory inputs, the backend _really_
5219 ;; wants to be able to do this between registers.
5221 (define_expand "floathi<mode>2"
5222 [(set (match_operand:X87MODEF 0 "register_operand" "")
5223 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5225 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5226 || TARGET_MIX_SSE_I387)"
5229 ;; Pre-reload splitter to add memory clobber to the pattern.
5230 (define_insn_and_split "*floathi<mode>2_1"
5231 [(set (match_operand:X87MODEF 0 "register_operand" "")
5232 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5234 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5235 || TARGET_MIX_SSE_I387)
5236 && can_create_pseudo_p ()"
5239 [(parallel [(set (match_dup 0)
5240 (float:X87MODEF (match_dup 1)))
5241 (clobber (match_dup 2))])]
5242 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5244 (define_insn "*floathi<mode>2_i387_with_temp"
5245 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5246 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5247 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5249 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5250 || TARGET_MIX_SSE_I387)"
5252 [(set_attr "type" "fmov,multi")
5253 (set_attr "mode" "<MODE>")
5254 (set_attr "unit" "*,i387")
5255 (set_attr "fp_int_src" "true")])
5257 (define_insn "*floathi<mode>2_i387"
5258 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5259 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5261 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5262 || TARGET_MIX_SSE_I387)"
5264 [(set_attr "type" "fmov")
5265 (set_attr "mode" "<MODE>")
5266 (set_attr "fp_int_src" "true")])
5269 [(set (match_operand:X87MODEF 0 "register_operand" "")
5270 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5271 (clobber (match_operand:HI 2 "memory_operand" ""))]
5273 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5274 || TARGET_MIX_SSE_I387)
5275 && reload_completed"
5276 [(set (match_dup 2) (match_dup 1))
5277 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5281 [(set (match_operand:X87MODEF 0 "register_operand" "")
5282 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5283 (clobber (match_operand:HI 2 "memory_operand" ""))]
5285 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5286 || TARGET_MIX_SSE_I387)
5287 && reload_completed"
5288 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5291 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5292 [(set (match_operand:X87MODEF 0 "register_operand" "")
5294 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5296 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5297 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5299 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5300 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5301 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5303 rtx reg = gen_reg_rtx (XFmode);
5306 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5308 if (<X87MODEF:MODE>mode == SFmode)
5309 insn = gen_truncxfsf2 (operands[0], reg);
5310 else if (<X87MODEF:MODE>mode == DFmode)
5311 insn = gen_truncxfdf2 (operands[0], reg);
5320 ;; Pre-reload splitter to add memory clobber to the pattern.
5321 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5322 [(set (match_operand:X87MODEF 0 "register_operand" "")
5323 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5325 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5326 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5327 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5328 || TARGET_MIX_SSE_I387))
5329 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5330 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5331 && ((<SSEMODEI24:MODE>mode == SImode
5332 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5333 && optimize_function_for_speed_p (cfun)
5334 && flag_trapping_math)
5335 || !(TARGET_INTER_UNIT_CONVERSIONS
5336 || optimize_function_for_size_p (cfun)))))
5337 && can_create_pseudo_p ()"
5340 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5341 (clobber (match_dup 2))])]
5343 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5345 /* Avoid store forwarding (partial memory) stall penalty
5346 by passing DImode value through XMM registers. */
5347 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5348 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5349 && optimize_function_for_speed_p (cfun))
5351 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5358 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5359 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5361 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5362 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5363 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5364 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5366 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5367 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5368 (set_attr "unit" "*,i387,*,*,*")
5369 (set_attr "athlon_decode" "*,*,double,direct,double")
5370 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5371 (set_attr "fp_int_src" "true")])
5373 (define_insn "*floatsi<mode>2_vector_mixed"
5374 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5375 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5376 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5377 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5381 [(set_attr "type" "fmov,sseicvt")
5382 (set_attr "mode" "<MODE>,<ssevecmode>")
5383 (set_attr "unit" "i387,*")
5384 (set_attr "athlon_decode" "*,direct")
5385 (set_attr "amdfam10_decode" "*,double")
5386 (set_attr "fp_int_src" "true")])
5388 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5389 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5391 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5392 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5393 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5394 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5396 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5397 (set_attr "mode" "<MODEF:MODE>")
5398 (set_attr "unit" "*,i387,*,*")
5399 (set_attr "athlon_decode" "*,*,double,direct")
5400 (set_attr "amdfam10_decode" "*,*,vector,double")
5401 (set_attr "fp_int_src" "true")])
5404 [(set (match_operand:MODEF 0 "register_operand" "")
5405 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5406 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5407 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5408 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5409 && TARGET_INTER_UNIT_CONVERSIONS
5411 && (SSE_REG_P (operands[0])
5412 || (GET_CODE (operands[0]) == SUBREG
5413 && SSE_REG_P (operands[0])))"
5414 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5418 [(set (match_operand:MODEF 0 "register_operand" "")
5419 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5420 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5421 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5422 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5423 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5425 && (SSE_REG_P (operands[0])
5426 || (GET_CODE (operands[0]) == SUBREG
5427 && SSE_REG_P (operands[0])))"
5428 [(set (match_dup 2) (match_dup 1))
5429 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5432 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5433 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5435 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5436 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5437 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5438 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5441 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5442 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5443 [(set_attr "type" "fmov,sseicvt,sseicvt")
5444 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5445 (set_attr "mode" "<MODEF:MODE>")
5446 (set (attr "prefix_rex")
5448 (and (eq_attr "prefix" "maybe_vex")
5449 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5451 (const_string "*")))
5452 (set_attr "unit" "i387,*,*")
5453 (set_attr "athlon_decode" "*,double,direct")
5454 (set_attr "amdfam10_decode" "*,vector,double")
5455 (set_attr "fp_int_src" "true")])
5457 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5458 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5460 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5461 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5462 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5463 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5466 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5467 [(set_attr "type" "fmov,sseicvt")
5468 (set_attr "prefix" "orig,maybe_vex")
5469 (set_attr "mode" "<MODEF:MODE>")
5470 (set (attr "prefix_rex")
5472 (and (eq_attr "prefix" "maybe_vex")
5473 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5475 (const_string "*")))
5476 (set_attr "athlon_decode" "*,direct")
5477 (set_attr "amdfam10_decode" "*,double")
5478 (set_attr "fp_int_src" "true")])
5480 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5481 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5483 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5484 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5485 "TARGET_SSE2 && TARGET_SSE_MATH
5486 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5488 [(set_attr "type" "sseicvt")
5489 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5490 (set_attr "athlon_decode" "double,direct,double")
5491 (set_attr "amdfam10_decode" "vector,double,double")
5492 (set_attr "fp_int_src" "true")])
5494 (define_insn "*floatsi<mode>2_vector_sse"
5495 [(set (match_operand:MODEF 0 "register_operand" "=x")
5496 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5497 "TARGET_SSE2 && TARGET_SSE_MATH
5498 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5500 [(set_attr "type" "sseicvt")
5501 (set_attr "mode" "<MODE>")
5502 (set_attr "athlon_decode" "direct")
5503 (set_attr "amdfam10_decode" "double")
5504 (set_attr "fp_int_src" "true")])
5507 [(set (match_operand:MODEF 0 "register_operand" "")
5508 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5509 (clobber (match_operand:SI 2 "memory_operand" ""))]
5510 "TARGET_SSE2 && TARGET_SSE_MATH
5511 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5513 && (SSE_REG_P (operands[0])
5514 || (GET_CODE (operands[0]) == SUBREG
5515 && SSE_REG_P (operands[0])))"
5518 rtx op1 = operands[1];
5520 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5522 if (GET_CODE (op1) == SUBREG)
5523 op1 = SUBREG_REG (op1);
5525 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5527 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5528 emit_insn (gen_sse2_loadld (operands[4],
5529 CONST0_RTX (V4SImode), operands[1]));
5531 /* We can ignore possible trapping value in the
5532 high part of SSE register for non-trapping math. */
5533 else if (SSE_REG_P (op1) && !flag_trapping_math)
5534 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5537 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5538 emit_move_insn (operands[2], operands[1]);
5539 emit_insn (gen_sse2_loadld (operands[4],
5540 CONST0_RTX (V4SImode), operands[2]));
5543 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5548 [(set (match_operand:MODEF 0 "register_operand" "")
5549 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5550 (clobber (match_operand:SI 2 "memory_operand" ""))]
5551 "TARGET_SSE2 && TARGET_SSE_MATH
5552 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5554 && (SSE_REG_P (operands[0])
5555 || (GET_CODE (operands[0]) == SUBREG
5556 && SSE_REG_P (operands[0])))"
5559 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5561 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5563 emit_insn (gen_sse2_loadld (operands[4],
5564 CONST0_RTX (V4SImode), operands[1]));
5566 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5571 [(set (match_operand:MODEF 0 "register_operand" "")
5572 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5573 "TARGET_SSE2 && TARGET_SSE_MATH
5574 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5576 && (SSE_REG_P (operands[0])
5577 || (GET_CODE (operands[0]) == SUBREG
5578 && SSE_REG_P (operands[0])))"
5581 rtx op1 = operands[1];
5583 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5585 if (GET_CODE (op1) == SUBREG)
5586 op1 = SUBREG_REG (op1);
5588 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5590 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5591 emit_insn (gen_sse2_loadld (operands[4],
5592 CONST0_RTX (V4SImode), operands[1]));
5594 /* We can ignore possible trapping value in the
5595 high part of SSE register for non-trapping math. */
5596 else if (SSE_REG_P (op1) && !flag_trapping_math)
5597 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5601 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5606 [(set (match_operand:MODEF 0 "register_operand" "")
5607 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5608 "TARGET_SSE2 && TARGET_SSE_MATH
5609 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5611 && (SSE_REG_P (operands[0])
5612 || (GET_CODE (operands[0]) == SUBREG
5613 && SSE_REG_P (operands[0])))"
5616 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5618 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5620 emit_insn (gen_sse2_loadld (operands[4],
5621 CONST0_RTX (V4SImode), operands[1]));
5623 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5627 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5628 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5630 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5631 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5632 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5633 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5635 [(set_attr "type" "sseicvt")
5636 (set_attr "mode" "<MODEF:MODE>")
5637 (set_attr "athlon_decode" "double,direct")
5638 (set_attr "amdfam10_decode" "vector,double")
5639 (set_attr "fp_int_src" "true")])
5641 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5642 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5644 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5645 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5646 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5647 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5648 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5649 [(set_attr "type" "sseicvt")
5650 (set_attr "prefix" "maybe_vex")
5651 (set_attr "mode" "<MODEF:MODE>")
5652 (set (attr "prefix_rex")
5654 (and (eq_attr "prefix" "maybe_vex")
5655 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5657 (const_string "*")))
5658 (set_attr "athlon_decode" "double,direct")
5659 (set_attr "amdfam10_decode" "vector,double")
5660 (set_attr "fp_int_src" "true")])
5663 [(set (match_operand:MODEF 0 "register_operand" "")
5664 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5665 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5666 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5667 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5668 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5670 && (SSE_REG_P (operands[0])
5671 || (GET_CODE (operands[0]) == SUBREG
5672 && SSE_REG_P (operands[0])))"
5673 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5676 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5677 [(set (match_operand:MODEF 0 "register_operand" "=x")
5679 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5680 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5681 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5682 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5683 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5684 [(set_attr "type" "sseicvt")
5685 (set_attr "prefix" "maybe_vex")
5686 (set_attr "mode" "<MODEF:MODE>")
5687 (set (attr "prefix_rex")
5689 (and (eq_attr "prefix" "maybe_vex")
5690 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5692 (const_string "*")))
5693 (set_attr "athlon_decode" "direct")
5694 (set_attr "amdfam10_decode" "double")
5695 (set_attr "fp_int_src" "true")])
5698 [(set (match_operand:MODEF 0 "register_operand" "")
5699 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5700 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5701 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5702 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5703 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5705 && (SSE_REG_P (operands[0])
5706 || (GET_CODE (operands[0]) == SUBREG
5707 && SSE_REG_P (operands[0])))"
5708 [(set (match_dup 2) (match_dup 1))
5709 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5713 [(set (match_operand:MODEF 0 "register_operand" "")
5714 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5715 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5716 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5717 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5719 && (SSE_REG_P (operands[0])
5720 || (GET_CODE (operands[0]) == SUBREG
5721 && SSE_REG_P (operands[0])))"
5722 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5725 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5726 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5728 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5729 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5731 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5735 [(set_attr "type" "fmov,multi")
5736 (set_attr "mode" "<X87MODEF:MODE>")
5737 (set_attr "unit" "*,i387")
5738 (set_attr "fp_int_src" "true")])
5740 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5741 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5743 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5745 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5747 [(set_attr "type" "fmov")
5748 (set_attr "mode" "<X87MODEF:MODE>")
5749 (set_attr "fp_int_src" "true")])
5752 [(set (match_operand:X87MODEF 0 "register_operand" "")
5753 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5754 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5756 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5758 && FP_REG_P (operands[0])"
5759 [(set (match_dup 2) (match_dup 1))
5760 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5764 [(set (match_operand:X87MODEF 0 "register_operand" "")
5765 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5766 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5768 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5770 && FP_REG_P (operands[0])"
5771 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5774 ;; Avoid store forwarding (partial memory) stall penalty
5775 ;; by passing DImode value through XMM registers. */
5777 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5778 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5780 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5781 (clobber (match_scratch:V4SI 3 "=X,x"))
5782 (clobber (match_scratch:V4SI 4 "=X,x"))
5783 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5784 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5785 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5786 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5788 [(set_attr "type" "multi")
5789 (set_attr "mode" "<X87MODEF:MODE>")
5790 (set_attr "unit" "i387")
5791 (set_attr "fp_int_src" "true")])
5794 [(set (match_operand:X87MODEF 0 "register_operand" "")
5795 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5796 (clobber (match_scratch:V4SI 3 ""))
5797 (clobber (match_scratch:V4SI 4 ""))
5798 (clobber (match_operand:DI 2 "memory_operand" ""))]
5799 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5800 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5801 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5803 && FP_REG_P (operands[0])"
5804 [(set (match_dup 2) (match_dup 3))
5805 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5807 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5808 Assemble the 64-bit DImode value in an xmm register. */
5809 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5810 gen_rtx_SUBREG (SImode, operands[1], 0)));
5811 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5812 gen_rtx_SUBREG (SImode, operands[1], 4)));
5813 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5816 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5820 [(set (match_operand:X87MODEF 0 "register_operand" "")
5821 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5822 (clobber (match_scratch:V4SI 3 ""))
5823 (clobber (match_scratch:V4SI 4 ""))
5824 (clobber (match_operand:DI 2 "memory_operand" ""))]
5825 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5826 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5827 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5829 && FP_REG_P (operands[0])"
5830 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5833 ;; Avoid store forwarding (partial memory) stall penalty by extending
5834 ;; SImode value to DImode through XMM register instead of pushing two
5835 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5836 ;; targets benefit from this optimization. Also note that fild
5837 ;; loads from memory only.
5839 (define_insn "*floatunssi<mode>2_1"
5840 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5841 (unsigned_float:X87MODEF
5842 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5843 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5844 (clobber (match_scratch:SI 3 "=X,x"))]
5846 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5849 [(set_attr "type" "multi")
5850 (set_attr "mode" "<MODE>")])
5853 [(set (match_operand:X87MODEF 0 "register_operand" "")
5854 (unsigned_float:X87MODEF
5855 (match_operand:SI 1 "register_operand" "")))
5856 (clobber (match_operand:DI 2 "memory_operand" ""))
5857 (clobber (match_scratch:SI 3 ""))]
5859 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5861 && reload_completed"
5862 [(set (match_dup 2) (match_dup 1))
5864 (float:X87MODEF (match_dup 2)))]
5865 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5868 [(set (match_operand:X87MODEF 0 "register_operand" "")
5869 (unsigned_float:X87MODEF
5870 (match_operand:SI 1 "memory_operand" "")))
5871 (clobber (match_operand:DI 2 "memory_operand" ""))
5872 (clobber (match_scratch:SI 3 ""))]
5874 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5876 && reload_completed"
5877 [(set (match_dup 2) (match_dup 3))
5879 (float:X87MODEF (match_dup 2)))]
5881 emit_move_insn (operands[3], operands[1]);
5882 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5885 (define_expand "floatunssi<mode>2"
5887 [(set (match_operand:X87MODEF 0 "register_operand" "")
5888 (unsigned_float:X87MODEF
5889 (match_operand:SI 1 "nonimmediate_operand" "")))
5890 (clobber (match_dup 2))
5891 (clobber (match_scratch:SI 3 ""))])]
5893 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5895 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5897 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5899 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5904 enum ix86_stack_slot slot = (virtuals_instantiated
5907 operands[2] = assign_386_stack_local (DImode, slot);
5911 (define_expand "floatunsdisf2"
5912 [(use (match_operand:SF 0 "register_operand" ""))
5913 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5914 "TARGET_64BIT && TARGET_SSE_MATH"
5915 "x86_emit_floatuns (operands); DONE;")
5917 (define_expand "floatunsdidf2"
5918 [(use (match_operand:DF 0 "register_operand" ""))
5919 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5920 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5921 && TARGET_SSE2 && TARGET_SSE_MATH"
5924 x86_emit_floatuns (operands);
5926 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5932 (define_expand "add<mode>3"
5933 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5934 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5935 (match_operand:SDWIM 2 "<general_operand>" "")))]
5937 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5939 (define_insn_and_split "*add<dwi>3_doubleword"
5940 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5942 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5943 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5944 (clobber (reg:CC FLAGS_REG))]
5945 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5948 [(parallel [(set (reg:CC FLAGS_REG)
5949 (unspec:CC [(match_dup 1) (match_dup 2)]
5952 (plus:DWIH (match_dup 1) (match_dup 2)))])
5953 (parallel [(set (match_dup 3)
5957 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5959 (clobber (reg:CC FLAGS_REG))])]
5960 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5962 (define_insn "*add<mode>3_cc"
5963 [(set (reg:CC FLAGS_REG)
5965 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5966 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5968 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5969 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5970 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5971 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5972 [(set_attr "type" "alu")
5973 (set_attr "mode" "<MODE>")])
5975 (define_insn "addqi3_cc"
5976 [(set (reg:CC FLAGS_REG)
5978 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5979 (match_operand:QI 2 "general_operand" "qn,qm")]
5981 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5982 (plus:QI (match_dup 1) (match_dup 2)))]
5983 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5984 "add{b}\t{%2, %0|%0, %2}"
5985 [(set_attr "type" "alu")
5986 (set_attr "mode" "QI")])
5988 (define_insn "*lea_1"
5989 [(set (match_operand:DWIH 0 "register_operand" "=r")
5990 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5992 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5993 [(set_attr "type" "lea")
5994 (set_attr "mode" "<MODE>")])
5996 (define_insn "*lea_2"
5997 [(set (match_operand:SI 0 "register_operand" "=r")
5998 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6000 "lea{l}\t{%a1, %0|%0, %a1}"
6001 [(set_attr "type" "lea")
6002 (set_attr "mode" "SI")])
6004 (define_insn "*lea_2_zext"
6005 [(set (match_operand:DI 0 "register_operand" "=r")
6007 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6009 "lea{l}\t{%a1, %k0|%k0, %a1}"
6010 [(set_attr "type" "lea")
6011 (set_attr "mode" "SI")])
6013 (define_insn "*add<mode>_1"
6014 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6016 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6017 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6018 (clobber (reg:CC FLAGS_REG))]
6019 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6021 switch (get_attr_type (insn))
6024 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6025 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6028 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6029 if (operands[2] == const1_rtx)
6030 return "inc{<imodesuffix>}\t%0";
6033 gcc_assert (operands[2] == constm1_rtx);
6034 return "dec{<imodesuffix>}\t%0";
6038 /* Use add as much as possible to replace lea for AGU optimization. */
6039 if (which_alternative == 2 && TARGET_OPT_AGU)
6040 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6042 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6043 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6044 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6046 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6050 (cond [(and (eq_attr "alternative" "2")
6051 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6052 (const_string "lea")
6053 (eq_attr "alternative" "3")
6054 (const_string "lea")
6055 ; Current assemblers are broken and do not allow @GOTOFF in
6056 ; ought but a memory context.
6057 (match_operand:SWI48 2 "pic_symbolic_operand" "")
6058 (const_string "lea")
6059 (match_operand:SWI48 2 "incdec_operand" "")
6060 (const_string "incdec")
6062 (const_string "alu")))
6063 (set (attr "length_immediate")
6065 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6067 (const_string "*")))
6068 (set_attr "mode" "<MODE>")])
6070 ;; It may seem that nonimmediate operand is proper one for operand 1.
6071 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6072 ;; we take care in ix86_binary_operator_ok to not allow two memory
6073 ;; operands so proper swapping will be done in reload. This allow
6074 ;; patterns constructed from addsi_1 to match.
6076 (define_insn "*addsi_1_zext"
6077 [(set (match_operand:DI 0 "register_operand" "=r,r")
6079 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6080 (match_operand:SI 2 "general_operand" "g,li"))))
6081 (clobber (reg:CC FLAGS_REG))]
6082 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6084 switch (get_attr_type (insn))
6087 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6088 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6091 if (operands[2] == const1_rtx)
6092 return "inc{l}\t%k0";
6095 gcc_assert (operands[2] == constm1_rtx);
6096 return "dec{l}\t%k0";
6100 if (x86_maybe_negate_const_int (&operands[2], SImode))
6101 return "sub{l}\t{%2, %k0|%k0, %2}";
6103 return "add{l}\t{%2, %k0|%k0, %2}";
6107 (cond [(eq_attr "alternative" "1")
6108 (const_string "lea")
6109 ; Current assemblers are broken and do not allow @GOTOFF in
6110 ; ought but a memory context.
6111 (match_operand:SI 2 "pic_symbolic_operand" "")
6112 (const_string "lea")
6113 (match_operand:SI 2 "incdec_operand" "")
6114 (const_string "incdec")
6116 (const_string "alu")))
6117 (set (attr "length_immediate")
6119 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6121 (const_string "*")))
6122 (set_attr "mode" "SI")])
6124 (define_insn "*addhi_1"
6125 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6126 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6127 (match_operand:HI 2 "general_operand" "rn,rm")))
6128 (clobber (reg:CC FLAGS_REG))]
6129 "TARGET_PARTIAL_REG_STALL
6130 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6132 switch (get_attr_type (insn))
6135 if (operands[2] == const1_rtx)
6136 return "inc{w}\t%0";
6139 gcc_assert (operands[2] == constm1_rtx);
6140 return "dec{w}\t%0";
6144 if (x86_maybe_negate_const_int (&operands[2], HImode))
6145 return "sub{w}\t{%2, %0|%0, %2}";
6147 return "add{w}\t{%2, %0|%0, %2}";
6151 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6152 (const_string "incdec")
6153 (const_string "alu")))
6154 (set (attr "length_immediate")
6156 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6158 (const_string "*")))
6159 (set_attr "mode" "HI")])
6161 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6162 ;; type optimizations enabled by define-splits. This is not important
6163 ;; for PII, and in fact harmful because of partial register stalls.
6165 (define_insn "*addhi_1_lea"
6166 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6167 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6168 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6169 (clobber (reg:CC FLAGS_REG))]
6170 "!TARGET_PARTIAL_REG_STALL
6171 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6173 switch (get_attr_type (insn))
6178 if (operands[2] == const1_rtx)
6179 return "inc{w}\t%0";
6182 gcc_assert (operands[2] == constm1_rtx);
6183 return "dec{w}\t%0";
6187 if (x86_maybe_negate_const_int (&operands[2], HImode))
6188 return "sub{w}\t{%2, %0|%0, %2}";
6190 return "add{w}\t{%2, %0|%0, %2}";
6194 (if_then_else (eq_attr "alternative" "2")
6195 (const_string "lea")
6196 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6197 (const_string "incdec")
6198 (const_string "alu"))))
6199 (set (attr "length_immediate")
6201 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6203 (const_string "*")))
6204 (set_attr "mode" "HI,HI,SI")])
6206 (define_insn "*addqi_1"
6207 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6208 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6209 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6210 (clobber (reg:CC FLAGS_REG))]
6211 "TARGET_PARTIAL_REG_STALL
6212 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6214 int widen = (which_alternative == 2);
6215 switch (get_attr_type (insn))
6218 if (operands[2] == const1_rtx)
6219 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6222 gcc_assert (operands[2] == constm1_rtx);
6223 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6227 if (x86_maybe_negate_const_int (&operands[2], QImode))
6230 return "sub{l}\t{%2, %k0|%k0, %2}";
6232 return "sub{b}\t{%2, %0|%0, %2}";
6235 return "add{l}\t{%k2, %k0|%k0, %k2}";
6237 return "add{b}\t{%2, %0|%0, %2}";
6241 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6242 (const_string "incdec")
6243 (const_string "alu")))
6244 (set (attr "length_immediate")
6246 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6248 (const_string "*")))
6249 (set_attr "mode" "QI,QI,SI")])
6251 ;; %%% Potential partial reg stall on alternative 2. What to do?
6252 (define_insn "*addqi_1_lea"
6253 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6254 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6255 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6256 (clobber (reg:CC FLAGS_REG))]
6257 "!TARGET_PARTIAL_REG_STALL
6258 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6260 int widen = (which_alternative == 2);
6261 switch (get_attr_type (insn))
6266 if (operands[2] == const1_rtx)
6267 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6270 gcc_assert (operands[2] == constm1_rtx);
6271 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6275 if (x86_maybe_negate_const_int (&operands[2], QImode))
6278 return "sub{l}\t{%2, %k0|%k0, %2}";
6280 return "sub{b}\t{%2, %0|%0, %2}";
6283 return "add{l}\t{%k2, %k0|%k0, %k2}";
6285 return "add{b}\t{%2, %0|%0, %2}";
6289 (if_then_else (eq_attr "alternative" "3")
6290 (const_string "lea")
6291 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6292 (const_string "incdec")
6293 (const_string "alu"))))
6294 (set (attr "length_immediate")
6296 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6298 (const_string "*")))
6299 (set_attr "mode" "QI,QI,SI,SI")])
6301 (define_insn "*addqi_1_slp"
6302 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6303 (plus:QI (match_dup 0)
6304 (match_operand:QI 1 "general_operand" "qn,qnm")))
6305 (clobber (reg:CC FLAGS_REG))]
6306 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6307 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6309 switch (get_attr_type (insn))
6312 if (operands[1] == const1_rtx)
6313 return "inc{b}\t%0";
6316 gcc_assert (operands[1] == constm1_rtx);
6317 return "dec{b}\t%0";
6321 if (x86_maybe_negate_const_int (&operands[1], QImode))
6322 return "sub{b}\t{%1, %0|%0, %1}";
6324 return "add{b}\t{%1, %0|%0, %1}";
6328 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6329 (const_string "incdec")
6330 (const_string "alu1")))
6331 (set (attr "memory")
6332 (if_then_else (match_operand 1 "memory_operand" "")
6333 (const_string "load")
6334 (const_string "none")))
6335 (set_attr "mode" "QI")])
6337 (define_insn "*add<mode>_2"
6338 [(set (reg FLAGS_REG)
6341 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6342 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6344 (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6345 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6346 "ix86_match_ccmode (insn, CCGOCmode)
6347 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6348 /* Current assemblers are broken and do not allow @GOTOFF in
6349 ought but a memory context. */
6350 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6352 switch (get_attr_type (insn))
6355 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6356 if (operands[2] == const1_rtx)
6357 return "inc{<imodesuffix>}\t%0";
6360 gcc_assert (operands[2] == constm1_rtx);
6361 return "dec{<imodesuffix>}\t%0";
6365 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6366 /* ???? In DImode, we ought to handle there the 32bit case too
6367 - do we need new constraint? */
6368 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6369 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6371 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6375 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6376 (const_string "incdec")
6377 (const_string "alu")))
6378 (set (attr "length_immediate")
6380 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6382 (const_string "*")))
6383 (set_attr "mode" "<MODE>")])
6385 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6386 (define_insn "*addsi_2_zext"
6387 [(set (reg FLAGS_REG)
6389 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6390 (match_operand:SI 2 "general_operand" "g"))
6392 (set (match_operand:DI 0 "register_operand" "=r")
6393 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6394 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6395 && ix86_binary_operator_ok (PLUS, SImode, operands)
6396 /* Current assemblers are broken and do not allow @GOTOFF in
6397 ought but a memory context. */
6398 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6400 switch (get_attr_type (insn))
6403 if (operands[2] == const1_rtx)
6404 return "inc{l}\t%k0";
6407 gcc_assert (operands[2] == constm1_rtx);
6408 return "dec{l}\t%k0";
6412 if (x86_maybe_negate_const_int (&operands[2], SImode))
6413 return "sub{l}\t{%2, %k0|%k0, %2}";
6415 return "add{l}\t{%2, %k0|%k0, %2}";
6419 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6420 (const_string "incdec")
6421 (const_string "alu")))
6422 (set (attr "length_immediate")
6424 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6426 (const_string "*")))
6427 (set_attr "mode" "SI")])
6429 (define_insn "*addhi_2"
6430 [(set (reg FLAGS_REG)
6432 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6433 (match_operand:HI 2 "general_operand" "rmn,rn"))
6435 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6436 (plus:HI (match_dup 1) (match_dup 2)))]
6437 "ix86_match_ccmode (insn, CCGOCmode)
6438 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6440 switch (get_attr_type (insn))
6443 if (operands[2] == const1_rtx)
6444 return "inc{w}\t%0";
6447 gcc_assert (operands[2] == constm1_rtx);
6448 return "dec{w}\t%0";
6452 if (x86_maybe_negate_const_int (&operands[2], HImode))
6453 return "sub{w}\t{%2, %0|%0, %2}";
6455 return "add{w}\t{%2, %0|%0, %2}";
6459 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6460 (const_string "incdec")
6461 (const_string "alu")))
6462 (set (attr "length_immediate")
6464 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6466 (const_string "*")))
6467 (set_attr "mode" "HI")])
6469 (define_insn "*addqi_2"
6470 [(set (reg FLAGS_REG)
6472 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6473 (match_operand:QI 2 "general_operand" "qmn,qn"))
6475 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6476 (plus:QI (match_dup 1) (match_dup 2)))]
6477 "ix86_match_ccmode (insn, CCGOCmode)
6478 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6480 switch (get_attr_type (insn))
6483 if (operands[2] == const1_rtx)
6484 return "inc{b}\t%0";
6487 gcc_assert (operands[2] == constm1_rtx
6488 || (CONST_INT_P (operands[2])
6489 && INTVAL (operands[2]) == 255));
6490 return "dec{b}\t%0";
6494 if (x86_maybe_negate_const_int (&operands[2], QImode))
6495 return "sub{b}\t{%2, %0|%0, %2}";
6497 return "add{b}\t{%2, %0|%0, %2}";
6501 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6502 (const_string "incdec")
6503 (const_string "alu")))
6504 (set_attr "mode" "QI")])
6506 (define_insn "*add<mode>_3"
6507 [(set (reg FLAGS_REG)
6509 (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6510 (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6511 (clobber (match_scratch:SWI48 0 "=r"))]
6512 "ix86_match_ccmode (insn, CCZmode)
6513 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6514 /* Current assemblers are broken and do not allow @GOTOFF in
6515 ought but a memory context. */
6516 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6518 switch (get_attr_type (insn))
6521 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6522 if (operands[2] == const1_rtx)
6523 return "inc{<imodesuffix>}\t%0";
6526 gcc_assert (operands[2] == constm1_rtx);
6527 return "dec{<imodesuffix>}\t%0";
6531 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6532 /* ???? In DImode, we ought to handle there the 32bit case too
6533 - do we need new constraint? */
6534 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6535 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6537 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6541 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6542 (const_string "incdec")
6543 (const_string "alu")))
6544 (set (attr "length_immediate")
6546 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6548 (const_string "*")))
6549 (set_attr "mode" "<MODE>")])
6551 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6552 (define_insn "*addsi_3_zext"
6553 [(set (reg FLAGS_REG)
6555 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6556 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6557 (set (match_operand:DI 0 "register_operand" "=r")
6558 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6559 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6560 && ix86_binary_operator_ok (PLUS, SImode, operands)
6561 /* Current assemblers are broken and do not allow @GOTOFF in
6562 ought but a memory context. */
6563 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6565 switch (get_attr_type (insn))
6568 if (operands[2] == const1_rtx)
6569 return "inc{l}\t%k0";
6572 gcc_assert (operands[2] == constm1_rtx);
6573 return "dec{l}\t%k0";
6577 if (x86_maybe_negate_const_int (&operands[2], SImode))
6578 return "sub{l}\t{%2, %k0|%k0, %2}";
6580 return "add{l}\t{%2, %k0|%k0, %2}";
6584 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6585 (const_string "incdec")
6586 (const_string "alu")))
6587 (set (attr "length_immediate")
6589 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6591 (const_string "*")))
6592 (set_attr "mode" "SI")])
6594 (define_insn "*addhi_3"
6595 [(set (reg FLAGS_REG)
6597 (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6598 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6599 (clobber (match_scratch:HI 0 "=r"))]
6600 "ix86_match_ccmode (insn, CCZmode)
6601 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6603 switch (get_attr_type (insn))
6606 if (operands[2] == const1_rtx)
6607 return "inc{w}\t%0";
6610 gcc_assert (operands[2] == constm1_rtx);
6611 return "dec{w}\t%0";
6615 if (x86_maybe_negate_const_int (&operands[2], HImode))
6616 return "sub{w}\t{%2, %0|%0, %2}";
6618 return "add{w}\t{%2, %0|%0, %2}";
6622 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6623 (const_string "incdec")
6624 (const_string "alu")))
6625 (set (attr "length_immediate")
6627 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6629 (const_string "*")))
6630 (set_attr "mode" "HI")])
6632 (define_insn "*addqi_3"
6633 [(set (reg FLAGS_REG)
6635 (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6636 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6637 (clobber (match_scratch:QI 0 "=q"))]
6638 "ix86_match_ccmode (insn, CCZmode)
6639 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6641 switch (get_attr_type (insn))
6644 if (operands[2] == const1_rtx)
6645 return "inc{b}\t%0";
6648 gcc_assert (operands[2] == constm1_rtx
6649 || (CONST_INT_P (operands[2])
6650 && INTVAL (operands[2]) == 255));
6651 return "dec{b}\t%0";
6655 if (x86_maybe_negate_const_int (&operands[2], QImode))
6656 return "sub{b}\t{%2, %0|%0, %2}";
6658 return "add{b}\t{%2, %0|%0, %2}";
6662 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6663 (const_string "incdec")
6664 (const_string "alu")))
6665 (set_attr "mode" "QI")])
6667 ; For comparisons against 1, -1 and 128, we may generate better code
6668 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6669 ; is matched then. We can't accept general immediate, because for
6670 ; case of overflows, the result is messed up.
6671 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6672 ; only for comparisons not depending on it.
6674 (define_insn "*adddi_4"
6675 [(set (reg FLAGS_REG)
6677 (match_operand:DI 1 "nonimmediate_operand" "0")
6678 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6679 (clobber (match_scratch:DI 0 "=rm"))]
6681 && ix86_match_ccmode (insn, CCGCmode)"
6683 switch (get_attr_type (insn))
6686 if (operands[2] == constm1_rtx)
6687 return "inc{q}\t%0";
6690 gcc_assert (operands[2] == const1_rtx);
6691 return "dec{q}\t%0";
6695 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6696 if (x86_maybe_negate_const_int (&operands[2], DImode))
6697 return "add{q}\t{%2, %0|%0, %2}";
6699 return "sub{q}\t{%2, %0|%0, %2}";
6703 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6704 (const_string "incdec")
6705 (const_string "alu")))
6706 (set (attr "length_immediate")
6708 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6710 (const_string "*")))
6711 (set_attr "mode" "DI")])
6713 ; For comparisons against 1, -1 and 128, we may generate better code
6714 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6715 ; is matched then. We can't accept general immediate, because for
6716 ; case of overflows, the result is messed up.
6717 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6718 ; only for comparisons not depending on it.
6720 (define_insn "*addsi_4"
6721 [(set (reg FLAGS_REG)
6723 (match_operand:SI 1 "nonimmediate_operand" "0")
6724 (match_operand:SI 2 "const_int_operand" "n")))
6725 (clobber (match_scratch:SI 0 "=rm"))]
6726 "ix86_match_ccmode (insn, CCGCmode)"
6728 switch (get_attr_type (insn))
6731 if (operands[2] == constm1_rtx)
6732 return "inc{l}\t%0";
6735 gcc_assert (operands[2] == const1_rtx);
6736 return "dec{l}\t%0";
6740 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6741 if (x86_maybe_negate_const_int (&operands[2], SImode))
6742 return "add{l}\t{%2, %0|%0, %2}";
6744 return "sub{l}\t{%2, %0|%0, %2}";
6748 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6749 (const_string "incdec")
6750 (const_string "alu")))
6751 (set (attr "length_immediate")
6753 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6755 (const_string "*")))
6756 (set_attr "mode" "SI")])
6758 ; See comments above addsi_4 for details.
6760 (define_insn "*addhi_4"
6761 [(set (reg FLAGS_REG)
6763 (match_operand:HI 1 "nonimmediate_operand" "0")
6764 (match_operand:HI 2 "const_int_operand" "n")))
6765 (clobber (match_scratch:HI 0 "=rm"))]
6766 "ix86_match_ccmode (insn, CCGCmode)"
6768 switch (get_attr_type (insn))
6771 if (operands[2] == constm1_rtx)
6772 return "inc{w}\t%0";
6775 gcc_assert (operands[2] == const1_rtx);
6776 return "dec{w}\t%0";
6780 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6781 if (x86_maybe_negate_const_int (&operands[2], HImode))
6782 return "add{w}\t{%2, %0|%0, %2}";
6784 return "sub{w}\t{%2, %0|%0, %2}";
6788 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6789 (const_string "incdec")
6790 (const_string "alu")))
6791 (set (attr "length_immediate")
6793 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6795 (const_string "*")))
6796 (set_attr "mode" "HI")])
6798 ; See comments above addsi_4 for details.
6800 (define_insn "*addqi_4"
6801 [(set (reg FLAGS_REG)
6803 (match_operand:QI 1 "nonimmediate_operand" "0")
6804 (match_operand:QI 2 "const_int_operand" "n")))
6805 (clobber (match_scratch:QI 0 "=qm"))]
6806 "ix86_match_ccmode (insn, CCGCmode)"
6808 switch (get_attr_type (insn))
6811 if (operands[2] == constm1_rtx
6812 || (CONST_INT_P (operands[2])
6813 && INTVAL (operands[2]) == 255))
6814 return "inc{b}\t%0";
6817 gcc_assert (operands[2] == const1_rtx);
6818 return "dec{b}\t%0";
6822 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6823 if (x86_maybe_negate_const_int (&operands[2], QImode))
6824 return "add{b}\t{%2, %0|%0, %2}";
6826 return "sub{b}\t{%2, %0|%0, %2}";
6830 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6831 (const_string "incdec")
6832 (const_string "alu")))
6833 (set_attr "mode" "QI")])
6835 (define_insn "*add<mode>_5"
6836 [(set (reg FLAGS_REG)
6839 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6840 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6842 (clobber (match_scratch:SWI48 0 "=r"))]
6843 "ix86_match_ccmode (insn, CCGOCmode)
6844 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6845 /* Current assemblers are broken and do not allow @GOTOFF in
6846 ought but a memory context. */
6847 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6849 switch (get_attr_type (insn))
6852 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6853 if (operands[2] == const1_rtx)
6854 return "inc{<imodesuffix>}\t%0";
6857 gcc_assert (operands[2] == constm1_rtx);
6858 return "dec{<imodesuffix>}\t%0";
6862 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6863 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6864 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6866 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6870 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6871 (const_string "incdec")
6872 (const_string "alu")))
6873 (set (attr "length_immediate")
6875 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6877 (const_string "*")))
6878 (set_attr "mode" "<MODE>")])
6880 (define_insn "*addhi_5"
6881 [(set (reg FLAGS_REG)
6883 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6884 (match_operand:HI 2 "general_operand" "rmn"))
6886 (clobber (match_scratch:HI 0 "=r"))]
6887 "ix86_match_ccmode (insn, CCGOCmode)
6888 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6890 switch (get_attr_type (insn))
6893 if (operands[2] == const1_rtx)
6894 return "inc{w}\t%0";
6897 gcc_assert (operands[2] == constm1_rtx);
6898 return "dec{w}\t%0";
6902 if (x86_maybe_negate_const_int (&operands[2], HImode))
6903 return "sub{w}\t{%2, %0|%0, %2}";
6905 return "add{w}\t{%2, %0|%0, %2}";
6909 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6910 (const_string "incdec")
6911 (const_string "alu")))
6912 (set (attr "length_immediate")
6914 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6916 (const_string "*")))
6917 (set_attr "mode" "HI")])
6919 (define_insn "*addqi_5"
6920 [(set (reg FLAGS_REG)
6922 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6923 (match_operand:QI 2 "general_operand" "qmn"))
6925 (clobber (match_scratch:QI 0 "=q"))]
6926 "ix86_match_ccmode (insn, CCGOCmode)
6927 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6929 switch (get_attr_type (insn))
6932 if (operands[2] == const1_rtx)
6933 return "inc{b}\t%0";
6936 gcc_assert (operands[2] == constm1_rtx
6937 || (CONST_INT_P (operands[2])
6938 && INTVAL (operands[2]) == 255));
6939 return "dec{b}\t%0";
6943 if (x86_maybe_negate_const_int (&operands[2], QImode))
6944 return "sub{b}\t{%2, %0|%0, %2}";
6946 return "add{b}\t{%2, %0|%0, %2}";
6950 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6951 (const_string "incdec")
6952 (const_string "alu")))
6953 (set_attr "mode" "QI")])
6955 (define_insn "*addqi_ext_1_rex64"
6956 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6961 (match_operand 1 "ext_register_operand" "0")
6964 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6965 (clobber (reg:CC FLAGS_REG))]
6968 switch (get_attr_type (insn))
6971 if (operands[2] == const1_rtx)
6972 return "inc{b}\t%h0";
6975 gcc_assert (operands[2] == constm1_rtx
6976 || (CONST_INT_P (operands[2])
6977 && INTVAL (operands[2]) == 255));
6978 return "dec{b}\t%h0";
6982 return "add{b}\t{%2, %h0|%h0, %2}";
6986 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6987 (const_string "incdec")
6988 (const_string "alu")))
6989 (set_attr "modrm" "1")
6990 (set_attr "mode" "QI")])
6992 (define_insn "addqi_ext_1"
6993 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6998 (match_operand 1 "ext_register_operand" "0")
7001 (match_operand:QI 2 "general_operand" "Qmn")))
7002 (clobber (reg:CC FLAGS_REG))]
7005 switch (get_attr_type (insn))
7008 if (operands[2] == const1_rtx)
7009 return "inc{b}\t%h0";
7012 gcc_assert (operands[2] == constm1_rtx
7013 || (CONST_INT_P (operands[2])
7014 && INTVAL (operands[2]) == 255));
7015 return "dec{b}\t%h0";
7019 return "add{b}\t{%2, %h0|%h0, %2}";
7023 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7024 (const_string "incdec")
7025 (const_string "alu")))
7026 (set_attr "modrm" "1")
7027 (set_attr "mode" "QI")])
7029 (define_insn "*addqi_ext_2"
7030 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7035 (match_operand 1 "ext_register_operand" "%0")
7039 (match_operand 2 "ext_register_operand" "Q")
7042 (clobber (reg:CC FLAGS_REG))]
7044 "add{b}\t{%h2, %h0|%h0, %h2}"
7045 [(set_attr "type" "alu")
7046 (set_attr "mode" "QI")])
7048 ;; The lea patterns for non-Pmodes needs to be matched by
7049 ;; several insns converted to real lea by splitters.
7051 (define_insn_and_split "*lea_general_1"
7052 [(set (match_operand 0 "register_operand" "=r")
7053 (plus (plus (match_operand 1 "index_register_operand" "l")
7054 (match_operand 2 "register_operand" "r"))
7055 (match_operand 3 "immediate_operand" "i")))]
7056 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7057 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7058 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7059 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7060 && GET_MODE (operands[0]) == GET_MODE (operands[2])
7061 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7062 || GET_MODE (operands[3]) == VOIDmode)"
7064 "&& reload_completed"
7068 operands[0] = gen_lowpart (SImode, operands[0]);
7069 operands[1] = gen_lowpart (Pmode, operands[1]);
7070 operands[2] = gen_lowpart (Pmode, operands[2]);
7071 operands[3] = gen_lowpart (Pmode, operands[3]);
7072 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7074 if (Pmode != SImode)
7075 pat = gen_rtx_SUBREG (SImode, pat, 0);
7076 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7079 [(set_attr "type" "lea")
7080 (set_attr "mode" "SI")])
7082 (define_insn_and_split "*lea_general_1_zext"
7083 [(set (match_operand:DI 0 "register_operand" "=r")
7086 (match_operand:SI 1 "index_register_operand" "l")
7087 (match_operand:SI 2 "register_operand" "r"))
7088 (match_operand:SI 3 "immediate_operand" "i"))))]
7091 "&& reload_completed"
7093 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7095 (match_dup 3)) 0)))]
7097 operands[1] = gen_lowpart (Pmode, operands[1]);
7098 operands[2] = gen_lowpart (Pmode, operands[2]);
7099 operands[3] = gen_lowpart (Pmode, operands[3]);
7101 [(set_attr "type" "lea")
7102 (set_attr "mode" "SI")])
7104 (define_insn_and_split "*lea_general_2"
7105 [(set (match_operand 0 "register_operand" "=r")
7106 (plus (mult (match_operand 1 "index_register_operand" "l")
7107 (match_operand 2 "const248_operand" "i"))
7108 (match_operand 3 "nonmemory_operand" "ri")))]
7109 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7110 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7111 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7112 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7113 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7114 || GET_MODE (operands[3]) == VOIDmode)"
7116 "&& reload_completed"
7120 operands[0] = gen_lowpart (SImode, operands[0]);
7121 operands[1] = gen_lowpart (Pmode, operands[1]);
7122 operands[3] = gen_lowpart (Pmode, operands[3]);
7123 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7125 if (Pmode != SImode)
7126 pat = gen_rtx_SUBREG (SImode, pat, 0);
7127 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7130 [(set_attr "type" "lea")
7131 (set_attr "mode" "SI")])
7133 (define_insn_and_split "*lea_general_2_zext"
7134 [(set (match_operand:DI 0 "register_operand" "=r")
7137 (match_operand:SI 1 "index_register_operand" "l")
7138 (match_operand:SI 2 "const248_operand" "n"))
7139 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7142 "&& reload_completed"
7144 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7146 (match_dup 3)) 0)))]
7148 operands[1] = gen_lowpart (Pmode, operands[1]);
7149 operands[3] = gen_lowpart (Pmode, operands[3]);
7151 [(set_attr "type" "lea")
7152 (set_attr "mode" "SI")])
7154 (define_insn_and_split "*lea_general_3"
7155 [(set (match_operand 0 "register_operand" "=r")
7156 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7157 (match_operand 2 "const248_operand" "i"))
7158 (match_operand 3 "register_operand" "r"))
7159 (match_operand 4 "immediate_operand" "i")))]
7160 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7161 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7162 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7163 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7164 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7166 "&& reload_completed"
7170 operands[0] = gen_lowpart (SImode, operands[0]);
7171 operands[1] = gen_lowpart (Pmode, operands[1]);
7172 operands[3] = gen_lowpart (Pmode, operands[3]);
7173 operands[4] = gen_lowpart (Pmode, operands[4]);
7174 pat = gen_rtx_PLUS (Pmode,
7175 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7179 if (Pmode != SImode)
7180 pat = gen_rtx_SUBREG (SImode, pat, 0);
7181 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7184 [(set_attr "type" "lea")
7185 (set_attr "mode" "SI")])
7187 (define_insn_and_split "*lea_general_3_zext"
7188 [(set (match_operand:DI 0 "register_operand" "=r")
7192 (match_operand:SI 1 "index_register_operand" "l")
7193 (match_operand:SI 2 "const248_operand" "n"))
7194 (match_operand:SI 3 "register_operand" "r"))
7195 (match_operand:SI 4 "immediate_operand" "i"))))]
7198 "&& reload_completed"
7200 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7203 (match_dup 4)) 0)))]
7205 operands[1] = gen_lowpart (Pmode, operands[1]);
7206 operands[3] = gen_lowpart (Pmode, operands[3]);
7207 operands[4] = gen_lowpart (Pmode, operands[4]);
7209 [(set_attr "type" "lea")
7210 (set_attr "mode" "SI")])
7212 ;; Convert lea to the lea pattern to avoid flags dependency.
7214 [(set (match_operand:DI 0 "register_operand" "")
7215 (plus:DI (match_operand:DI 1 "register_operand" "")
7216 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7217 (clobber (reg:CC FLAGS_REG))]
7218 "TARGET_64BIT && reload_completed
7219 && ix86_lea_for_add_ok (PLUS, insn, operands)"
7221 (plus:DI (match_dup 1)
7225 ;; Convert lea to the lea pattern to avoid flags dependency.
7227 [(set (match_operand 0 "register_operand" "")
7228 (plus (match_operand 1 "register_operand" "")
7229 (match_operand 2 "nonmemory_operand" "")))
7230 (clobber (reg:CC FLAGS_REG))]
7231 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
7235 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7236 may confuse gen_lowpart. */
7237 if (GET_MODE (operands[0]) != Pmode)
7239 operands[1] = gen_lowpart (Pmode, operands[1]);
7240 operands[2] = gen_lowpart (Pmode, operands[2]);
7242 operands[0] = gen_lowpart (SImode, operands[0]);
7243 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7244 if (Pmode != SImode)
7245 pat = gen_rtx_SUBREG (SImode, pat, 0);
7246 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7250 ;; Convert lea to the lea pattern to avoid flags dependency.
7252 [(set (match_operand:DI 0 "register_operand" "")
7254 (plus:SI (match_operand:SI 1 "register_operand" "")
7255 (match_operand:SI 2 "nonmemory_operand" ""))))
7256 (clobber (reg:CC FLAGS_REG))]
7257 "TARGET_64BIT && reload_completed
7258 && true_regnum (operands[0]) != true_regnum (operands[1])"
7260 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7262 operands[1] = gen_lowpart (Pmode, operands[1]);
7263 operands[2] = gen_lowpart (Pmode, operands[2]);
7266 ;; Subtract instructions
7268 (define_expand "sub<mode>3"
7269 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7270 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7271 (match_operand:SDWIM 2 "<general_operand>" "")))]
7273 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7275 (define_insn_and_split "*sub<dwi>3_doubleword"
7276 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7278 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7279 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7280 (clobber (reg:CC FLAGS_REG))]
7281 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7284 [(parallel [(set (reg:CC FLAGS_REG)
7285 (compare:CC (match_dup 1) (match_dup 2)))
7287 (minus:DWIH (match_dup 1) (match_dup 2)))])
7288 (parallel [(set (match_dup 3)
7292 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7294 (clobber (reg:CC FLAGS_REG))])]
7295 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7297 (define_insn "*sub<mode>_1"
7298 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7300 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7301 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7302 (clobber (reg:CC FLAGS_REG))]
7303 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7304 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7305 [(set_attr "type" "alu")
7306 (set_attr "mode" "<MODE>")])
7308 (define_insn "*subsi_1_zext"
7309 [(set (match_operand:DI 0 "register_operand" "=r")
7311 (minus:SI (match_operand:SI 1 "register_operand" "0")
7312 (match_operand:SI 2 "general_operand" "g"))))
7313 (clobber (reg:CC FLAGS_REG))]
7314 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7315 "sub{l}\t{%2, %k0|%k0, %2}"
7316 [(set_attr "type" "alu")
7317 (set_attr "mode" "SI")])
7319 (define_insn "*subqi_1_slp"
7320 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7321 (minus:QI (match_dup 0)
7322 (match_operand:QI 1 "general_operand" "qn,qm")))
7323 (clobber (reg:CC FLAGS_REG))]
7324 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7325 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7326 "sub{b}\t{%1, %0|%0, %1}"
7327 [(set_attr "type" "alu1")
7328 (set_attr "mode" "QI")])
7330 (define_insn "*sub<mode>_2"
7331 [(set (reg FLAGS_REG)
7334 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7335 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7337 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7338 (minus:SWI (match_dup 1) (match_dup 2)))]
7339 "ix86_match_ccmode (insn, CCGOCmode)
7340 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7341 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7342 [(set_attr "type" "alu")
7343 (set_attr "mode" "<MODE>")])
7345 (define_insn "*subsi_2_zext"
7346 [(set (reg FLAGS_REG)
7348 (minus:SI (match_operand:SI 1 "register_operand" "0")
7349 (match_operand:SI 2 "general_operand" "g"))
7351 (set (match_operand:DI 0 "register_operand" "=r")
7353 (minus:SI (match_dup 1)
7355 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7356 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7357 "sub{l}\t{%2, %k0|%k0, %2}"
7358 [(set_attr "type" "alu")
7359 (set_attr "mode" "SI")])
7361 (define_insn "*sub<mode>_3"
7362 [(set (reg FLAGS_REG)
7363 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7364 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7365 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7366 (minus:SWI (match_dup 1) (match_dup 2)))]
7367 "ix86_match_ccmode (insn, CCmode)
7368 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7369 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7370 [(set_attr "type" "alu")
7371 (set_attr "mode" "<MODE>")])
7373 (define_insn "*subsi_3_zext"
7374 [(set (reg FLAGS_REG)
7375 (compare (match_operand:SI 1 "register_operand" "0")
7376 (match_operand:SI 2 "general_operand" "g")))
7377 (set (match_operand:DI 0 "register_operand" "=r")
7379 (minus:SI (match_dup 1)
7381 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7382 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7383 "sub{l}\t{%2, %1|%1, %2}"
7384 [(set_attr "type" "alu")
7385 (set_attr "mode" "SI")])
7387 ;; Add with carry and subtract with borrow
7389 (define_expand "<plusminus_insn><mode>3_carry"
7391 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7393 (match_operand:SWI 1 "nonimmediate_operand" "")
7394 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7395 [(match_operand 3 "flags_reg_operand" "")
7397 (match_operand:SWI 2 "<general_operand>" ""))))
7398 (clobber (reg:CC FLAGS_REG))])]
7399 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7402 (define_insn "*<plusminus_insn><mode>3_carry"
7403 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7405 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7407 (match_operator 3 "ix86_carry_flag_operator"
7408 [(reg FLAGS_REG) (const_int 0)])
7409 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7410 (clobber (reg:CC FLAGS_REG))]
7411 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7412 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7413 [(set_attr "type" "alu")
7414 (set_attr "use_carry" "1")
7415 (set_attr "pent_pair" "pu")
7416 (set_attr "mode" "<MODE>")])
7418 (define_insn "*addsi3_carry_zext"
7419 [(set (match_operand:DI 0 "register_operand" "=r")
7421 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7422 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7423 [(reg FLAGS_REG) (const_int 0)])
7424 (match_operand:SI 2 "general_operand" "g")))))
7425 (clobber (reg:CC FLAGS_REG))]
7426 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7427 "adc{l}\t{%2, %k0|%k0, %2}"
7428 [(set_attr "type" "alu")
7429 (set_attr "use_carry" "1")
7430 (set_attr "pent_pair" "pu")
7431 (set_attr "mode" "SI")])
7433 (define_insn "*subsi3_carry_zext"
7434 [(set (match_operand:DI 0 "register_operand" "=r")
7436 (minus:SI (match_operand:SI 1 "register_operand" "0")
7437 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7438 [(reg FLAGS_REG) (const_int 0)])
7439 (match_operand:SI 2 "general_operand" "g")))))
7440 (clobber (reg:CC FLAGS_REG))]
7441 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7442 "sbb{l}\t{%2, %k0|%k0, %2}"
7443 [(set_attr "type" "alu")
7444 (set_attr "pent_pair" "pu")
7445 (set_attr "mode" "SI")])
7447 ;; Overflow setting add and subtract instructions
7449 (define_insn "*add<mode>3_cconly_overflow"
7450 [(set (reg:CCC FLAGS_REG)
7453 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7454 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7456 (clobber (match_scratch:SWI 0 "=<r>"))]
7457 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7458 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7459 [(set_attr "type" "alu")
7460 (set_attr "mode" "<MODE>")])
7462 (define_insn "*sub<mode>3_cconly_overflow"
7463 [(set (reg:CCC FLAGS_REG)
7466 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7467 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7470 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7471 [(set_attr "type" "icmp")
7472 (set_attr "mode" "<MODE>")])
7474 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7475 [(set (reg:CCC FLAGS_REG)
7478 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7479 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7481 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7482 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7483 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7484 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7485 [(set_attr "type" "alu")
7486 (set_attr "mode" "<MODE>")])
7488 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7489 [(set (reg:CCC FLAGS_REG)
7492 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7493 (match_operand:SI 2 "general_operand" "g"))
7495 (set (match_operand:DI 0 "register_operand" "=r")
7496 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7497 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7498 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7499 [(set_attr "type" "alu")
7500 (set_attr "mode" "SI")])
7502 ;; The patterns that match these are at the end of this file.
7504 (define_expand "<plusminus_insn>xf3"
7505 [(set (match_operand:XF 0 "register_operand" "")
7507 (match_operand:XF 1 "register_operand" "")
7508 (match_operand:XF 2 "register_operand" "")))]
7512 (define_expand "<plusminus_insn><mode>3"
7513 [(set (match_operand:MODEF 0 "register_operand" "")
7515 (match_operand:MODEF 1 "register_operand" "")
7516 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7517 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7518 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7521 ;; Multiply instructions
7523 (define_expand "mul<mode>3"
7524 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7526 (match_operand:SWIM248 1 "register_operand" "")
7527 (match_operand:SWIM248 2 "<general_operand>" "")))
7528 (clobber (reg:CC FLAGS_REG))])]
7532 (define_expand "mulqi3"
7533 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7535 (match_operand:QI 1 "register_operand" "")
7536 (match_operand:QI 2 "nonimmediate_operand" "")))
7537 (clobber (reg:CC FLAGS_REG))])]
7538 "TARGET_QIMODE_MATH"
7542 ;; IMUL reg32/64, reg32/64, imm8 Direct
7543 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7544 ;; IMUL reg32/64, reg32/64, imm32 Direct
7545 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7546 ;; IMUL reg32/64, reg32/64 Direct
7547 ;; IMUL reg32/64, mem32/64 Direct
7549 (define_insn "*mul<mode>3_1"
7550 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7552 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7553 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7554 (clobber (reg:CC FLAGS_REG))]
7555 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7557 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7558 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7559 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7560 [(set_attr "type" "imul")
7561 (set_attr "prefix_0f" "0,0,1")
7562 (set (attr "athlon_decode")
7563 (cond [(eq_attr "cpu" "athlon")
7564 (const_string "vector")
7565 (eq_attr "alternative" "1")
7566 (const_string "vector")
7567 (and (eq_attr "alternative" "2")
7568 (match_operand 1 "memory_operand" ""))
7569 (const_string "vector")]
7570 (const_string "direct")))
7571 (set (attr "amdfam10_decode")
7572 (cond [(and (eq_attr "alternative" "0,1")
7573 (match_operand 1 "memory_operand" ""))
7574 (const_string "vector")]
7575 (const_string "direct")))
7576 (set_attr "mode" "<MODE>")])
7578 (define_insn "*mulsi3_1_zext"
7579 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7581 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7582 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7583 (clobber (reg:CC FLAGS_REG))]
7585 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7587 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7588 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7589 imul{l}\t{%2, %k0|%k0, %2}"
7590 [(set_attr "type" "imul")
7591 (set_attr "prefix_0f" "0,0,1")
7592 (set (attr "athlon_decode")
7593 (cond [(eq_attr "cpu" "athlon")
7594 (const_string "vector")
7595 (eq_attr "alternative" "1")
7596 (const_string "vector")
7597 (and (eq_attr "alternative" "2")
7598 (match_operand 1 "memory_operand" ""))
7599 (const_string "vector")]
7600 (const_string "direct")))
7601 (set (attr "amdfam10_decode")
7602 (cond [(and (eq_attr "alternative" "0,1")
7603 (match_operand 1 "memory_operand" ""))
7604 (const_string "vector")]
7605 (const_string "direct")))
7606 (set_attr "mode" "SI")])
7609 ;; IMUL reg16, reg16, imm8 VectorPath
7610 ;; IMUL reg16, mem16, imm8 VectorPath
7611 ;; IMUL reg16, reg16, imm16 VectorPath
7612 ;; IMUL reg16, mem16, imm16 VectorPath
7613 ;; IMUL reg16, reg16 Direct
7614 ;; IMUL reg16, mem16 Direct
7616 (define_insn "*mulhi3_1"
7617 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7618 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7619 (match_operand:HI 2 "general_operand" "K,n,mr")))
7620 (clobber (reg:CC FLAGS_REG))]
7622 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7624 imul{w}\t{%2, %1, %0|%0, %1, %2}
7625 imul{w}\t{%2, %1, %0|%0, %1, %2}
7626 imul{w}\t{%2, %0|%0, %2}"
7627 [(set_attr "type" "imul")
7628 (set_attr "prefix_0f" "0,0,1")
7629 (set (attr "athlon_decode")
7630 (cond [(eq_attr "cpu" "athlon")
7631 (const_string "vector")
7632 (eq_attr "alternative" "1,2")
7633 (const_string "vector")]
7634 (const_string "direct")))
7635 (set (attr "amdfam10_decode")
7636 (cond [(eq_attr "alternative" "0,1")
7637 (const_string "vector")]
7638 (const_string "direct")))
7639 (set_attr "mode" "HI")])
7645 (define_insn "*mulqi3_1"
7646 [(set (match_operand:QI 0 "register_operand" "=a")
7647 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7648 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7649 (clobber (reg:CC FLAGS_REG))]
7651 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7653 [(set_attr "type" "imul")
7654 (set_attr "length_immediate" "0")
7655 (set (attr "athlon_decode")
7656 (if_then_else (eq_attr "cpu" "athlon")
7657 (const_string "vector")
7658 (const_string "direct")))
7659 (set_attr "amdfam10_decode" "direct")
7660 (set_attr "mode" "QI")])
7662 (define_expand "<u>mul<mode><dwi>3"
7663 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7666 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7668 (match_operand:DWIH 2 "register_operand" ""))))
7669 (clobber (reg:CC FLAGS_REG))])]
7673 (define_expand "<u>mulqihi3"
7674 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7677 (match_operand:QI 1 "nonimmediate_operand" ""))
7679 (match_operand:QI 2 "register_operand" ""))))
7680 (clobber (reg:CC FLAGS_REG))])]
7681 "TARGET_QIMODE_MATH"
7684 (define_insn "*<u>mul<mode><dwi>3_1"
7685 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7688 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7690 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7691 (clobber (reg:CC FLAGS_REG))]
7692 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7693 "<sgnprefix>mul{<imodesuffix>}\t%2"
7694 [(set_attr "type" "imul")
7695 (set_attr "length_immediate" "0")
7696 (set (attr "athlon_decode")
7697 (if_then_else (eq_attr "cpu" "athlon")
7698 (const_string "vector")
7699 (const_string "double")))
7700 (set_attr "amdfam10_decode" "double")
7701 (set_attr "mode" "<MODE>")])
7703 (define_insn "*<u>mulqihi3_1"
7704 [(set (match_operand:HI 0 "register_operand" "=a")
7707 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7709 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7710 (clobber (reg:CC FLAGS_REG))]
7712 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7713 "<sgnprefix>mul{b}\t%2"
7714 [(set_attr "type" "imul")
7715 (set_attr "length_immediate" "0")
7716 (set (attr "athlon_decode")
7717 (if_then_else (eq_attr "cpu" "athlon")
7718 (const_string "vector")
7719 (const_string "direct")))
7720 (set_attr "amdfam10_decode" "direct")
7721 (set_attr "mode" "QI")])
7723 (define_expand "<s>mul<mode>3_highpart"
7724 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7729 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7731 (match_operand:SWI48 2 "register_operand" "")))
7733 (clobber (match_scratch:SWI48 3 ""))
7734 (clobber (reg:CC FLAGS_REG))])]
7736 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7738 (define_insn "*<s>muldi3_highpart_1"
7739 [(set (match_operand:DI 0 "register_operand" "=d")
7744 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7746 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7748 (clobber (match_scratch:DI 3 "=1"))
7749 (clobber (reg:CC FLAGS_REG))]
7751 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7752 "<sgnprefix>mul{q}\t%2"
7753 [(set_attr "type" "imul")
7754 (set_attr "length_immediate" "0")
7755 (set (attr "athlon_decode")
7756 (if_then_else (eq_attr "cpu" "athlon")
7757 (const_string "vector")
7758 (const_string "double")))
7759 (set_attr "amdfam10_decode" "double")
7760 (set_attr "mode" "DI")])
7762 (define_insn "*<s>mulsi3_highpart_1"
7763 [(set (match_operand:SI 0 "register_operand" "=d")
7768 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7770 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7772 (clobber (match_scratch:SI 3 "=1"))
7773 (clobber (reg:CC FLAGS_REG))]
7774 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7775 "<sgnprefix>mul{l}\t%2"
7776 [(set_attr "type" "imul")
7777 (set_attr "length_immediate" "0")
7778 (set (attr "athlon_decode")
7779 (if_then_else (eq_attr "cpu" "athlon")
7780 (const_string "vector")
7781 (const_string "double")))
7782 (set_attr "amdfam10_decode" "double")
7783 (set_attr "mode" "SI")])
7785 (define_insn "*<s>mulsi3_highpart_zext"
7786 [(set (match_operand:DI 0 "register_operand" "=d")
7787 (zero_extend:DI (truncate:SI
7789 (mult:DI (any_extend:DI
7790 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7792 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7794 (clobber (match_scratch:SI 3 "=1"))
7795 (clobber (reg:CC FLAGS_REG))]
7797 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7798 "<sgnprefix>mul{l}\t%2"
7799 [(set_attr "type" "imul")
7800 (set_attr "length_immediate" "0")
7801 (set (attr "athlon_decode")
7802 (if_then_else (eq_attr "cpu" "athlon")
7803 (const_string "vector")
7804 (const_string "double")))
7805 (set_attr "amdfam10_decode" "double")
7806 (set_attr "mode" "SI")])
7808 ;; The patterns that match these are at the end of this file.
7810 (define_expand "mulxf3"
7811 [(set (match_operand:XF 0 "register_operand" "")
7812 (mult:XF (match_operand:XF 1 "register_operand" "")
7813 (match_operand:XF 2 "register_operand" "")))]
7817 (define_expand "mul<mode>3"
7818 [(set (match_operand:MODEF 0 "register_operand" "")
7819 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7820 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7821 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7822 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7825 ;; Divide instructions
7827 (define_insn "<u>divqi3"
7828 [(set (match_operand:QI 0 "register_operand" "=a")
7830 (match_operand:HI 1 "register_operand" "0")
7831 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7832 (clobber (reg:CC FLAGS_REG))]
7833 "TARGET_QIMODE_MATH"
7834 "<sgnprefix>div{b}\t%2"
7835 [(set_attr "type" "idiv")
7836 (set_attr "mode" "QI")])
7838 ;; The patterns that match these are at the end of this file.
7840 (define_expand "divxf3"
7841 [(set (match_operand:XF 0 "register_operand" "")
7842 (div:XF (match_operand:XF 1 "register_operand" "")
7843 (match_operand:XF 2 "register_operand" "")))]
7847 (define_expand "divdf3"
7848 [(set (match_operand:DF 0 "register_operand" "")
7849 (div:DF (match_operand:DF 1 "register_operand" "")
7850 (match_operand:DF 2 "nonimmediate_operand" "")))]
7851 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7852 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7855 (define_expand "divsf3"
7856 [(set (match_operand:SF 0 "register_operand" "")
7857 (div:SF (match_operand:SF 1 "register_operand" "")
7858 (match_operand:SF 2 "nonimmediate_operand" "")))]
7859 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7862 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7863 && flag_finite_math_only && !flag_trapping_math
7864 && flag_unsafe_math_optimizations)
7866 ix86_emit_swdivsf (operands[0], operands[1],
7867 operands[2], SFmode);
7872 ;; Divmod instructions.
7874 (define_expand "divmod<mode>4"
7875 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7877 (match_operand:SWIM248 1 "register_operand" "")
7878 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7879 (set (match_operand:SWIM248 3 "register_operand" "")
7880 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7881 (clobber (reg:CC FLAGS_REG))])]
7885 (define_insn_and_split "*divmod<mode>4"
7886 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7887 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7888 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7889 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7890 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7891 (clobber (reg:CC FLAGS_REG))]
7894 "&& reload_completed"
7895 [(parallel [(set (match_dup 1)
7896 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7897 (clobber (reg:CC FLAGS_REG))])
7898 (parallel [(set (match_dup 0)
7899 (div:SWIM248 (match_dup 2) (match_dup 3)))
7901 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7903 (clobber (reg:CC FLAGS_REG))])]
7905 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
7907 if (<MODE>mode != HImode
7908 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7909 operands[4] = operands[2];
7912 /* Avoid use of cltd in favor of a mov+shift. */
7913 emit_move_insn (operands[1], operands[2]);
7914 operands[4] = operands[1];
7917 [(set_attr "type" "multi")
7918 (set_attr "mode" "<MODE>")])
7920 (define_insn "*divmod<mode>4_noext"
7921 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7922 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7923 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7924 (set (match_operand:SWIM248 1 "register_operand" "=d")
7925 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7926 (use (match_operand:SWIM248 4 "register_operand" "1"))
7927 (clobber (reg:CC FLAGS_REG))]
7929 "idiv{<imodesuffix>}\t%3"
7930 [(set_attr "type" "idiv")
7931 (set_attr "mode" "<MODE>")])
7933 (define_expand "udivmod<mode>4"
7934 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7936 (match_operand:SWIM248 1 "register_operand" "")
7937 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7938 (set (match_operand:SWIM248 3 "register_operand" "")
7939 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7940 (clobber (reg:CC FLAGS_REG))])]
7944 (define_insn_and_split "*udivmod<mode>4"
7945 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7946 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7947 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7948 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7949 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7950 (clobber (reg:CC FLAGS_REG))]
7953 "&& reload_completed"
7954 [(set (match_dup 1) (const_int 0))
7955 (parallel [(set (match_dup 0)
7956 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7958 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7960 (clobber (reg:CC FLAGS_REG))])]
7962 [(set_attr "type" "multi")
7963 (set_attr "mode" "<MODE>")])
7965 (define_insn "*udivmod<mode>4_noext"
7966 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7967 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7968 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7969 (set (match_operand:SWIM248 1 "register_operand" "=d")
7970 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7971 (use (match_operand:SWIM248 4 "register_operand" "1"))
7972 (clobber (reg:CC FLAGS_REG))]
7974 "div{<imodesuffix>}\t%3"
7975 [(set_attr "type" "idiv")
7976 (set_attr "mode" "<MODE>")])
7978 ;; We cannot use div/idiv for double division, because it causes
7979 ;; "division by zero" on the overflow and that's not what we expect
7980 ;; from truncate. Because true (non truncating) double division is
7981 ;; never generated, we can't create this insn anyway.
7984 ; [(set (match_operand:SI 0 "register_operand" "=a")
7986 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7988 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7989 ; (set (match_operand:SI 3 "register_operand" "=d")
7991 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7992 ; (clobber (reg:CC FLAGS_REG))]
7994 ; "div{l}\t{%2, %0|%0, %2}"
7995 ; [(set_attr "type" "idiv")])
7997 ;;- Logical AND instructions
7999 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8000 ;; Note that this excludes ah.
8002 (define_expand "testsi_ccno_1"
8003 [(set (reg:CCNO FLAGS_REG)
8005 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8006 (match_operand:SI 1 "nonmemory_operand" ""))
8011 (define_expand "testqi_ccz_1"
8012 [(set (reg:CCZ FLAGS_REG)
8013 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8014 (match_operand:QI 1 "nonmemory_operand" ""))
8019 (define_insn "*testdi_1"
8020 [(set (reg FLAGS_REG)
8023 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8024 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8026 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8027 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8029 test{l}\t{%k1, %k0|%k0, %k1}
8030 test{l}\t{%k1, %k0|%k0, %k1}
8031 test{q}\t{%1, %0|%0, %1}
8032 test{q}\t{%1, %0|%0, %1}
8033 test{q}\t{%1, %0|%0, %1}"
8034 [(set_attr "type" "test")
8035 (set_attr "modrm" "0,1,0,1,1")
8036 (set_attr "mode" "SI,SI,DI,DI,DI")])
8038 (define_insn "*testqi_1_maybe_si"
8039 [(set (reg FLAGS_REG)
8042 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8043 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8045 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8046 && ix86_match_ccmode (insn,
8047 CONST_INT_P (operands[1])
8048 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8050 if (which_alternative == 3)
8052 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8053 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8054 return "test{l}\t{%1, %k0|%k0, %1}";
8056 return "test{b}\t{%1, %0|%0, %1}";
8058 [(set_attr "type" "test")
8059 (set_attr "modrm" "0,1,1,1")
8060 (set_attr "mode" "QI,QI,QI,SI")
8061 (set_attr "pent_pair" "uv,np,uv,np")])
8063 (define_insn "*test<mode>_1"
8064 [(set (reg FLAGS_REG)
8067 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8068 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8070 "ix86_match_ccmode (insn, CCNOmode)
8071 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8072 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8073 [(set_attr "type" "test")
8074 (set_attr "modrm" "0,1,1")
8075 (set_attr "mode" "<MODE>")
8076 (set_attr "pent_pair" "uv,np,uv")])
8078 (define_expand "testqi_ext_ccno_0"
8079 [(set (reg:CCNO FLAGS_REG)
8083 (match_operand 0 "ext_register_operand" "")
8086 (match_operand 1 "const_int_operand" ""))
8091 (define_insn "*testqi_ext_0"
8092 [(set (reg FLAGS_REG)
8096 (match_operand 0 "ext_register_operand" "Q")
8099 (match_operand 1 "const_int_operand" "n"))
8101 "ix86_match_ccmode (insn, CCNOmode)"
8102 "test{b}\t{%1, %h0|%h0, %1}"
8103 [(set_attr "type" "test")
8104 (set_attr "mode" "QI")
8105 (set_attr "length_immediate" "1")
8106 (set_attr "modrm" "1")
8107 (set_attr "pent_pair" "np")])
8109 (define_insn "*testqi_ext_1_rex64"
8110 [(set (reg FLAGS_REG)
8114 (match_operand 0 "ext_register_operand" "Q")
8118 (match_operand:QI 1 "register_operand" "Q")))
8120 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8121 "test{b}\t{%1, %h0|%h0, %1}"
8122 [(set_attr "type" "test")
8123 (set_attr "mode" "QI")])
8125 (define_insn "*testqi_ext_1"
8126 [(set (reg FLAGS_REG)
8130 (match_operand 0 "ext_register_operand" "Q")
8134 (match_operand:QI 1 "general_operand" "Qm")))
8136 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8137 "test{b}\t{%1, %h0|%h0, %1}"
8138 [(set_attr "type" "test")
8139 (set_attr "mode" "QI")])
8141 (define_insn "*testqi_ext_2"
8142 [(set (reg FLAGS_REG)
8146 (match_operand 0 "ext_register_operand" "Q")
8150 (match_operand 1 "ext_register_operand" "Q")
8154 "ix86_match_ccmode (insn, CCNOmode)"
8155 "test{b}\t{%h1, %h0|%h0, %h1}"
8156 [(set_attr "type" "test")
8157 (set_attr "mode" "QI")])
8159 (define_insn "*testqi_ext_3_rex64"
8160 [(set (reg FLAGS_REG)
8161 (compare (zero_extract:DI
8162 (match_operand 0 "nonimmediate_operand" "rm")
8163 (match_operand:DI 1 "const_int_operand" "")
8164 (match_operand:DI 2 "const_int_operand" ""))
8167 && ix86_match_ccmode (insn, CCNOmode)
8168 && INTVAL (operands[1]) > 0
8169 && INTVAL (operands[2]) >= 0
8170 /* Ensure that resulting mask is zero or sign extended operand. */
8171 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8172 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8173 && INTVAL (operands[1]) > 32))
8174 && (GET_MODE (operands[0]) == SImode
8175 || GET_MODE (operands[0]) == DImode
8176 || GET_MODE (operands[0]) == HImode
8177 || GET_MODE (operands[0]) == QImode)"
8180 ;; Combine likes to form bit extractions for some tests. Humor it.
8181 (define_insn "*testqi_ext_3"
8182 [(set (reg FLAGS_REG)
8183 (compare (zero_extract:SI
8184 (match_operand 0 "nonimmediate_operand" "rm")
8185 (match_operand:SI 1 "const_int_operand" "")
8186 (match_operand:SI 2 "const_int_operand" ""))
8188 "ix86_match_ccmode (insn, CCNOmode)
8189 && INTVAL (operands[1]) > 0
8190 && INTVAL (operands[2]) >= 0
8191 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8192 && (GET_MODE (operands[0]) == SImode
8193 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8194 || GET_MODE (operands[0]) == HImode
8195 || GET_MODE (operands[0]) == QImode)"
8199 [(set (match_operand 0 "flags_reg_operand" "")
8200 (match_operator 1 "compare_operator"
8202 (match_operand 2 "nonimmediate_operand" "")
8203 (match_operand 3 "const_int_operand" "")
8204 (match_operand 4 "const_int_operand" ""))
8206 "ix86_match_ccmode (insn, CCNOmode)"
8207 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8209 rtx val = operands[2];
8210 HOST_WIDE_INT len = INTVAL (operands[3]);
8211 HOST_WIDE_INT pos = INTVAL (operands[4]);
8213 enum machine_mode mode, submode;
8215 mode = GET_MODE (val);
8218 /* ??? Combine likes to put non-volatile mem extractions in QImode
8219 no matter the size of the test. So find a mode that works. */
8220 if (! MEM_VOLATILE_P (val))
8222 mode = smallest_mode_for_size (pos + len, MODE_INT);
8223 val = adjust_address (val, mode, 0);
8226 else if (GET_CODE (val) == SUBREG
8227 && (submode = GET_MODE (SUBREG_REG (val)),
8228 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8229 && pos + len <= GET_MODE_BITSIZE (submode)
8230 && GET_MODE_CLASS (submode) == MODE_INT)
8232 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8234 val = SUBREG_REG (val);
8236 else if (mode == HImode && pos + len <= 8)
8238 /* Small HImode tests can be converted to QImode. */
8240 val = gen_lowpart (QImode, val);
8243 if (len == HOST_BITS_PER_WIDE_INT)
8246 mask = ((HOST_WIDE_INT)1 << len) - 1;
8249 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8252 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8253 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8254 ;; this is relatively important trick.
8255 ;; Do the conversion only post-reload to avoid limiting of the register class
8258 [(set (match_operand 0 "flags_reg_operand" "")
8259 (match_operator 1 "compare_operator"
8260 [(and (match_operand 2 "register_operand" "")
8261 (match_operand 3 "const_int_operand" ""))
8264 && QI_REG_P (operands[2])
8265 && GET_MODE (operands[2]) != QImode
8266 && ((ix86_match_ccmode (insn, CCZmode)
8267 && !(INTVAL (operands[3]) & ~(255 << 8)))
8268 || (ix86_match_ccmode (insn, CCNOmode)
8269 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8272 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8275 "operands[2] = gen_lowpart (SImode, operands[2]);
8276 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8279 [(set (match_operand 0 "flags_reg_operand" "")
8280 (match_operator 1 "compare_operator"
8281 [(and (match_operand 2 "nonimmediate_operand" "")
8282 (match_operand 3 "const_int_operand" ""))
8285 && GET_MODE (operands[2]) != QImode
8286 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8287 && ((ix86_match_ccmode (insn, CCZmode)
8288 && !(INTVAL (operands[3]) & ~255))
8289 || (ix86_match_ccmode (insn, CCNOmode)
8290 && !(INTVAL (operands[3]) & ~127)))"
8292 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8294 "operands[2] = gen_lowpart (QImode, operands[2]);
8295 operands[3] = gen_lowpart (QImode, operands[3]);")
8297 ;; %%% This used to optimize known byte-wide and operations to memory,
8298 ;; and sometimes to QImode registers. If this is considered useful,
8299 ;; it should be done with splitters.
8301 (define_expand "and<mode>3"
8302 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8303 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8304 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8306 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8308 (define_insn "*anddi_1"
8309 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8311 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8312 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8313 (clobber (reg:CC FLAGS_REG))]
8314 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8316 switch (get_attr_type (insn))
8320 enum machine_mode mode;
8322 gcc_assert (CONST_INT_P (operands[2]));
8323 if (INTVAL (operands[2]) == 0xff)
8327 gcc_assert (INTVAL (operands[2]) == 0xffff);
8331 operands[1] = gen_lowpart (mode, operands[1]);
8333 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8335 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8339 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8340 if (get_attr_mode (insn) == MODE_SI)
8341 return "and{l}\t{%k2, %k0|%k0, %k2}";
8343 return "and{q}\t{%2, %0|%0, %2}";
8346 [(set_attr "type" "alu,alu,alu,imovx")
8347 (set_attr "length_immediate" "*,*,*,0")
8348 (set (attr "prefix_rex")
8350 (and (eq_attr "type" "imovx")
8351 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8352 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8354 (const_string "*")))
8355 (set_attr "mode" "SI,DI,DI,SI")])
8357 (define_insn "*andsi_1"
8358 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8359 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8360 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8361 (clobber (reg:CC FLAGS_REG))]
8362 "ix86_binary_operator_ok (AND, SImode, operands)"
8364 switch (get_attr_type (insn))
8368 enum machine_mode mode;
8370 gcc_assert (CONST_INT_P (operands[2]));
8371 if (INTVAL (operands[2]) == 0xff)
8375 gcc_assert (INTVAL (operands[2]) == 0xffff);
8379 operands[1] = gen_lowpart (mode, operands[1]);
8381 return "movz{bl|x}\t{%1, %0|%0, %1}";
8383 return "movz{wl|x}\t{%1, %0|%0, %1}";
8387 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8388 return "and{l}\t{%2, %0|%0, %2}";
8391 [(set_attr "type" "alu,alu,imovx")
8392 (set (attr "prefix_rex")
8394 (and (eq_attr "type" "imovx")
8395 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8396 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8398 (const_string "*")))
8399 (set_attr "length_immediate" "*,*,0")
8400 (set_attr "mode" "SI")])
8402 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8403 (define_insn "*andsi_1_zext"
8404 [(set (match_operand:DI 0 "register_operand" "=r")
8406 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8407 (match_operand:SI 2 "general_operand" "g"))))
8408 (clobber (reg:CC FLAGS_REG))]
8409 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8410 "and{l}\t{%2, %k0|%k0, %2}"
8411 [(set_attr "type" "alu")
8412 (set_attr "mode" "SI")])
8414 (define_insn "*andhi_1"
8415 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8416 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8417 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8418 (clobber (reg:CC FLAGS_REG))]
8419 "ix86_binary_operator_ok (AND, HImode, operands)"
8421 switch (get_attr_type (insn))
8424 gcc_assert (CONST_INT_P (operands[2]));
8425 gcc_assert (INTVAL (operands[2]) == 0xff);
8426 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8429 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8431 return "and{w}\t{%2, %0|%0, %2}";
8434 [(set_attr "type" "alu,alu,imovx")
8435 (set_attr "length_immediate" "*,*,0")
8436 (set (attr "prefix_rex")
8438 (and (eq_attr "type" "imovx")
8439 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8441 (const_string "*")))
8442 (set_attr "mode" "HI,HI,SI")])
8444 ;; %%% Potential partial reg stall on alternative 2. What to do?
8445 (define_insn "*andqi_1"
8446 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8447 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8448 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8449 (clobber (reg:CC FLAGS_REG))]
8450 "ix86_binary_operator_ok (AND, QImode, operands)"
8452 and{b}\t{%2, %0|%0, %2}
8453 and{b}\t{%2, %0|%0, %2}
8454 and{l}\t{%k2, %k0|%k0, %k2}"
8455 [(set_attr "type" "alu")
8456 (set_attr "mode" "QI,QI,SI")])
8458 (define_insn "*andqi_1_slp"
8459 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8460 (and:QI (match_dup 0)
8461 (match_operand:QI 1 "general_operand" "qn,qmn")))
8462 (clobber (reg:CC FLAGS_REG))]
8463 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8464 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8465 "and{b}\t{%1, %0|%0, %1}"
8466 [(set_attr "type" "alu1")
8467 (set_attr "mode" "QI")])
8470 [(set (match_operand 0 "register_operand" "")
8472 (const_int -65536)))
8473 (clobber (reg:CC FLAGS_REG))]
8474 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8475 || optimize_function_for_size_p (cfun)"
8476 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8477 "operands[1] = gen_lowpart (HImode, operands[0]);")
8480 [(set (match_operand 0 "ext_register_operand" "")
8483 (clobber (reg:CC FLAGS_REG))]
8484 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8485 && reload_completed"
8486 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8487 "operands[1] = gen_lowpart (QImode, operands[0]);")
8490 [(set (match_operand 0 "ext_register_operand" "")
8492 (const_int -65281)))
8493 (clobber (reg:CC FLAGS_REG))]
8494 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8495 && reload_completed"
8496 [(parallel [(set (zero_extract:SI (match_dup 0)
8500 (zero_extract:SI (match_dup 0)
8503 (zero_extract:SI (match_dup 0)
8506 (clobber (reg:CC FLAGS_REG))])]
8507 "operands[0] = gen_lowpart (SImode, operands[0]);")
8509 (define_insn "*anddi_2"
8510 [(set (reg FLAGS_REG)
8513 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8514 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8516 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8517 (and:DI (match_dup 1) (match_dup 2)))]
8518 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8519 && ix86_binary_operator_ok (AND, DImode, operands)"
8521 and{l}\t{%k2, %k0|%k0, %k2}
8522 and{q}\t{%2, %0|%0, %2}
8523 and{q}\t{%2, %0|%0, %2}"
8524 [(set_attr "type" "alu")
8525 (set_attr "mode" "SI,DI,DI")])
8527 (define_insn "*andqi_2_maybe_si"
8528 [(set (reg FLAGS_REG)
8530 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8531 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8533 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8534 (and:QI (match_dup 1) (match_dup 2)))]
8535 "ix86_binary_operator_ok (AND, QImode, operands)
8536 && ix86_match_ccmode (insn,
8537 CONST_INT_P (operands[2])
8538 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8540 if (which_alternative == 2)
8542 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8543 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8544 return "and{l}\t{%2, %k0|%k0, %2}";
8546 return "and{b}\t{%2, %0|%0, %2}";
8548 [(set_attr "type" "alu")
8549 (set_attr "mode" "QI,QI,SI")])
8551 (define_insn "*and<mode>_2"
8552 [(set (reg FLAGS_REG)
8553 (compare (and:SWI124
8554 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8555 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8557 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8558 (and:SWI124 (match_dup 1) (match_dup 2)))]
8559 "ix86_match_ccmode (insn, CCNOmode)
8560 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8561 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8562 [(set_attr "type" "alu")
8563 (set_attr "mode" "<MODE>")])
8565 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8566 (define_insn "*andsi_2_zext"
8567 [(set (reg FLAGS_REG)
8569 (match_operand:SI 1 "nonimmediate_operand" "%0")
8570 (match_operand:SI 2 "general_operand" "g"))
8572 (set (match_operand:DI 0 "register_operand" "=r")
8573 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8574 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8575 && ix86_binary_operator_ok (AND, SImode, operands)"
8576 "and{l}\t{%2, %k0|%k0, %2}"
8577 [(set_attr "type" "alu")
8578 (set_attr "mode" "SI")])
8580 (define_insn "*andqi_2_slp"
8581 [(set (reg FLAGS_REG)
8583 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8584 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8586 (set (strict_low_part (match_dup 0))
8587 (and:QI (match_dup 0) (match_dup 1)))]
8588 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8589 && ix86_match_ccmode (insn, CCNOmode)
8590 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8591 "and{b}\t{%1, %0|%0, %1}"
8592 [(set_attr "type" "alu1")
8593 (set_attr "mode" "QI")])
8595 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8596 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8597 ;; for a QImode operand, which of course failed.
8598 (define_insn "andqi_ext_0"
8599 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8604 (match_operand 1 "ext_register_operand" "0")
8607 (match_operand 2 "const_int_operand" "n")))
8608 (clobber (reg:CC FLAGS_REG))]
8610 "and{b}\t{%2, %h0|%h0, %2}"
8611 [(set_attr "type" "alu")
8612 (set_attr "length_immediate" "1")
8613 (set_attr "modrm" "1")
8614 (set_attr "mode" "QI")])
8616 ;; Generated by peephole translating test to and. This shows up
8617 ;; often in fp comparisons.
8618 (define_insn "*andqi_ext_0_cc"
8619 [(set (reg FLAGS_REG)
8623 (match_operand 1 "ext_register_operand" "0")
8626 (match_operand 2 "const_int_operand" "n"))
8628 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8637 "ix86_match_ccmode (insn, CCNOmode)"
8638 "and{b}\t{%2, %h0|%h0, %2}"
8639 [(set_attr "type" "alu")
8640 (set_attr "length_immediate" "1")
8641 (set_attr "modrm" "1")
8642 (set_attr "mode" "QI")])
8644 (define_insn "*andqi_ext_1_rex64"
8645 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8650 (match_operand 1 "ext_register_operand" "0")
8654 (match_operand 2 "ext_register_operand" "Q"))))
8655 (clobber (reg:CC FLAGS_REG))]
8657 "and{b}\t{%2, %h0|%h0, %2}"
8658 [(set_attr "type" "alu")
8659 (set_attr "length_immediate" "0")
8660 (set_attr "mode" "QI")])
8662 (define_insn "*andqi_ext_1"
8663 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8668 (match_operand 1 "ext_register_operand" "0")
8672 (match_operand:QI 2 "general_operand" "Qm"))))
8673 (clobber (reg:CC FLAGS_REG))]
8675 "and{b}\t{%2, %h0|%h0, %2}"
8676 [(set_attr "type" "alu")
8677 (set_attr "length_immediate" "0")
8678 (set_attr "mode" "QI")])
8680 (define_insn "*andqi_ext_2"
8681 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8686 (match_operand 1 "ext_register_operand" "%0")
8690 (match_operand 2 "ext_register_operand" "Q")
8693 (clobber (reg:CC FLAGS_REG))]
8695 "and{b}\t{%h2, %h0|%h0, %h2}"
8696 [(set_attr "type" "alu")
8697 (set_attr "length_immediate" "0")
8698 (set_attr "mode" "QI")])
8700 ;; Convert wide AND instructions with immediate operand to shorter QImode
8701 ;; equivalents when possible.
8702 ;; Don't do the splitting with memory operands, since it introduces risk
8703 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8704 ;; for size, but that can (should?) be handled by generic code instead.
8706 [(set (match_operand 0 "register_operand" "")
8707 (and (match_operand 1 "register_operand" "")
8708 (match_operand 2 "const_int_operand" "")))
8709 (clobber (reg:CC FLAGS_REG))]
8711 && QI_REG_P (operands[0])
8712 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8713 && !(~INTVAL (operands[2]) & ~(255 << 8))
8714 && GET_MODE (operands[0]) != QImode"
8715 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8716 (and:SI (zero_extract:SI (match_dup 1)
8717 (const_int 8) (const_int 8))
8719 (clobber (reg:CC FLAGS_REG))])]
8720 "operands[0] = gen_lowpart (SImode, operands[0]);
8721 operands[1] = gen_lowpart (SImode, operands[1]);
8722 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8724 ;; Since AND can be encoded with sign extended immediate, this is only
8725 ;; profitable when 7th bit is not set.
8727 [(set (match_operand 0 "register_operand" "")
8728 (and (match_operand 1 "general_operand" "")
8729 (match_operand 2 "const_int_operand" "")))
8730 (clobber (reg:CC FLAGS_REG))]
8732 && ANY_QI_REG_P (operands[0])
8733 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8734 && !(~INTVAL (operands[2]) & ~255)
8735 && !(INTVAL (operands[2]) & 128)
8736 && GET_MODE (operands[0]) != QImode"
8737 [(parallel [(set (strict_low_part (match_dup 0))
8738 (and:QI (match_dup 1)
8740 (clobber (reg:CC FLAGS_REG))])]
8741 "operands[0] = gen_lowpart (QImode, operands[0]);
8742 operands[1] = gen_lowpart (QImode, operands[1]);
8743 operands[2] = gen_lowpart (QImode, operands[2]);")
8745 ;; Logical inclusive and exclusive OR instructions
8747 ;; %%% This used to optimize known byte-wide and operations to memory.
8748 ;; If this is considered useful, it should be done with splitters.
8750 (define_expand "<code><mode>3"
8751 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8752 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8753 (match_operand:SWIM 2 "<general_operand>" "")))]
8755 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8757 (define_insn "*<code><mode>_1"
8758 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8760 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8761 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8762 (clobber (reg:CC FLAGS_REG))]
8763 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8764 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8765 [(set_attr "type" "alu")
8766 (set_attr "mode" "<MODE>")])
8768 ;; %%% Potential partial reg stall on alternative 2. What to do?
8769 (define_insn "*<code>qi_1"
8770 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8771 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8772 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8773 (clobber (reg:CC FLAGS_REG))]
8774 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8776 <logicprefix>{b}\t{%2, %0|%0, %2}
8777 <logicprefix>{b}\t{%2, %0|%0, %2}
8778 <logicprefix>{l}\t{%k2, %k0|%k0, %k2}"
8779 [(set_attr "type" "alu")
8780 (set_attr "mode" "QI,QI,SI")])
8782 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8783 (define_insn "*<code>si_1_zext"
8784 [(set (match_operand:DI 0 "register_operand" "=r")
8786 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8787 (match_operand:SI 2 "general_operand" "g"))))
8788 (clobber (reg:CC FLAGS_REG))]
8789 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8790 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8791 [(set_attr "type" "alu")
8792 (set_attr "mode" "SI")])
8794 (define_insn "*<code>si_1_zext_imm"
8795 [(set (match_operand:DI 0 "register_operand" "=r")
8797 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8798 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8799 (clobber (reg:CC FLAGS_REG))]
8800 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8801 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8802 [(set_attr "type" "alu")
8803 (set_attr "mode" "SI")])
8805 (define_insn "*<code>qi_1_slp"
8806 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8807 (any_or:QI (match_dup 0)
8808 (match_operand:QI 1 "general_operand" "qmn,qn")))
8809 (clobber (reg:CC FLAGS_REG))]
8810 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8811 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8812 "<logicprefix>{b}\t{%1, %0|%0, %1}"
8813 [(set_attr "type" "alu1")
8814 (set_attr "mode" "QI")])
8816 (define_insn "*<code><mode>_2"
8817 [(set (reg FLAGS_REG)
8818 (compare (any_or:SWI
8819 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8820 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8822 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8823 (any_or:SWI (match_dup 1) (match_dup 2)))]
8824 "ix86_match_ccmode (insn, CCNOmode)
8825 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8826 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8827 [(set_attr "type" "alu")
8828 (set_attr "mode" "<MODE>")])
8830 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8831 ;; ??? Special case for immediate operand is missing - it is tricky.
8832 (define_insn "*<code>si_2_zext"
8833 [(set (reg FLAGS_REG)
8834 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8835 (match_operand:SI 2 "general_operand" "g"))
8837 (set (match_operand:DI 0 "register_operand" "=r")
8838 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8839 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8840 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8841 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8842 [(set_attr "type" "alu")
8843 (set_attr "mode" "SI")])
8845 (define_insn "*<code>si_2_zext_imm"
8846 [(set (reg FLAGS_REG)
8848 (match_operand:SI 1 "nonimmediate_operand" "%0")
8849 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8851 (set (match_operand:DI 0 "register_operand" "=r")
8852 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8853 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8854 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8855 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8856 [(set_attr "type" "alu")
8857 (set_attr "mode" "SI")])
8859 (define_insn "*<code>qi_2_slp"
8860 [(set (reg FLAGS_REG)
8861 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8862 (match_operand:QI 1 "general_operand" "qmn,qn"))
8864 (set (strict_low_part (match_dup 0))
8865 (any_or:QI (match_dup 0) (match_dup 1)))]
8866 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8867 && ix86_match_ccmode (insn, CCNOmode)
8868 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8869 "<logicprefix>{b}\t{%1, %0|%0, %1}"
8870 [(set_attr "type" "alu1")
8871 (set_attr "mode" "QI")])
8873 (define_insn "*<code><mode>_3"
8874 [(set (reg FLAGS_REG)
8875 (compare (any_or:SWI
8876 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8877 (match_operand:SWI 2 "<general_operand>" "<g>"))
8879 (clobber (match_scratch:SWI 0 "=<r>"))]
8880 "ix86_match_ccmode (insn, CCNOmode)
8881 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8882 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8883 [(set_attr "type" "alu")
8884 (set_attr "mode" "<MODE>")])
8886 (define_insn "*<code>qi_ext_0"
8887 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8892 (match_operand 1 "ext_register_operand" "0")
8895 (match_operand 2 "const_int_operand" "n")))
8896 (clobber (reg:CC FLAGS_REG))]
8897 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8898 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8899 [(set_attr "type" "alu")
8900 (set_attr "length_immediate" "1")
8901 (set_attr "modrm" "1")
8902 (set_attr "mode" "QI")])
8904 (define_insn "*<code>qi_ext_1_rex64"
8905 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8910 (match_operand 1 "ext_register_operand" "0")
8914 (match_operand 2 "ext_register_operand" "Q"))))
8915 (clobber (reg:CC FLAGS_REG))]
8917 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8918 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8919 [(set_attr "type" "alu")
8920 (set_attr "length_immediate" "0")
8921 (set_attr "mode" "QI")])
8923 (define_insn "*<code>qi_ext_1"
8924 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8929 (match_operand 1 "ext_register_operand" "0")
8933 (match_operand:QI 2 "general_operand" "Qm"))))
8934 (clobber (reg:CC FLAGS_REG))]
8936 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8937 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8938 [(set_attr "type" "alu")
8939 (set_attr "length_immediate" "0")
8940 (set_attr "mode" "QI")])
8942 (define_insn "*<code>qi_ext_2"
8943 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8947 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8950 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8953 (clobber (reg:CC FLAGS_REG))]
8954 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8955 "<logicprefix>{b}\t{%h2, %h0|%h0, %h2}"
8956 [(set_attr "type" "alu")
8957 (set_attr "length_immediate" "0")
8958 (set_attr "mode" "QI")])
8961 [(set (match_operand 0 "register_operand" "")
8962 (any_or (match_operand 1 "register_operand" "")
8963 (match_operand 2 "const_int_operand" "")))
8964 (clobber (reg:CC FLAGS_REG))]
8966 && QI_REG_P (operands[0])
8967 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8968 && !(INTVAL (operands[2]) & ~(255 << 8))
8969 && GET_MODE (operands[0]) != QImode"
8970 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8971 (any_or:SI (zero_extract:SI (match_dup 1)
8972 (const_int 8) (const_int 8))
8974 (clobber (reg:CC FLAGS_REG))])]
8975 "operands[0] = gen_lowpart (SImode, operands[0]);
8976 operands[1] = gen_lowpart (SImode, operands[1]);
8977 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8979 ;; Since OR can be encoded with sign extended immediate, this is only
8980 ;; profitable when 7th bit is set.
8982 [(set (match_operand 0 "register_operand" "")
8983 (any_or (match_operand 1 "general_operand" "")
8984 (match_operand 2 "const_int_operand" "")))
8985 (clobber (reg:CC FLAGS_REG))]
8987 && ANY_QI_REG_P (operands[0])
8988 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8989 && !(INTVAL (operands[2]) & ~255)
8990 && (INTVAL (operands[2]) & 128)
8991 && GET_MODE (operands[0]) != QImode"
8992 [(parallel [(set (strict_low_part (match_dup 0))
8993 (any_or:QI (match_dup 1)
8995 (clobber (reg:CC FLAGS_REG))])]
8996 "operands[0] = gen_lowpart (QImode, operands[0]);
8997 operands[1] = gen_lowpart (QImode, operands[1]);
8998 operands[2] = gen_lowpart (QImode, operands[2]);")
9000 (define_expand "xorqi_cc_ext_1"
9002 (set (reg:CCNO FLAGS_REG)
9006 (match_operand 1 "ext_register_operand" "")
9009 (match_operand:QI 2 "general_operand" ""))
9011 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9023 (define_insn "*xorqi_cc_ext_1_rex64"
9024 [(set (reg FLAGS_REG)
9028 (match_operand 1 "ext_register_operand" "0")
9031 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9033 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9042 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9043 "xor{b}\t{%2, %h0|%h0, %2}"
9044 [(set_attr "type" "alu")
9045 (set_attr "modrm" "1")
9046 (set_attr "mode" "QI")])
9048 (define_insn "*xorqi_cc_ext_1"
9049 [(set (reg FLAGS_REG)
9053 (match_operand 1 "ext_register_operand" "0")
9056 (match_operand:QI 2 "general_operand" "qmn"))
9058 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9067 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9068 "xor{b}\t{%2, %h0|%h0, %2}"
9069 [(set_attr "type" "alu")
9070 (set_attr "modrm" "1")
9071 (set_attr "mode" "QI")])
9073 ;; Negation instructions
9075 (define_expand "neg<mode>2"
9076 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9077 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9079 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9081 (define_insn_and_split "*neg<dwi>2_doubleword"
9082 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9083 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9084 (clobber (reg:CC FLAGS_REG))]
9085 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9089 [(set (reg:CCZ FLAGS_REG)
9090 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9091 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9094 (plus:DWIH (match_dup 3)
9095 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9097 (clobber (reg:CC FLAGS_REG))])
9100 (neg:DWIH (match_dup 2)))
9101 (clobber (reg:CC FLAGS_REG))])]
9102 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9104 (define_insn "*neg<mode>2_1"
9105 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9106 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9107 (clobber (reg:CC FLAGS_REG))]
9108 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9109 "neg{<imodesuffix>}\t%0"
9110 [(set_attr "type" "negnot")
9111 (set_attr "mode" "<MODE>")])
9113 ;; Combine is quite creative about this pattern.
9114 (define_insn "*negsi2_1_zext"
9115 [(set (match_operand:DI 0 "register_operand" "=r")
9117 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9120 (clobber (reg:CC FLAGS_REG))]
9121 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9123 [(set_attr "type" "negnot")
9124 (set_attr "mode" "SI")])
9126 ;; The problem with neg is that it does not perform (compare x 0),
9127 ;; it really performs (compare 0 x), which leaves us with the zero
9128 ;; flag being the only useful item.
9130 (define_insn "*neg<mode>2_cmpz"
9131 [(set (reg:CCZ FLAGS_REG)
9133 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9135 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9136 (neg:SWI (match_dup 1)))]
9137 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9138 "neg{<imodesuffix>}\t%0"
9139 [(set_attr "type" "negnot")
9140 (set_attr "mode" "<MODE>")])
9142 (define_insn "*negsi2_cmpz_zext"
9143 [(set (reg:CCZ FLAGS_REG)
9147 (match_operand:DI 1 "register_operand" "0")
9151 (set (match_operand:DI 0 "register_operand" "=r")
9152 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9155 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9157 [(set_attr "type" "negnot")
9158 (set_attr "mode" "SI")])
9160 ;; Changing of sign for FP values is doable using integer unit too.
9162 (define_expand "<code><mode>2"
9163 [(set (match_operand:X87MODEF 0 "register_operand" "")
9164 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9165 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9166 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9168 (define_insn "*absneg<mode>2_mixed"
9169 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9170 (match_operator:MODEF 3 "absneg_operator"
9171 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9172 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9173 (clobber (reg:CC FLAGS_REG))]
9174 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9177 (define_insn "*absneg<mode>2_sse"
9178 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9179 (match_operator:MODEF 3 "absneg_operator"
9180 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9181 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9182 (clobber (reg:CC FLAGS_REG))]
9183 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9186 (define_insn "*absneg<mode>2_i387"
9187 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9188 (match_operator:X87MODEF 3 "absneg_operator"
9189 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9190 (use (match_operand 2 "" ""))
9191 (clobber (reg:CC FLAGS_REG))]
9192 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9195 (define_expand "<code>tf2"
9196 [(set (match_operand:TF 0 "register_operand" "")
9197 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9199 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9201 (define_insn "*absnegtf2_sse"
9202 [(set (match_operand:TF 0 "register_operand" "=x,x")
9203 (match_operator:TF 3 "absneg_operator"
9204 [(match_operand:TF 1 "register_operand" "0,x")]))
9205 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9206 (clobber (reg:CC FLAGS_REG))]
9210 ;; Splitters for fp abs and neg.
9213 [(set (match_operand 0 "fp_register_operand" "")
9214 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9215 (use (match_operand 2 "" ""))
9216 (clobber (reg:CC FLAGS_REG))]
9218 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9221 [(set (match_operand 0 "register_operand" "")
9222 (match_operator 3 "absneg_operator"
9223 [(match_operand 1 "register_operand" "")]))
9224 (use (match_operand 2 "nonimmediate_operand" ""))
9225 (clobber (reg:CC FLAGS_REG))]
9226 "reload_completed && SSE_REG_P (operands[0])"
9227 [(set (match_dup 0) (match_dup 3))]
9229 enum machine_mode mode = GET_MODE (operands[0]);
9230 enum machine_mode vmode = GET_MODE (operands[2]);
9233 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9234 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9235 if (operands_match_p (operands[0], operands[2]))
9238 operands[1] = operands[2];
9241 if (GET_CODE (operands[3]) == ABS)
9242 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9244 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9249 [(set (match_operand:SF 0 "register_operand" "")
9250 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9251 (use (match_operand:V4SF 2 "" ""))
9252 (clobber (reg:CC FLAGS_REG))]
9254 [(parallel [(set (match_dup 0) (match_dup 1))
9255 (clobber (reg:CC FLAGS_REG))])]
9258 operands[0] = gen_lowpart (SImode, operands[0]);
9259 if (GET_CODE (operands[1]) == ABS)
9261 tmp = gen_int_mode (0x7fffffff, SImode);
9262 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9266 tmp = gen_int_mode (0x80000000, SImode);
9267 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9273 [(set (match_operand:DF 0 "register_operand" "")
9274 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9275 (use (match_operand 2 "" ""))
9276 (clobber (reg:CC FLAGS_REG))]
9278 [(parallel [(set (match_dup 0) (match_dup 1))
9279 (clobber (reg:CC FLAGS_REG))])]
9284 tmp = gen_lowpart (DImode, operands[0]);
9285 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9288 if (GET_CODE (operands[1]) == ABS)
9291 tmp = gen_rtx_NOT (DImode, tmp);
9295 operands[0] = gen_highpart (SImode, operands[0]);
9296 if (GET_CODE (operands[1]) == ABS)
9298 tmp = gen_int_mode (0x7fffffff, SImode);
9299 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9303 tmp = gen_int_mode (0x80000000, SImode);
9304 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9311 [(set (match_operand:XF 0 "register_operand" "")
9312 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9313 (use (match_operand 2 "" ""))
9314 (clobber (reg:CC FLAGS_REG))]
9316 [(parallel [(set (match_dup 0) (match_dup 1))
9317 (clobber (reg:CC FLAGS_REG))])]
9320 operands[0] = gen_rtx_REG (SImode,
9321 true_regnum (operands[0])
9322 + (TARGET_64BIT ? 1 : 2));
9323 if (GET_CODE (operands[1]) == ABS)
9325 tmp = GEN_INT (0x7fff);
9326 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9330 tmp = GEN_INT (0x8000);
9331 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9336 ;; Conditionalize these after reload. If they match before reload, we
9337 ;; lose the clobber and ability to use integer instructions.
9339 (define_insn "*<code><mode>2_1"
9340 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9341 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9343 && (reload_completed
9344 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9346 [(set_attr "type" "fsgn")
9347 (set_attr "mode" "<MODE>")])
9349 (define_insn "*<code>extendsfdf2"
9350 [(set (match_operand:DF 0 "register_operand" "=f")
9351 (absneg:DF (float_extend:DF
9352 (match_operand:SF 1 "register_operand" "0"))))]
9353 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9355 [(set_attr "type" "fsgn")
9356 (set_attr "mode" "DF")])
9358 (define_insn "*<code>extendsfxf2"
9359 [(set (match_operand:XF 0 "register_operand" "=f")
9360 (absneg:XF (float_extend:XF
9361 (match_operand:SF 1 "register_operand" "0"))))]
9364 [(set_attr "type" "fsgn")
9365 (set_attr "mode" "XF")])
9367 (define_insn "*<code>extenddfxf2"
9368 [(set (match_operand:XF 0 "register_operand" "=f")
9369 (absneg:XF (float_extend:XF
9370 (match_operand:DF 1 "register_operand" "0"))))]
9373 [(set_attr "type" "fsgn")
9374 (set_attr "mode" "XF")])
9376 ;; Copysign instructions
9378 (define_mode_iterator CSGNMODE [SF DF TF])
9379 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9381 (define_expand "copysign<mode>3"
9382 [(match_operand:CSGNMODE 0 "register_operand" "")
9383 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9384 (match_operand:CSGNMODE 2 "register_operand" "")]
9385 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9386 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9388 ix86_expand_copysign (operands);
9392 (define_insn_and_split "copysign<mode>3_const"
9393 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9395 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9396 (match_operand:CSGNMODE 2 "register_operand" "0")
9397 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9399 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9400 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9402 "&& reload_completed"
9405 ix86_split_copysign_const (operands);
9409 (define_insn "copysign<mode>3_var"
9410 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9412 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9413 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9414 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9415 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9417 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9418 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9419 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9423 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9425 [(match_operand:CSGNMODE 2 "register_operand" "")
9426 (match_operand:CSGNMODE 3 "register_operand" "")
9427 (match_operand:<CSGNVMODE> 4 "" "")
9428 (match_operand:<CSGNVMODE> 5 "" "")]
9430 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9431 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9432 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9433 && reload_completed"
9436 ix86_split_copysign_var (operands);
9440 ;; One complement instructions
9442 (define_expand "one_cmpl<mode>2"
9443 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9444 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9446 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9448 (define_insn "*one_cmpl<mode>2_1"
9449 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9450 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9451 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9452 "not{<imodesuffix>}\t%0"
9453 [(set_attr "type" "negnot")
9454 (set_attr "mode" "<MODE>")])
9456 ;; %%% Potential partial reg stall on alternative 1. What to do?
9457 (define_insn "*one_cmplqi2_1"
9458 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9459 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9460 "ix86_unary_operator_ok (NOT, QImode, operands)"
9464 [(set_attr "type" "negnot")
9465 (set_attr "mode" "QI,SI")])
9467 ;; ??? Currently never generated - xor is used instead.
9468 (define_insn "*one_cmplsi2_1_zext"
9469 [(set (match_operand:DI 0 "register_operand" "=r")
9471 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9472 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9474 [(set_attr "type" "negnot")
9475 (set_attr "mode" "SI")])
9477 (define_insn "*one_cmpl<mode>2_2"
9478 [(set (reg FLAGS_REG)
9479 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9481 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9482 (not:SWI (match_dup 1)))]
9483 "ix86_match_ccmode (insn, CCNOmode)
9484 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9486 [(set_attr "type" "alu1")
9487 (set_attr "mode" "<MODE>")])
9490 [(set (match_operand 0 "flags_reg_operand" "")
9491 (match_operator 2 "compare_operator"
9492 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9494 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9495 (not:SWI (match_dup 3)))]
9496 "ix86_match_ccmode (insn, CCNOmode)"
9497 [(parallel [(set (match_dup 0)
9498 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9501 (xor:SWI (match_dup 3) (const_int -1)))])]
9504 ;; ??? Currently never generated - xor is used instead.
9505 (define_insn "*one_cmplsi2_2_zext"
9506 [(set (reg FLAGS_REG)
9507 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9509 (set (match_operand:DI 0 "register_operand" "=r")
9510 (zero_extend:DI (not:SI (match_dup 1))))]
9511 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9512 && ix86_unary_operator_ok (NOT, SImode, operands)"
9514 [(set_attr "type" "alu1")
9515 (set_attr "mode" "SI")])
9518 [(set (match_operand 0 "flags_reg_operand" "")
9519 (match_operator 2 "compare_operator"
9520 [(not:SI (match_operand:SI 3 "register_operand" ""))
9522 (set (match_operand:DI 1 "register_operand" "")
9523 (zero_extend:DI (not:SI (match_dup 3))))]
9524 "ix86_match_ccmode (insn, CCNOmode)"
9525 [(parallel [(set (match_dup 0)
9526 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9529 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9532 ;; Arithmetic shift instructions
9534 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9535 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9536 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9537 ;; from the assembler input.
9539 ;; This instruction shifts the target reg/mem as usual, but instead of
9540 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9541 ;; is a left shift double, bits are taken from the high order bits of
9542 ;; reg, else if the insn is a shift right double, bits are taken from the
9543 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9544 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9546 ;; Since sh[lr]d does not change the `reg' operand, that is done
9547 ;; separately, making all shifts emit pairs of shift double and normal
9548 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9549 ;; support a 63 bit shift, each shift where the count is in a reg expands
9550 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9552 ;; If the shift count is a constant, we need never emit more than one
9553 ;; shift pair, instead using moves and sign extension for counts greater
9556 (define_expand "ashl<mode>3"
9557 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9558 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9559 (match_operand:QI 2 "nonmemory_operand" "")))]
9561 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9563 (define_insn "*ashl<mode>3_doubleword"
9564 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9565 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9566 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9567 (clobber (reg:CC FLAGS_REG))]
9570 [(set_attr "type" "multi")])
9573 [(set (match_operand:DWI 0 "register_operand" "")
9574 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9575 (match_operand:QI 2 "nonmemory_operand" "")))
9576 (clobber (reg:CC FLAGS_REG))]
9577 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9579 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9581 ;; By default we don't ask for a scratch register, because when DWImode
9582 ;; values are manipulated, registers are already at a premium. But if
9583 ;; we have one handy, we won't turn it away.
9586 [(match_scratch:DWIH 3 "r")
9587 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9589 (match_operand:<DWI> 1 "nonmemory_operand" "")
9590 (match_operand:QI 2 "nonmemory_operand" "")))
9591 (clobber (reg:CC FLAGS_REG))])
9595 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9597 (define_insn "x86_64_shld"
9598 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9599 (ior:DI (ashift:DI (match_dup 0)
9600 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9601 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9602 (minus:QI (const_int 64) (match_dup 2)))))
9603 (clobber (reg:CC FLAGS_REG))]
9605 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9606 [(set_attr "type" "ishift")
9607 (set_attr "prefix_0f" "1")
9608 (set_attr "mode" "DI")
9609 (set_attr "athlon_decode" "vector")
9610 (set_attr "amdfam10_decode" "vector")])
9612 (define_insn "x86_shld"
9613 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9614 (ior:SI (ashift:SI (match_dup 0)
9615 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9616 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9617 (minus:QI (const_int 32) (match_dup 2)))))
9618 (clobber (reg:CC FLAGS_REG))]
9620 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9621 [(set_attr "type" "ishift")
9622 (set_attr "prefix_0f" "1")
9623 (set_attr "mode" "SI")
9624 (set_attr "pent_pair" "np")
9625 (set_attr "athlon_decode" "vector")
9626 (set_attr "amdfam10_decode" "vector")])
9628 (define_expand "x86_shift<mode>_adj_1"
9629 [(set (reg:CCZ FLAGS_REG)
9630 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9633 (set (match_operand:SWI48 0 "register_operand" "")
9634 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9635 (match_operand:SWI48 1 "register_operand" "")
9638 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9639 (match_operand:SWI48 3 "register_operand" "r")
9642 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9644 (define_expand "x86_shift<mode>_adj_2"
9645 [(use (match_operand:SWI48 0 "register_operand" ""))
9646 (use (match_operand:SWI48 1 "register_operand" ""))
9647 (use (match_operand:QI 2 "register_operand" ""))]
9650 rtx label = gen_label_rtx ();
9653 emit_insn (gen_testqi_ccz_1 (operands[2],
9654 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9656 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9657 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9658 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9659 gen_rtx_LABEL_REF (VOIDmode, label),
9661 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9662 JUMP_LABEL (tmp) = label;
9664 emit_move_insn (operands[0], operands[1]);
9665 ix86_expand_clear (operands[1]);
9668 LABEL_NUSES (label) = 1;
9673 (define_insn "*ashl<mode>3_1"
9674 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9675 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9676 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9677 (clobber (reg:CC FLAGS_REG))]
9678 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9680 switch (get_attr_type (insn))
9683 gcc_assert (operands[2] == const1_rtx);
9684 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9685 return "add{<imodesuffix>}\t%0, %0";
9691 if (REG_P (operands[2]))
9692 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9693 else if (operands[2] == const1_rtx
9694 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9695 return "sal{<imodesuffix>}\t%0";
9697 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9701 (cond [(eq_attr "alternative" "1")
9702 (const_string "lea")
9703 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9705 (match_operand 0 "register_operand" ""))
9706 (match_operand 2 "const1_operand" ""))
9707 (const_string "alu")
9709 (const_string "ishift")))
9710 (set (attr "length_immediate")
9712 (ior (eq_attr "type" "alu")
9713 (and (eq_attr "type" "ishift")
9714 (and (match_operand 2 "const1_operand" "")
9715 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9718 (const_string "*")))
9719 (set_attr "mode" "<MODE>")])
9721 (define_insn "*ashlsi3_1_zext"
9722 [(set (match_operand:DI 0 "register_operand" "=r,r")
9724 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9725 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9726 (clobber (reg:CC FLAGS_REG))]
9727 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9729 switch (get_attr_type (insn))
9732 gcc_assert (operands[2] == const1_rtx);
9733 return "add{l}\t%k0, %k0";
9739 if (REG_P (operands[2]))
9740 return "sal{l}\t{%b2, %k0|%k0, %b2}";
9741 else if (operands[2] == const1_rtx
9742 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9743 return "sal{l}\t%k0";
9745 return "sal{l}\t{%2, %k0|%k0, %2}";
9749 (cond [(eq_attr "alternative" "1")
9750 (const_string "lea")
9751 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9753 (match_operand 2 "const1_operand" ""))
9754 (const_string "alu")
9756 (const_string "ishift")))
9757 (set (attr "length_immediate")
9759 (ior (eq_attr "type" "alu")
9760 (and (eq_attr "type" "ishift")
9761 (and (match_operand 2 "const1_operand" "")
9762 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9765 (const_string "*")))
9766 (set_attr "mode" "SI")])
9768 (define_insn "*ashlhi3_1"
9769 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9770 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9771 (match_operand:QI 2 "nonmemory_operand" "cI")))
9772 (clobber (reg:CC FLAGS_REG))]
9773 "TARGET_PARTIAL_REG_STALL
9774 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9776 switch (get_attr_type (insn))
9779 gcc_assert (operands[2] == const1_rtx);
9780 return "add{w}\t%0, %0";
9783 if (REG_P (operands[2]))
9784 return "sal{w}\t{%b2, %0|%0, %b2}";
9785 else if (operands[2] == const1_rtx
9786 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9787 return "sal{w}\t%0";
9789 return "sal{w}\t{%2, %0|%0, %2}";
9793 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9795 (match_operand 0 "register_operand" ""))
9796 (match_operand 2 "const1_operand" ""))
9797 (const_string "alu")
9799 (const_string "ishift")))
9800 (set (attr "length_immediate")
9802 (ior (eq_attr "type" "alu")
9803 (and (eq_attr "type" "ishift")
9804 (and (match_operand 2 "const1_operand" "")
9805 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9808 (const_string "*")))
9809 (set_attr "mode" "HI")])
9811 (define_insn "*ashlhi3_1_lea"
9812 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9813 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9814 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9815 (clobber (reg:CC FLAGS_REG))]
9816 "!TARGET_PARTIAL_REG_STALL
9817 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9819 switch (get_attr_type (insn))
9824 gcc_assert (operands[2] == const1_rtx);
9825 return "add{w}\t%0, %0";
9828 if (REG_P (operands[2]))
9829 return "sal{w}\t{%b2, %0|%0, %b2}";
9830 else if (operands[2] == const1_rtx
9831 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9832 return "sal{w}\t%0";
9834 return "sal{w}\t{%2, %0|%0, %2}";
9838 (cond [(eq_attr "alternative" "1")
9839 (const_string "lea")
9840 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9842 (match_operand 0 "register_operand" ""))
9843 (match_operand 2 "const1_operand" ""))
9844 (const_string "alu")
9846 (const_string "ishift")))
9847 (set (attr "length_immediate")
9849 (ior (eq_attr "type" "alu")
9850 (and (eq_attr "type" "ishift")
9851 (and (match_operand 2 "const1_operand" "")
9852 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9855 (const_string "*")))
9856 (set_attr "mode" "HI,SI")])
9858 (define_insn "*ashlqi3_1"
9859 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9860 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9861 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9862 (clobber (reg:CC FLAGS_REG))]
9863 "TARGET_PARTIAL_REG_STALL
9864 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9866 switch (get_attr_type (insn))
9869 gcc_assert (operands[2] == const1_rtx);
9870 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9871 return "add{l}\t%k0, %k0";
9873 return "add{b}\t%0, %0";
9876 if (REG_P (operands[2]))
9878 if (get_attr_mode (insn) == MODE_SI)
9879 return "sal{l}\t{%b2, %k0|%k0, %b2}";
9881 return "sal{b}\t{%b2, %0|%0, %b2}";
9883 else if (operands[2] == const1_rtx
9884 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9886 if (get_attr_mode (insn) == MODE_SI)
9887 return "sal{l}\t%0";
9889 return "sal{b}\t%0";
9893 if (get_attr_mode (insn) == MODE_SI)
9894 return "sal{l}\t{%2, %k0|%k0, %2}";
9896 return "sal{b}\t{%2, %0|%0, %2}";
9901 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9903 (match_operand 0 "register_operand" ""))
9904 (match_operand 2 "const1_operand" ""))
9905 (const_string "alu")
9907 (const_string "ishift")))
9908 (set (attr "length_immediate")
9910 (ior (eq_attr "type" "alu")
9911 (and (eq_attr "type" "ishift")
9912 (and (match_operand 2 "const1_operand" "")
9913 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9916 (const_string "*")))
9917 (set_attr "mode" "QI,SI")])
9919 ;; %%% Potential partial reg stall on alternative 2. What to do?
9920 (define_insn "*ashlqi3_1_lea"
9921 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9922 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9923 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9924 (clobber (reg:CC FLAGS_REG))]
9925 "!TARGET_PARTIAL_REG_STALL
9926 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9928 switch (get_attr_type (insn))
9933 gcc_assert (operands[2] == const1_rtx);
9934 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9935 return "add{l}\t%k0, %k0";
9937 return "add{b}\t%0, %0";
9940 if (REG_P (operands[2]))
9942 if (get_attr_mode (insn) == MODE_SI)
9943 return "sal{l}\t{%b2, %k0|%k0, %b2}";
9945 return "sal{b}\t{%b2, %0|%0, %b2}";
9947 else if (operands[2] == const1_rtx
9948 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9950 if (get_attr_mode (insn) == MODE_SI)
9951 return "sal{l}\t%0";
9953 return "sal{b}\t%0";
9957 if (get_attr_mode (insn) == MODE_SI)
9958 return "sal{l}\t{%2, %k0|%k0, %2}";
9960 return "sal{b}\t{%2, %0|%0, %2}";
9965 (cond [(eq_attr "alternative" "2")
9966 (const_string "lea")
9967 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9969 (match_operand 0 "register_operand" ""))
9970 (match_operand 2 "const1_operand" ""))
9971 (const_string "alu")
9973 (const_string "ishift")))
9974 (set (attr "length_immediate")
9976 (ior (eq_attr "type" "alu")
9977 (and (eq_attr "type" "ishift")
9978 (and (match_operand 2 "const1_operand" "")
9979 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9982 (const_string "*")))
9983 (set_attr "mode" "QI,SI,SI")])
9985 ;; Convert lea to the lea pattern to avoid flags dependency.
9987 [(set (match_operand:DI 0 "register_operand" "")
9988 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9989 (match_operand:QI 2 "const_int_operand" "")))
9990 (clobber (reg:CC FLAGS_REG))]
9991 "TARGET_64BIT && reload_completed
9992 && true_regnum (operands[0]) != true_regnum (operands[1])"
9994 (mult:DI (match_dup 1)
9996 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9998 ;; Convert lea to the lea pattern to avoid flags dependency.
10000 [(set (match_operand 0 "register_operand" "")
10001 (ashift (match_operand 1 "index_register_operand" "")
10002 (match_operand:QI 2 "const_int_operand" "")))
10003 (clobber (reg:CC FLAGS_REG))]
10005 && true_regnum (operands[0]) != true_regnum (operands[1])
10006 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10010 enum machine_mode mode = GET_MODE (operands[0]);
10012 if (GET_MODE_SIZE (mode) < 4)
10013 operands[0] = gen_lowpart (SImode, operands[0]);
10015 operands[1] = gen_lowpart (Pmode, operands[1]);
10016 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10018 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10019 if (Pmode != SImode)
10020 pat = gen_rtx_SUBREG (SImode, pat, 0);
10021 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10025 ;; Rare case of shifting RSP is handled by generating move and shift
10027 [(set (match_operand 0 "register_operand" "")
10028 (ashift (match_operand 1 "register_operand" "")
10029 (match_operand:QI 2 "const_int_operand" "")))
10030 (clobber (reg:CC FLAGS_REG))]
10032 && true_regnum (operands[0]) != true_regnum (operands[1])"
10036 emit_move_insn (operands[0], operands[1]);
10037 pat = gen_rtx_SET (VOIDmode, operands[0],
10038 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10039 operands[0], operands[2]));
10040 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10041 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10045 ;; Convert lea to the lea pattern to avoid flags dependency.
10047 [(set (match_operand:DI 0 "register_operand" "")
10049 (ashift:SI (match_operand:SI 1 "register_operand" "")
10050 (match_operand:QI 2 "const_int_operand" ""))))
10051 (clobber (reg:CC FLAGS_REG))]
10052 "TARGET_64BIT && reload_completed
10053 && true_regnum (operands[0]) != true_regnum (operands[1])"
10054 [(set (match_dup 0)
10055 (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10057 operands[1] = gen_lowpart (Pmode, operands[1]);
10058 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10061 ;; This pattern can't accept a variable shift count, since shifts by
10062 ;; zero don't affect the flags. We assume that shifts by constant
10063 ;; zero are optimized away.
10064 (define_insn "*ashl<mode>3_cmp"
10065 [(set (reg FLAGS_REG)
10067 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10068 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10070 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10071 (ashift:SWI (match_dup 1) (match_dup 2)))]
10072 "(optimize_function_for_size_p (cfun)
10073 || !TARGET_PARTIAL_FLAG_REG_STALL
10074 || (operands[2] == const1_rtx
10076 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10077 && ix86_match_ccmode (insn, CCGOCmode)
10078 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10080 switch (get_attr_type (insn))
10083 gcc_assert (operands[2] == const1_rtx);
10084 return "add{<imodesuffix>}\t%0, %0";
10087 if (operands[2] == const1_rtx
10088 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10089 return "sal{<imodesuffix>}\t%0";
10091 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10094 [(set (attr "type")
10095 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10097 (match_operand 0 "register_operand" ""))
10098 (match_operand 2 "const1_operand" ""))
10099 (const_string "alu")
10101 (const_string "ishift")))
10102 (set (attr "length_immediate")
10104 (ior (eq_attr "type" "alu")
10105 (and (eq_attr "type" "ishift")
10106 (and (match_operand 2 "const1_operand" "")
10107 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10110 (const_string "*")))
10111 (set_attr "mode" "<MODE>")])
10113 (define_insn "*ashlsi3_cmp_zext"
10114 [(set (reg FLAGS_REG)
10116 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10117 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10119 (set (match_operand:DI 0 "register_operand" "=r")
10120 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10122 && (optimize_function_for_size_p (cfun)
10123 || !TARGET_PARTIAL_FLAG_REG_STALL
10124 || (operands[2] == const1_rtx
10126 || TARGET_DOUBLE_WITH_ADD)))
10127 && ix86_match_ccmode (insn, CCGOCmode)
10128 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10130 switch (get_attr_type (insn))
10133 gcc_assert (operands[2] == const1_rtx);
10134 return "add{l}\t%k0, %k0";
10137 if (operands[2] == const1_rtx
10138 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10139 return "sal{l}\t%k0";
10141 return "sal{l}\t{%2, %k0|%k0, %2}";
10144 [(set (attr "type")
10145 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10147 (match_operand 2 "const1_operand" ""))
10148 (const_string "alu")
10150 (const_string "ishift")))
10151 (set (attr "length_immediate")
10153 (ior (eq_attr "type" "alu")
10154 (and (eq_attr "type" "ishift")
10155 (and (match_operand 2 "const1_operand" "")
10156 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10159 (const_string "*")))
10160 (set_attr "mode" "SI")])
10162 (define_insn "*ashl<mode>3_cconly"
10163 [(set (reg FLAGS_REG)
10165 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10166 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10168 (clobber (match_scratch:SWI 0 "=<r>"))]
10169 "(optimize_function_for_size_p (cfun)
10170 || !TARGET_PARTIAL_FLAG_REG_STALL
10171 || (operands[2] == const1_rtx
10173 || TARGET_DOUBLE_WITH_ADD)))
10174 && ix86_match_ccmode (insn, CCGOCmode)
10175 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10177 switch (get_attr_type (insn))
10180 gcc_assert (operands[2] == const1_rtx);
10181 return "add{<imodesuffix>}\t%0, %0";
10184 if (operands[2] == const1_rtx
10185 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10186 return "sal{<imodesuffix>}\t%0";
10188 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10191 [(set (attr "type")
10192 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10194 (match_operand 0 "register_operand" ""))
10195 (match_operand 2 "const1_operand" ""))
10196 (const_string "alu")
10198 (const_string "ishift")))
10199 (set (attr "length_immediate")
10201 (ior (eq_attr "type" "alu")
10202 (and (eq_attr "type" "ishift")
10203 (and (match_operand 2 "const1_operand" "")
10204 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10207 (const_string "*")))
10208 (set_attr "mode" "<MODE>")])
10210 ;; See comment above `ashldi3' about how this works.
10212 (define_expand "ashrti3"
10213 [(set (match_operand:TI 0 "register_operand" "")
10214 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10215 (match_operand:QI 2 "nonmemory_operand" "")))]
10217 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
10219 (define_insn "*ashrti3_1"
10220 [(set (match_operand:TI 0 "register_operand" "=r")
10221 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
10222 (match_operand:QI 2 "nonmemory_operand" "Oc")))
10223 (clobber (reg:CC FLAGS_REG))]
10226 [(set_attr "type" "multi")])
10229 [(match_scratch:DI 3 "r")
10230 (parallel [(set (match_operand:TI 0 "register_operand" "")
10231 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10232 (match_operand:QI 2 "nonmemory_operand" "")))
10233 (clobber (reg:CC FLAGS_REG))])
10237 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
10240 [(set (match_operand:TI 0 "register_operand" "")
10241 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10242 (match_operand:QI 2 "nonmemory_operand" "")))
10243 (clobber (reg:CC FLAGS_REG))]
10244 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10245 ? epilogue_completed : reload_completed)"
10247 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
10249 (define_insn "x86_64_shrd"
10250 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10251 (ior:DI (ashiftrt:DI (match_dup 0)
10252 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10253 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10254 (minus:QI (const_int 64) (match_dup 2)))))
10255 (clobber (reg:CC FLAGS_REG))]
10257 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10258 [(set_attr "type" "ishift")
10259 (set_attr "prefix_0f" "1")
10260 (set_attr "mode" "DI")
10261 (set_attr "athlon_decode" "vector")
10262 (set_attr "amdfam10_decode" "vector")])
10264 (define_expand "ashrdi3"
10265 [(set (match_operand:DI 0 "shiftdi_operand" "")
10266 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10267 (match_operand:QI 2 "nonmemory_operand" "")))]
10269 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10271 (define_expand "x86_64_shift_adj_3"
10272 [(use (match_operand:DI 0 "register_operand" ""))
10273 (use (match_operand:DI 1 "register_operand" ""))
10274 (use (match_operand:QI 2 "register_operand" ""))]
10277 rtx label = gen_label_rtx ();
10280 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10282 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10283 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10284 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10285 gen_rtx_LABEL_REF (VOIDmode, label),
10287 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10288 JUMP_LABEL (tmp) = label;
10290 emit_move_insn (operands[0], operands[1]);
10291 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
10293 emit_label (label);
10294 LABEL_NUSES (label) = 1;
10299 (define_insn "ashrdi3_63_rex64"
10300 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10301 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10302 (match_operand:DI 2 "const_int_operand" "i,i")))
10303 (clobber (reg:CC FLAGS_REG))]
10304 "TARGET_64BIT && INTVAL (operands[2]) == 63
10305 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10306 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10309 sar{q}\t{%2, %0|%0, %2}"
10310 [(set_attr "type" "imovx,ishift")
10311 (set_attr "prefix_0f" "0,*")
10312 (set_attr "length_immediate" "0,*")
10313 (set_attr "modrm" "0,1")
10314 (set_attr "mode" "DI")])
10316 (define_insn "*ashrdi3_1_one_bit_rex64"
10317 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10318 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10319 (match_operand:QI 2 "const1_operand" "")))
10320 (clobber (reg:CC FLAGS_REG))]
10322 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10323 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10325 [(set_attr "type" "ishift")
10326 (set_attr "length_immediate" "0")
10327 (set_attr "mode" "DI")])
10329 (define_insn "*ashrdi3_1_rex64"
10330 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10331 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10332 (match_operand:QI 2 "nonmemory_operand" "J,c")))
10333 (clobber (reg:CC FLAGS_REG))]
10334 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10336 sar{q}\t{%2, %0|%0, %2}
10337 sar{q}\t{%b2, %0|%0, %b2}"
10338 [(set_attr "type" "ishift")
10339 (set_attr "mode" "DI")])
10341 ;; This pattern can't accept a variable shift count, since shifts by
10342 ;; zero don't affect the flags. We assume that shifts by constant
10343 ;; zero are optimized away.
10344 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10345 [(set (reg FLAGS_REG)
10347 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10348 (match_operand:QI 2 "const1_operand" ""))
10350 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10351 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10353 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10354 && ix86_match_ccmode (insn, CCGOCmode)
10355 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10357 [(set_attr "type" "ishift")
10358 (set_attr "length_immediate" "0")
10359 (set_attr "mode" "DI")])
10361 (define_insn "*ashrdi3_one_bit_cconly_rex64"
10362 [(set (reg FLAGS_REG)
10364 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10365 (match_operand:QI 2 "const1_operand" ""))
10367 (clobber (match_scratch:DI 0 "=r"))]
10369 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10370 && ix86_match_ccmode (insn, CCGOCmode)
10371 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10373 [(set_attr "type" "ishift")
10374 (set_attr "length_immediate" "0")
10375 (set_attr "mode" "DI")])
10377 ;; This pattern can't accept a variable shift count, since shifts by
10378 ;; zero don't affect the flags. We assume that shifts by constant
10379 ;; zero are optimized away.
10380 (define_insn "*ashrdi3_cmp_rex64"
10381 [(set (reg FLAGS_REG)
10383 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10384 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10386 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10387 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10389 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10390 && ix86_match_ccmode (insn, CCGOCmode)
10391 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10392 "sar{q}\t{%2, %0|%0, %2}"
10393 [(set_attr "type" "ishift")
10394 (set_attr "mode" "DI")])
10396 (define_insn "*ashrdi3_cconly_rex64"
10397 [(set (reg FLAGS_REG)
10399 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10400 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10402 (clobber (match_scratch:DI 0 "=r"))]
10404 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10405 && ix86_match_ccmode (insn, CCGOCmode)
10406 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10407 "sar{q}\t{%2, %0|%0, %2}"
10408 [(set_attr "type" "ishift")
10409 (set_attr "mode" "DI")])
10411 (define_insn "*ashrdi3_1"
10412 [(set (match_operand:DI 0 "register_operand" "=r")
10413 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10414 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10415 (clobber (reg:CC FLAGS_REG))]
10418 [(set_attr "type" "multi")])
10420 ;; By default we don't ask for a scratch register, because when DImode
10421 ;; values are manipulated, registers are already at a premium. But if
10422 ;; we have one handy, we won't turn it away.
10424 [(match_scratch:SI 3 "r")
10425 (parallel [(set (match_operand:DI 0 "register_operand" "")
10426 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10427 (match_operand:QI 2 "nonmemory_operand" "")))
10428 (clobber (reg:CC FLAGS_REG))])
10430 "!TARGET_64BIT && TARGET_CMOVE"
10432 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
10435 [(set (match_operand:DI 0 "register_operand" "")
10436 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10437 (match_operand:QI 2 "nonmemory_operand" "")))
10438 (clobber (reg:CC FLAGS_REG))]
10439 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10440 ? epilogue_completed : reload_completed)"
10442 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
10444 (define_insn "x86_shrd"
10445 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10446 (ior:SI (ashiftrt:SI (match_dup 0)
10447 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10448 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10449 (minus:QI (const_int 32) (match_dup 2)))))
10450 (clobber (reg:CC FLAGS_REG))]
10452 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10453 [(set_attr "type" "ishift")
10454 (set_attr "prefix_0f" "1")
10455 (set_attr "pent_pair" "np")
10456 (set_attr "mode" "SI")])
10458 (define_expand "x86_shift_adj_3"
10459 [(use (match_operand:SI 0 "register_operand" ""))
10460 (use (match_operand:SI 1 "register_operand" ""))
10461 (use (match_operand:QI 2 "register_operand" ""))]
10464 rtx label = gen_label_rtx ();
10467 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10469 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10470 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10471 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10472 gen_rtx_LABEL_REF (VOIDmode, label),
10474 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10475 JUMP_LABEL (tmp) = label;
10477 emit_move_insn (operands[0], operands[1]);
10478 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10480 emit_label (label);
10481 LABEL_NUSES (label) = 1;
10486 (define_expand "ashrsi3_31"
10487 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10488 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10489 (match_operand:SI 2 "const_int_operand" "i,i")))
10490 (clobber (reg:CC FLAGS_REG))])]
10493 (define_insn "*ashrsi3_31"
10494 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10495 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10496 (match_operand:SI 2 "const_int_operand" "i,i")))
10497 (clobber (reg:CC FLAGS_REG))]
10498 "INTVAL (operands[2]) == 31
10499 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10500 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10503 sar{l}\t{%2, %0|%0, %2}"
10504 [(set_attr "type" "imovx,ishift")
10505 (set_attr "prefix_0f" "0,*")
10506 (set_attr "length_immediate" "0,*")
10507 (set_attr "modrm" "0,1")
10508 (set_attr "mode" "SI")])
10510 (define_insn "*ashrsi3_31_zext"
10511 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10512 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10513 (match_operand:SI 2 "const_int_operand" "i,i"))))
10514 (clobber (reg:CC FLAGS_REG))]
10515 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10516 && INTVAL (operands[2]) == 31
10517 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10520 sar{l}\t{%2, %k0|%k0, %2}"
10521 [(set_attr "type" "imovx,ishift")
10522 (set_attr "prefix_0f" "0,*")
10523 (set_attr "length_immediate" "0,*")
10524 (set_attr "modrm" "0,1")
10525 (set_attr "mode" "SI")])
10527 (define_expand "ashrsi3"
10528 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10529 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10530 (match_operand:QI 2 "nonmemory_operand" "")))]
10532 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10534 (define_insn "*ashrsi3_1_one_bit"
10535 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10536 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10537 (match_operand:QI 2 "const1_operand" "")))
10538 (clobber (reg:CC FLAGS_REG))]
10539 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10540 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10542 [(set_attr "type" "ishift")
10543 (set_attr "length_immediate" "0")
10544 (set_attr "mode" "SI")])
10546 (define_insn "*ashrsi3_1_one_bit_zext"
10547 [(set (match_operand:DI 0 "register_operand" "=r")
10548 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10549 (match_operand:QI 2 "const1_operand" ""))))
10550 (clobber (reg:CC FLAGS_REG))]
10552 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10553 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10555 [(set_attr "type" "ishift")
10556 (set_attr "length_immediate" "0")
10557 (set_attr "mode" "SI")])
10559 (define_insn "*ashrsi3_1"
10560 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
10561 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
10562 (match_operand:QI 2 "nonmemory_operand" "I,c")))
10563 (clobber (reg:CC FLAGS_REG))]
10564 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10566 sar{l}\t{%2, %0|%0, %2}
10567 sar{l}\t{%b2, %0|%0, %b2}"
10568 [(set_attr "type" "ishift")
10569 (set_attr "mode" "SI")])
10571 (define_insn "*ashrsi3_1_zext"
10572 [(set (match_operand:DI 0 "register_operand" "=r,r")
10573 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
10574 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
10575 (clobber (reg:CC FLAGS_REG))]
10576 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10578 sar{l}\t{%2, %k0|%k0, %2}
10579 sar{l}\t{%b2, %k0|%k0, %b2}"
10580 [(set_attr "type" "ishift")
10581 (set_attr "mode" "SI")])
10583 ;; This pattern can't accept a variable shift count, since shifts by
10584 ;; zero don't affect the flags. We assume that shifts by constant
10585 ;; zero are optimized away.
10586 (define_insn "*ashrsi3_one_bit_cmp"
10587 [(set (reg FLAGS_REG)
10589 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10590 (match_operand:QI 2 "const1_operand" ""))
10592 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10593 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
10594 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10595 && ix86_match_ccmode (insn, CCGOCmode)
10596 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10598 [(set_attr "type" "ishift")
10599 (set_attr "length_immediate" "0")
10600 (set_attr "mode" "SI")])
10602 (define_insn "*ashrsi3_one_bit_cconly"
10603 [(set (reg FLAGS_REG)
10605 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10606 (match_operand:QI 2 "const1_operand" ""))
10608 (clobber (match_scratch:SI 0 "=r"))]
10609 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10610 && ix86_match_ccmode (insn, CCGOCmode)
10611 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10613 [(set_attr "type" "ishift")
10614 (set_attr "length_immediate" "0")
10615 (set_attr "mode" "SI")])
10617 (define_insn "*ashrsi3_one_bit_cmp_zext"
10618 [(set (reg FLAGS_REG)
10620 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10621 (match_operand:QI 2 "const1_operand" ""))
10623 (set (match_operand:DI 0 "register_operand" "=r")
10624 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
10626 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10627 && ix86_match_ccmode (insn, CCmode)
10628 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10630 [(set_attr "type" "ishift")
10631 (set_attr "length_immediate" "0")
10632 (set_attr "mode" "SI")])
10634 ;; This pattern can't accept a variable shift count, since shifts by
10635 ;; zero don't affect the flags. We assume that shifts by constant
10636 ;; zero are optimized away.
10637 (define_insn "*ashrsi3_cmp"
10638 [(set (reg FLAGS_REG)
10640 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10641 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10643 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10644 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
10645 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10646 && ix86_match_ccmode (insn, CCGOCmode)
10647 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10648 "sar{l}\t{%2, %0|%0, %2}"
10649 [(set_attr "type" "ishift")
10650 (set_attr "mode" "SI")])
10652 (define_insn "*ashrsi3_cconly"
10653 [(set (reg FLAGS_REG)
10655 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10656 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10658 (clobber (match_scratch:SI 0 "=r"))]
10659 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10660 && ix86_match_ccmode (insn, CCGOCmode)
10661 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10662 "sar{l}\t{%2, %0|%0, %2}"
10663 [(set_attr "type" "ishift")
10664 (set_attr "mode" "SI")])
10666 (define_insn "*ashrsi3_cmp_zext"
10667 [(set (reg FLAGS_REG)
10669 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10670 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10672 (set (match_operand:DI 0 "register_operand" "=r")
10673 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
10675 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10676 && ix86_match_ccmode (insn, CCGOCmode)
10677 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10678 "sar{l}\t{%2, %k0|%k0, %2}"
10679 [(set_attr "type" "ishift")
10680 (set_attr "mode" "SI")])
10682 (define_expand "ashrhi3"
10683 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10684 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
10685 (match_operand:QI 2 "nonmemory_operand" "")))]
10686 "TARGET_HIMODE_MATH"
10687 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
10689 (define_insn "*ashrhi3_1_one_bit"
10690 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10691 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10692 (match_operand:QI 2 "const1_operand" "")))
10693 (clobber (reg:CC FLAGS_REG))]
10694 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10695 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
10697 [(set_attr "type" "ishift")
10698 (set_attr "length_immediate" "0")
10699 (set_attr "mode" "HI")])
10701 (define_insn "*ashrhi3_1"
10702 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
10703 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
10704 (match_operand:QI 2 "nonmemory_operand" "I,c")))
10705 (clobber (reg:CC FLAGS_REG))]
10706 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
10708 sar{w}\t{%2, %0|%0, %2}
10709 sar{w}\t{%b2, %0|%0, %b2}"
10710 [(set_attr "type" "ishift")
10711 (set_attr "mode" "HI")])
10713 ;; This pattern can't accept a variable shift count, since shifts by
10714 ;; zero don't affect the flags. We assume that shifts by constant
10715 ;; zero are optimized away.
10716 (define_insn "*ashrhi3_one_bit_cmp"
10717 [(set (reg FLAGS_REG)
10719 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10720 (match_operand:QI 2 "const1_operand" ""))
10722 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10723 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
10724 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10725 && ix86_match_ccmode (insn, CCGOCmode)
10726 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
10728 [(set_attr "type" "ishift")
10729 (set_attr "length_immediate" "0")
10730 (set_attr "mode" "HI")])
10732 (define_insn "*ashrhi3_one_bit_cconly"
10733 [(set (reg FLAGS_REG)
10735 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10736 (match_operand:QI 2 "const1_operand" ""))
10738 (clobber (match_scratch:HI 0 "=r"))]
10739 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10740 && ix86_match_ccmode (insn, CCGOCmode)
10741 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
10743 [(set_attr "type" "ishift")
10744 (set_attr "length_immediate" "0")
10745 (set_attr "mode" "HI")])
10747 ;; This pattern can't accept a variable shift count, since shifts by
10748 ;; zero don't affect the flags. We assume that shifts by constant
10749 ;; zero are optimized away.
10750 (define_insn "*ashrhi3_cmp"
10751 [(set (reg FLAGS_REG)
10753 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10754 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10756 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10757 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
10758 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10759 && ix86_match_ccmode (insn, CCGOCmode)
10760 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
10761 "sar{w}\t{%2, %0|%0, %2}"
10762 [(set_attr "type" "ishift")
10763 (set_attr "mode" "HI")])
10765 (define_insn "*ashrhi3_cconly"
10766 [(set (reg FLAGS_REG)
10768 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10769 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10771 (clobber (match_scratch:HI 0 "=r"))]
10772 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10773 && ix86_match_ccmode (insn, CCGOCmode)
10774 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
10775 "sar{w}\t{%2, %0|%0, %2}"
10776 [(set_attr "type" "ishift")
10777 (set_attr "mode" "HI")])
10779 (define_expand "ashrqi3"
10780 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10781 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
10782 (match_operand:QI 2 "nonmemory_operand" "")))]
10783 "TARGET_QIMODE_MATH"
10784 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
10786 (define_insn "*ashrqi3_1_one_bit"
10787 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10788 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10789 (match_operand:QI 2 "const1_operand" "")))
10790 (clobber (reg:CC FLAGS_REG))]
10791 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10792 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
10794 [(set_attr "type" "ishift")
10795 (set_attr "length_immediate" "0")
10796 (set_attr "mode" "QI")])
10798 (define_insn "*ashrqi3_1_one_bit_slp"
10799 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10800 (ashiftrt:QI (match_dup 0)
10801 (match_operand:QI 1 "const1_operand" "")))
10802 (clobber (reg:CC FLAGS_REG))]
10803 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10804 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10805 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
10807 [(set_attr "type" "ishift1")
10808 (set_attr "length_immediate" "0")
10809 (set_attr "mode" "QI")])
10811 (define_insn "*ashrqi3_1"
10812 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
10813 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10814 (match_operand:QI 2 "nonmemory_operand" "I,c")))
10815 (clobber (reg:CC FLAGS_REG))]
10816 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
10818 sar{b}\t{%2, %0|%0, %2}
10819 sar{b}\t{%b2, %0|%0, %b2}"
10820 [(set_attr "type" "ishift")
10821 (set_attr "mode" "QI")])
10823 (define_insn "*ashrqi3_1_slp"
10824 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
10825 (ashiftrt:QI (match_dup 0)
10826 (match_operand:QI 1 "nonmemory_operand" "I,c")))
10827 (clobber (reg:CC FLAGS_REG))]
10828 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10829 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10831 sar{b}\t{%1, %0|%0, %1}
10832 sar{b}\t{%b1, %0|%0, %b1}"
10833 [(set_attr "type" "ishift1")
10834 (set_attr "mode" "QI")])
10836 ;; This pattern can't accept a variable shift count, since shifts by
10837 ;; zero don't affect the flags. We assume that shifts by constant
10838 ;; zero are optimized away.
10839 (define_insn "*ashrqi3_one_bit_cmp"
10840 [(set (reg FLAGS_REG)
10842 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10843 (match_operand:QI 2 "const1_operand" "I"))
10845 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10846 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
10847 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10848 && ix86_match_ccmode (insn, CCGOCmode)
10849 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
10851 [(set_attr "type" "ishift")
10852 (set_attr "length_immediate" "0")
10853 (set_attr "mode" "QI")])
10855 (define_insn "*ashrqi3_one_bit_cconly"
10856 [(set (reg FLAGS_REG)
10858 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10859 (match_operand:QI 2 "const1_operand" ""))
10861 (clobber (match_scratch:QI 0 "=q"))]
10862 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10863 && ix86_match_ccmode (insn, CCGOCmode)
10864 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
10866 [(set_attr "type" "ishift")
10867 (set_attr "length_immediate" "0")
10868 (set_attr "mode" "QI")])
10870 ;; This pattern can't accept a variable shift count, since shifts by
10871 ;; zero don't affect the flags. We assume that shifts by constant
10872 ;; zero are optimized away.
10873 (define_insn "*ashrqi3_cmp"
10874 [(set (reg FLAGS_REG)
10876 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10877 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10879 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10880 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
10881 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10882 && ix86_match_ccmode (insn, CCGOCmode)
10883 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
10884 "sar{b}\t{%2, %0|%0, %2}"
10885 [(set_attr "type" "ishift")
10886 (set_attr "mode" "QI")])
10888 (define_insn "*ashrqi3_cconly"
10889 [(set (reg FLAGS_REG)
10891 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10892 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10894 (clobber (match_scratch:QI 0 "=q"))]
10895 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10896 && ix86_match_ccmode (insn, CCGOCmode)
10897 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
10898 "sar{b}\t{%2, %0|%0, %2}"
10899 [(set_attr "type" "ishift")
10900 (set_attr "mode" "QI")])
10903 ;; Logical shift instructions
10905 ;; See comment above `ashldi3' about how this works.
10907 (define_expand "lshrti3"
10908 [(set (match_operand:TI 0 "register_operand" "")
10909 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
10910 (match_operand:QI 2 "nonmemory_operand" "")))]
10912 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
10914 (define_insn "*lshrti3_1"
10915 [(set (match_operand:TI 0 "register_operand" "=r")
10916 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
10917 (match_operand:QI 2 "nonmemory_operand" "Oc")))
10918 (clobber (reg:CC FLAGS_REG))]
10921 [(set_attr "type" "multi")])
10924 [(match_scratch:DI 3 "r")
10925 (parallel [(set (match_operand:TI 0 "register_operand" "")
10926 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
10927 (match_operand:QI 2 "nonmemory_operand" "")))
10928 (clobber (reg:CC FLAGS_REG))])
10932 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
10935 [(set (match_operand:TI 0 "register_operand" "")
10936 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
10937 (match_operand:QI 2 "nonmemory_operand" "")))
10938 (clobber (reg:CC FLAGS_REG))]
10939 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10940 ? epilogue_completed : reload_completed)"
10942 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
10944 (define_expand "lshrdi3"
10945 [(set (match_operand:DI 0 "shiftdi_operand" "")
10946 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10947 (match_operand:QI 2 "nonmemory_operand" "")))]
10949 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
10951 (define_insn "*lshrdi3_1_one_bit_rex64"
10952 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10953 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10954 (match_operand:QI 2 "const1_operand" "")))
10955 (clobber (reg:CC FLAGS_REG))]
10957 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10958 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
10960 [(set_attr "type" "ishift")
10961 (set_attr "length_immediate" "0")
10962 (set_attr "mode" "DI")])
10964 (define_insn "*lshrdi3_1_rex64"
10965 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10966 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10967 (match_operand:QI 2 "nonmemory_operand" "J,c")))
10968 (clobber (reg:CC FLAGS_REG))]
10969 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
10971 shr{q}\t{%2, %0|%0, %2}
10972 shr{q}\t{%b2, %0|%0, %b2}"
10973 [(set_attr "type" "ishift")
10974 (set_attr "mode" "DI")])
10976 ;; This pattern can't accept a variable shift count, since shifts by
10977 ;; zero don't affect the flags. We assume that shifts by constant
10978 ;; zero are optimized away.
10979 (define_insn "*lshrdi3_cmp_one_bit_rex64"
10980 [(set (reg FLAGS_REG)
10982 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10983 (match_operand:QI 2 "const1_operand" ""))
10985 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10986 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
10988 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10989 && ix86_match_ccmode (insn, CCGOCmode)
10990 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
10992 [(set_attr "type" "ishift")
10993 (set_attr "length_immediate" "0")
10994 (set_attr "mode" "DI")])
10996 (define_insn "*lshrdi3_cconly_one_bit_rex64"
10997 [(set (reg FLAGS_REG)
10999 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11000 (match_operand:QI 2 "const1_operand" ""))
11002 (clobber (match_scratch:DI 0 "=r"))]
11004 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11005 && ix86_match_ccmode (insn, CCGOCmode)
11006 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11008 [(set_attr "type" "ishift")
11009 (set_attr "length_immediate" "0")
11010 (set_attr "mode" "DI")])
11012 ;; This pattern can't accept a variable shift count, since shifts by
11013 ;; zero don't affect the flags. We assume that shifts by constant
11014 ;; zero are optimized away.
11015 (define_insn "*lshrdi3_cmp_rex64"
11016 [(set (reg FLAGS_REG)
11018 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11019 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11021 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11022 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11024 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11025 && ix86_match_ccmode (insn, CCGOCmode)
11026 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11027 "shr{q}\t{%2, %0|%0, %2}"
11028 [(set_attr "type" "ishift")
11029 (set_attr "mode" "DI")])
11031 (define_insn "*lshrdi3_cconly_rex64"
11032 [(set (reg FLAGS_REG)
11034 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11035 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11037 (clobber (match_scratch:DI 0 "=r"))]
11039 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11040 && ix86_match_ccmode (insn, CCGOCmode)
11041 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11042 "shr{q}\t{%2, %0|%0, %2}"
11043 [(set_attr "type" "ishift")
11044 (set_attr "mode" "DI")])
11046 (define_insn "*lshrdi3_1"
11047 [(set (match_operand:DI 0 "register_operand" "=r")
11048 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11049 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11050 (clobber (reg:CC FLAGS_REG))]
11053 [(set_attr "type" "multi")])
11055 ;; By default we don't ask for a scratch register, because when DImode
11056 ;; values are manipulated, registers are already at a premium. But if
11057 ;; we have one handy, we won't turn it away.
11059 [(match_scratch:SI 3 "r")
11060 (parallel [(set (match_operand:DI 0 "register_operand" "")
11061 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11062 (match_operand:QI 2 "nonmemory_operand" "")))
11063 (clobber (reg:CC FLAGS_REG))])
11065 "!TARGET_64BIT && TARGET_CMOVE"
11067 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11070 [(set (match_operand:DI 0 "register_operand" "")
11071 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11072 (match_operand:QI 2 "nonmemory_operand" "")))
11073 (clobber (reg:CC FLAGS_REG))]
11074 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11075 ? epilogue_completed : reload_completed)"
11077 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11079 (define_expand "lshrsi3"
11080 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11081 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11082 (match_operand:QI 2 "nonmemory_operand" "")))]
11084 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11086 (define_insn "*lshrsi3_1_one_bit"
11087 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11088 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11089 (match_operand:QI 2 "const1_operand" "")))
11090 (clobber (reg:CC FLAGS_REG))]
11091 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11092 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11094 [(set_attr "type" "ishift")
11095 (set_attr "length_immediate" "0")
11096 (set_attr "mode" "SI")])
11098 (define_insn "*lshrsi3_1_one_bit_zext"
11099 [(set (match_operand:DI 0 "register_operand" "=r")
11100 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11101 (match_operand:QI 2 "const1_operand" "")))
11102 (clobber (reg:CC FLAGS_REG))]
11104 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11105 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11107 [(set_attr "type" "ishift")
11108 (set_attr "length_immediate" "0")
11109 (set_attr "mode" "SI")])
11111 (define_insn "*lshrsi3_1"
11112 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11113 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11114 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11115 (clobber (reg:CC FLAGS_REG))]
11116 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11118 shr{l}\t{%2, %0|%0, %2}
11119 shr{l}\t{%b2, %0|%0, %b2}"
11120 [(set_attr "type" "ishift")
11121 (set_attr "mode" "SI")])
11123 (define_insn "*lshrsi3_1_zext"
11124 [(set (match_operand:DI 0 "register_operand" "=r,r")
11126 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11127 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11128 (clobber (reg:CC FLAGS_REG))]
11129 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11131 shr{l}\t{%2, %k0|%k0, %2}
11132 shr{l}\t{%b2, %k0|%k0, %b2}"
11133 [(set_attr "type" "ishift")
11134 (set_attr "mode" "SI")])
11136 ;; This pattern can't accept a variable shift count, since shifts by
11137 ;; zero don't affect the flags. We assume that shifts by constant
11138 ;; zero are optimized away.
11139 (define_insn "*lshrsi3_one_bit_cmp"
11140 [(set (reg FLAGS_REG)
11142 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11143 (match_operand:QI 2 "const1_operand" ""))
11145 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11146 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11147 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11148 && ix86_match_ccmode (insn, CCGOCmode)
11149 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11151 [(set_attr "type" "ishift")
11152 (set_attr "length_immediate" "0")
11153 (set_attr "mode" "SI")])
11155 (define_insn "*lshrsi3_one_bit_cconly"
11156 [(set (reg FLAGS_REG)
11158 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11159 (match_operand:QI 2 "const1_operand" ""))
11161 (clobber (match_scratch:SI 0 "=r"))]
11162 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11163 && ix86_match_ccmode (insn, CCGOCmode)
11164 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11166 [(set_attr "type" "ishift")
11167 (set_attr "length_immediate" "0")
11168 (set_attr "mode" "SI")])
11170 (define_insn "*lshrsi3_cmp_one_bit_zext"
11171 [(set (reg FLAGS_REG)
11173 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11174 (match_operand:QI 2 "const1_operand" ""))
11176 (set (match_operand:DI 0 "register_operand" "=r")
11177 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11179 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11180 && ix86_match_ccmode (insn, CCGOCmode)
11181 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11183 [(set_attr "type" "ishift")
11184 (set_attr "length_immediate" "0")
11185 (set_attr "mode" "SI")])
11187 ;; This pattern can't accept a variable shift count, since shifts by
11188 ;; zero don't affect the flags. We assume that shifts by constant
11189 ;; zero are optimized away.
11190 (define_insn "*lshrsi3_cmp"
11191 [(set (reg FLAGS_REG)
11193 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11194 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11196 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11197 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11198 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11199 && ix86_match_ccmode (insn, CCGOCmode)
11200 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11201 "shr{l}\t{%2, %0|%0, %2}"
11202 [(set_attr "type" "ishift")
11203 (set_attr "mode" "SI")])
11205 (define_insn "*lshrsi3_cconly"
11206 [(set (reg FLAGS_REG)
11208 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11209 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11211 (clobber (match_scratch:SI 0 "=r"))]
11212 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11213 && ix86_match_ccmode (insn, CCGOCmode)
11214 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11215 "shr{l}\t{%2, %0|%0, %2}"
11216 [(set_attr "type" "ishift")
11217 (set_attr "mode" "SI")])
11219 (define_insn "*lshrsi3_cmp_zext"
11220 [(set (reg FLAGS_REG)
11222 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11223 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11225 (set (match_operand:DI 0 "register_operand" "=r")
11226 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11228 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11229 && ix86_match_ccmode (insn, CCGOCmode)
11230 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11231 "shr{l}\t{%2, %k0|%k0, %2}"
11232 [(set_attr "type" "ishift")
11233 (set_attr "mode" "SI")])
11235 (define_expand "lshrhi3"
11236 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11237 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11238 (match_operand:QI 2 "nonmemory_operand" "")))]
11239 "TARGET_HIMODE_MATH"
11240 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11242 (define_insn "*lshrhi3_1_one_bit"
11243 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11244 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11245 (match_operand:QI 2 "const1_operand" "")))
11246 (clobber (reg:CC FLAGS_REG))]
11247 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11248 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11250 [(set_attr "type" "ishift")
11251 (set_attr "length_immediate" "0")
11252 (set_attr "mode" "HI")])
11254 (define_insn "*lshrhi3_1"
11255 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11256 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11257 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11258 (clobber (reg:CC FLAGS_REG))]
11259 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11261 shr{w}\t{%2, %0|%0, %2}
11262 shr{w}\t{%b2, %0|%0, %b2}"
11263 [(set_attr "type" "ishift")
11264 (set_attr "mode" "HI")])
11266 ;; This pattern can't accept a variable shift count, since shifts by
11267 ;; zero don't affect the flags. We assume that shifts by constant
11268 ;; zero are optimized away.
11269 (define_insn "*lshrhi3_one_bit_cmp"
11270 [(set (reg FLAGS_REG)
11272 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11273 (match_operand:QI 2 "const1_operand" ""))
11275 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11276 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11277 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11278 && ix86_match_ccmode (insn, CCGOCmode)
11279 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11281 [(set_attr "type" "ishift")
11282 (set_attr "length_immediate" "0")
11283 (set_attr "mode" "HI")])
11285 (define_insn "*lshrhi3_one_bit_cconly"
11286 [(set (reg FLAGS_REG)
11288 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11289 (match_operand:QI 2 "const1_operand" ""))
11291 (clobber (match_scratch:HI 0 "=r"))]
11292 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11293 && ix86_match_ccmode (insn, CCGOCmode)
11294 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11296 [(set_attr "type" "ishift")
11297 (set_attr "length_immediate" "0")
11298 (set_attr "mode" "HI")])
11300 ;; This pattern can't accept a variable shift count, since shifts by
11301 ;; zero don't affect the flags. We assume that shifts by constant
11302 ;; zero are optimized away.
11303 (define_insn "*lshrhi3_cmp"
11304 [(set (reg FLAGS_REG)
11306 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11307 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11309 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11310 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11311 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11312 && ix86_match_ccmode (insn, CCGOCmode)
11313 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11314 "shr{w}\t{%2, %0|%0, %2}"
11315 [(set_attr "type" "ishift")
11316 (set_attr "mode" "HI")])
11318 (define_insn "*lshrhi3_cconly"
11319 [(set (reg FLAGS_REG)
11321 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11322 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11324 (clobber (match_scratch:HI 0 "=r"))]
11325 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11326 && ix86_match_ccmode (insn, CCGOCmode)
11327 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11328 "shr{w}\t{%2, %0|%0, %2}"
11329 [(set_attr "type" "ishift")
11330 (set_attr "mode" "HI")])
11332 (define_expand "lshrqi3"
11333 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11334 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11335 (match_operand:QI 2 "nonmemory_operand" "")))]
11336 "TARGET_QIMODE_MATH"
11337 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11339 (define_insn "*lshrqi3_1_one_bit"
11340 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11341 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11342 (match_operand:QI 2 "const1_operand" "")))
11343 (clobber (reg:CC FLAGS_REG))]
11344 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11345 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11347 [(set_attr "type" "ishift")
11348 (set_attr "length_immediate" "0")
11349 (set_attr "mode" "QI")])
11351 (define_insn "*lshrqi3_1_one_bit_slp"
11352 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11353 (lshiftrt:QI (match_dup 0)
11354 (match_operand:QI 1 "const1_operand" "")))
11355 (clobber (reg:CC FLAGS_REG))]
11356 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11357 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
11359 [(set_attr "type" "ishift1")
11360 (set_attr "length_immediate" "0")
11361 (set_attr "mode" "QI")])
11363 (define_insn "*lshrqi3_1"
11364 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11365 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11366 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11367 (clobber (reg:CC FLAGS_REG))]
11368 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11370 shr{b}\t{%2, %0|%0, %2}
11371 shr{b}\t{%b2, %0|%0, %b2}"
11372 [(set_attr "type" "ishift")
11373 (set_attr "mode" "QI")])
11375 (define_insn "*lshrqi3_1_slp"
11376 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11377 (lshiftrt:QI (match_dup 0)
11378 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11379 (clobber (reg:CC FLAGS_REG))]
11380 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11381 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11383 shr{b}\t{%1, %0|%0, %1}
11384 shr{b}\t{%b1, %0|%0, %b1}"
11385 [(set_attr "type" "ishift1")
11386 (set_attr "mode" "QI")])
11388 ;; This pattern can't accept a variable shift count, since shifts by
11389 ;; zero don't affect the flags. We assume that shifts by constant
11390 ;; zero are optimized away.
11391 (define_insn "*lshrqi2_one_bit_cmp"
11392 [(set (reg FLAGS_REG)
11394 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11395 (match_operand:QI 2 "const1_operand" ""))
11397 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11398 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11399 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11400 && ix86_match_ccmode (insn, CCGOCmode)
11401 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11403 [(set_attr "type" "ishift")
11404 (set_attr "length_immediate" "0")
11405 (set_attr "mode" "QI")])
11407 (define_insn "*lshrqi2_one_bit_cconly"
11408 [(set (reg FLAGS_REG)
11410 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11411 (match_operand:QI 2 "const1_operand" ""))
11413 (clobber (match_scratch:QI 0 "=q"))]
11414 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11415 && ix86_match_ccmode (insn, CCGOCmode)
11416 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11418 [(set_attr "type" "ishift")
11419 (set_attr "length_immediate" "0")
11420 (set_attr "mode" "QI")])
11422 ;; This pattern can't accept a variable shift count, since shifts by
11423 ;; zero don't affect the flags. We assume that shifts by constant
11424 ;; zero are optimized away.
11425 (define_insn "*lshrqi2_cmp"
11426 [(set (reg FLAGS_REG)
11428 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11429 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11431 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11432 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11433 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11434 && ix86_match_ccmode (insn, CCGOCmode)
11435 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11436 "shr{b}\t{%2, %0|%0, %2}"
11437 [(set_attr "type" "ishift")
11438 (set_attr "mode" "QI")])
11440 (define_insn "*lshrqi2_cconly"
11441 [(set (reg FLAGS_REG)
11443 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11444 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11446 (clobber (match_scratch:QI 0 "=q"))]
11447 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11448 && ix86_match_ccmode (insn, CCGOCmode)
11449 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11450 "shr{b}\t{%2, %0|%0, %2}"
11451 [(set_attr "type" "ishift")
11452 (set_attr "mode" "QI")])
11454 ;; Rotate instructions
11456 (define_expand "rotldi3"
11457 [(set (match_operand:DI 0 "shiftdi_operand" "")
11458 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
11459 (match_operand:QI 2 "nonmemory_operand" "")))]
11464 ix86_expand_binary_operator (ROTATE, DImode, operands);
11467 if (!const_1_to_31_operand (operands[2], VOIDmode))
11469 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
11473 ;; Implement rotation using two double-precision shift instructions
11474 ;; and a scratch register.
11475 (define_insn_and_split "ix86_rotldi3"
11476 [(set (match_operand:DI 0 "register_operand" "=r")
11477 (rotate:DI (match_operand:DI 1 "register_operand" "0")
11478 (match_operand:QI 2 "const_1_to_31_operand" "I")))
11479 (clobber (reg:CC FLAGS_REG))
11480 (clobber (match_scratch:SI 3 "=&r"))]
11483 "&& reload_completed"
11484 [(set (match_dup 3) (match_dup 4))
11486 [(set (match_dup 4)
11487 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
11488 (lshiftrt:SI (match_dup 5)
11489 (minus:QI (const_int 32) (match_dup 2)))))
11490 (clobber (reg:CC FLAGS_REG))])
11492 [(set (match_dup 5)
11493 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
11494 (lshiftrt:SI (match_dup 3)
11495 (minus:QI (const_int 32) (match_dup 2)))))
11496 (clobber (reg:CC FLAGS_REG))])]
11497 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
11499 (define_insn "*rotlsi3_1_one_bit_rex64"
11500 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11501 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11502 (match_operand:QI 2 "const1_operand" "")))
11503 (clobber (reg:CC FLAGS_REG))]
11505 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11506 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11508 [(set_attr "type" "rotate")
11509 (set_attr "length_immediate" "0")
11510 (set_attr "mode" "DI")])
11512 (define_insn "*rotldi3_1_rex64"
11513 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11514 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11515 (match_operand:QI 2 "nonmemory_operand" "e,c")))
11516 (clobber (reg:CC FLAGS_REG))]
11517 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11519 rol{q}\t{%2, %0|%0, %2}
11520 rol{q}\t{%b2, %0|%0, %b2}"
11521 [(set_attr "type" "rotate")
11522 (set_attr "mode" "DI")])
11524 (define_expand "rotlsi3"
11525 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11526 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11527 (match_operand:QI 2 "nonmemory_operand" "")))]
11529 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11531 (define_insn "*rotlsi3_1_one_bit"
11532 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11533 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11534 (match_operand:QI 2 "const1_operand" "")))
11535 (clobber (reg:CC FLAGS_REG))]
11536 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11537 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11539 [(set_attr "type" "rotate")
11540 (set_attr "length_immediate" "0")
11541 (set_attr "mode" "SI")])
11543 (define_insn "*rotlsi3_1_one_bit_zext"
11544 [(set (match_operand:DI 0 "register_operand" "=r")
11546 (rotate:SI (match_operand:SI 1 "register_operand" "0")
11547 (match_operand:QI 2 "const1_operand" ""))))
11548 (clobber (reg:CC FLAGS_REG))]
11550 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11551 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11553 [(set_attr "type" "rotate")
11554 (set_attr "length_immediate" "0")
11555 (set_attr "mode" "SI")])
11557 (define_insn "*rotlsi3_1"
11558 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11559 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11560 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11561 (clobber (reg:CC FLAGS_REG))]
11562 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11564 rol{l}\t{%2, %0|%0, %2}
11565 rol{l}\t{%b2, %0|%0, %b2}"
11566 [(set_attr "type" "rotate")
11567 (set_attr "mode" "SI")])
11569 (define_insn "*rotlsi3_1_zext"
11570 [(set (match_operand:DI 0 "register_operand" "=r,r")
11572 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11573 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11574 (clobber (reg:CC FLAGS_REG))]
11575 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11577 rol{l}\t{%2, %k0|%k0, %2}
11578 rol{l}\t{%b2, %k0|%k0, %b2}"
11579 [(set_attr "type" "rotate")
11580 (set_attr "mode" "SI")])
11582 (define_expand "rotlhi3"
11583 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11584 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11585 (match_operand:QI 2 "nonmemory_operand" "")))]
11586 "TARGET_HIMODE_MATH"
11587 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11589 (define_insn "*rotlhi3_1_one_bit"
11590 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11591 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11592 (match_operand:QI 2 "const1_operand" "")))
11593 (clobber (reg:CC FLAGS_REG))]
11594 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11595 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
11597 [(set_attr "type" "rotate")
11598 (set_attr "length_immediate" "0")
11599 (set_attr "mode" "HI")])
11601 (define_insn "*rotlhi3_1"
11602 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11603 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11604 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11605 (clobber (reg:CC FLAGS_REG))]
11606 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11608 rol{w}\t{%2, %0|%0, %2}
11609 rol{w}\t{%b2, %0|%0, %b2}"
11610 [(set_attr "type" "rotate")
11611 (set_attr "mode" "HI")])
11614 [(set (match_operand:HI 0 "register_operand" "")
11615 (rotate:HI (match_dup 0) (const_int 8)))
11616 (clobber (reg:CC FLAGS_REG))]
11618 [(parallel [(set (strict_low_part (match_dup 0))
11619 (bswap:HI (match_dup 0)))
11620 (clobber (reg:CC FLAGS_REG))])]
11623 (define_expand "rotlqi3"
11624 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11625 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11626 (match_operand:QI 2 "nonmemory_operand" "")))]
11627 "TARGET_QIMODE_MATH"
11628 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11630 (define_insn "*rotlqi3_1_one_bit_slp"
11631 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11632 (rotate:QI (match_dup 0)
11633 (match_operand:QI 1 "const1_operand" "")))
11634 (clobber (reg:CC FLAGS_REG))]
11635 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11636 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
11638 [(set_attr "type" "rotate1")
11639 (set_attr "length_immediate" "0")
11640 (set_attr "mode" "QI")])
11642 (define_insn "*rotlqi3_1_one_bit"
11643 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11644 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11645 (match_operand:QI 2 "const1_operand" "")))
11646 (clobber (reg:CC FLAGS_REG))]
11647 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11648 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
11650 [(set_attr "type" "rotate")
11651 (set_attr "length_immediate" "0")
11652 (set_attr "mode" "QI")])
11654 (define_insn "*rotlqi3_1_slp"
11655 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11656 (rotate:QI (match_dup 0)
11657 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11658 (clobber (reg:CC FLAGS_REG))]
11659 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11660 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11662 rol{b}\t{%1, %0|%0, %1}
11663 rol{b}\t{%b1, %0|%0, %b1}"
11664 [(set_attr "type" "rotate1")
11665 (set_attr "mode" "QI")])
11667 (define_insn "*rotlqi3_1"
11668 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11669 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11670 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11671 (clobber (reg:CC FLAGS_REG))]
11672 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11674 rol{b}\t{%2, %0|%0, %2}
11675 rol{b}\t{%b2, %0|%0, %b2}"
11676 [(set_attr "type" "rotate")
11677 (set_attr "mode" "QI")])
11679 (define_expand "rotrdi3"
11680 [(set (match_operand:DI 0 "shiftdi_operand" "")
11681 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
11682 (match_operand:QI 2 "nonmemory_operand" "")))]
11687 ix86_expand_binary_operator (ROTATERT, DImode, operands);
11690 if (!const_1_to_31_operand (operands[2], VOIDmode))
11692 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
11696 ;; Implement rotation using two double-precision shift instructions
11697 ;; and a scratch register.
11698 (define_insn_and_split "ix86_rotrdi3"
11699 [(set (match_operand:DI 0 "register_operand" "=r")
11700 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
11701 (match_operand:QI 2 "const_1_to_31_operand" "I")))
11702 (clobber (reg:CC FLAGS_REG))
11703 (clobber (match_scratch:SI 3 "=&r"))]
11706 "&& reload_completed"
11707 [(set (match_dup 3) (match_dup 4))
11709 [(set (match_dup 4)
11710 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
11711 (ashift:SI (match_dup 5)
11712 (minus:QI (const_int 32) (match_dup 2)))))
11713 (clobber (reg:CC FLAGS_REG))])
11715 [(set (match_dup 5)
11716 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
11717 (ashift:SI (match_dup 3)
11718 (minus:QI (const_int 32) (match_dup 2)))))
11719 (clobber (reg:CC FLAGS_REG))])]
11720 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
11722 (define_insn "*rotrdi3_1_one_bit_rex64"
11723 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11724 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11725 (match_operand:QI 2 "const1_operand" "")))
11726 (clobber (reg:CC FLAGS_REG))]
11728 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11729 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11731 [(set_attr "type" "rotate")
11732 (set_attr "length_immediate" "0")
11733 (set_attr "mode" "DI")])
11735 (define_insn "*rotrdi3_1_rex64"
11736 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11737 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11738 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11739 (clobber (reg:CC FLAGS_REG))]
11740 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11742 ror{q}\t{%2, %0|%0, %2}
11743 ror{q}\t{%b2, %0|%0, %b2}"
11744 [(set_attr "type" "rotate")
11745 (set_attr "mode" "DI")])
11747 (define_expand "rotrsi3"
11748 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11749 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11750 (match_operand:QI 2 "nonmemory_operand" "")))]
11752 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11754 (define_insn "*rotrsi3_1_one_bit"
11755 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11756 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11757 (match_operand:QI 2 "const1_operand" "")))
11758 (clobber (reg:CC FLAGS_REG))]
11759 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11760 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11762 [(set_attr "type" "rotate")
11763 (set_attr "length_immediate" "0")
11764 (set_attr "mode" "SI")])
11766 (define_insn "*rotrsi3_1_one_bit_zext"
11767 [(set (match_operand:DI 0 "register_operand" "=r")
11769 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11770 (match_operand:QI 2 "const1_operand" ""))))
11771 (clobber (reg:CC FLAGS_REG))]
11773 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11774 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11776 [(set_attr "type" "rotate")
11777 (set_attr "length_immediate" "0")
11778 (set_attr "mode" "SI")])
11780 (define_insn "*rotrsi3_1"
11781 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11782 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11783 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11784 (clobber (reg:CC FLAGS_REG))]
11785 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11787 ror{l}\t{%2, %0|%0, %2}
11788 ror{l}\t{%b2, %0|%0, %b2}"
11789 [(set_attr "type" "rotate")
11790 (set_attr "mode" "SI")])
11792 (define_insn "*rotrsi3_1_zext"
11793 [(set (match_operand:DI 0 "register_operand" "=r,r")
11795 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11796 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11797 (clobber (reg:CC FLAGS_REG))]
11798 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11800 ror{l}\t{%2, %k0|%k0, %2}
11801 ror{l}\t{%b2, %k0|%k0, %b2}"
11802 [(set_attr "type" "rotate")
11803 (set_attr "mode" "SI")])
11805 (define_expand "rotrhi3"
11806 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11807 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11808 (match_operand:QI 2 "nonmemory_operand" "")))]
11809 "TARGET_HIMODE_MATH"
11810 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11812 (define_insn "*rotrhi3_one_bit"
11813 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11814 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11815 (match_operand:QI 2 "const1_operand" "")))
11816 (clobber (reg:CC FLAGS_REG))]
11817 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11818 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11820 [(set_attr "type" "rotate")
11821 (set_attr "length_immediate" "0")
11822 (set_attr "mode" "HI")])
11824 (define_insn "*rotrhi3_1"
11825 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11826 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11827 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11828 (clobber (reg:CC FLAGS_REG))]
11829 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11831 ror{w}\t{%2, %0|%0, %2}
11832 ror{w}\t{%b2, %0|%0, %b2}"
11833 [(set_attr "type" "rotate")
11834 (set_attr "mode" "HI")])
11837 [(set (match_operand:HI 0 "register_operand" "")
11838 (rotatert:HI (match_dup 0) (const_int 8)))
11839 (clobber (reg:CC FLAGS_REG))]
11841 [(parallel [(set (strict_low_part (match_dup 0))
11842 (bswap:HI (match_dup 0)))
11843 (clobber (reg:CC FLAGS_REG))])]
11846 (define_expand "rotrqi3"
11847 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11848 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
11849 (match_operand:QI 2 "nonmemory_operand" "")))]
11850 "TARGET_QIMODE_MATH"
11851 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
11853 (define_insn "*rotrqi3_1_one_bit"
11854 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11855 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11856 (match_operand:QI 2 "const1_operand" "")))
11857 (clobber (reg:CC FLAGS_REG))]
11858 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11859 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
11861 [(set_attr "type" "rotate")
11862 (set_attr "length_immediate" "0")
11863 (set_attr "mode" "QI")])
11865 (define_insn "*rotrqi3_1_one_bit_slp"
11866 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11867 (rotatert:QI (match_dup 0)
11868 (match_operand:QI 1 "const1_operand" "")))
11869 (clobber (reg:CC FLAGS_REG))]
11870 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11871 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
11873 [(set_attr "type" "rotate1")
11874 (set_attr "length_immediate" "0")
11875 (set_attr "mode" "QI")])
11877 (define_insn "*rotrqi3_1"
11878 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11879 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11880 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11881 (clobber (reg:CC FLAGS_REG))]
11882 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
11884 ror{b}\t{%2, %0|%0, %2}
11885 ror{b}\t{%b2, %0|%0, %b2}"
11886 [(set_attr "type" "rotate")
11887 (set_attr "mode" "QI")])
11889 (define_insn "*rotrqi3_1_slp"
11890 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11891 (rotatert:QI (match_dup 0)
11892 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11893 (clobber (reg:CC FLAGS_REG))]
11894 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11895 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11897 ror{b}\t{%1, %0|%0, %1}
11898 ror{b}\t{%b1, %0|%0, %b1}"
11899 [(set_attr "type" "rotate1")
11900 (set_attr "mode" "QI")])
11902 ;; Bit set / bit test instructions
11904 (define_expand "extv"
11905 [(set (match_operand:SI 0 "register_operand" "")
11906 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
11907 (match_operand:SI 2 "const8_operand" "")
11908 (match_operand:SI 3 "const8_operand" "")))]
11911 /* Handle extractions from %ah et al. */
11912 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
11915 /* From mips.md: extract_bit_field doesn't verify that our source
11916 matches the predicate, so check it again here. */
11917 if (! ext_register_operand (operands[1], VOIDmode))
11921 (define_expand "extzv"
11922 [(set (match_operand:SI 0 "register_operand" "")
11923 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
11924 (match_operand:SI 2 "const8_operand" "")
11925 (match_operand:SI 3 "const8_operand" "")))]
11928 /* Handle extractions from %ah et al. */
11929 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
11932 /* From mips.md: extract_bit_field doesn't verify that our source
11933 matches the predicate, so check it again here. */
11934 if (! ext_register_operand (operands[1], VOIDmode))
11938 (define_expand "insv"
11939 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
11940 (match_operand 1 "const8_operand" "")
11941 (match_operand 2 "const8_operand" ""))
11942 (match_operand 3 "register_operand" ""))]
11945 /* Handle insertions to %ah et al. */
11946 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
11949 /* From mips.md: insert_bit_field doesn't verify that our source
11950 matches the predicate, so check it again here. */
11951 if (! ext_register_operand (operands[0], VOIDmode))
11955 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
11957 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
11962 ;; %%% bts, btr, btc, bt.
11963 ;; In general these instructions are *slow* when applied to memory,
11964 ;; since they enforce atomic operation. When applied to registers,
11965 ;; it depends on the cpu implementation. They're never faster than
11966 ;; the corresponding and/ior/xor operations, so with 32-bit there's
11967 ;; no point. But in 64-bit, we can't hold the relevant immediates
11968 ;; within the instruction itself, so operating on bits in the high
11969 ;; 32-bits of a register becomes easier.
11971 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
11972 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11973 ;; negdf respectively, so they can never be disabled entirely.
11975 (define_insn "*btsq"
11976 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11978 (match_operand:DI 1 "const_0_to_63_operand" ""))
11980 (clobber (reg:CC FLAGS_REG))]
11981 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11982 "bts{q}\t{%1, %0|%0, %1}"
11983 [(set_attr "type" "alu1")
11984 (set_attr "prefix_0f" "1")
11985 (set_attr "mode" "DI")])
11987 (define_insn "*btrq"
11988 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11990 (match_operand:DI 1 "const_0_to_63_operand" ""))
11992 (clobber (reg:CC FLAGS_REG))]
11993 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11994 "btr{q}\t{%1, %0|%0, %1}"
11995 [(set_attr "type" "alu1")
11996 (set_attr "prefix_0f" "1")
11997 (set_attr "mode" "DI")])
11999 (define_insn "*btcq"
12000 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12002 (match_operand:DI 1 "const_0_to_63_operand" ""))
12003 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12004 (clobber (reg:CC FLAGS_REG))]
12005 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12006 "btc{q}\t{%1, %0|%0, %1}"
12007 [(set_attr "type" "alu1")
12008 (set_attr "prefix_0f" "1")
12009 (set_attr "mode" "DI")])
12011 ;; Allow Nocona to avoid these instructions if a register is available.
12014 [(match_scratch:DI 2 "r")
12015 (parallel [(set (zero_extract:DI
12016 (match_operand:DI 0 "register_operand" "")
12018 (match_operand:DI 1 "const_0_to_63_operand" ""))
12020 (clobber (reg:CC FLAGS_REG))])]
12021 "TARGET_64BIT && !TARGET_USE_BT"
12024 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12027 if (HOST_BITS_PER_WIDE_INT >= 64)
12028 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12029 else if (i < HOST_BITS_PER_WIDE_INT)
12030 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12032 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12034 op1 = immed_double_const (lo, hi, DImode);
12037 emit_move_insn (operands[2], op1);
12041 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12046 [(match_scratch:DI 2 "r")
12047 (parallel [(set (zero_extract:DI
12048 (match_operand:DI 0 "register_operand" "")
12050 (match_operand:DI 1 "const_0_to_63_operand" ""))
12052 (clobber (reg:CC FLAGS_REG))])]
12053 "TARGET_64BIT && !TARGET_USE_BT"
12056 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12059 if (HOST_BITS_PER_WIDE_INT >= 64)
12060 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12061 else if (i < HOST_BITS_PER_WIDE_INT)
12062 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12064 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12066 op1 = immed_double_const (~lo, ~hi, DImode);
12069 emit_move_insn (operands[2], op1);
12073 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12078 [(match_scratch:DI 2 "r")
12079 (parallel [(set (zero_extract:DI
12080 (match_operand:DI 0 "register_operand" "")
12082 (match_operand:DI 1 "const_0_to_63_operand" ""))
12083 (not:DI (zero_extract:DI
12084 (match_dup 0) (const_int 1) (match_dup 1))))
12085 (clobber (reg:CC FLAGS_REG))])]
12086 "TARGET_64BIT && !TARGET_USE_BT"
12089 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12092 if (HOST_BITS_PER_WIDE_INT >= 64)
12093 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12094 else if (i < HOST_BITS_PER_WIDE_INT)
12095 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12097 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12099 op1 = immed_double_const (lo, hi, DImode);
12102 emit_move_insn (operands[2], op1);
12106 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12110 (define_insn "*btdi_rex64"
12111 [(set (reg:CCC FLAGS_REG)
12114 (match_operand:DI 0 "register_operand" "r")
12116 (match_operand:DI 1 "nonmemory_operand" "rN"))
12118 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
12119 "bt{q}\t{%1, %0|%0, %1}"
12120 [(set_attr "type" "alu1")
12121 (set_attr "prefix_0f" "1")
12122 (set_attr "mode" "DI")])
12124 (define_insn "*btsi"
12125 [(set (reg:CCC FLAGS_REG)
12128 (match_operand:SI 0 "register_operand" "r")
12130 (match_operand:SI 1 "nonmemory_operand" "rN"))
12132 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12133 "bt{l}\t{%1, %0|%0, %1}"
12134 [(set_attr "type" "alu1")
12135 (set_attr "prefix_0f" "1")
12136 (set_attr "mode" "SI")])
12138 ;; Store-flag instructions.
12140 ;; For all sCOND expanders, also expand the compare or test insn that
12141 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12143 (define_insn_and_split "*setcc_di_1"
12144 [(set (match_operand:DI 0 "register_operand" "=q")
12145 (match_operator:DI 1 "ix86_comparison_operator"
12146 [(reg FLAGS_REG) (const_int 0)]))]
12147 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12149 "&& reload_completed"
12150 [(set (match_dup 2) (match_dup 1))
12151 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12153 PUT_MODE (operands[1], QImode);
12154 operands[2] = gen_lowpart (QImode, operands[0]);
12157 (define_insn_and_split "*setcc_si_1_and"
12158 [(set (match_operand:SI 0 "register_operand" "=q")
12159 (match_operator:SI 1 "ix86_comparison_operator"
12160 [(reg FLAGS_REG) (const_int 0)]))
12161 (clobber (reg:CC FLAGS_REG))]
12162 "!TARGET_PARTIAL_REG_STALL
12163 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12165 "&& reload_completed"
12166 [(set (match_dup 2) (match_dup 1))
12167 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12168 (clobber (reg:CC FLAGS_REG))])]
12170 PUT_MODE (operands[1], QImode);
12171 operands[2] = gen_lowpart (QImode, operands[0]);
12174 (define_insn_and_split "*setcc_si_1_movzbl"
12175 [(set (match_operand:SI 0 "register_operand" "=q")
12176 (match_operator:SI 1 "ix86_comparison_operator"
12177 [(reg FLAGS_REG) (const_int 0)]))]
12178 "!TARGET_PARTIAL_REG_STALL
12179 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12181 "&& reload_completed"
12182 [(set (match_dup 2) (match_dup 1))
12183 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12185 PUT_MODE (operands[1], QImode);
12186 operands[2] = gen_lowpart (QImode, operands[0]);
12189 (define_insn "*setcc_qi"
12190 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12191 (match_operator:QI 1 "ix86_comparison_operator"
12192 [(reg FLAGS_REG) (const_int 0)]))]
12195 [(set_attr "type" "setcc")
12196 (set_attr "mode" "QI")])
12198 (define_insn "*setcc_qi_slp"
12199 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12200 (match_operator:QI 1 "ix86_comparison_operator"
12201 [(reg FLAGS_REG) (const_int 0)]))]
12204 [(set_attr "type" "setcc")
12205 (set_attr "mode" "QI")])
12207 ;; In general it is not safe to assume too much about CCmode registers,
12208 ;; so simplify-rtx stops when it sees a second one. Under certain
12209 ;; conditions this is safe on x86, so help combine not create
12216 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12217 (ne:QI (match_operator 1 "ix86_comparison_operator"
12218 [(reg FLAGS_REG) (const_int 0)])
12221 [(set (match_dup 0) (match_dup 1))]
12223 PUT_MODE (operands[1], QImode);
12227 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12228 (ne:QI (match_operator 1 "ix86_comparison_operator"
12229 [(reg FLAGS_REG) (const_int 0)])
12232 [(set (match_dup 0) (match_dup 1))]
12234 PUT_MODE (operands[1], QImode);
12238 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12239 (eq:QI (match_operator 1 "ix86_comparison_operator"
12240 [(reg FLAGS_REG) (const_int 0)])
12243 [(set (match_dup 0) (match_dup 1))]
12245 rtx new_op1 = copy_rtx (operands[1]);
12246 operands[1] = new_op1;
12247 PUT_MODE (new_op1, QImode);
12248 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12249 GET_MODE (XEXP (new_op1, 0))));
12251 /* Make sure that (a) the CCmode we have for the flags is strong
12252 enough for the reversed compare or (b) we have a valid FP compare. */
12253 if (! ix86_comparison_operator (new_op1, VOIDmode))
12258 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12259 (eq:QI (match_operator 1 "ix86_comparison_operator"
12260 [(reg FLAGS_REG) (const_int 0)])
12263 [(set (match_dup 0) (match_dup 1))]
12265 rtx new_op1 = copy_rtx (operands[1]);
12266 operands[1] = new_op1;
12267 PUT_MODE (new_op1, QImode);
12268 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12269 GET_MODE (XEXP (new_op1, 0))));
12271 /* Make sure that (a) the CCmode we have for the flags is strong
12272 enough for the reversed compare or (b) we have a valid FP compare. */
12273 if (! ix86_comparison_operator (new_op1, VOIDmode))
12277 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12278 ;; subsequent logical operations are used to imitate conditional moves.
12279 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12282 (define_insn "*avx_setcc<mode>"
12283 [(set (match_operand:MODEF 0 "register_operand" "=x")
12284 (match_operator:MODEF 1 "avx_comparison_float_operator"
12285 [(match_operand:MODEF 2 "register_operand" "x")
12286 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12288 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
12289 [(set_attr "type" "ssecmp")
12290 (set_attr "prefix" "vex")
12291 (set_attr "length_immediate" "1")
12292 (set_attr "mode" "<MODE>")])
12294 (define_insn "*sse_setcc<mode>"
12295 [(set (match_operand:MODEF 0 "register_operand" "=x")
12296 (match_operator:MODEF 1 "sse_comparison_operator"
12297 [(match_operand:MODEF 2 "register_operand" "0")
12298 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12299 "SSE_FLOAT_MODE_P (<MODE>mode)"
12300 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
12301 [(set_attr "type" "ssecmp")
12302 (set_attr "length_immediate" "1")
12303 (set_attr "mode" "<MODE>")])
12305 ;; Basic conditional jump instructions.
12306 ;; We ignore the overflow flag for signed branch instructions.
12308 (define_insn "*jcc_1"
12310 (if_then_else (match_operator 1 "ix86_comparison_operator"
12311 [(reg FLAGS_REG) (const_int 0)])
12312 (label_ref (match_operand 0 "" ""))
12316 [(set_attr "type" "ibr")
12317 (set_attr "modrm" "0")
12318 (set (attr "length")
12319 (if_then_else (and (ge (minus (match_dup 0) (pc))
12321 (lt (minus (match_dup 0) (pc))
12326 (define_insn "*jcc_2"
12328 (if_then_else (match_operator 1 "ix86_comparison_operator"
12329 [(reg FLAGS_REG) (const_int 0)])
12331 (label_ref (match_operand 0 "" ""))))]
12334 [(set_attr "type" "ibr")
12335 (set_attr "modrm" "0")
12336 (set (attr "length")
12337 (if_then_else (and (ge (minus (match_dup 0) (pc))
12339 (lt (minus (match_dup 0) (pc))
12344 ;; In general it is not safe to assume too much about CCmode registers,
12345 ;; so simplify-rtx stops when it sees a second one. Under certain
12346 ;; conditions this is safe on x86, so help combine not create
12354 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12355 [(reg FLAGS_REG) (const_int 0)])
12357 (label_ref (match_operand 1 "" ""))
12361 (if_then_else (match_dup 0)
12362 (label_ref (match_dup 1))
12365 PUT_MODE (operands[0], VOIDmode);
12370 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12371 [(reg FLAGS_REG) (const_int 0)])
12373 (label_ref (match_operand 1 "" ""))
12377 (if_then_else (match_dup 0)
12378 (label_ref (match_dup 1))
12381 rtx new_op0 = copy_rtx (operands[0]);
12382 operands[0] = new_op0;
12383 PUT_MODE (new_op0, VOIDmode);
12384 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12385 GET_MODE (XEXP (new_op0, 0))));
12387 /* Make sure that (a) the CCmode we have for the flags is strong
12388 enough for the reversed compare or (b) we have a valid FP compare. */
12389 if (! ix86_comparison_operator (new_op0, VOIDmode))
12393 ;; zero_extend in SImode is correct, since this is what combine pass
12394 ;; generates from shift insn with QImode operand. Actually, the mode of
12395 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
12396 ;; appropriate modulo of the bit offset value.
12398 (define_insn_and_split "*jcc_btdi_rex64"
12400 (if_then_else (match_operator 0 "bt_comparison_operator"
12402 (match_operand:DI 1 "register_operand" "r")
12405 (match_operand:QI 2 "register_operand" "r")))
12407 (label_ref (match_operand 3 "" ""))
12409 (clobber (reg:CC FLAGS_REG))]
12410 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
12413 [(set (reg:CCC FLAGS_REG)
12421 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12422 (label_ref (match_dup 3))
12425 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
12427 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12430 ;; avoid useless masking of bit offset operand
12431 (define_insn_and_split "*jcc_btdi_mask_rex64"
12433 (if_then_else (match_operator 0 "bt_comparison_operator"
12435 (match_operand:DI 1 "register_operand" "r")
12438 (match_operand:SI 2 "register_operand" "r")
12439 (match_operand:SI 3 "const_int_operand" "n")))])
12440 (label_ref (match_operand 4 "" ""))
12442 (clobber (reg:CC FLAGS_REG))]
12443 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
12444 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
12447 [(set (reg:CCC FLAGS_REG)
12455 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12456 (label_ref (match_dup 4))
12459 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
12461 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12464 (define_insn_and_split "*jcc_btsi"
12466 (if_then_else (match_operator 0 "bt_comparison_operator"
12468 (match_operand:SI 1 "register_operand" "r")
12471 (match_operand:QI 2 "register_operand" "r")))
12473 (label_ref (match_operand 3 "" ""))
12475 (clobber (reg:CC FLAGS_REG))]
12476 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12479 [(set (reg:CCC FLAGS_REG)
12487 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12488 (label_ref (match_dup 3))
12491 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
12493 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12496 ;; avoid useless masking of bit offset operand
12497 (define_insn_and_split "*jcc_btsi_mask"
12499 (if_then_else (match_operator 0 "bt_comparison_operator"
12501 (match_operand:SI 1 "register_operand" "r")
12504 (match_operand:SI 2 "register_operand" "r")
12505 (match_operand:SI 3 "const_int_operand" "n")))])
12506 (label_ref (match_operand 4 "" ""))
12508 (clobber (reg:CC FLAGS_REG))]
12509 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12510 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
12513 [(set (reg:CCC FLAGS_REG)
12521 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12522 (label_ref (match_dup 4))
12524 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
12526 (define_insn_and_split "*jcc_btsi_1"
12528 (if_then_else (match_operator 0 "bt_comparison_operator"
12531 (match_operand:SI 1 "register_operand" "r")
12532 (match_operand:QI 2 "register_operand" "r"))
12535 (label_ref (match_operand 3 "" ""))
12537 (clobber (reg:CC FLAGS_REG))]
12538 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12541 [(set (reg:CCC FLAGS_REG)
12549 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12550 (label_ref (match_dup 3))
12553 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
12555 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12558 ;; avoid useless masking of bit offset operand
12559 (define_insn_and_split "*jcc_btsi_mask_1"
12562 (match_operator 0 "bt_comparison_operator"
12565 (match_operand:SI 1 "register_operand" "r")
12568 (match_operand:SI 2 "register_operand" "r")
12569 (match_operand:SI 3 "const_int_operand" "n")) 0))
12572 (label_ref (match_operand 4 "" ""))
12574 (clobber (reg:CC FLAGS_REG))]
12575 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12576 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
12579 [(set (reg:CCC FLAGS_REG)
12587 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12588 (label_ref (match_dup 4))
12590 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
12592 ;; Define combination compare-and-branch fp compare instructions to help
12595 (define_insn "*fp_jcc_3_387"
12597 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12598 [(match_operand 1 "register_operand" "f")
12599 (match_operand 2 "nonimmediate_operand" "fm")])
12600 (label_ref (match_operand 3 "" ""))
12602 (clobber (reg:CCFP FPSR_REG))
12603 (clobber (reg:CCFP FLAGS_REG))
12604 (clobber (match_scratch:HI 4 "=a"))]
12606 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12607 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12608 && SELECT_CC_MODE (GET_CODE (operands[0]),
12609 operands[1], operands[2]) == CCFPmode
12613 (define_insn "*fp_jcc_4_387"
12615 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12616 [(match_operand 1 "register_operand" "f")
12617 (match_operand 2 "nonimmediate_operand" "fm")])
12619 (label_ref (match_operand 3 "" ""))))
12620 (clobber (reg:CCFP FPSR_REG))
12621 (clobber (reg:CCFP FLAGS_REG))
12622 (clobber (match_scratch:HI 4 "=a"))]
12624 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12625 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12626 && SELECT_CC_MODE (GET_CODE (operands[0]),
12627 operands[1], operands[2]) == CCFPmode
12631 (define_insn "*fp_jcc_5_387"
12633 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12634 [(match_operand 1 "register_operand" "f")
12635 (match_operand 2 "register_operand" "f")])
12636 (label_ref (match_operand 3 "" ""))
12638 (clobber (reg:CCFP FPSR_REG))
12639 (clobber (reg:CCFP FLAGS_REG))
12640 (clobber (match_scratch:HI 4 "=a"))]
12641 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
12642 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12646 (define_insn "*fp_jcc_6_387"
12648 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12649 [(match_operand 1 "register_operand" "f")
12650 (match_operand 2 "register_operand" "f")])
12652 (label_ref (match_operand 3 "" ""))))
12653 (clobber (reg:CCFP FPSR_REG))
12654 (clobber (reg:CCFP FLAGS_REG))
12655 (clobber (match_scratch:HI 4 "=a"))]
12656 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
12657 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12661 (define_insn "*fp_jcc_7_387"
12663 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12664 [(match_operand 1 "register_operand" "f")
12665 (match_operand 2 "const0_operand" "")])
12666 (label_ref (match_operand 3 "" ""))
12668 (clobber (reg:CCFP FPSR_REG))
12669 (clobber (reg:CCFP FLAGS_REG))
12670 (clobber (match_scratch:HI 4 "=a"))]
12671 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
12672 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12673 && SELECT_CC_MODE (GET_CODE (operands[0]),
12674 operands[1], operands[2]) == CCFPmode
12678 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
12679 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12680 ;; with a precedence over other operators and is always put in the first
12681 ;; place. Swap condition and operands to match ficom instruction.
12683 (define_insn "*fp_jcc_8<mode>_387"
12685 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12686 [(match_operator 1 "float_operator"
12687 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
12688 (match_operand 3 "register_operand" "f,f")])
12689 (label_ref (match_operand 4 "" ""))
12691 (clobber (reg:CCFP FPSR_REG))
12692 (clobber (reg:CCFP FLAGS_REG))
12693 (clobber (match_scratch:HI 5 "=a,a"))]
12694 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
12695 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
12696 && GET_MODE (operands[1]) == GET_MODE (operands[3])
12697 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12703 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12704 [(match_operand 1 "register_operand" "")
12705 (match_operand 2 "nonimmediate_operand" "")])
12706 (match_operand 3 "" "")
12707 (match_operand 4 "" "")))
12708 (clobber (reg:CCFP FPSR_REG))
12709 (clobber (reg:CCFP FLAGS_REG))]
12713 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12714 operands[3], operands[4], NULL_RTX, NULL_RTX);
12720 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12721 [(match_operand 1 "register_operand" "")
12722 (match_operand 2 "general_operand" "")])
12723 (match_operand 3 "" "")
12724 (match_operand 4 "" "")))
12725 (clobber (reg:CCFP FPSR_REG))
12726 (clobber (reg:CCFP FLAGS_REG))
12727 (clobber (match_scratch:HI 5 "=a"))]
12731 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12732 operands[3], operands[4], operands[5], NULL_RTX);
12738 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12739 [(match_operator 1 "float_operator"
12740 [(match_operand:X87MODEI12 2 "memory_operand" "")])
12741 (match_operand 3 "register_operand" "")])
12742 (match_operand 4 "" "")
12743 (match_operand 5 "" "")))
12744 (clobber (reg:CCFP FPSR_REG))
12745 (clobber (reg:CCFP FLAGS_REG))
12746 (clobber (match_scratch:HI 6 "=a"))]
12750 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
12751 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12752 operands[3], operands[7],
12753 operands[4], operands[5], operands[6], NULL_RTX);
12757 ;; %%% Kill this when reload knows how to do it.
12760 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12761 [(match_operator 1 "float_operator"
12762 [(match_operand:X87MODEI12 2 "register_operand" "")])
12763 (match_operand 3 "register_operand" "")])
12764 (match_operand 4 "" "")
12765 (match_operand 5 "" "")))
12766 (clobber (reg:CCFP FPSR_REG))
12767 (clobber (reg:CCFP FLAGS_REG))
12768 (clobber (match_scratch:HI 6 "=a"))]
12772 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12773 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
12774 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12775 operands[3], operands[7],
12776 operands[4], operands[5], operands[6], operands[2]);
12780 ;; Unconditional and other jump instructions
12782 (define_insn "jump"
12784 (label_ref (match_operand 0 "" "")))]
12787 [(set_attr "type" "ibr")
12788 (set (attr "length")
12789 (if_then_else (and (ge (minus (match_dup 0) (pc))
12791 (lt (minus (match_dup 0) (pc))
12795 (set_attr "modrm" "0")])
12797 (define_expand "indirect_jump"
12798 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
12802 (define_insn "*indirect_jump"
12803 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
12806 [(set_attr "type" "ibr")
12807 (set_attr "length_immediate" "0")])
12809 (define_expand "tablejump"
12810 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
12811 (use (label_ref (match_operand 1 "" "")))])]
12814 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12815 relative. Convert the relative address to an absolute address. */
12819 enum rtx_code code;
12821 /* We can't use @GOTOFF for text labels on VxWorks;
12822 see gotoff_operand. */
12823 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12827 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12829 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12833 op1 = pic_offset_table_rtx;
12838 op0 = pic_offset_table_rtx;
12842 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12847 (define_insn "*tablejump_1"
12848 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
12849 (use (label_ref (match_operand 1 "" "")))]
12852 [(set_attr "type" "ibr")
12853 (set_attr "length_immediate" "0")])
12855 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12858 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
12859 (set (match_operand:QI 1 "register_operand" "")
12860 (match_operator:QI 2 "ix86_comparison_operator"
12861 [(reg FLAGS_REG) (const_int 0)]))
12862 (set (match_operand 3 "q_regs_operand" "")
12863 (zero_extend (match_dup 1)))]
12864 "(peep2_reg_dead_p (3, operands[1])
12865 || operands_match_p (operands[1], operands[3]))
12866 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
12867 [(set (match_dup 4) (match_dup 0))
12868 (set (strict_low_part (match_dup 5))
12871 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12872 operands[5] = gen_lowpart (QImode, operands[3]);
12873 ix86_expand_clear (operands[3]);
12876 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
12879 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
12880 (set (match_operand:QI 1 "register_operand" "")
12881 (match_operator:QI 2 "ix86_comparison_operator"
12882 [(reg FLAGS_REG) (const_int 0)]))
12883 (parallel [(set (match_operand 3 "q_regs_operand" "")
12884 (zero_extend (match_dup 1)))
12885 (clobber (reg:CC FLAGS_REG))])]
12886 "(peep2_reg_dead_p (3, operands[1])
12887 || operands_match_p (operands[1], operands[3]))
12888 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
12889 [(set (match_dup 4) (match_dup 0))
12890 (set (strict_low_part (match_dup 5))
12893 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12894 operands[5] = gen_lowpart (QImode, operands[3]);
12895 ix86_expand_clear (operands[3]);
12898 ;; Call instructions.
12900 ;; The predicates normally associated with named expanders are not properly
12901 ;; checked for calls. This is a bug in the generic code, but it isn't that
12902 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12904 ;; P6 processors will jump to the address after the decrement when %esp
12905 ;; is used as a call operand, so they will execute return address as a code.
12906 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12908 ;; Call subroutine returning no value.
12910 (define_expand "call_pop"
12911 [(parallel [(call (match_operand:QI 0 "" "")
12912 (match_operand:SI 1 "" ""))
12913 (set (reg:SI SP_REG)
12914 (plus:SI (reg:SI SP_REG)
12915 (match_operand:SI 3 "" "")))])]
12918 ix86_expand_call (NULL, operands[0], operands[1],
12919 operands[2], operands[3], 0);
12923 (define_insn "*call_pop_0"
12924 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
12925 (match_operand:SI 1 "" ""))
12926 (set (reg:SI SP_REG)
12927 (plus:SI (reg:SI SP_REG)
12928 (match_operand:SI 2 "immediate_operand" "")))]
12931 if (SIBLING_CALL_P (insn))
12934 return "call\t%P0";
12936 [(set_attr "type" "call")])
12938 (define_insn "*call_pop_1"
12939 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
12940 (match_operand:SI 1 "" ""))
12941 (set (reg:SI SP_REG)
12942 (plus:SI (reg:SI SP_REG)
12943 (match_operand:SI 2 "immediate_operand" "i")))]
12944 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12946 if (constant_call_address_operand (operands[0], Pmode))
12947 return "call\t%P0";
12948 return "call\t%A0";
12950 [(set_attr "type" "call")])
12952 (define_insn "*sibcall_pop_1"
12953 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
12954 (match_operand:SI 1 "" ""))
12955 (set (reg:SI SP_REG)
12956 (plus:SI (reg:SI SP_REG)
12957 (match_operand:SI 2 "immediate_operand" "i,i")))]
12958 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12962 [(set_attr "type" "call")])
12964 (define_expand "call"
12965 [(call (match_operand:QI 0 "" "")
12966 (match_operand 1 "" ""))
12967 (use (match_operand 2 "" ""))]
12970 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
12974 (define_expand "sibcall"
12975 [(call (match_operand:QI 0 "" "")
12976 (match_operand 1 "" ""))
12977 (use (match_operand 2 "" ""))]
12980 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
12984 (define_insn "*call_0"
12985 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
12986 (match_operand 1 "" ""))]
12989 if (SIBLING_CALL_P (insn))
12992 return "call\t%P0";
12994 [(set_attr "type" "call")])
12996 (define_insn "*call_1"
12997 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
12998 (match_operand 1 "" ""))]
12999 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13001 if (constant_call_address_operand (operands[0], Pmode))
13002 return "call\t%P0";
13003 return "call\t%A0";
13005 [(set_attr "type" "call")])
13007 (define_insn "*sibcall_1"
13008 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13009 (match_operand 1 "" ""))]
13010 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13014 [(set_attr "type" "call")])
13016 (define_insn "*call_1_rex64"
13017 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13018 (match_operand 1 "" ""))]
13019 "TARGET_64BIT && !SIBLING_CALL_P (insn)
13020 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
13022 if (constant_call_address_operand (operands[0], Pmode))
13023 return "call\t%P0";
13024 return "call\t%A0";
13026 [(set_attr "type" "call")])
13028 (define_insn "*call_1_rex64_ms_sysv"
13029 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13030 (match_operand 1 "" ""))
13031 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
13032 (clobber (reg:TI XMM6_REG))
13033 (clobber (reg:TI XMM7_REG))
13034 (clobber (reg:TI XMM8_REG))
13035 (clobber (reg:TI XMM9_REG))
13036 (clobber (reg:TI XMM10_REG))
13037 (clobber (reg:TI XMM11_REG))
13038 (clobber (reg:TI XMM12_REG))
13039 (clobber (reg:TI XMM13_REG))
13040 (clobber (reg:TI XMM14_REG))
13041 (clobber (reg:TI XMM15_REG))
13042 (clobber (reg:DI SI_REG))
13043 (clobber (reg:DI DI_REG))]
13044 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13046 if (constant_call_address_operand (operands[0], Pmode))
13047 return "call\t%P0";
13048 return "call\t%A0";
13050 [(set_attr "type" "call")])
13052 (define_insn "*call_1_rex64_large"
13053 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
13054 (match_operand 1 "" ""))]
13055 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13057 [(set_attr "type" "call")])
13059 (define_insn "*sibcall_1_rex64"
13060 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
13061 (match_operand 1 "" ""))]
13062 "TARGET_64BIT && SIBLING_CALL_P (insn)"
13066 [(set_attr "type" "call")])
13068 ;; Call subroutine, returning value in operand 0
13069 (define_expand "call_value_pop"
13070 [(parallel [(set (match_operand 0 "" "")
13071 (call (match_operand:QI 1 "" "")
13072 (match_operand:SI 2 "" "")))
13073 (set (reg:SI SP_REG)
13074 (plus:SI (reg:SI SP_REG)
13075 (match_operand:SI 4 "" "")))])]
13078 ix86_expand_call (operands[0], operands[1], operands[2],
13079 operands[3], operands[4], 0);
13083 (define_expand "call_value"
13084 [(set (match_operand 0 "" "")
13085 (call (match_operand:QI 1 "" "")
13086 (match_operand:SI 2 "" "")))
13087 (use (match_operand:SI 3 "" ""))]
13088 ;; Operand 3 is not used on the i386.
13091 ix86_expand_call (operands[0], operands[1], operands[2],
13092 operands[3], NULL, 0);
13096 (define_expand "sibcall_value"
13097 [(set (match_operand 0 "" "")
13098 (call (match_operand:QI 1 "" "")
13099 (match_operand:SI 2 "" "")))
13100 (use (match_operand:SI 3 "" ""))]
13101 ;; Operand 3 is not used on the i386.
13104 ix86_expand_call (operands[0], operands[1], operands[2],
13105 operands[3], NULL, 1);
13109 ;; Call subroutine returning any type.
13111 (define_expand "untyped_call"
13112 [(parallel [(call (match_operand 0 "" "")
13114 (match_operand 1 "" "")
13115 (match_operand 2 "" "")])]
13120 /* In order to give reg-stack an easier job in validating two
13121 coprocessor registers as containing a possible return value,
13122 simply pretend the untyped call returns a complex long double
13125 We can't use SSE_REGPARM_MAX here since callee is unprototyped
13126 and should have the default ABI. */
13128 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13129 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13130 operands[0], const0_rtx,
13131 GEN_INT ((TARGET_64BIT
13132 ? (ix86_abi == SYSV_ABI
13133 ? X86_64_SSE_REGPARM_MAX
13134 : X86_64_MS_SSE_REGPARM_MAX)
13135 : X86_32_SSE_REGPARM_MAX)
13139 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13141 rtx set = XVECEXP (operands[2], 0, i);
13142 emit_move_insn (SET_DEST (set), SET_SRC (set));
13145 /* The optimizer does not know that the call sets the function value
13146 registers we stored in the result block. We avoid problems by
13147 claiming that all hard registers are used and clobbered at this
13149 emit_insn (gen_blockage ());
13154 ;; Prologue and epilogue instructions
13156 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13157 ;; all of memory. This blocks insns from being moved across this point.
13159 (define_insn "blockage"
13160 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13163 [(set_attr "length" "0")])
13165 ;; Do not schedule instructions accessing memory across this point.
13167 (define_expand "memory_blockage"
13168 [(set (match_dup 0)
13169 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13172 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13173 MEM_VOLATILE_P (operands[0]) = 1;
13176 (define_insn "*memory_blockage"
13177 [(set (match_operand:BLK 0 "" "")
13178 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13181 [(set_attr "length" "0")])
13183 ;; As USE insns aren't meaningful after reload, this is used instead
13184 ;; to prevent deleting instructions setting registers for PIC code
13185 (define_insn "prologue_use"
13186 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
13189 [(set_attr "length" "0")])
13191 ;; Insn emitted into the body of a function to return from a function.
13192 ;; This is only done if the function's epilogue is known to be simple.
13193 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13195 (define_expand "return"
13197 "ix86_can_use_return_insn_p ()"
13199 if (crtl->args.pops_args)
13201 rtx popc = GEN_INT (crtl->args.pops_args);
13202 emit_jump_insn (gen_return_pop_internal (popc));
13207 (define_insn "return_internal"
13211 [(set_attr "length" "1")
13212 (set_attr "atom_unit" "jeu")
13213 (set_attr "length_immediate" "0")
13214 (set_attr "modrm" "0")])
13216 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13217 ;; instruction Athlon and K8 have.
13219 (define_insn "return_internal_long"
13221 (unspec [(const_int 0)] UNSPEC_REP)]
13224 [(set_attr "length" "2")
13225 (set_attr "atom_unit" "jeu")
13226 (set_attr "length_immediate" "0")
13227 (set_attr "prefix_rep" "1")
13228 (set_attr "modrm" "0")])
13230 (define_insn "return_pop_internal"
13232 (use (match_operand:SI 0 "const_int_operand" ""))]
13235 [(set_attr "length" "3")
13236 (set_attr "atom_unit" "jeu")
13237 (set_attr "length_immediate" "2")
13238 (set_attr "modrm" "0")])
13240 (define_insn "return_indirect_internal"
13242 (use (match_operand:SI 0 "register_operand" "r"))]
13245 [(set_attr "type" "ibr")
13246 (set_attr "length_immediate" "0")])
13252 [(set_attr "length" "1")
13253 (set_attr "length_immediate" "0")
13254 (set_attr "modrm" "0")])
13256 (define_insn "vswapmov"
13257 [(set (match_operand:SI 0 "register_operand" "=r")
13258 (match_operand:SI 1 "register_operand" "r"))
13259 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
13261 "movl.s\t{%1, %0|%0, %1}"
13262 [(set_attr "length" "2")
13263 (set_attr "length_immediate" "0")
13264 (set_attr "modrm" "0")])
13266 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13267 ;; branch prediction penalty for the third jump in a 16-byte
13271 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13274 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13275 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13277 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13278 The align insn is used to avoid 3 jump instructions in the row to improve
13279 branch prediction and the benefits hardly outweigh the cost of extra 8
13280 nops on the average inserted by full alignment pseudo operation. */
13284 [(set_attr "length" "16")])
13286 (define_expand "prologue"
13289 "ix86_expand_prologue (); DONE;")
13291 (define_insn "set_got"
13292 [(set (match_operand:SI 0 "register_operand" "=r")
13293 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13294 (clobber (reg:CC FLAGS_REG))]
13296 { return output_set_got (operands[0], NULL_RTX); }
13297 [(set_attr "type" "multi")
13298 (set_attr "length" "12")])
13300 (define_insn "set_got_labelled"
13301 [(set (match_operand:SI 0 "register_operand" "=r")
13302 (unspec:SI [(label_ref (match_operand 1 "" ""))]
13304 (clobber (reg:CC FLAGS_REG))]
13306 { return output_set_got (operands[0], operands[1]); }
13307 [(set_attr "type" "multi")
13308 (set_attr "length" "12")])
13310 (define_insn "set_got_rex64"
13311 [(set (match_operand:DI 0 "register_operand" "=r")
13312 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13314 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13315 [(set_attr "type" "lea")
13316 (set_attr "length_address" "4")
13317 (set_attr "mode" "DI")])
13319 (define_insn "set_rip_rex64"
13320 [(set (match_operand:DI 0 "register_operand" "=r")
13321 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
13323 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13324 [(set_attr "type" "lea")
13325 (set_attr "length_address" "4")
13326 (set_attr "mode" "DI")])
13328 (define_insn "set_got_offset_rex64"
13329 [(set (match_operand:DI 0 "register_operand" "=r")
13331 [(label_ref (match_operand 1 "" ""))]
13332 UNSPEC_SET_GOT_OFFSET))]
13334 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13335 [(set_attr "type" "imov")
13336 (set_attr "length_immediate" "0")
13337 (set_attr "length_address" "8")
13338 (set_attr "mode" "DI")])
13340 (define_expand "epilogue"
13343 "ix86_expand_epilogue (1); DONE;")
13345 (define_expand "sibcall_epilogue"
13348 "ix86_expand_epilogue (0); DONE;")
13350 (define_expand "eh_return"
13351 [(use (match_operand 0 "register_operand" ""))]
13354 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13356 /* Tricky bit: we write the address of the handler to which we will
13357 be returning into someone else's stack frame, one word below the
13358 stack address we wish to restore. */
13359 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13360 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13361 tmp = gen_rtx_MEM (Pmode, tmp);
13362 emit_move_insn (tmp, ra);
13364 emit_jump_insn (gen_eh_return_internal ());
13369 (define_insn_and_split "eh_return_internal"
13373 "epilogue_completed"
13375 "ix86_expand_epilogue (2); DONE;")
13377 (define_insn "leave"
13378 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13379 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13380 (clobber (mem:BLK (scratch)))]
13383 [(set_attr "type" "leave")])
13385 (define_insn "leave_rex64"
13386 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13387 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13388 (clobber (mem:BLK (scratch)))]
13391 [(set_attr "type" "leave")])
13393 (define_expand "ffssi2"
13395 [(set (match_operand:SI 0 "register_operand" "")
13396 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13397 (clobber (match_scratch:SI 2 ""))
13398 (clobber (reg:CC FLAGS_REG))])]
13403 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
13408 (define_expand "ffs_cmove"
13409 [(set (match_dup 2) (const_int -1))
13410 (parallel [(set (reg:CCZ FLAGS_REG)
13411 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
13413 (set (match_operand:SI 0 "register_operand" "")
13414 (ctz:SI (match_dup 1)))])
13415 (set (match_dup 0) (if_then_else:SI
13416 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13419 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13420 (clobber (reg:CC FLAGS_REG))])]
13422 "operands[2] = gen_reg_rtx (SImode);")
13424 (define_insn_and_split "*ffs_no_cmove"
13425 [(set (match_operand:SI 0 "register_operand" "=r")
13426 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13427 (clobber (match_scratch:SI 2 "=&q"))
13428 (clobber (reg:CC FLAGS_REG))]
13431 "&& reload_completed"
13432 [(parallel [(set (reg:CCZ FLAGS_REG)
13433 (compare:CCZ (match_dup 1) (const_int 0)))
13434 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13435 (set (strict_low_part (match_dup 3))
13436 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13437 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13438 (clobber (reg:CC FLAGS_REG))])
13439 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13440 (clobber (reg:CC FLAGS_REG))])
13441 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13442 (clobber (reg:CC FLAGS_REG))])]
13444 operands[3] = gen_lowpart (QImode, operands[2]);
13445 ix86_expand_clear (operands[2]);
13448 (define_insn "*ffssi_1"
13449 [(set (reg:CCZ FLAGS_REG)
13450 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13452 (set (match_operand:SI 0 "register_operand" "=r")
13453 (ctz:SI (match_dup 1)))]
13455 "bsf{l}\t{%1, %0|%0, %1}"
13456 [(set_attr "type" "alu1")
13457 (set_attr "prefix_0f" "1")
13458 (set_attr "mode" "SI")])
13460 (define_expand "ffsdi2"
13461 [(set (match_dup 2) (const_int -1))
13462 (parallel [(set (reg:CCZ FLAGS_REG)
13463 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
13465 (set (match_operand:DI 0 "register_operand" "")
13466 (ctz:DI (match_dup 1)))])
13467 (set (match_dup 0) (if_then_else:DI
13468 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13471 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13472 (clobber (reg:CC FLAGS_REG))])]
13474 "operands[2] = gen_reg_rtx (DImode);")
13476 (define_insn "*ffsdi_1"
13477 [(set (reg:CCZ FLAGS_REG)
13478 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13480 (set (match_operand:DI 0 "register_operand" "=r")
13481 (ctz:DI (match_dup 1)))]
13483 "bsf{q}\t{%1, %0|%0, %1}"
13484 [(set_attr "type" "alu1")
13485 (set_attr "prefix_0f" "1")
13486 (set_attr "mode" "DI")])
13488 (define_insn "ctzsi2"
13489 [(set (match_operand:SI 0 "register_operand" "=r")
13490 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13491 (clobber (reg:CC FLAGS_REG))]
13493 "bsf{l}\t{%1, %0|%0, %1}"
13494 [(set_attr "type" "alu1")
13495 (set_attr "prefix_0f" "1")
13496 (set_attr "mode" "SI")])
13498 (define_insn "ctzdi2"
13499 [(set (match_operand:DI 0 "register_operand" "=r")
13500 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13501 (clobber (reg:CC FLAGS_REG))]
13503 "bsf{q}\t{%1, %0|%0, %1}"
13504 [(set_attr "type" "alu1")
13505 (set_attr "prefix_0f" "1")
13506 (set_attr "mode" "DI")])
13508 (define_expand "clzsi2"
13510 [(set (match_operand:SI 0 "register_operand" "")
13511 (minus:SI (const_int 31)
13512 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13513 (clobber (reg:CC FLAGS_REG))])
13515 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13516 (clobber (reg:CC FLAGS_REG))])]
13521 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
13526 (define_insn "clzsi2_abm"
13527 [(set (match_operand:SI 0 "register_operand" "=r")
13528 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13529 (clobber (reg:CC FLAGS_REG))]
13531 "lzcnt{l}\t{%1, %0|%0, %1}"
13532 [(set_attr "prefix_rep" "1")
13533 (set_attr "type" "bitmanip")
13534 (set_attr "mode" "SI")])
13537 [(set (match_operand:SI 0 "register_operand" "=r")
13538 (minus:SI (const_int 31)
13539 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13540 (clobber (reg:CC FLAGS_REG))]
13542 "bsr{l}\t{%1, %0|%0, %1}"
13543 [(set_attr "type" "alu1")
13544 (set_attr "prefix_0f" "1")
13545 (set_attr "mode" "SI")])
13547 (define_insn "popcount<mode>2"
13548 [(set (match_operand:SWI248 0 "register_operand" "=r")
13550 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13551 (clobber (reg:CC FLAGS_REG))]
13555 return "popcnt\t{%1, %0|%0, %1}";
13557 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13560 [(set_attr "prefix_rep" "1")
13561 (set_attr "type" "bitmanip")
13562 (set_attr "mode" "<MODE>")])
13564 (define_insn "*popcount<mode>2_cmp"
13565 [(set (reg FLAGS_REG)
13568 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
13570 (set (match_operand:SWI248 0 "register_operand" "=r")
13571 (popcount:SWI248 (match_dup 1)))]
13572 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
13575 return "popcnt\t{%1, %0|%0, %1}";
13577 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13580 [(set_attr "prefix_rep" "1")
13581 (set_attr "type" "bitmanip")
13582 (set_attr "mode" "<MODE>")])
13584 (define_insn "*popcountsi2_cmp_zext"
13585 [(set (reg FLAGS_REG)
13587 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
13589 (set (match_operand:DI 0 "register_operand" "=r")
13590 (zero_extend:DI(popcount:SI (match_dup 1))))]
13591 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
13594 return "popcnt\t{%1, %0|%0, %1}";
13596 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13599 [(set_attr "prefix_rep" "1")
13600 (set_attr "type" "bitmanip")
13601 (set_attr "mode" "SI")])
13603 (define_expand "bswapsi2"
13604 [(set (match_operand:SI 0 "register_operand" "")
13605 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
13608 if (!(TARGET_BSWAP || TARGET_MOVBE))
13610 rtx x = operands[0];
13612 emit_move_insn (x, operands[1]);
13613 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13614 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13615 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13620 (define_insn "*bswapsi_movbe"
13621 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
13622 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
13623 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13626 movbe\t{%1, %0|%0, %1}
13627 movbe\t{%1, %0|%0, %1}"
13628 [(set_attr "type" "*,imov,imov")
13629 (set_attr "modrm" "*,1,1")
13630 (set_attr "prefix_0f" "1")
13631 (set_attr "prefix_extra" "*,1,1")
13632 (set_attr "length" "2,*,*")
13633 (set_attr "mode" "SI")])
13635 (define_insn "*bswapsi_1"
13636 [(set (match_operand:SI 0 "register_operand" "=r")
13637 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
13640 [(set_attr "prefix_0f" "1")
13641 (set_attr "length" "2")])
13643 (define_insn "*bswaphi_lowpart_1"
13644 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13645 (bswap:HI (match_dup 0)))
13646 (clobber (reg:CC FLAGS_REG))]
13647 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13649 xchg{b}\t{%h0, %b0|%b0, %h0}
13650 rol{w}\t{$8, %0|%0, 8}"
13651 [(set_attr "length" "2,4")
13652 (set_attr "mode" "QI,HI")])
13654 (define_insn "bswaphi_lowpart"
13655 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13656 (bswap:HI (match_dup 0)))
13657 (clobber (reg:CC FLAGS_REG))]
13659 "rol{w}\t{$8, %0|%0, 8}"
13660 [(set_attr "length" "4")
13661 (set_attr "mode" "HI")])
13663 (define_expand "bswapdi2"
13664 [(set (match_operand:DI 0 "register_operand" "")
13665 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
13669 (define_insn "*bswapdi_movbe"
13670 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
13671 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
13672 "TARGET_64BIT && TARGET_MOVBE
13673 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13676 movbe\t{%1, %0|%0, %1}
13677 movbe\t{%1, %0|%0, %1}"
13678 [(set_attr "type" "*,imov,imov")
13679 (set_attr "modrm" "*,1,1")
13680 (set_attr "prefix_0f" "1")
13681 (set_attr "prefix_extra" "*,1,1")
13682 (set_attr "length" "3,*,*")
13683 (set_attr "mode" "DI")])
13685 (define_insn "*bswapdi_1"
13686 [(set (match_operand:DI 0 "register_operand" "=r")
13687 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
13690 [(set_attr "prefix_0f" "1")
13691 (set_attr "length" "3")])
13693 (define_expand "clzdi2"
13695 [(set (match_operand:DI 0 "register_operand" "")
13696 (minus:DI (const_int 63)
13697 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13698 (clobber (reg:CC FLAGS_REG))])
13700 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13701 (clobber (reg:CC FLAGS_REG))])]
13706 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
13711 (define_insn "clzdi2_abm"
13712 [(set (match_operand:DI 0 "register_operand" "=r")
13713 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13714 (clobber (reg:CC FLAGS_REG))]
13715 "TARGET_64BIT && TARGET_ABM"
13716 "lzcnt{q}\t{%1, %0|%0, %1}"
13717 [(set_attr "prefix_rep" "1")
13718 (set_attr "type" "bitmanip")
13719 (set_attr "mode" "DI")])
13721 (define_insn "bsr_rex64"
13722 [(set (match_operand:DI 0 "register_operand" "=r")
13723 (minus:DI (const_int 63)
13724 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13725 (clobber (reg:CC FLAGS_REG))]
13727 "bsr{q}\t{%1, %0|%0, %1}"
13728 [(set_attr "type" "alu1")
13729 (set_attr "prefix_0f" "1")
13730 (set_attr "mode" "DI")])
13732 (define_expand "clzhi2"
13734 [(set (match_operand:HI 0 "register_operand" "")
13735 (minus:HI (const_int 15)
13736 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
13737 (clobber (reg:CC FLAGS_REG))])
13739 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
13740 (clobber (reg:CC FLAGS_REG))])]
13745 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
13750 (define_insn "clzhi2_abm"
13751 [(set (match_operand:HI 0 "register_operand" "=r")
13752 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
13753 (clobber (reg:CC FLAGS_REG))]
13755 "lzcnt{w}\t{%1, %0|%0, %1}"
13756 [(set_attr "prefix_rep" "1")
13757 (set_attr "type" "bitmanip")
13758 (set_attr "mode" "HI")])
13760 (define_insn "*bsrhi"
13761 [(set (match_operand:HI 0 "register_operand" "=r")
13762 (minus:HI (const_int 15)
13763 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13764 (clobber (reg:CC FLAGS_REG))]
13766 "bsr{w}\t{%1, %0|%0, %1}"
13767 [(set_attr "type" "alu1")
13768 (set_attr "prefix_0f" "1")
13769 (set_attr "mode" "HI")])
13771 (define_expand "paritydi2"
13772 [(set (match_operand:DI 0 "register_operand" "")
13773 (parity:DI (match_operand:DI 1 "register_operand" "")))]
13776 rtx scratch = gen_reg_rtx (QImode);
13779 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13780 NULL_RTX, operands[1]));
13782 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13783 gen_rtx_REG (CCmode, FLAGS_REG),
13785 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13788 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13791 rtx tmp = gen_reg_rtx (SImode);
13793 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13794 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13799 (define_insn_and_split "paritydi2_cmp"
13800 [(set (reg:CC FLAGS_REG)
13801 (parity:CC (match_operand:DI 3 "register_operand" "0")))
13802 (clobber (match_scratch:DI 0 "=r"))
13803 (clobber (match_scratch:SI 1 "=&r"))
13804 (clobber (match_scratch:HI 2 "=Q"))]
13807 "&& reload_completed"
13809 [(set (match_dup 1)
13810 (xor:SI (match_dup 1) (match_dup 4)))
13811 (clobber (reg:CC FLAGS_REG))])
13813 [(set (reg:CC FLAGS_REG)
13814 (parity:CC (match_dup 1)))
13815 (clobber (match_dup 1))
13816 (clobber (match_dup 2))])]
13818 operands[4] = gen_lowpart (SImode, operands[3]);
13822 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13823 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13826 operands[1] = gen_highpart (SImode, operands[3]);
13829 (define_expand "paritysi2"
13830 [(set (match_operand:SI 0 "register_operand" "")
13831 (parity:SI (match_operand:SI 1 "register_operand" "")))]
13834 rtx scratch = gen_reg_rtx (QImode);
13837 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13839 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13840 gen_rtx_REG (CCmode, FLAGS_REG),
13842 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13844 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13848 (define_insn_and_split "paritysi2_cmp"
13849 [(set (reg:CC FLAGS_REG)
13850 (parity:CC (match_operand:SI 2 "register_operand" "0")))
13851 (clobber (match_scratch:SI 0 "=r"))
13852 (clobber (match_scratch:HI 1 "=&Q"))]
13855 "&& reload_completed"
13857 [(set (match_dup 1)
13858 (xor:HI (match_dup 1) (match_dup 3)))
13859 (clobber (reg:CC FLAGS_REG))])
13861 [(set (reg:CC FLAGS_REG)
13862 (parity:CC (match_dup 1)))
13863 (clobber (match_dup 1))])]
13865 operands[3] = gen_lowpart (HImode, operands[2]);
13867 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13868 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13871 (define_insn "*parityhi2_cmp"
13872 [(set (reg:CC FLAGS_REG)
13873 (parity:CC (match_operand:HI 1 "register_operand" "0")))
13874 (clobber (match_scratch:HI 0 "=Q"))]
13876 "xor{b}\t{%h0, %b0|%b0, %h0}"
13877 [(set_attr "length" "2")
13878 (set_attr "mode" "HI")])
13880 (define_insn "*parityqi2_cmp"
13881 [(set (reg:CC FLAGS_REG)
13882 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
13885 [(set_attr "length" "2")
13886 (set_attr "mode" "QI")])
13888 ;; Thread-local storage patterns for ELF.
13890 ;; Note that these code sequences must appear exactly as shown
13891 ;; in order to allow linker relaxation.
13893 (define_insn "*tls_global_dynamic_32_gnu"
13894 [(set (match_operand:SI 0 "register_operand" "=a")
13895 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13896 (match_operand:SI 2 "tls_symbolic_operand" "")
13897 (match_operand:SI 3 "call_insn_operand" "")]
13899 (clobber (match_scratch:SI 4 "=d"))
13900 (clobber (match_scratch:SI 5 "=c"))
13901 (clobber (reg:CC FLAGS_REG))]
13902 "!TARGET_64BIT && TARGET_GNU_TLS"
13903 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
13904 [(set_attr "type" "multi")
13905 (set_attr "length" "12")])
13907 (define_expand "tls_global_dynamic_32"
13908 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13911 (match_operand:SI 1 "tls_symbolic_operand" "")
13914 (clobber (match_scratch:SI 4 ""))
13915 (clobber (match_scratch:SI 5 ""))
13916 (clobber (reg:CC FLAGS_REG))])]
13920 operands[2] = pic_offset_table_rtx;
13923 operands[2] = gen_reg_rtx (Pmode);
13924 emit_insn (gen_set_got (operands[2]));
13926 if (TARGET_GNU2_TLS)
13928 emit_insn (gen_tls_dynamic_gnu2_32
13929 (operands[0], operands[1], operands[2]));
13932 operands[3] = ix86_tls_get_addr ();
13935 (define_insn "*tls_global_dynamic_64"
13936 [(set (match_operand:DI 0 "register_operand" "=a")
13937 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13938 (match_operand:DI 3 "" "")))
13939 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13942 { 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"; }
13943 [(set_attr "type" "multi")
13944 (set_attr "length" "16")])
13946 (define_expand "tls_global_dynamic_64"
13947 [(parallel [(set (match_operand:DI 0 "register_operand" "")
13948 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
13949 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13953 if (TARGET_GNU2_TLS)
13955 emit_insn (gen_tls_dynamic_gnu2_64
13956 (operands[0], operands[1]));
13959 operands[2] = ix86_tls_get_addr ();
13962 (define_insn "*tls_local_dynamic_base_32_gnu"
13963 [(set (match_operand:SI 0 "register_operand" "=a")
13964 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13965 (match_operand:SI 2 "call_insn_operand" "")]
13966 UNSPEC_TLS_LD_BASE))
13967 (clobber (match_scratch:SI 3 "=d"))
13968 (clobber (match_scratch:SI 4 "=c"))
13969 (clobber (reg:CC FLAGS_REG))]
13970 "!TARGET_64BIT && TARGET_GNU_TLS"
13971 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
13972 [(set_attr "type" "multi")
13973 (set_attr "length" "11")])
13975 (define_expand "tls_local_dynamic_base_32"
13976 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13977 (unspec:SI [(match_dup 1) (match_dup 2)]
13978 UNSPEC_TLS_LD_BASE))
13979 (clobber (match_scratch:SI 3 ""))
13980 (clobber (match_scratch:SI 4 ""))
13981 (clobber (reg:CC FLAGS_REG))])]
13985 operands[1] = pic_offset_table_rtx;
13988 operands[1] = gen_reg_rtx (Pmode);
13989 emit_insn (gen_set_got (operands[1]));
13991 if (TARGET_GNU2_TLS)
13993 emit_insn (gen_tls_dynamic_gnu2_32
13994 (operands[0], ix86_tls_module_base (), operands[1]));
13997 operands[2] = ix86_tls_get_addr ();
14000 (define_insn "*tls_local_dynamic_base_64"
14001 [(set (match_operand:DI 0 "register_operand" "=a")
14002 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14003 (match_operand:DI 2 "" "")))
14004 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14006 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
14007 [(set_attr "type" "multi")
14008 (set_attr "length" "12")])
14010 (define_expand "tls_local_dynamic_base_64"
14011 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14012 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14013 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14016 if (TARGET_GNU2_TLS)
14018 emit_insn (gen_tls_dynamic_gnu2_64
14019 (operands[0], ix86_tls_module_base ()));
14022 operands[1] = ix86_tls_get_addr ();
14025 ;; Local dynamic of a single variable is a lose. Show combine how
14026 ;; to convert that back to global dynamic.
14028 (define_insn_and_split "*tls_local_dynamic_32_once"
14029 [(set (match_operand:SI 0 "register_operand" "=a")
14030 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14031 (match_operand:SI 2 "call_insn_operand" "")]
14032 UNSPEC_TLS_LD_BASE)
14033 (const:SI (unspec:SI
14034 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14036 (clobber (match_scratch:SI 4 "=d"))
14037 (clobber (match_scratch:SI 5 "=c"))
14038 (clobber (reg:CC FLAGS_REG))]
14042 [(parallel [(set (match_dup 0)
14043 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14045 (clobber (match_dup 4))
14046 (clobber (match_dup 5))
14047 (clobber (reg:CC FLAGS_REG))])]
14050 ;; Load and add the thread base pointer from %gs:0.
14052 (define_insn "*load_tp_si"
14053 [(set (match_operand:SI 0 "register_operand" "=r")
14054 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14056 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14057 [(set_attr "type" "imov")
14058 (set_attr "modrm" "0")
14059 (set_attr "length" "7")
14060 (set_attr "memory" "load")
14061 (set_attr "imm_disp" "false")])
14063 (define_insn "*add_tp_si"
14064 [(set (match_operand:SI 0 "register_operand" "=r")
14065 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14066 (match_operand:SI 1 "register_operand" "0")))
14067 (clobber (reg:CC FLAGS_REG))]
14069 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14070 [(set_attr "type" "alu")
14071 (set_attr "modrm" "0")
14072 (set_attr "length" "7")
14073 (set_attr "memory" "load")
14074 (set_attr "imm_disp" "false")])
14076 (define_insn "*load_tp_di"
14077 [(set (match_operand:DI 0 "register_operand" "=r")
14078 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14080 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14081 [(set_attr "type" "imov")
14082 (set_attr "modrm" "0")
14083 (set_attr "length" "7")
14084 (set_attr "memory" "load")
14085 (set_attr "imm_disp" "false")])
14087 (define_insn "*add_tp_di"
14088 [(set (match_operand:DI 0 "register_operand" "=r")
14089 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14090 (match_operand:DI 1 "register_operand" "0")))
14091 (clobber (reg:CC FLAGS_REG))]
14093 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14094 [(set_attr "type" "alu")
14095 (set_attr "modrm" "0")
14096 (set_attr "length" "7")
14097 (set_attr "memory" "load")
14098 (set_attr "imm_disp" "false")])
14100 ;; GNU2 TLS patterns can be split.
14102 (define_expand "tls_dynamic_gnu2_32"
14103 [(set (match_dup 3)
14104 (plus:SI (match_operand:SI 2 "register_operand" "")
14106 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14109 [(set (match_operand:SI 0 "register_operand" "")
14110 (unspec:SI [(match_dup 1) (match_dup 3)
14111 (match_dup 2) (reg:SI SP_REG)]
14113 (clobber (reg:CC FLAGS_REG))])]
14114 "!TARGET_64BIT && TARGET_GNU2_TLS"
14116 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14117 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14120 (define_insn "*tls_dynamic_lea_32"
14121 [(set (match_operand:SI 0 "register_operand" "=r")
14122 (plus:SI (match_operand:SI 1 "register_operand" "b")
14124 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14125 UNSPEC_TLSDESC))))]
14126 "!TARGET_64BIT && TARGET_GNU2_TLS"
14127 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14128 [(set_attr "type" "lea")
14129 (set_attr "mode" "SI")
14130 (set_attr "length" "6")
14131 (set_attr "length_address" "4")])
14133 (define_insn "*tls_dynamic_call_32"
14134 [(set (match_operand:SI 0 "register_operand" "=a")
14135 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14136 (match_operand:SI 2 "register_operand" "0")
14137 ;; we have to make sure %ebx still points to the GOT
14138 (match_operand:SI 3 "register_operand" "b")
14141 (clobber (reg:CC FLAGS_REG))]
14142 "!TARGET_64BIT && TARGET_GNU2_TLS"
14143 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14144 [(set_attr "type" "call")
14145 (set_attr "length" "2")
14146 (set_attr "length_address" "0")])
14148 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14149 [(set (match_operand:SI 0 "register_operand" "=&a")
14151 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14152 (match_operand:SI 4 "" "")
14153 (match_operand:SI 2 "register_operand" "b")
14156 (const:SI (unspec:SI
14157 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14159 (clobber (reg:CC FLAGS_REG))]
14160 "!TARGET_64BIT && TARGET_GNU2_TLS"
14163 [(set (match_dup 0) (match_dup 5))]
14165 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14166 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14169 (define_expand "tls_dynamic_gnu2_64"
14170 [(set (match_dup 2)
14171 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14174 [(set (match_operand:DI 0 "register_operand" "")
14175 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14177 (clobber (reg:CC FLAGS_REG))])]
14178 "TARGET_64BIT && TARGET_GNU2_TLS"
14180 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14181 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14184 (define_insn "*tls_dynamic_lea_64"
14185 [(set (match_operand:DI 0 "register_operand" "=r")
14186 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14188 "TARGET_64BIT && TARGET_GNU2_TLS"
14189 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
14190 [(set_attr "type" "lea")
14191 (set_attr "mode" "DI")
14192 (set_attr "length" "7")
14193 (set_attr "length_address" "4")])
14195 (define_insn "*tls_dynamic_call_64"
14196 [(set (match_operand:DI 0 "register_operand" "=a")
14197 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14198 (match_operand:DI 2 "register_operand" "0")
14201 (clobber (reg:CC FLAGS_REG))]
14202 "TARGET_64BIT && TARGET_GNU2_TLS"
14203 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14204 [(set_attr "type" "call")
14205 (set_attr "length" "2")
14206 (set_attr "length_address" "0")])
14208 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14209 [(set (match_operand:DI 0 "register_operand" "=&a")
14211 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14212 (match_operand:DI 3 "" "")
14215 (const:DI (unspec:DI
14216 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14218 (clobber (reg:CC FLAGS_REG))]
14219 "TARGET_64BIT && TARGET_GNU2_TLS"
14222 [(set (match_dup 0) (match_dup 4))]
14224 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14225 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14230 ;; These patterns match the binary 387 instructions for addM3, subM3,
14231 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14232 ;; SFmode. The first is the normal insn, the second the same insn but
14233 ;; with one operand a conversion, and the third the same insn but with
14234 ;; the other operand a conversion. The conversion may be SFmode or
14235 ;; SImode if the target mode DFmode, but only SImode if the target mode
14238 ;; Gcc is slightly more smart about handling normal two address instructions
14239 ;; so use special patterns for add and mull.
14241 (define_insn "*fop_<mode>_comm_mixed_avx"
14242 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14243 (match_operator:MODEF 3 "binary_fp_operator"
14244 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
14245 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14246 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14247 && COMMUTATIVE_ARITH_P (operands[3])
14248 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14249 "* return output_387_binary_op (insn, operands);"
14250 [(set (attr "type")
14251 (if_then_else (eq_attr "alternative" "1")
14252 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14253 (const_string "ssemul")
14254 (const_string "sseadd"))
14255 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14256 (const_string "fmul")
14257 (const_string "fop"))))
14258 (set_attr "prefix" "orig,maybe_vex")
14259 (set_attr "mode" "<MODE>")])
14261 (define_insn "*fop_<mode>_comm_mixed"
14262 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14263 (match_operator:MODEF 3 "binary_fp_operator"
14264 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
14265 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14266 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14267 && COMMUTATIVE_ARITH_P (operands[3])
14268 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14269 "* return output_387_binary_op (insn, operands);"
14270 [(set (attr "type")
14271 (if_then_else (eq_attr "alternative" "1")
14272 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14273 (const_string "ssemul")
14274 (const_string "sseadd"))
14275 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14276 (const_string "fmul")
14277 (const_string "fop"))))
14278 (set_attr "mode" "<MODE>")])
14280 (define_insn "*fop_<mode>_comm_avx"
14281 [(set (match_operand:MODEF 0 "register_operand" "=x")
14282 (match_operator:MODEF 3 "binary_fp_operator"
14283 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
14284 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14285 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14286 && COMMUTATIVE_ARITH_P (operands[3])
14287 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14288 "* return output_387_binary_op (insn, operands);"
14289 [(set (attr "type")
14290 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14291 (const_string "ssemul")
14292 (const_string "sseadd")))
14293 (set_attr "prefix" "vex")
14294 (set_attr "mode" "<MODE>")])
14296 (define_insn "*fop_<mode>_comm_sse"
14297 [(set (match_operand:MODEF 0 "register_operand" "=x")
14298 (match_operator:MODEF 3 "binary_fp_operator"
14299 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14300 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14301 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14302 && COMMUTATIVE_ARITH_P (operands[3])
14303 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14304 "* return output_387_binary_op (insn, operands);"
14305 [(set (attr "type")
14306 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14307 (const_string "ssemul")
14308 (const_string "sseadd")))
14309 (set_attr "mode" "<MODE>")])
14311 (define_insn "*fop_<mode>_comm_i387"
14312 [(set (match_operand:MODEF 0 "register_operand" "=f")
14313 (match_operator:MODEF 3 "binary_fp_operator"
14314 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14315 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
14316 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14317 && COMMUTATIVE_ARITH_P (operands[3])
14318 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14319 "* return output_387_binary_op (insn, operands);"
14320 [(set (attr "type")
14321 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14322 (const_string "fmul")
14323 (const_string "fop")))
14324 (set_attr "mode" "<MODE>")])
14326 (define_insn "*fop_<mode>_1_mixed_avx"
14327 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14328 (match_operator:MODEF 3 "binary_fp_operator"
14329 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
14330 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14331 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14332 && !COMMUTATIVE_ARITH_P (operands[3])
14333 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14334 "* return output_387_binary_op (insn, operands);"
14335 [(set (attr "type")
14336 (cond [(and (eq_attr "alternative" "2")
14337 (match_operand:MODEF 3 "mult_operator" ""))
14338 (const_string "ssemul")
14339 (and (eq_attr "alternative" "2")
14340 (match_operand:MODEF 3 "div_operator" ""))
14341 (const_string "ssediv")
14342 (eq_attr "alternative" "2")
14343 (const_string "sseadd")
14344 (match_operand:MODEF 3 "mult_operator" "")
14345 (const_string "fmul")
14346 (match_operand:MODEF 3 "div_operator" "")
14347 (const_string "fdiv")
14349 (const_string "fop")))
14350 (set_attr "prefix" "orig,orig,maybe_vex")
14351 (set_attr "mode" "<MODE>")])
14353 (define_insn "*fop_<mode>_1_mixed"
14354 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14355 (match_operator:MODEF 3 "binary_fp_operator"
14356 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
14357 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14358 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14359 && !COMMUTATIVE_ARITH_P (operands[3])
14360 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14361 "* return output_387_binary_op (insn, operands);"
14362 [(set (attr "type")
14363 (cond [(and (eq_attr "alternative" "2")
14364 (match_operand:MODEF 3 "mult_operator" ""))
14365 (const_string "ssemul")
14366 (and (eq_attr "alternative" "2")
14367 (match_operand:MODEF 3 "div_operator" ""))
14368 (const_string "ssediv")
14369 (eq_attr "alternative" "2")
14370 (const_string "sseadd")
14371 (match_operand:MODEF 3 "mult_operator" "")
14372 (const_string "fmul")
14373 (match_operand:MODEF 3 "div_operator" "")
14374 (const_string "fdiv")
14376 (const_string "fop")))
14377 (set_attr "mode" "<MODE>")])
14379 (define_insn "*rcpsf2_sse"
14380 [(set (match_operand:SF 0 "register_operand" "=x")
14381 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14384 "%vrcpss\t{%1, %d0|%d0, %1}"
14385 [(set_attr "type" "sse")
14386 (set_attr "atom_sse_attr" "rcp")
14387 (set_attr "prefix" "maybe_vex")
14388 (set_attr "mode" "SF")])
14390 (define_insn "*fop_<mode>_1_avx"
14391 [(set (match_operand:MODEF 0 "register_operand" "=x")
14392 (match_operator:MODEF 3 "binary_fp_operator"
14393 [(match_operand:MODEF 1 "register_operand" "x")
14394 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14395 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14396 && !COMMUTATIVE_ARITH_P (operands[3])"
14397 "* return output_387_binary_op (insn, operands);"
14398 [(set (attr "type")
14399 (cond [(match_operand:MODEF 3 "mult_operator" "")
14400 (const_string "ssemul")
14401 (match_operand:MODEF 3 "div_operator" "")
14402 (const_string "ssediv")
14404 (const_string "sseadd")))
14405 (set_attr "prefix" "vex")
14406 (set_attr "mode" "<MODE>")])
14408 (define_insn "*fop_<mode>_1_sse"
14409 [(set (match_operand:MODEF 0 "register_operand" "=x")
14410 (match_operator:MODEF 3 "binary_fp_operator"
14411 [(match_operand:MODEF 1 "register_operand" "0")
14412 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14413 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14414 && !COMMUTATIVE_ARITH_P (operands[3])"
14415 "* return output_387_binary_op (insn, operands);"
14416 [(set (attr "type")
14417 (cond [(match_operand:MODEF 3 "mult_operator" "")
14418 (const_string "ssemul")
14419 (match_operand:MODEF 3 "div_operator" "")
14420 (const_string "ssediv")
14422 (const_string "sseadd")))
14423 (set_attr "mode" "<MODE>")])
14425 ;; This pattern is not fully shadowed by the pattern above.
14426 (define_insn "*fop_<mode>_1_i387"
14427 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
14428 (match_operator:MODEF 3 "binary_fp_operator"
14429 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
14430 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
14431 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14432 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14433 && !COMMUTATIVE_ARITH_P (operands[3])
14434 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14435 "* return output_387_binary_op (insn, operands);"
14436 [(set (attr "type")
14437 (cond [(match_operand:MODEF 3 "mult_operator" "")
14438 (const_string "fmul")
14439 (match_operand:MODEF 3 "div_operator" "")
14440 (const_string "fdiv")
14442 (const_string "fop")))
14443 (set_attr "mode" "<MODE>")])
14445 ;; ??? Add SSE splitters for these!
14446 (define_insn "*fop_<MODEF:mode>_2_i387"
14447 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
14448 (match_operator:MODEF 3 "binary_fp_operator"
14450 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14451 (match_operand:MODEF 2 "register_operand" "0,0")]))]
14452 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
14453 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14454 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14455 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14456 [(set (attr "type")
14457 (cond [(match_operand:MODEF 3 "mult_operator" "")
14458 (const_string "fmul")
14459 (match_operand:MODEF 3 "div_operator" "")
14460 (const_string "fdiv")
14462 (const_string "fop")))
14463 (set_attr "fp_int_src" "true")
14464 (set_attr "mode" "<X87MODEI12:MODE>")])
14466 (define_insn "*fop_<MODEF:mode>_3_i387"
14467 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
14468 (match_operator:MODEF 3 "binary_fp_operator"
14469 [(match_operand:MODEF 1 "register_operand" "0,0")
14471 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14472 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
14473 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14474 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14475 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14476 [(set (attr "type")
14477 (cond [(match_operand:MODEF 3 "mult_operator" "")
14478 (const_string "fmul")
14479 (match_operand:MODEF 3 "div_operator" "")
14480 (const_string "fdiv")
14482 (const_string "fop")))
14483 (set_attr "fp_int_src" "true")
14484 (set_attr "mode" "<MODE>")])
14486 (define_insn "*fop_df_4_i387"
14487 [(set (match_operand:DF 0 "register_operand" "=f,f")
14488 (match_operator:DF 3 "binary_fp_operator"
14490 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14491 (match_operand:DF 2 "register_operand" "0,f")]))]
14492 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14493 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14494 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14495 "* return output_387_binary_op (insn, operands);"
14496 [(set (attr "type")
14497 (cond [(match_operand:DF 3 "mult_operator" "")
14498 (const_string "fmul")
14499 (match_operand:DF 3 "div_operator" "")
14500 (const_string "fdiv")
14502 (const_string "fop")))
14503 (set_attr "mode" "SF")])
14505 (define_insn "*fop_df_5_i387"
14506 [(set (match_operand:DF 0 "register_operand" "=f,f")
14507 (match_operator:DF 3 "binary_fp_operator"
14508 [(match_operand:DF 1 "register_operand" "0,f")
14510 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14511 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14512 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14513 "* return output_387_binary_op (insn, operands);"
14514 [(set (attr "type")
14515 (cond [(match_operand:DF 3 "mult_operator" "")
14516 (const_string "fmul")
14517 (match_operand:DF 3 "div_operator" "")
14518 (const_string "fdiv")
14520 (const_string "fop")))
14521 (set_attr "mode" "SF")])
14523 (define_insn "*fop_df_6_i387"
14524 [(set (match_operand:DF 0 "register_operand" "=f,f")
14525 (match_operator:DF 3 "binary_fp_operator"
14527 (match_operand:SF 1 "register_operand" "0,f"))
14529 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14530 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14531 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14532 "* return output_387_binary_op (insn, operands);"
14533 [(set (attr "type")
14534 (cond [(match_operand:DF 3 "mult_operator" "")
14535 (const_string "fmul")
14536 (match_operand:DF 3 "div_operator" "")
14537 (const_string "fdiv")
14539 (const_string "fop")))
14540 (set_attr "mode" "SF")])
14542 (define_insn "*fop_xf_comm_i387"
14543 [(set (match_operand:XF 0 "register_operand" "=f")
14544 (match_operator:XF 3 "binary_fp_operator"
14545 [(match_operand:XF 1 "register_operand" "%0")
14546 (match_operand:XF 2 "register_operand" "f")]))]
14548 && COMMUTATIVE_ARITH_P (operands[3])"
14549 "* return output_387_binary_op (insn, operands);"
14550 [(set (attr "type")
14551 (if_then_else (match_operand:XF 3 "mult_operator" "")
14552 (const_string "fmul")
14553 (const_string "fop")))
14554 (set_attr "mode" "XF")])
14556 (define_insn "*fop_xf_1_i387"
14557 [(set (match_operand:XF 0 "register_operand" "=f,f")
14558 (match_operator:XF 3 "binary_fp_operator"
14559 [(match_operand:XF 1 "register_operand" "0,f")
14560 (match_operand:XF 2 "register_operand" "f,0")]))]
14562 && !COMMUTATIVE_ARITH_P (operands[3])"
14563 "* return output_387_binary_op (insn, operands);"
14564 [(set (attr "type")
14565 (cond [(match_operand:XF 3 "mult_operator" "")
14566 (const_string "fmul")
14567 (match_operand:XF 3 "div_operator" "")
14568 (const_string "fdiv")
14570 (const_string "fop")))
14571 (set_attr "mode" "XF")])
14573 (define_insn "*fop_xf_2_i387"
14574 [(set (match_operand:XF 0 "register_operand" "=f,f")
14575 (match_operator:XF 3 "binary_fp_operator"
14577 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14578 (match_operand:XF 2 "register_operand" "0,0")]))]
14579 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14580 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14581 [(set (attr "type")
14582 (cond [(match_operand:XF 3 "mult_operator" "")
14583 (const_string "fmul")
14584 (match_operand:XF 3 "div_operator" "")
14585 (const_string "fdiv")
14587 (const_string "fop")))
14588 (set_attr "fp_int_src" "true")
14589 (set_attr "mode" "<MODE>")])
14591 (define_insn "*fop_xf_3_i387"
14592 [(set (match_operand:XF 0 "register_operand" "=f,f")
14593 (match_operator:XF 3 "binary_fp_operator"
14594 [(match_operand:XF 1 "register_operand" "0,0")
14596 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14597 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14598 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14599 [(set (attr "type")
14600 (cond [(match_operand:XF 3 "mult_operator" "")
14601 (const_string "fmul")
14602 (match_operand:XF 3 "div_operator" "")
14603 (const_string "fdiv")
14605 (const_string "fop")))
14606 (set_attr "fp_int_src" "true")
14607 (set_attr "mode" "<MODE>")])
14609 (define_insn "*fop_xf_4_i387"
14610 [(set (match_operand:XF 0 "register_operand" "=f,f")
14611 (match_operator:XF 3 "binary_fp_operator"
14613 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14614 (match_operand:XF 2 "register_operand" "0,f")]))]
14616 "* return output_387_binary_op (insn, operands);"
14617 [(set (attr "type")
14618 (cond [(match_operand:XF 3 "mult_operator" "")
14619 (const_string "fmul")
14620 (match_operand:XF 3 "div_operator" "")
14621 (const_string "fdiv")
14623 (const_string "fop")))
14624 (set_attr "mode" "<MODE>")])
14626 (define_insn "*fop_xf_5_i387"
14627 [(set (match_operand:XF 0 "register_operand" "=f,f")
14628 (match_operator:XF 3 "binary_fp_operator"
14629 [(match_operand:XF 1 "register_operand" "0,f")
14631 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14633 "* return output_387_binary_op (insn, operands);"
14634 [(set (attr "type")
14635 (cond [(match_operand:XF 3 "mult_operator" "")
14636 (const_string "fmul")
14637 (match_operand:XF 3 "div_operator" "")
14638 (const_string "fdiv")
14640 (const_string "fop")))
14641 (set_attr "mode" "<MODE>")])
14643 (define_insn "*fop_xf_6_i387"
14644 [(set (match_operand:XF 0 "register_operand" "=f,f")
14645 (match_operator:XF 3 "binary_fp_operator"
14647 (match_operand:MODEF 1 "register_operand" "0,f"))
14649 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14651 "* return output_387_binary_op (insn, operands);"
14652 [(set (attr "type")
14653 (cond [(match_operand:XF 3 "mult_operator" "")
14654 (const_string "fmul")
14655 (match_operand:XF 3 "div_operator" "")
14656 (const_string "fdiv")
14658 (const_string "fop")))
14659 (set_attr "mode" "<MODE>")])
14662 [(set (match_operand 0 "register_operand" "")
14663 (match_operator 3 "binary_fp_operator"
14664 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14665 (match_operand 2 "register_operand" "")]))]
14667 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
14668 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
14671 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14672 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14673 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14674 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14675 GET_MODE (operands[3]),
14678 ix86_free_from_memory (GET_MODE (operands[1]));
14683 [(set (match_operand 0 "register_operand" "")
14684 (match_operator 3 "binary_fp_operator"
14685 [(match_operand 1 "register_operand" "")
14686 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14688 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
14689 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
14692 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14693 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14694 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14695 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14696 GET_MODE (operands[3]),
14699 ix86_free_from_memory (GET_MODE (operands[2]));
14703 ;; FPU special functions.
14705 ;; This pattern implements a no-op XFmode truncation for
14706 ;; all fancy i386 XFmode math functions.
14708 (define_insn "truncxf<mode>2_i387_noop_unspec"
14709 [(set (match_operand:MODEF 0 "register_operand" "=f")
14710 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14711 UNSPEC_TRUNC_NOOP))]
14712 "TARGET_USE_FANCY_MATH_387"
14713 "* return output_387_reg_move (insn, operands);"
14714 [(set_attr "type" "fmov")
14715 (set_attr "mode" "<MODE>")])
14717 (define_insn "sqrtxf2"
14718 [(set (match_operand:XF 0 "register_operand" "=f")
14719 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14720 "TARGET_USE_FANCY_MATH_387"
14722 [(set_attr "type" "fpspc")
14723 (set_attr "mode" "XF")
14724 (set_attr "athlon_decode" "direct")
14725 (set_attr "amdfam10_decode" "direct")])
14727 (define_insn "sqrt_extend<mode>xf2_i387"
14728 [(set (match_operand:XF 0 "register_operand" "=f")
14731 (match_operand:MODEF 1 "register_operand" "0"))))]
14732 "TARGET_USE_FANCY_MATH_387"
14734 [(set_attr "type" "fpspc")
14735 (set_attr "mode" "XF")
14736 (set_attr "athlon_decode" "direct")
14737 (set_attr "amdfam10_decode" "direct")])
14739 (define_insn "*rsqrtsf2_sse"
14740 [(set (match_operand:SF 0 "register_operand" "=x")
14741 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14744 "%vrsqrtss\t{%1, %d0|%d0, %1}"
14745 [(set_attr "type" "sse")
14746 (set_attr "atom_sse_attr" "rcp")
14747 (set_attr "prefix" "maybe_vex")
14748 (set_attr "mode" "SF")])
14750 (define_expand "rsqrtsf2"
14751 [(set (match_operand:SF 0 "register_operand" "")
14752 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
14756 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14760 (define_insn "*sqrt<mode>2_sse"
14761 [(set (match_operand:MODEF 0 "register_operand" "=x")
14763 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
14764 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14765 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
14766 [(set_attr "type" "sse")
14767 (set_attr "atom_sse_attr" "sqrt")
14768 (set_attr "prefix" "maybe_vex")
14769 (set_attr "mode" "<MODE>")
14770 (set_attr "athlon_decode" "*")
14771 (set_attr "amdfam10_decode" "*")])
14773 (define_expand "sqrt<mode>2"
14774 [(set (match_operand:MODEF 0 "register_operand" "")
14776 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
14777 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14778 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14780 if (<MODE>mode == SFmode
14781 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
14782 && flag_finite_math_only && !flag_trapping_math
14783 && flag_unsafe_math_optimizations)
14785 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14789 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14791 rtx op0 = gen_reg_rtx (XFmode);
14792 rtx op1 = force_reg (<MODE>mode, operands[1]);
14794 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14795 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14800 (define_insn "fpremxf4_i387"
14801 [(set (match_operand:XF 0 "register_operand" "=f")
14802 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14803 (match_operand:XF 3 "register_operand" "1")]
14805 (set (match_operand:XF 1 "register_operand" "=u")
14806 (unspec:XF [(match_dup 2) (match_dup 3)]
14808 (set (reg:CCFP FPSR_REG)
14809 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14811 "TARGET_USE_FANCY_MATH_387"
14813 [(set_attr "type" "fpspc")
14814 (set_attr "mode" "XF")])
14816 (define_expand "fmodxf3"
14817 [(use (match_operand:XF 0 "register_operand" ""))
14818 (use (match_operand:XF 1 "general_operand" ""))
14819 (use (match_operand:XF 2 "general_operand" ""))]
14820 "TARGET_USE_FANCY_MATH_387"
14822 rtx label = gen_label_rtx ();
14824 rtx op1 = gen_reg_rtx (XFmode);
14825 rtx op2 = gen_reg_rtx (XFmode);
14827 emit_move_insn (op2, operands[2]);
14828 emit_move_insn (op1, operands[1]);
14830 emit_label (label);
14831 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14832 ix86_emit_fp_unordered_jump (label);
14833 LABEL_NUSES (label) = 1;
14835 emit_move_insn (operands[0], op1);
14839 (define_expand "fmod<mode>3"
14840 [(use (match_operand:MODEF 0 "register_operand" ""))
14841 (use (match_operand:MODEF 1 "general_operand" ""))
14842 (use (match_operand:MODEF 2 "general_operand" ""))]
14843 "TARGET_USE_FANCY_MATH_387"
14845 rtx label = gen_label_rtx ();
14847 rtx op1 = gen_reg_rtx (XFmode);
14848 rtx op2 = gen_reg_rtx (XFmode);
14850 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14851 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14853 emit_label (label);
14854 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14855 ix86_emit_fp_unordered_jump (label);
14856 LABEL_NUSES (label) = 1;
14858 /* Truncate the result properly for strict SSE math. */
14859 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14860 && !TARGET_MIX_SSE_I387)
14861 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
14863 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
14868 (define_insn "fprem1xf4_i387"
14869 [(set (match_operand:XF 0 "register_operand" "=f")
14870 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14871 (match_operand:XF 3 "register_operand" "1")]
14873 (set (match_operand:XF 1 "register_operand" "=u")
14874 (unspec:XF [(match_dup 2) (match_dup 3)]
14876 (set (reg:CCFP FPSR_REG)
14877 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14879 "TARGET_USE_FANCY_MATH_387"
14881 [(set_attr "type" "fpspc")
14882 (set_attr "mode" "XF")])
14884 (define_expand "remainderxf3"
14885 [(use (match_operand:XF 0 "register_operand" ""))
14886 (use (match_operand:XF 1 "general_operand" ""))
14887 (use (match_operand:XF 2 "general_operand" ""))]
14888 "TARGET_USE_FANCY_MATH_387"
14890 rtx label = gen_label_rtx ();
14892 rtx op1 = gen_reg_rtx (XFmode);
14893 rtx op2 = gen_reg_rtx (XFmode);
14895 emit_move_insn (op2, operands[2]);
14896 emit_move_insn (op1, operands[1]);
14898 emit_label (label);
14899 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14900 ix86_emit_fp_unordered_jump (label);
14901 LABEL_NUSES (label) = 1;
14903 emit_move_insn (operands[0], op1);
14907 (define_expand "remainder<mode>3"
14908 [(use (match_operand:MODEF 0 "register_operand" ""))
14909 (use (match_operand:MODEF 1 "general_operand" ""))
14910 (use (match_operand:MODEF 2 "general_operand" ""))]
14911 "TARGET_USE_FANCY_MATH_387"
14913 rtx label = gen_label_rtx ();
14915 rtx op1 = gen_reg_rtx (XFmode);
14916 rtx op2 = gen_reg_rtx (XFmode);
14918 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14919 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14921 emit_label (label);
14923 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14924 ix86_emit_fp_unordered_jump (label);
14925 LABEL_NUSES (label) = 1;
14927 /* Truncate the result properly for strict SSE math. */
14928 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14929 && !TARGET_MIX_SSE_I387)
14930 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
14932 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
14937 (define_insn "*sinxf2_i387"
14938 [(set (match_operand:XF 0 "register_operand" "=f")
14939 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14940 "TARGET_USE_FANCY_MATH_387
14941 && flag_unsafe_math_optimizations"
14943 [(set_attr "type" "fpspc")
14944 (set_attr "mode" "XF")])
14946 (define_insn "*sin_extend<mode>xf2_i387"
14947 [(set (match_operand:XF 0 "register_operand" "=f")
14948 (unspec:XF [(float_extend:XF
14949 (match_operand:MODEF 1 "register_operand" "0"))]
14951 "TARGET_USE_FANCY_MATH_387
14952 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14953 || TARGET_MIX_SSE_I387)
14954 && flag_unsafe_math_optimizations"
14956 [(set_attr "type" "fpspc")
14957 (set_attr "mode" "XF")])
14959 (define_insn "*cosxf2_i387"
14960 [(set (match_operand:XF 0 "register_operand" "=f")
14961 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14962 "TARGET_USE_FANCY_MATH_387
14963 && flag_unsafe_math_optimizations"
14965 [(set_attr "type" "fpspc")
14966 (set_attr "mode" "XF")])
14968 (define_insn "*cos_extend<mode>xf2_i387"
14969 [(set (match_operand:XF 0 "register_operand" "=f")
14970 (unspec:XF [(float_extend:XF
14971 (match_operand:MODEF 1 "register_operand" "0"))]
14973 "TARGET_USE_FANCY_MATH_387
14974 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14975 || TARGET_MIX_SSE_I387)
14976 && flag_unsafe_math_optimizations"
14978 [(set_attr "type" "fpspc")
14979 (set_attr "mode" "XF")])
14981 ;; When sincos pattern is defined, sin and cos builtin functions will be
14982 ;; expanded to sincos pattern with one of its outputs left unused.
14983 ;; CSE pass will figure out if two sincos patterns can be combined,
14984 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14985 ;; depending on the unused output.
14987 (define_insn "sincosxf3"
14988 [(set (match_operand:XF 0 "register_operand" "=f")
14989 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14990 UNSPEC_SINCOS_COS))
14991 (set (match_operand:XF 1 "register_operand" "=u")
14992 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14993 "TARGET_USE_FANCY_MATH_387
14994 && flag_unsafe_math_optimizations"
14996 [(set_attr "type" "fpspc")
14997 (set_attr "mode" "XF")])
15000 [(set (match_operand:XF 0 "register_operand" "")
15001 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15002 UNSPEC_SINCOS_COS))
15003 (set (match_operand:XF 1 "register_operand" "")
15004 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15005 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15006 && !(reload_completed || reload_in_progress)"
15007 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15011 [(set (match_operand:XF 0 "register_operand" "")
15012 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15013 UNSPEC_SINCOS_COS))
15014 (set (match_operand:XF 1 "register_operand" "")
15015 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15016 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15017 && !(reload_completed || reload_in_progress)"
15018 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15021 (define_insn "sincos_extend<mode>xf3_i387"
15022 [(set (match_operand:XF 0 "register_operand" "=f")
15023 (unspec:XF [(float_extend:XF
15024 (match_operand:MODEF 2 "register_operand" "0"))]
15025 UNSPEC_SINCOS_COS))
15026 (set (match_operand:XF 1 "register_operand" "=u")
15027 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15028 "TARGET_USE_FANCY_MATH_387
15029 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15030 || TARGET_MIX_SSE_I387)
15031 && flag_unsafe_math_optimizations"
15033 [(set_attr "type" "fpspc")
15034 (set_attr "mode" "XF")])
15037 [(set (match_operand:XF 0 "register_operand" "")
15038 (unspec:XF [(float_extend:XF
15039 (match_operand:MODEF 2 "register_operand" ""))]
15040 UNSPEC_SINCOS_COS))
15041 (set (match_operand:XF 1 "register_operand" "")
15042 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15043 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15044 && !(reload_completed || reload_in_progress)"
15045 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15049 [(set (match_operand:XF 0 "register_operand" "")
15050 (unspec:XF [(float_extend:XF
15051 (match_operand:MODEF 2 "register_operand" ""))]
15052 UNSPEC_SINCOS_COS))
15053 (set (match_operand:XF 1 "register_operand" "")
15054 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15055 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15056 && !(reload_completed || reload_in_progress)"
15057 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15060 (define_expand "sincos<mode>3"
15061 [(use (match_operand:MODEF 0 "register_operand" ""))
15062 (use (match_operand:MODEF 1 "register_operand" ""))
15063 (use (match_operand:MODEF 2 "register_operand" ""))]
15064 "TARGET_USE_FANCY_MATH_387
15065 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15066 || TARGET_MIX_SSE_I387)
15067 && flag_unsafe_math_optimizations"
15069 rtx op0 = gen_reg_rtx (XFmode);
15070 rtx op1 = gen_reg_rtx (XFmode);
15072 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15073 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15074 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15078 (define_insn "fptanxf4_i387"
15079 [(set (match_operand:XF 0 "register_operand" "=f")
15080 (match_operand:XF 3 "const_double_operand" "F"))
15081 (set (match_operand:XF 1 "register_operand" "=u")
15082 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15084 "TARGET_USE_FANCY_MATH_387
15085 && flag_unsafe_math_optimizations
15086 && standard_80387_constant_p (operands[3]) == 2"
15088 [(set_attr "type" "fpspc")
15089 (set_attr "mode" "XF")])
15091 (define_insn "fptan_extend<mode>xf4_i387"
15092 [(set (match_operand:MODEF 0 "register_operand" "=f")
15093 (match_operand:MODEF 3 "const_double_operand" "F"))
15094 (set (match_operand:XF 1 "register_operand" "=u")
15095 (unspec:XF [(float_extend:XF
15096 (match_operand:MODEF 2 "register_operand" "0"))]
15098 "TARGET_USE_FANCY_MATH_387
15099 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15100 || TARGET_MIX_SSE_I387)
15101 && flag_unsafe_math_optimizations
15102 && standard_80387_constant_p (operands[3]) == 2"
15104 [(set_attr "type" "fpspc")
15105 (set_attr "mode" "XF")])
15107 (define_expand "tanxf2"
15108 [(use (match_operand:XF 0 "register_operand" ""))
15109 (use (match_operand:XF 1 "register_operand" ""))]
15110 "TARGET_USE_FANCY_MATH_387
15111 && flag_unsafe_math_optimizations"
15113 rtx one = gen_reg_rtx (XFmode);
15114 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15116 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15120 (define_expand "tan<mode>2"
15121 [(use (match_operand:MODEF 0 "register_operand" ""))
15122 (use (match_operand:MODEF 1 "register_operand" ""))]
15123 "TARGET_USE_FANCY_MATH_387
15124 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15125 || TARGET_MIX_SSE_I387)
15126 && flag_unsafe_math_optimizations"
15128 rtx op0 = gen_reg_rtx (XFmode);
15130 rtx one = gen_reg_rtx (<MODE>mode);
15131 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15133 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15134 operands[1], op2));
15135 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15139 (define_insn "*fpatanxf3_i387"
15140 [(set (match_operand:XF 0 "register_operand" "=f")
15141 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15142 (match_operand:XF 2 "register_operand" "u")]
15144 (clobber (match_scratch:XF 3 "=2"))]
15145 "TARGET_USE_FANCY_MATH_387
15146 && flag_unsafe_math_optimizations"
15148 [(set_attr "type" "fpspc")
15149 (set_attr "mode" "XF")])
15151 (define_insn "fpatan_extend<mode>xf3_i387"
15152 [(set (match_operand:XF 0 "register_operand" "=f")
15153 (unspec:XF [(float_extend:XF
15154 (match_operand:MODEF 1 "register_operand" "0"))
15156 (match_operand:MODEF 2 "register_operand" "u"))]
15158 (clobber (match_scratch:XF 3 "=2"))]
15159 "TARGET_USE_FANCY_MATH_387
15160 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15161 || TARGET_MIX_SSE_I387)
15162 && flag_unsafe_math_optimizations"
15164 [(set_attr "type" "fpspc")
15165 (set_attr "mode" "XF")])
15167 (define_expand "atan2xf3"
15168 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15169 (unspec:XF [(match_operand:XF 2 "register_operand" "")
15170 (match_operand:XF 1 "register_operand" "")]
15172 (clobber (match_scratch:XF 3 ""))])]
15173 "TARGET_USE_FANCY_MATH_387
15174 && flag_unsafe_math_optimizations"
15177 (define_expand "atan2<mode>3"
15178 [(use (match_operand:MODEF 0 "register_operand" ""))
15179 (use (match_operand:MODEF 1 "register_operand" ""))
15180 (use (match_operand:MODEF 2 "register_operand" ""))]
15181 "TARGET_USE_FANCY_MATH_387
15182 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15183 || TARGET_MIX_SSE_I387)
15184 && flag_unsafe_math_optimizations"
15186 rtx op0 = gen_reg_rtx (XFmode);
15188 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15189 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15193 (define_expand "atanxf2"
15194 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15195 (unspec:XF [(match_dup 2)
15196 (match_operand:XF 1 "register_operand" "")]
15198 (clobber (match_scratch:XF 3 ""))])]
15199 "TARGET_USE_FANCY_MATH_387
15200 && flag_unsafe_math_optimizations"
15202 operands[2] = gen_reg_rtx (XFmode);
15203 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15206 (define_expand "atan<mode>2"
15207 [(use (match_operand:MODEF 0 "register_operand" ""))
15208 (use (match_operand:MODEF 1 "register_operand" ""))]
15209 "TARGET_USE_FANCY_MATH_387
15210 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15211 || TARGET_MIX_SSE_I387)
15212 && flag_unsafe_math_optimizations"
15214 rtx op0 = gen_reg_rtx (XFmode);
15216 rtx op2 = gen_reg_rtx (<MODE>mode);
15217 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
15219 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15220 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15224 (define_expand "asinxf2"
15225 [(set (match_dup 2)
15226 (mult:XF (match_operand:XF 1 "register_operand" "")
15228 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15229 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15230 (parallel [(set (match_operand:XF 0 "register_operand" "")
15231 (unspec:XF [(match_dup 5) (match_dup 1)]
15233 (clobber (match_scratch:XF 6 ""))])]
15234 "TARGET_USE_FANCY_MATH_387
15235 && flag_unsafe_math_optimizations"
15239 if (optimize_insn_for_size_p ())
15242 for (i = 2; i < 6; i++)
15243 operands[i] = gen_reg_rtx (XFmode);
15245 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15248 (define_expand "asin<mode>2"
15249 [(use (match_operand:MODEF 0 "register_operand" ""))
15250 (use (match_operand:MODEF 1 "general_operand" ""))]
15251 "TARGET_USE_FANCY_MATH_387
15252 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15253 || TARGET_MIX_SSE_I387)
15254 && flag_unsafe_math_optimizations"
15256 rtx op0 = gen_reg_rtx (XFmode);
15257 rtx op1 = gen_reg_rtx (XFmode);
15259 if (optimize_insn_for_size_p ())
15262 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15263 emit_insn (gen_asinxf2 (op0, op1));
15264 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15268 (define_expand "acosxf2"
15269 [(set (match_dup 2)
15270 (mult:XF (match_operand:XF 1 "register_operand" "")
15272 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15273 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15274 (parallel [(set (match_operand:XF 0 "register_operand" "")
15275 (unspec:XF [(match_dup 1) (match_dup 5)]
15277 (clobber (match_scratch:XF 6 ""))])]
15278 "TARGET_USE_FANCY_MATH_387
15279 && flag_unsafe_math_optimizations"
15283 if (optimize_insn_for_size_p ())
15286 for (i = 2; i < 6; i++)
15287 operands[i] = gen_reg_rtx (XFmode);
15289 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15292 (define_expand "acos<mode>2"
15293 [(use (match_operand:MODEF 0 "register_operand" ""))
15294 (use (match_operand:MODEF 1 "general_operand" ""))]
15295 "TARGET_USE_FANCY_MATH_387
15296 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15297 || TARGET_MIX_SSE_I387)
15298 && flag_unsafe_math_optimizations"
15300 rtx op0 = gen_reg_rtx (XFmode);
15301 rtx op1 = gen_reg_rtx (XFmode);
15303 if (optimize_insn_for_size_p ())
15306 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15307 emit_insn (gen_acosxf2 (op0, op1));
15308 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15312 (define_insn "fyl2xxf3_i387"
15313 [(set (match_operand:XF 0 "register_operand" "=f")
15314 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15315 (match_operand:XF 2 "register_operand" "u")]
15317 (clobber (match_scratch:XF 3 "=2"))]
15318 "TARGET_USE_FANCY_MATH_387
15319 && flag_unsafe_math_optimizations"
15321 [(set_attr "type" "fpspc")
15322 (set_attr "mode" "XF")])
15324 (define_insn "fyl2x_extend<mode>xf3_i387"
15325 [(set (match_operand:XF 0 "register_operand" "=f")
15326 (unspec:XF [(float_extend:XF
15327 (match_operand:MODEF 1 "register_operand" "0"))
15328 (match_operand:XF 2 "register_operand" "u")]
15330 (clobber (match_scratch:XF 3 "=2"))]
15331 "TARGET_USE_FANCY_MATH_387
15332 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15333 || TARGET_MIX_SSE_I387)
15334 && flag_unsafe_math_optimizations"
15336 [(set_attr "type" "fpspc")
15337 (set_attr "mode" "XF")])
15339 (define_expand "logxf2"
15340 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15341 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15342 (match_dup 2)] UNSPEC_FYL2X))
15343 (clobber (match_scratch:XF 3 ""))])]
15344 "TARGET_USE_FANCY_MATH_387
15345 && flag_unsafe_math_optimizations"
15347 operands[2] = gen_reg_rtx (XFmode);
15348 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15351 (define_expand "log<mode>2"
15352 [(use (match_operand:MODEF 0 "register_operand" ""))
15353 (use (match_operand:MODEF 1 "register_operand" ""))]
15354 "TARGET_USE_FANCY_MATH_387
15355 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15356 || TARGET_MIX_SSE_I387)
15357 && flag_unsafe_math_optimizations"
15359 rtx op0 = gen_reg_rtx (XFmode);
15361 rtx op2 = gen_reg_rtx (XFmode);
15362 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15364 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15365 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15369 (define_expand "log10xf2"
15370 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15371 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15372 (match_dup 2)] UNSPEC_FYL2X))
15373 (clobber (match_scratch:XF 3 ""))])]
15374 "TARGET_USE_FANCY_MATH_387
15375 && flag_unsafe_math_optimizations"
15377 operands[2] = gen_reg_rtx (XFmode);
15378 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15381 (define_expand "log10<mode>2"
15382 [(use (match_operand:MODEF 0 "register_operand" ""))
15383 (use (match_operand:MODEF 1 "register_operand" ""))]
15384 "TARGET_USE_FANCY_MATH_387
15385 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15386 || TARGET_MIX_SSE_I387)
15387 && flag_unsafe_math_optimizations"
15389 rtx op0 = gen_reg_rtx (XFmode);
15391 rtx op2 = gen_reg_rtx (XFmode);
15392 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15394 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15395 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15399 (define_expand "log2xf2"
15400 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15401 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15402 (match_dup 2)] UNSPEC_FYL2X))
15403 (clobber (match_scratch:XF 3 ""))])]
15404 "TARGET_USE_FANCY_MATH_387
15405 && flag_unsafe_math_optimizations"
15407 operands[2] = gen_reg_rtx (XFmode);
15408 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15411 (define_expand "log2<mode>2"
15412 [(use (match_operand:MODEF 0 "register_operand" ""))
15413 (use (match_operand:MODEF 1 "register_operand" ""))]
15414 "TARGET_USE_FANCY_MATH_387
15415 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15416 || TARGET_MIX_SSE_I387)
15417 && flag_unsafe_math_optimizations"
15419 rtx op0 = gen_reg_rtx (XFmode);
15421 rtx op2 = gen_reg_rtx (XFmode);
15422 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15424 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15425 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15429 (define_insn "fyl2xp1xf3_i387"
15430 [(set (match_operand:XF 0 "register_operand" "=f")
15431 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15432 (match_operand:XF 2 "register_operand" "u")]
15434 (clobber (match_scratch:XF 3 "=2"))]
15435 "TARGET_USE_FANCY_MATH_387
15436 && flag_unsafe_math_optimizations"
15438 [(set_attr "type" "fpspc")
15439 (set_attr "mode" "XF")])
15441 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15442 [(set (match_operand:XF 0 "register_operand" "=f")
15443 (unspec:XF [(float_extend:XF
15444 (match_operand:MODEF 1 "register_operand" "0"))
15445 (match_operand:XF 2 "register_operand" "u")]
15447 (clobber (match_scratch:XF 3 "=2"))]
15448 "TARGET_USE_FANCY_MATH_387
15449 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15450 || TARGET_MIX_SSE_I387)
15451 && flag_unsafe_math_optimizations"
15453 [(set_attr "type" "fpspc")
15454 (set_attr "mode" "XF")])
15456 (define_expand "log1pxf2"
15457 [(use (match_operand:XF 0 "register_operand" ""))
15458 (use (match_operand:XF 1 "register_operand" ""))]
15459 "TARGET_USE_FANCY_MATH_387
15460 && flag_unsafe_math_optimizations"
15462 if (optimize_insn_for_size_p ())
15465 ix86_emit_i387_log1p (operands[0], operands[1]);
15469 (define_expand "log1p<mode>2"
15470 [(use (match_operand:MODEF 0 "register_operand" ""))
15471 (use (match_operand:MODEF 1 "register_operand" ""))]
15472 "TARGET_USE_FANCY_MATH_387
15473 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15474 || TARGET_MIX_SSE_I387)
15475 && flag_unsafe_math_optimizations"
15479 if (optimize_insn_for_size_p ())
15482 op0 = gen_reg_rtx (XFmode);
15484 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15486 ix86_emit_i387_log1p (op0, operands[1]);
15487 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15491 (define_insn "fxtractxf3_i387"
15492 [(set (match_operand:XF 0 "register_operand" "=f")
15493 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15494 UNSPEC_XTRACT_FRACT))
15495 (set (match_operand:XF 1 "register_operand" "=u")
15496 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15497 "TARGET_USE_FANCY_MATH_387
15498 && flag_unsafe_math_optimizations"
15500 [(set_attr "type" "fpspc")
15501 (set_attr "mode" "XF")])
15503 (define_insn "fxtract_extend<mode>xf3_i387"
15504 [(set (match_operand:XF 0 "register_operand" "=f")
15505 (unspec:XF [(float_extend:XF
15506 (match_operand:MODEF 2 "register_operand" "0"))]
15507 UNSPEC_XTRACT_FRACT))
15508 (set (match_operand:XF 1 "register_operand" "=u")
15509 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15510 "TARGET_USE_FANCY_MATH_387
15511 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15512 || TARGET_MIX_SSE_I387)
15513 && flag_unsafe_math_optimizations"
15515 [(set_attr "type" "fpspc")
15516 (set_attr "mode" "XF")])
15518 (define_expand "logbxf2"
15519 [(parallel [(set (match_dup 2)
15520 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15521 UNSPEC_XTRACT_FRACT))
15522 (set (match_operand:XF 0 "register_operand" "")
15523 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15524 "TARGET_USE_FANCY_MATH_387
15525 && flag_unsafe_math_optimizations"
15527 operands[2] = gen_reg_rtx (XFmode);
15530 (define_expand "logb<mode>2"
15531 [(use (match_operand:MODEF 0 "register_operand" ""))
15532 (use (match_operand:MODEF 1 "register_operand" ""))]
15533 "TARGET_USE_FANCY_MATH_387
15534 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15535 || TARGET_MIX_SSE_I387)
15536 && flag_unsafe_math_optimizations"
15538 rtx op0 = gen_reg_rtx (XFmode);
15539 rtx op1 = gen_reg_rtx (XFmode);
15541 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15542 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15546 (define_expand "ilogbxf2"
15547 [(use (match_operand:SI 0 "register_operand" ""))
15548 (use (match_operand:XF 1 "register_operand" ""))]
15549 "TARGET_USE_FANCY_MATH_387
15550 && flag_unsafe_math_optimizations"
15554 if (optimize_insn_for_size_p ())
15557 op0 = gen_reg_rtx (XFmode);
15558 op1 = gen_reg_rtx (XFmode);
15560 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15561 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15565 (define_expand "ilogb<mode>2"
15566 [(use (match_operand:SI 0 "register_operand" ""))
15567 (use (match_operand:MODEF 1 "register_operand" ""))]
15568 "TARGET_USE_FANCY_MATH_387
15569 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15570 || TARGET_MIX_SSE_I387)
15571 && flag_unsafe_math_optimizations"
15575 if (optimize_insn_for_size_p ())
15578 op0 = gen_reg_rtx (XFmode);
15579 op1 = gen_reg_rtx (XFmode);
15581 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15582 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15586 (define_insn "*f2xm1xf2_i387"
15587 [(set (match_operand:XF 0 "register_operand" "=f")
15588 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15590 "TARGET_USE_FANCY_MATH_387
15591 && flag_unsafe_math_optimizations"
15593 [(set_attr "type" "fpspc")
15594 (set_attr "mode" "XF")])
15596 (define_insn "*fscalexf4_i387"
15597 [(set (match_operand:XF 0 "register_operand" "=f")
15598 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15599 (match_operand:XF 3 "register_operand" "1")]
15600 UNSPEC_FSCALE_FRACT))
15601 (set (match_operand:XF 1 "register_operand" "=u")
15602 (unspec:XF [(match_dup 2) (match_dup 3)]
15603 UNSPEC_FSCALE_EXP))]
15604 "TARGET_USE_FANCY_MATH_387
15605 && flag_unsafe_math_optimizations"
15607 [(set_attr "type" "fpspc")
15608 (set_attr "mode" "XF")])
15610 (define_expand "expNcorexf3"
15611 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15612 (match_operand:XF 2 "register_operand" "")))
15613 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15614 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15615 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15616 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15617 (parallel [(set (match_operand:XF 0 "register_operand" "")
15618 (unspec:XF [(match_dup 8) (match_dup 4)]
15619 UNSPEC_FSCALE_FRACT))
15621 (unspec:XF [(match_dup 8) (match_dup 4)]
15622 UNSPEC_FSCALE_EXP))])]
15623 "TARGET_USE_FANCY_MATH_387
15624 && flag_unsafe_math_optimizations"
15628 if (optimize_insn_for_size_p ())
15631 for (i = 3; i < 10; i++)
15632 operands[i] = gen_reg_rtx (XFmode);
15634 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15637 (define_expand "expxf2"
15638 [(use (match_operand:XF 0 "register_operand" ""))
15639 (use (match_operand:XF 1 "register_operand" ""))]
15640 "TARGET_USE_FANCY_MATH_387
15641 && flag_unsafe_math_optimizations"
15645 if (optimize_insn_for_size_p ())
15648 op2 = gen_reg_rtx (XFmode);
15649 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15651 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15655 (define_expand "exp<mode>2"
15656 [(use (match_operand:MODEF 0 "register_operand" ""))
15657 (use (match_operand:MODEF 1 "general_operand" ""))]
15658 "TARGET_USE_FANCY_MATH_387
15659 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15660 || TARGET_MIX_SSE_I387)
15661 && flag_unsafe_math_optimizations"
15665 if (optimize_insn_for_size_p ())
15668 op0 = gen_reg_rtx (XFmode);
15669 op1 = gen_reg_rtx (XFmode);
15671 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15672 emit_insn (gen_expxf2 (op0, op1));
15673 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15677 (define_expand "exp10xf2"
15678 [(use (match_operand:XF 0 "register_operand" ""))
15679 (use (match_operand:XF 1 "register_operand" ""))]
15680 "TARGET_USE_FANCY_MATH_387
15681 && flag_unsafe_math_optimizations"
15685 if (optimize_insn_for_size_p ())
15688 op2 = gen_reg_rtx (XFmode);
15689 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15691 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15695 (define_expand "exp10<mode>2"
15696 [(use (match_operand:MODEF 0 "register_operand" ""))
15697 (use (match_operand:MODEF 1 "general_operand" ""))]
15698 "TARGET_USE_FANCY_MATH_387
15699 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15700 || TARGET_MIX_SSE_I387)
15701 && flag_unsafe_math_optimizations"
15705 if (optimize_insn_for_size_p ())
15708 op0 = gen_reg_rtx (XFmode);
15709 op1 = gen_reg_rtx (XFmode);
15711 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15712 emit_insn (gen_exp10xf2 (op0, op1));
15713 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15717 (define_expand "exp2xf2"
15718 [(use (match_operand:XF 0 "register_operand" ""))
15719 (use (match_operand:XF 1 "register_operand" ""))]
15720 "TARGET_USE_FANCY_MATH_387
15721 && flag_unsafe_math_optimizations"
15725 if (optimize_insn_for_size_p ())
15728 op2 = gen_reg_rtx (XFmode);
15729 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15731 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15735 (define_expand "exp2<mode>2"
15736 [(use (match_operand:MODEF 0 "register_operand" ""))
15737 (use (match_operand:MODEF 1 "general_operand" ""))]
15738 "TARGET_USE_FANCY_MATH_387
15739 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15740 || TARGET_MIX_SSE_I387)
15741 && flag_unsafe_math_optimizations"
15745 if (optimize_insn_for_size_p ())
15748 op0 = gen_reg_rtx (XFmode);
15749 op1 = gen_reg_rtx (XFmode);
15751 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15752 emit_insn (gen_exp2xf2 (op0, op1));
15753 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15757 (define_expand "expm1xf2"
15758 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15760 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15761 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15762 (set (match_dup 9) (float_extend:XF (match_dup 13)))
15763 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15764 (parallel [(set (match_dup 7)
15765 (unspec:XF [(match_dup 6) (match_dup 4)]
15766 UNSPEC_FSCALE_FRACT))
15768 (unspec:XF [(match_dup 6) (match_dup 4)]
15769 UNSPEC_FSCALE_EXP))])
15770 (parallel [(set (match_dup 10)
15771 (unspec:XF [(match_dup 9) (match_dup 8)]
15772 UNSPEC_FSCALE_FRACT))
15773 (set (match_dup 11)
15774 (unspec:XF [(match_dup 9) (match_dup 8)]
15775 UNSPEC_FSCALE_EXP))])
15776 (set (match_dup 12) (minus:XF (match_dup 10)
15777 (float_extend:XF (match_dup 13))))
15778 (set (match_operand:XF 0 "register_operand" "")
15779 (plus:XF (match_dup 12) (match_dup 7)))]
15780 "TARGET_USE_FANCY_MATH_387
15781 && flag_unsafe_math_optimizations"
15785 if (optimize_insn_for_size_p ())
15788 for (i = 2; i < 13; i++)
15789 operands[i] = gen_reg_rtx (XFmode);
15792 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15794 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15797 (define_expand "expm1<mode>2"
15798 [(use (match_operand:MODEF 0 "register_operand" ""))
15799 (use (match_operand:MODEF 1 "general_operand" ""))]
15800 "TARGET_USE_FANCY_MATH_387
15801 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15802 || TARGET_MIX_SSE_I387)
15803 && flag_unsafe_math_optimizations"
15807 if (optimize_insn_for_size_p ())
15810 op0 = gen_reg_rtx (XFmode);
15811 op1 = gen_reg_rtx (XFmode);
15813 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15814 emit_insn (gen_expm1xf2 (op0, op1));
15815 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15819 (define_expand "ldexpxf3"
15820 [(set (match_dup 3)
15821 (float:XF (match_operand:SI 2 "register_operand" "")))
15822 (parallel [(set (match_operand:XF 0 " register_operand" "")
15823 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15825 UNSPEC_FSCALE_FRACT))
15827 (unspec:XF [(match_dup 1) (match_dup 3)]
15828 UNSPEC_FSCALE_EXP))])]
15829 "TARGET_USE_FANCY_MATH_387
15830 && flag_unsafe_math_optimizations"
15832 if (optimize_insn_for_size_p ())
15835 operands[3] = gen_reg_rtx (XFmode);
15836 operands[4] = gen_reg_rtx (XFmode);
15839 (define_expand "ldexp<mode>3"
15840 [(use (match_operand:MODEF 0 "register_operand" ""))
15841 (use (match_operand:MODEF 1 "general_operand" ""))
15842 (use (match_operand:SI 2 "register_operand" ""))]
15843 "TARGET_USE_FANCY_MATH_387
15844 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15845 || TARGET_MIX_SSE_I387)
15846 && flag_unsafe_math_optimizations"
15850 if (optimize_insn_for_size_p ())
15853 op0 = gen_reg_rtx (XFmode);
15854 op1 = gen_reg_rtx (XFmode);
15856 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15857 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15858 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15862 (define_expand "scalbxf3"
15863 [(parallel [(set (match_operand:XF 0 " register_operand" "")
15864 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15865 (match_operand:XF 2 "register_operand" "")]
15866 UNSPEC_FSCALE_FRACT))
15868 (unspec:XF [(match_dup 1) (match_dup 2)]
15869 UNSPEC_FSCALE_EXP))])]
15870 "TARGET_USE_FANCY_MATH_387
15871 && flag_unsafe_math_optimizations"
15873 if (optimize_insn_for_size_p ())
15876 operands[3] = gen_reg_rtx (XFmode);
15879 (define_expand "scalb<mode>3"
15880 [(use (match_operand:MODEF 0 "register_operand" ""))
15881 (use (match_operand:MODEF 1 "general_operand" ""))
15882 (use (match_operand:MODEF 2 "general_operand" ""))]
15883 "TARGET_USE_FANCY_MATH_387
15884 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15885 || TARGET_MIX_SSE_I387)
15886 && flag_unsafe_math_optimizations"
15890 if (optimize_insn_for_size_p ())
15893 op0 = gen_reg_rtx (XFmode);
15894 op1 = gen_reg_rtx (XFmode);
15895 op2 = gen_reg_rtx (XFmode);
15897 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15898 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15899 emit_insn (gen_scalbxf3 (op0, op1, op2));
15900 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15904 (define_expand "significandxf2"
15905 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15906 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15907 UNSPEC_XTRACT_FRACT))
15909 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15910 "TARGET_USE_FANCY_MATH_387
15911 && flag_unsafe_math_optimizations"
15913 operands[2] = gen_reg_rtx (XFmode);
15916 (define_expand "significand<mode>2"
15917 [(use (match_operand:MODEF 0 "register_operand" ""))
15918 (use (match_operand:MODEF 1 "register_operand" ""))]
15919 "TARGET_USE_FANCY_MATH_387
15920 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15921 || TARGET_MIX_SSE_I387)
15922 && flag_unsafe_math_optimizations"
15924 rtx op0 = gen_reg_rtx (XFmode);
15925 rtx op1 = gen_reg_rtx (XFmode);
15927 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15928 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15933 (define_insn "sse4_1_round<mode>2"
15934 [(set (match_operand:MODEF 0 "register_operand" "=x")
15935 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15936 (match_operand:SI 2 "const_0_to_15_operand" "n")]
15939 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15940 [(set_attr "type" "ssecvt")
15941 (set_attr "prefix_extra" "1")
15942 (set_attr "prefix" "maybe_vex")
15943 (set_attr "mode" "<MODE>")])
15945 (define_insn "rintxf2"
15946 [(set (match_operand:XF 0 "register_operand" "=f")
15947 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15949 "TARGET_USE_FANCY_MATH_387
15950 && flag_unsafe_math_optimizations"
15952 [(set_attr "type" "fpspc")
15953 (set_attr "mode" "XF")])
15955 (define_expand "rint<mode>2"
15956 [(use (match_operand:MODEF 0 "register_operand" ""))
15957 (use (match_operand:MODEF 1 "register_operand" ""))]
15958 "(TARGET_USE_FANCY_MATH_387
15959 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15960 || TARGET_MIX_SSE_I387)
15961 && flag_unsafe_math_optimizations)
15962 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15963 && !flag_trapping_math)"
15965 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15966 && !flag_trapping_math)
15968 if (!TARGET_ROUND && optimize_insn_for_size_p ())
15971 emit_insn (gen_sse4_1_round<mode>2
15972 (operands[0], operands[1], GEN_INT (0x04)));
15974 ix86_expand_rint (operand0, operand1);
15978 rtx op0 = gen_reg_rtx (XFmode);
15979 rtx op1 = gen_reg_rtx (XFmode);
15981 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15982 emit_insn (gen_rintxf2 (op0, op1));
15984 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15989 (define_expand "round<mode>2"
15990 [(match_operand:MODEF 0 "register_operand" "")
15991 (match_operand:MODEF 1 "nonimmediate_operand" "")]
15992 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15993 && !flag_trapping_math && !flag_rounding_math"
15995 if (optimize_insn_for_size_p ())
15997 if (TARGET_64BIT || (<MODE>mode != DFmode))
15998 ix86_expand_round (operand0, operand1);
16000 ix86_expand_rounddf_32 (operand0, operand1);
16004 (define_insn_and_split "*fistdi2_1"
16005 [(set (match_operand:DI 0 "nonimmediate_operand" "")
16006 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16008 "TARGET_USE_FANCY_MATH_387
16009 && can_create_pseudo_p ()"
16014 if (memory_operand (operands[0], VOIDmode))
16015 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16018 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16019 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16024 [(set_attr "type" "fpspc")
16025 (set_attr "mode" "DI")])
16027 (define_insn "fistdi2"
16028 [(set (match_operand:DI 0 "memory_operand" "=m")
16029 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16031 (clobber (match_scratch:XF 2 "=&1f"))]
16032 "TARGET_USE_FANCY_MATH_387"
16033 "* return output_fix_trunc (insn, operands, 0);"
16034 [(set_attr "type" "fpspc")
16035 (set_attr "mode" "DI")])
16037 (define_insn "fistdi2_with_temp"
16038 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16039 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16041 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16042 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16043 "TARGET_USE_FANCY_MATH_387"
16045 [(set_attr "type" "fpspc")
16046 (set_attr "mode" "DI")])
16049 [(set (match_operand:DI 0 "register_operand" "")
16050 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16052 (clobber (match_operand:DI 2 "memory_operand" ""))
16053 (clobber (match_scratch 3 ""))]
16055 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16056 (clobber (match_dup 3))])
16057 (set (match_dup 0) (match_dup 2))]
16061 [(set (match_operand:DI 0 "memory_operand" "")
16062 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16064 (clobber (match_operand:DI 2 "memory_operand" ""))
16065 (clobber (match_scratch 3 ""))]
16067 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16068 (clobber (match_dup 3))])]
16071 (define_insn_and_split "*fist<mode>2_1"
16072 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16073 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16075 "TARGET_USE_FANCY_MATH_387
16076 && can_create_pseudo_p ()"
16081 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16082 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16086 [(set_attr "type" "fpspc")
16087 (set_attr "mode" "<MODE>")])
16089 (define_insn "fist<mode>2"
16090 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16091 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16093 "TARGET_USE_FANCY_MATH_387"
16094 "* return output_fix_trunc (insn, operands, 0);"
16095 [(set_attr "type" "fpspc")
16096 (set_attr "mode" "<MODE>")])
16098 (define_insn "fist<mode>2_with_temp"
16099 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16100 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16102 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16103 "TARGET_USE_FANCY_MATH_387"
16105 [(set_attr "type" "fpspc")
16106 (set_attr "mode" "<MODE>")])
16109 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16110 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16112 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16114 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
16115 (set (match_dup 0) (match_dup 2))]
16119 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16120 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16122 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16124 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
16127 (define_expand "lrintxf<mode>2"
16128 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16129 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16131 "TARGET_USE_FANCY_MATH_387"
16134 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
16135 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16136 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
16137 UNSPEC_FIX_NOTRUNC))]
16138 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16139 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
16142 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
16143 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16144 (match_operand:MODEF 1 "register_operand" "")]
16145 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16146 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
16147 && !flag_trapping_math && !flag_rounding_math"
16149 if (optimize_insn_for_size_p ())
16151 ix86_expand_lround (operand0, operand1);
16155 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16156 (define_insn_and_split "frndintxf2_floor"
16157 [(set (match_operand:XF 0 "register_operand" "")
16158 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16159 UNSPEC_FRNDINT_FLOOR))
16160 (clobber (reg:CC FLAGS_REG))]
16161 "TARGET_USE_FANCY_MATH_387
16162 && flag_unsafe_math_optimizations
16163 && can_create_pseudo_p ()"
16168 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16170 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16171 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16173 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16174 operands[2], operands[3]));
16177 [(set_attr "type" "frndint")
16178 (set_attr "i387_cw" "floor")
16179 (set_attr "mode" "XF")])
16181 (define_insn "frndintxf2_floor_i387"
16182 [(set (match_operand:XF 0 "register_operand" "=f")
16183 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16184 UNSPEC_FRNDINT_FLOOR))
16185 (use (match_operand:HI 2 "memory_operand" "m"))
16186 (use (match_operand:HI 3 "memory_operand" "m"))]
16187 "TARGET_USE_FANCY_MATH_387
16188 && flag_unsafe_math_optimizations"
16189 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16190 [(set_attr "type" "frndint")
16191 (set_attr "i387_cw" "floor")
16192 (set_attr "mode" "XF")])
16194 (define_expand "floorxf2"
16195 [(use (match_operand:XF 0 "register_operand" ""))
16196 (use (match_operand:XF 1 "register_operand" ""))]
16197 "TARGET_USE_FANCY_MATH_387
16198 && flag_unsafe_math_optimizations"
16200 if (optimize_insn_for_size_p ())
16202 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16206 (define_expand "floor<mode>2"
16207 [(use (match_operand:MODEF 0 "register_operand" ""))
16208 (use (match_operand:MODEF 1 "register_operand" ""))]
16209 "(TARGET_USE_FANCY_MATH_387
16210 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16211 || TARGET_MIX_SSE_I387)
16212 && flag_unsafe_math_optimizations)
16213 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16214 && !flag_trapping_math)"
16216 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16217 && !flag_trapping_math
16218 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
16220 if (!TARGET_ROUND && optimize_insn_for_size_p ())
16223 emit_insn (gen_sse4_1_round<mode>2
16224 (operands[0], operands[1], GEN_INT (0x01)));
16225 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16226 ix86_expand_floorceil (operand0, operand1, true);
16228 ix86_expand_floorceildf_32 (operand0, operand1, true);
16234 if (optimize_insn_for_size_p ())
16237 op0 = gen_reg_rtx (XFmode);
16238 op1 = gen_reg_rtx (XFmode);
16239 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16240 emit_insn (gen_frndintxf2_floor (op0, op1));
16242 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16247 (define_insn_and_split "*fist<mode>2_floor_1"
16248 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16249 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16250 UNSPEC_FIST_FLOOR))
16251 (clobber (reg:CC FLAGS_REG))]
16252 "TARGET_USE_FANCY_MATH_387
16253 && flag_unsafe_math_optimizations
16254 && can_create_pseudo_p ()"
16259 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16261 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16262 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16263 if (memory_operand (operands[0], VOIDmode))
16264 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16265 operands[2], operands[3]));
16268 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16269 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16270 operands[2], operands[3],
16275 [(set_attr "type" "fistp")
16276 (set_attr "i387_cw" "floor")
16277 (set_attr "mode" "<MODE>")])
16279 (define_insn "fistdi2_floor"
16280 [(set (match_operand:DI 0 "memory_operand" "=m")
16281 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16282 UNSPEC_FIST_FLOOR))
16283 (use (match_operand:HI 2 "memory_operand" "m"))
16284 (use (match_operand:HI 3 "memory_operand" "m"))
16285 (clobber (match_scratch:XF 4 "=&1f"))]
16286 "TARGET_USE_FANCY_MATH_387
16287 && flag_unsafe_math_optimizations"
16288 "* return output_fix_trunc (insn, operands, 0);"
16289 [(set_attr "type" "fistp")
16290 (set_attr "i387_cw" "floor")
16291 (set_attr "mode" "DI")])
16293 (define_insn "fistdi2_floor_with_temp"
16294 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16295 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16296 UNSPEC_FIST_FLOOR))
16297 (use (match_operand:HI 2 "memory_operand" "m,m"))
16298 (use (match_operand:HI 3 "memory_operand" "m,m"))
16299 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16300 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16301 "TARGET_USE_FANCY_MATH_387
16302 && flag_unsafe_math_optimizations"
16304 [(set_attr "type" "fistp")
16305 (set_attr "i387_cw" "floor")
16306 (set_attr "mode" "DI")])
16309 [(set (match_operand:DI 0 "register_operand" "")
16310 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16311 UNSPEC_FIST_FLOOR))
16312 (use (match_operand:HI 2 "memory_operand" ""))
16313 (use (match_operand:HI 3 "memory_operand" ""))
16314 (clobber (match_operand:DI 4 "memory_operand" ""))
16315 (clobber (match_scratch 5 ""))]
16317 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16318 (use (match_dup 2))
16319 (use (match_dup 3))
16320 (clobber (match_dup 5))])
16321 (set (match_dup 0) (match_dup 4))]
16325 [(set (match_operand:DI 0 "memory_operand" "")
16326 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16327 UNSPEC_FIST_FLOOR))
16328 (use (match_operand:HI 2 "memory_operand" ""))
16329 (use (match_operand:HI 3 "memory_operand" ""))
16330 (clobber (match_operand:DI 4 "memory_operand" ""))
16331 (clobber (match_scratch 5 ""))]
16333 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16334 (use (match_dup 2))
16335 (use (match_dup 3))
16336 (clobber (match_dup 5))])]
16339 (define_insn "fist<mode>2_floor"
16340 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16341 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16342 UNSPEC_FIST_FLOOR))
16343 (use (match_operand:HI 2 "memory_operand" "m"))
16344 (use (match_operand:HI 3 "memory_operand" "m"))]
16345 "TARGET_USE_FANCY_MATH_387
16346 && flag_unsafe_math_optimizations"
16347 "* return output_fix_trunc (insn, operands, 0);"
16348 [(set_attr "type" "fistp")
16349 (set_attr "i387_cw" "floor")
16350 (set_attr "mode" "<MODE>")])
16352 (define_insn "fist<mode>2_floor_with_temp"
16353 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16354 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16355 UNSPEC_FIST_FLOOR))
16356 (use (match_operand:HI 2 "memory_operand" "m,m"))
16357 (use (match_operand:HI 3 "memory_operand" "m,m"))
16358 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
16359 "TARGET_USE_FANCY_MATH_387
16360 && flag_unsafe_math_optimizations"
16362 [(set_attr "type" "fistp")
16363 (set_attr "i387_cw" "floor")
16364 (set_attr "mode" "<MODE>")])
16367 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16368 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16369 UNSPEC_FIST_FLOOR))
16370 (use (match_operand:HI 2 "memory_operand" ""))
16371 (use (match_operand:HI 3 "memory_operand" ""))
16372 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16374 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16375 UNSPEC_FIST_FLOOR))
16376 (use (match_dup 2))
16377 (use (match_dup 3))])
16378 (set (match_dup 0) (match_dup 4))]
16382 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16383 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16384 UNSPEC_FIST_FLOOR))
16385 (use (match_operand:HI 2 "memory_operand" ""))
16386 (use (match_operand:HI 3 "memory_operand" ""))
16387 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16389 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16390 UNSPEC_FIST_FLOOR))
16391 (use (match_dup 2))
16392 (use (match_dup 3))])]
16395 (define_expand "lfloorxf<mode>2"
16396 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16397 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16398 UNSPEC_FIST_FLOOR))
16399 (clobber (reg:CC FLAGS_REG))])]
16400 "TARGET_USE_FANCY_MATH_387
16401 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16402 && flag_unsafe_math_optimizations"
16405 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
16406 [(match_operand:SWI48 0 "nonimmediate_operand" "")
16407 (match_operand:MODEF 1 "register_operand" "")]
16408 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16409 && !flag_trapping_math"
16411 if (TARGET_64BIT && optimize_insn_for_size_p ())
16413 ix86_expand_lfloorceil (operand0, operand1, true);
16417 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16418 (define_insn_and_split "frndintxf2_ceil"
16419 [(set (match_operand:XF 0 "register_operand" "")
16420 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16421 UNSPEC_FRNDINT_CEIL))
16422 (clobber (reg:CC FLAGS_REG))]
16423 "TARGET_USE_FANCY_MATH_387
16424 && flag_unsafe_math_optimizations
16425 && can_create_pseudo_p ()"
16430 ix86_optimize_mode_switching[I387_CEIL] = 1;
16432 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16433 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16435 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16436 operands[2], operands[3]));
16439 [(set_attr "type" "frndint")
16440 (set_attr "i387_cw" "ceil")
16441 (set_attr "mode" "XF")])
16443 (define_insn "frndintxf2_ceil_i387"
16444 [(set (match_operand:XF 0 "register_operand" "=f")
16445 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16446 UNSPEC_FRNDINT_CEIL))
16447 (use (match_operand:HI 2 "memory_operand" "m"))
16448 (use (match_operand:HI 3 "memory_operand" "m"))]
16449 "TARGET_USE_FANCY_MATH_387
16450 && flag_unsafe_math_optimizations"
16451 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16452 [(set_attr "type" "frndint")
16453 (set_attr "i387_cw" "ceil")
16454 (set_attr "mode" "XF")])
16456 (define_expand "ceilxf2"
16457 [(use (match_operand:XF 0 "register_operand" ""))
16458 (use (match_operand:XF 1 "register_operand" ""))]
16459 "TARGET_USE_FANCY_MATH_387
16460 && flag_unsafe_math_optimizations"
16462 if (optimize_insn_for_size_p ())
16464 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16468 (define_expand "ceil<mode>2"
16469 [(use (match_operand:MODEF 0 "register_operand" ""))
16470 (use (match_operand:MODEF 1 "register_operand" ""))]
16471 "(TARGET_USE_FANCY_MATH_387
16472 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16473 || TARGET_MIX_SSE_I387)
16474 && flag_unsafe_math_optimizations)
16475 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16476 && !flag_trapping_math)"
16478 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16479 && !flag_trapping_math
16480 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
16483 emit_insn (gen_sse4_1_round<mode>2
16484 (operands[0], operands[1], GEN_INT (0x02)));
16485 else if (optimize_insn_for_size_p ())
16487 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16488 ix86_expand_floorceil (operand0, operand1, false);
16490 ix86_expand_floorceildf_32 (operand0, operand1, false);
16496 if (optimize_insn_for_size_p ())
16499 op0 = gen_reg_rtx (XFmode);
16500 op1 = gen_reg_rtx (XFmode);
16501 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16502 emit_insn (gen_frndintxf2_ceil (op0, op1));
16504 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16509 (define_insn_and_split "*fist<mode>2_ceil_1"
16510 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16511 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16513 (clobber (reg:CC FLAGS_REG))]
16514 "TARGET_USE_FANCY_MATH_387
16515 && flag_unsafe_math_optimizations
16516 && can_create_pseudo_p ()"
16521 ix86_optimize_mode_switching[I387_CEIL] = 1;
16523 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16524 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16525 if (memory_operand (operands[0], VOIDmode))
16526 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16527 operands[2], operands[3]));
16530 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16531 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16532 operands[2], operands[3],
16537 [(set_attr "type" "fistp")
16538 (set_attr "i387_cw" "ceil")
16539 (set_attr "mode" "<MODE>")])
16541 (define_insn "fistdi2_ceil"
16542 [(set (match_operand:DI 0 "memory_operand" "=m")
16543 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16545 (use (match_operand:HI 2 "memory_operand" "m"))
16546 (use (match_operand:HI 3 "memory_operand" "m"))
16547 (clobber (match_scratch:XF 4 "=&1f"))]
16548 "TARGET_USE_FANCY_MATH_387
16549 && flag_unsafe_math_optimizations"
16550 "* return output_fix_trunc (insn, operands, 0);"
16551 [(set_attr "type" "fistp")
16552 (set_attr "i387_cw" "ceil")
16553 (set_attr "mode" "DI")])
16555 (define_insn "fistdi2_ceil_with_temp"
16556 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16557 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16559 (use (match_operand:HI 2 "memory_operand" "m,m"))
16560 (use (match_operand:HI 3 "memory_operand" "m,m"))
16561 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16562 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16563 "TARGET_USE_FANCY_MATH_387
16564 && flag_unsafe_math_optimizations"
16566 [(set_attr "type" "fistp")
16567 (set_attr "i387_cw" "ceil")
16568 (set_attr "mode" "DI")])
16571 [(set (match_operand:DI 0 "register_operand" "")
16572 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16574 (use (match_operand:HI 2 "memory_operand" ""))
16575 (use (match_operand:HI 3 "memory_operand" ""))
16576 (clobber (match_operand:DI 4 "memory_operand" ""))
16577 (clobber (match_scratch 5 ""))]
16579 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16580 (use (match_dup 2))
16581 (use (match_dup 3))
16582 (clobber (match_dup 5))])
16583 (set (match_dup 0) (match_dup 4))]
16587 [(set (match_operand:DI 0 "memory_operand" "")
16588 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16590 (use (match_operand:HI 2 "memory_operand" ""))
16591 (use (match_operand:HI 3 "memory_operand" ""))
16592 (clobber (match_operand:DI 4 "memory_operand" ""))
16593 (clobber (match_scratch 5 ""))]
16595 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16596 (use (match_dup 2))
16597 (use (match_dup 3))
16598 (clobber (match_dup 5))])]
16601 (define_insn "fist<mode>2_ceil"
16602 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16603 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16605 (use (match_operand:HI 2 "memory_operand" "m"))
16606 (use (match_operand:HI 3 "memory_operand" "m"))]
16607 "TARGET_USE_FANCY_MATH_387
16608 && flag_unsafe_math_optimizations"
16609 "* return output_fix_trunc (insn, operands, 0);"
16610 [(set_attr "type" "fistp")
16611 (set_attr "i387_cw" "ceil")
16612 (set_attr "mode" "<MODE>")])
16614 (define_insn "fist<mode>2_ceil_with_temp"
16615 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16616 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16618 (use (match_operand:HI 2 "memory_operand" "m,m"))
16619 (use (match_operand:HI 3 "memory_operand" "m,m"))
16620 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
16621 "TARGET_USE_FANCY_MATH_387
16622 && flag_unsafe_math_optimizations"
16624 [(set_attr "type" "fistp")
16625 (set_attr "i387_cw" "ceil")
16626 (set_attr "mode" "<MODE>")])
16629 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16630 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16632 (use (match_operand:HI 2 "memory_operand" ""))
16633 (use (match_operand:HI 3 "memory_operand" ""))
16634 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16636 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16638 (use (match_dup 2))
16639 (use (match_dup 3))])
16640 (set (match_dup 0) (match_dup 4))]
16644 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16645 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16647 (use (match_operand:HI 2 "memory_operand" ""))
16648 (use (match_operand:HI 3 "memory_operand" ""))
16649 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16651 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16653 (use (match_dup 2))
16654 (use (match_dup 3))])]
16657 (define_expand "lceilxf<mode>2"
16658 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16659 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16661 (clobber (reg:CC FLAGS_REG))])]
16662 "TARGET_USE_FANCY_MATH_387
16663 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16664 && flag_unsafe_math_optimizations"
16667 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
16668 [(match_operand:SWI48 0 "nonimmediate_operand" "")
16669 (match_operand:MODEF 1 "register_operand" "")]
16670 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16671 && !flag_trapping_math"
16673 ix86_expand_lfloorceil (operand0, operand1, false);
16677 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16678 (define_insn_and_split "frndintxf2_trunc"
16679 [(set (match_operand:XF 0 "register_operand" "")
16680 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16681 UNSPEC_FRNDINT_TRUNC))
16682 (clobber (reg:CC FLAGS_REG))]
16683 "TARGET_USE_FANCY_MATH_387
16684 && flag_unsafe_math_optimizations
16685 && can_create_pseudo_p ()"
16690 ix86_optimize_mode_switching[I387_TRUNC] = 1;
16692 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16693 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
16695 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
16696 operands[2], operands[3]));
16699 [(set_attr "type" "frndint")
16700 (set_attr "i387_cw" "trunc")
16701 (set_attr "mode" "XF")])
16703 (define_insn "frndintxf2_trunc_i387"
16704 [(set (match_operand:XF 0 "register_operand" "=f")
16705 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16706 UNSPEC_FRNDINT_TRUNC))
16707 (use (match_operand:HI 2 "memory_operand" "m"))
16708 (use (match_operand:HI 3 "memory_operand" "m"))]
16709 "TARGET_USE_FANCY_MATH_387
16710 && flag_unsafe_math_optimizations"
16711 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16712 [(set_attr "type" "frndint")
16713 (set_attr "i387_cw" "trunc")
16714 (set_attr "mode" "XF")])
16716 (define_expand "btruncxf2"
16717 [(use (match_operand:XF 0 "register_operand" ""))
16718 (use (match_operand:XF 1 "register_operand" ""))]
16719 "TARGET_USE_FANCY_MATH_387
16720 && flag_unsafe_math_optimizations"
16722 if (optimize_insn_for_size_p ())
16724 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
16728 (define_expand "btrunc<mode>2"
16729 [(use (match_operand:MODEF 0 "register_operand" ""))
16730 (use (match_operand:MODEF 1 "register_operand" ""))]
16731 "(TARGET_USE_FANCY_MATH_387
16732 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16733 || TARGET_MIX_SSE_I387)
16734 && flag_unsafe_math_optimizations)
16735 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16736 && !flag_trapping_math)"
16738 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16739 && !flag_trapping_math
16740 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
16743 emit_insn (gen_sse4_1_round<mode>2
16744 (operands[0], operands[1], GEN_INT (0x03)));
16745 else if (optimize_insn_for_size_p ())
16747 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16748 ix86_expand_trunc (operand0, operand1);
16750 ix86_expand_truncdf_32 (operand0, operand1);
16756 if (optimize_insn_for_size_p ())
16759 op0 = gen_reg_rtx (XFmode);
16760 op1 = gen_reg_rtx (XFmode);
16761 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16762 emit_insn (gen_frndintxf2_trunc (op0, op1));
16764 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16769 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16770 (define_insn_and_split "frndintxf2_mask_pm"
16771 [(set (match_operand:XF 0 "register_operand" "")
16772 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16773 UNSPEC_FRNDINT_MASK_PM))
16774 (clobber (reg:CC FLAGS_REG))]
16775 "TARGET_USE_FANCY_MATH_387
16776 && flag_unsafe_math_optimizations
16777 && can_create_pseudo_p ()"
16782 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16784 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16785 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16787 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16788 operands[2], operands[3]));
16791 [(set_attr "type" "frndint")
16792 (set_attr "i387_cw" "mask_pm")
16793 (set_attr "mode" "XF")])
16795 (define_insn "frndintxf2_mask_pm_i387"
16796 [(set (match_operand:XF 0 "register_operand" "=f")
16797 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16798 UNSPEC_FRNDINT_MASK_PM))
16799 (use (match_operand:HI 2 "memory_operand" "m"))
16800 (use (match_operand:HI 3 "memory_operand" "m"))]
16801 "TARGET_USE_FANCY_MATH_387
16802 && flag_unsafe_math_optimizations"
16803 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16804 [(set_attr "type" "frndint")
16805 (set_attr "i387_cw" "mask_pm")
16806 (set_attr "mode" "XF")])
16808 (define_expand "nearbyintxf2"
16809 [(use (match_operand:XF 0 "register_operand" ""))
16810 (use (match_operand:XF 1 "register_operand" ""))]
16811 "TARGET_USE_FANCY_MATH_387
16812 && flag_unsafe_math_optimizations"
16814 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
16819 (define_expand "nearbyint<mode>2"
16820 [(use (match_operand:MODEF 0 "register_operand" ""))
16821 (use (match_operand:MODEF 1 "register_operand" ""))]
16822 "TARGET_USE_FANCY_MATH_387
16823 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16824 || TARGET_MIX_SSE_I387)
16825 && flag_unsafe_math_optimizations"
16827 rtx op0 = gen_reg_rtx (XFmode);
16828 rtx op1 = gen_reg_rtx (XFmode);
16830 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16831 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16833 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16837 (define_insn "fxam<mode>2_i387"
16838 [(set (match_operand:HI 0 "register_operand" "=a")
16840 [(match_operand:X87MODEF 1 "register_operand" "f")]
16842 "TARGET_USE_FANCY_MATH_387"
16843 "fxam\n\tfnstsw\t%0"
16844 [(set_attr "type" "multi")
16845 (set_attr "length" "4")
16846 (set_attr "unit" "i387")
16847 (set_attr "mode" "<MODE>")])
16849 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16850 [(set (match_operand:HI 0 "register_operand" "")
16852 [(match_operand:MODEF 1 "memory_operand" "")]
16854 "TARGET_USE_FANCY_MATH_387
16855 && can_create_pseudo_p ()"
16858 [(set (match_dup 2)(match_dup 1))
16860 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16862 operands[2] = gen_reg_rtx (<MODE>mode);
16864 MEM_VOLATILE_P (operands[1]) = 1;
16866 [(set_attr "type" "multi")
16867 (set_attr "unit" "i387")
16868 (set_attr "mode" "<MODE>")])
16870 (define_expand "isinfxf2"
16871 [(use (match_operand:SI 0 "register_operand" ""))
16872 (use (match_operand:XF 1 "register_operand" ""))]
16873 "TARGET_USE_FANCY_MATH_387
16874 && TARGET_C99_FUNCTIONS"
16876 rtx mask = GEN_INT (0x45);
16877 rtx val = GEN_INT (0x05);
16881 rtx scratch = gen_reg_rtx (HImode);
16882 rtx res = gen_reg_rtx (QImode);
16884 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16886 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16887 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16888 cond = gen_rtx_fmt_ee (EQ, QImode,
16889 gen_rtx_REG (CCmode, FLAGS_REG),
16891 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
16892 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16896 (define_expand "isinf<mode>2"
16897 [(use (match_operand:SI 0 "register_operand" ""))
16898 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
16899 "TARGET_USE_FANCY_MATH_387
16900 && TARGET_C99_FUNCTIONS
16901 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16903 rtx mask = GEN_INT (0x45);
16904 rtx val = GEN_INT (0x05);
16908 rtx scratch = gen_reg_rtx (HImode);
16909 rtx res = gen_reg_rtx (QImode);
16911 /* Remove excess precision by forcing value through memory. */
16912 if (memory_operand (operands[1], VOIDmode))
16913 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16916 enum ix86_stack_slot slot = (virtuals_instantiated
16919 rtx temp = assign_386_stack_local (<MODE>mode, slot);
16921 emit_move_insn (temp, operands[1]);
16922 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16925 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16926 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16927 cond = gen_rtx_fmt_ee (EQ, QImode,
16928 gen_rtx_REG (CCmode, FLAGS_REG),
16930 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
16931 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16935 (define_expand "signbit<mode>2"
16936 [(use (match_operand:SI 0 "register_operand" ""))
16937 (use (match_operand:X87MODEF 1 "register_operand" ""))]
16938 "TARGET_USE_FANCY_MATH_387
16939 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16941 rtx mask = GEN_INT (0x0200);
16943 rtx scratch = gen_reg_rtx (HImode);
16945 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
16946 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
16950 ;; Block operation instructions
16953 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16956 [(set_attr "length" "1")
16957 (set_attr "length_immediate" "0")
16958 (set_attr "modrm" "0")])
16960 (define_expand "movmemsi"
16961 [(use (match_operand:BLK 0 "memory_operand" ""))
16962 (use (match_operand:BLK 1 "memory_operand" ""))
16963 (use (match_operand:SI 2 "nonmemory_operand" ""))
16964 (use (match_operand:SI 3 "const_int_operand" ""))
16965 (use (match_operand:SI 4 "const_int_operand" ""))
16966 (use (match_operand:SI 5 "const_int_operand" ""))]
16969 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
16970 operands[4], operands[5]))
16976 (define_expand "movmemdi"
16977 [(use (match_operand:BLK 0 "memory_operand" ""))
16978 (use (match_operand:BLK 1 "memory_operand" ""))
16979 (use (match_operand:DI 2 "nonmemory_operand" ""))
16980 (use (match_operand:DI 3 "const_int_operand" ""))
16981 (use (match_operand:SI 4 "const_int_operand" ""))
16982 (use (match_operand:SI 5 "const_int_operand" ""))]
16985 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
16986 operands[4], operands[5]))
16992 ;; Most CPUs don't like single string operations
16993 ;; Handle this case here to simplify previous expander.
16995 (define_expand "strmov"
16996 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16997 (set (match_operand 1 "memory_operand" "") (match_dup 4))
16998 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16999 (clobber (reg:CC FLAGS_REG))])
17000 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17001 (clobber (reg:CC FLAGS_REG))])]
17004 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17006 /* If .md ever supports :P for Pmode, these can be directly
17007 in the pattern above. */
17008 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17009 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17011 /* Can't use this if the user has appropriated esi or edi. */
17012 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17013 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17015 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17016 operands[2], operands[3],
17017 operands[5], operands[6]));
17021 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17024 (define_expand "strmov_singleop"
17025 [(parallel [(set (match_operand 1 "memory_operand" "")
17026 (match_operand 3 "memory_operand" ""))
17027 (set (match_operand 0 "register_operand" "")
17028 (match_operand 4 "" ""))
17029 (set (match_operand 2 "register_operand" "")
17030 (match_operand 5 "" ""))])]
17032 "ix86_current_function_needs_cld = 1;")
17034 (define_insn "*strmovdi_rex_1"
17035 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17036 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17037 (set (match_operand:DI 0 "register_operand" "=D")
17038 (plus:DI (match_dup 2)
17040 (set (match_operand:DI 1 "register_operand" "=S")
17041 (plus:DI (match_dup 3)
17045 [(set_attr "type" "str")
17046 (set_attr "mode" "DI")
17047 (set_attr "memory" "both")])
17049 (define_insn "*strmovsi_1"
17050 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17051 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17052 (set (match_operand:SI 0 "register_operand" "=D")
17053 (plus:SI (match_dup 2)
17055 (set (match_operand:SI 1 "register_operand" "=S")
17056 (plus:SI (match_dup 3)
17060 [(set_attr "type" "str")
17061 (set_attr "mode" "SI")
17062 (set_attr "memory" "both")])
17064 (define_insn "*strmovsi_rex_1"
17065 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17066 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17067 (set (match_operand:DI 0 "register_operand" "=D")
17068 (plus:DI (match_dup 2)
17070 (set (match_operand:DI 1 "register_operand" "=S")
17071 (plus:DI (match_dup 3)
17075 [(set_attr "type" "str")
17076 (set_attr "mode" "SI")
17077 (set_attr "memory" "both")])
17079 (define_insn "*strmovhi_1"
17080 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17081 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17082 (set (match_operand:SI 0 "register_operand" "=D")
17083 (plus:SI (match_dup 2)
17085 (set (match_operand:SI 1 "register_operand" "=S")
17086 (plus:SI (match_dup 3)
17090 [(set_attr "type" "str")
17091 (set_attr "memory" "both")
17092 (set_attr "mode" "HI")])
17094 (define_insn "*strmovhi_rex_1"
17095 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17096 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17097 (set (match_operand:DI 0 "register_operand" "=D")
17098 (plus:DI (match_dup 2)
17100 (set (match_operand:DI 1 "register_operand" "=S")
17101 (plus:DI (match_dup 3)
17105 [(set_attr "type" "str")
17106 (set_attr "memory" "both")
17107 (set_attr "mode" "HI")])
17109 (define_insn "*strmovqi_1"
17110 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17111 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17112 (set (match_operand:SI 0 "register_operand" "=D")
17113 (plus:SI (match_dup 2)
17115 (set (match_operand:SI 1 "register_operand" "=S")
17116 (plus:SI (match_dup 3)
17120 [(set_attr "type" "str")
17121 (set_attr "memory" "both")
17122 (set_attr "mode" "QI")])
17124 (define_insn "*strmovqi_rex_1"
17125 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17126 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17127 (set (match_operand:DI 0 "register_operand" "=D")
17128 (plus:DI (match_dup 2)
17130 (set (match_operand:DI 1 "register_operand" "=S")
17131 (plus:DI (match_dup 3)
17135 [(set_attr "type" "str")
17136 (set_attr "memory" "both")
17137 (set_attr "prefix_rex" "0")
17138 (set_attr "mode" "QI")])
17140 (define_expand "rep_mov"
17141 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17142 (set (match_operand 0 "register_operand" "")
17143 (match_operand 5 "" ""))
17144 (set (match_operand 2 "register_operand" "")
17145 (match_operand 6 "" ""))
17146 (set (match_operand 1 "memory_operand" "")
17147 (match_operand 3 "memory_operand" ""))
17148 (use (match_dup 4))])]
17150 "ix86_current_function_needs_cld = 1;")
17152 (define_insn "*rep_movdi_rex64"
17153 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17154 (set (match_operand:DI 0 "register_operand" "=D")
17155 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17157 (match_operand:DI 3 "register_operand" "0")))
17158 (set (match_operand:DI 1 "register_operand" "=S")
17159 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17160 (match_operand:DI 4 "register_operand" "1")))
17161 (set (mem:BLK (match_dup 3))
17162 (mem:BLK (match_dup 4)))
17163 (use (match_dup 5))]
17166 [(set_attr "type" "str")
17167 (set_attr "prefix_rep" "1")
17168 (set_attr "memory" "both")
17169 (set_attr "mode" "DI")])
17171 (define_insn "*rep_movsi"
17172 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17173 (set (match_operand:SI 0 "register_operand" "=D")
17174 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17176 (match_operand:SI 3 "register_operand" "0")))
17177 (set (match_operand:SI 1 "register_operand" "=S")
17178 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17179 (match_operand:SI 4 "register_operand" "1")))
17180 (set (mem:BLK (match_dup 3))
17181 (mem:BLK (match_dup 4)))
17182 (use (match_dup 5))]
17185 [(set_attr "type" "str")
17186 (set_attr "prefix_rep" "1")
17187 (set_attr "memory" "both")
17188 (set_attr "mode" "SI")])
17190 (define_insn "*rep_movsi_rex64"
17191 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17192 (set (match_operand:DI 0 "register_operand" "=D")
17193 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17195 (match_operand:DI 3 "register_operand" "0")))
17196 (set (match_operand:DI 1 "register_operand" "=S")
17197 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17198 (match_operand:DI 4 "register_operand" "1")))
17199 (set (mem:BLK (match_dup 3))
17200 (mem:BLK (match_dup 4)))
17201 (use (match_dup 5))]
17204 [(set_attr "type" "str")
17205 (set_attr "prefix_rep" "1")
17206 (set_attr "memory" "both")
17207 (set_attr "mode" "SI")])
17209 (define_insn "*rep_movqi"
17210 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17211 (set (match_operand:SI 0 "register_operand" "=D")
17212 (plus:SI (match_operand:SI 3 "register_operand" "0")
17213 (match_operand:SI 5 "register_operand" "2")))
17214 (set (match_operand:SI 1 "register_operand" "=S")
17215 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17216 (set (mem:BLK (match_dup 3))
17217 (mem:BLK (match_dup 4)))
17218 (use (match_dup 5))]
17221 [(set_attr "type" "str")
17222 (set_attr "prefix_rep" "1")
17223 (set_attr "memory" "both")
17224 (set_attr "mode" "SI")])
17226 (define_insn "*rep_movqi_rex64"
17227 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17228 (set (match_operand:DI 0 "register_operand" "=D")
17229 (plus:DI (match_operand:DI 3 "register_operand" "0")
17230 (match_operand:DI 5 "register_operand" "2")))
17231 (set (match_operand:DI 1 "register_operand" "=S")
17232 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17233 (set (mem:BLK (match_dup 3))
17234 (mem:BLK (match_dup 4)))
17235 (use (match_dup 5))]
17238 [(set_attr "type" "str")
17239 (set_attr "prefix_rep" "1")
17240 (set_attr "memory" "both")
17241 (set_attr "mode" "SI")])
17243 (define_expand "setmemsi"
17244 [(use (match_operand:BLK 0 "memory_operand" ""))
17245 (use (match_operand:SI 1 "nonmemory_operand" ""))
17246 (use (match_operand 2 "const_int_operand" ""))
17247 (use (match_operand 3 "const_int_operand" ""))
17248 (use (match_operand:SI 4 "const_int_operand" ""))
17249 (use (match_operand:SI 5 "const_int_operand" ""))]
17252 if (ix86_expand_setmem (operands[0], operands[1],
17253 operands[2], operands[3],
17254 operands[4], operands[5]))
17260 (define_expand "setmemdi"
17261 [(use (match_operand:BLK 0 "memory_operand" ""))
17262 (use (match_operand:DI 1 "nonmemory_operand" ""))
17263 (use (match_operand 2 "const_int_operand" ""))
17264 (use (match_operand 3 "const_int_operand" ""))
17265 (use (match_operand 4 "const_int_operand" ""))
17266 (use (match_operand 5 "const_int_operand" ""))]
17269 if (ix86_expand_setmem (operands[0], operands[1],
17270 operands[2], operands[3],
17271 operands[4], operands[5]))
17277 ;; Most CPUs don't like single string operations
17278 ;; Handle this case here to simplify previous expander.
17280 (define_expand "strset"
17281 [(set (match_operand 1 "memory_operand" "")
17282 (match_operand 2 "register_operand" ""))
17283 (parallel [(set (match_operand 0 "register_operand" "")
17285 (clobber (reg:CC FLAGS_REG))])]
17288 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17289 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17291 /* If .md ever supports :P for Pmode, this can be directly
17292 in the pattern above. */
17293 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17294 GEN_INT (GET_MODE_SIZE (GET_MODE
17296 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17298 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17304 (define_expand "strset_singleop"
17305 [(parallel [(set (match_operand 1 "memory_operand" "")
17306 (match_operand 2 "register_operand" ""))
17307 (set (match_operand 0 "register_operand" "")
17308 (match_operand 3 "" ""))])]
17310 "ix86_current_function_needs_cld = 1;")
17312 (define_insn "*strsetdi_rex_1"
17313 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17314 (match_operand:DI 2 "register_operand" "a"))
17315 (set (match_operand:DI 0 "register_operand" "=D")
17316 (plus:DI (match_dup 1)
17320 [(set_attr "type" "str")
17321 (set_attr "memory" "store")
17322 (set_attr "mode" "DI")])
17324 (define_insn "*strsetsi_1"
17325 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17326 (match_operand:SI 2 "register_operand" "a"))
17327 (set (match_operand:SI 0 "register_operand" "=D")
17328 (plus:SI (match_dup 1)
17332 [(set_attr "type" "str")
17333 (set_attr "memory" "store")
17334 (set_attr "mode" "SI")])
17336 (define_insn "*strsetsi_rex_1"
17337 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17338 (match_operand:SI 2 "register_operand" "a"))
17339 (set (match_operand:DI 0 "register_operand" "=D")
17340 (plus:DI (match_dup 1)
17344 [(set_attr "type" "str")
17345 (set_attr "memory" "store")
17346 (set_attr "mode" "SI")])
17348 (define_insn "*strsethi_1"
17349 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17350 (match_operand:HI 2 "register_operand" "a"))
17351 (set (match_operand:SI 0 "register_operand" "=D")
17352 (plus:SI (match_dup 1)
17356 [(set_attr "type" "str")
17357 (set_attr "memory" "store")
17358 (set_attr "mode" "HI")])
17360 (define_insn "*strsethi_rex_1"
17361 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17362 (match_operand:HI 2 "register_operand" "a"))
17363 (set (match_operand:DI 0 "register_operand" "=D")
17364 (plus:DI (match_dup 1)
17368 [(set_attr "type" "str")
17369 (set_attr "memory" "store")
17370 (set_attr "mode" "HI")])
17372 (define_insn "*strsetqi_1"
17373 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17374 (match_operand:QI 2 "register_operand" "a"))
17375 (set (match_operand:SI 0 "register_operand" "=D")
17376 (plus:SI (match_dup 1)
17380 [(set_attr "type" "str")
17381 (set_attr "memory" "store")
17382 (set_attr "mode" "QI")])
17384 (define_insn "*strsetqi_rex_1"
17385 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17386 (match_operand:QI 2 "register_operand" "a"))
17387 (set (match_operand:DI 0 "register_operand" "=D")
17388 (plus:DI (match_dup 1)
17392 [(set_attr "type" "str")
17393 (set_attr "memory" "store")
17394 (set_attr "prefix_rex" "0")
17395 (set_attr "mode" "QI")])
17397 (define_expand "rep_stos"
17398 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17399 (set (match_operand 0 "register_operand" "")
17400 (match_operand 4 "" ""))
17401 (set (match_operand 2 "memory_operand" "") (const_int 0))
17402 (use (match_operand 3 "register_operand" ""))
17403 (use (match_dup 1))])]
17405 "ix86_current_function_needs_cld = 1;")
17407 (define_insn "*rep_stosdi_rex64"
17408 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17409 (set (match_operand:DI 0 "register_operand" "=D")
17410 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17412 (match_operand:DI 3 "register_operand" "0")))
17413 (set (mem:BLK (match_dup 3))
17415 (use (match_operand:DI 2 "register_operand" "a"))
17416 (use (match_dup 4))]
17419 [(set_attr "type" "str")
17420 (set_attr "prefix_rep" "1")
17421 (set_attr "memory" "store")
17422 (set_attr "mode" "DI")])
17424 (define_insn "*rep_stossi"
17425 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17426 (set (match_operand:SI 0 "register_operand" "=D")
17427 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17429 (match_operand:SI 3 "register_operand" "0")))
17430 (set (mem:BLK (match_dup 3))
17432 (use (match_operand:SI 2 "register_operand" "a"))
17433 (use (match_dup 4))]
17436 [(set_attr "type" "str")
17437 (set_attr "prefix_rep" "1")
17438 (set_attr "memory" "store")
17439 (set_attr "mode" "SI")])
17441 (define_insn "*rep_stossi_rex64"
17442 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17443 (set (match_operand:DI 0 "register_operand" "=D")
17444 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17446 (match_operand:DI 3 "register_operand" "0")))
17447 (set (mem:BLK (match_dup 3))
17449 (use (match_operand:SI 2 "register_operand" "a"))
17450 (use (match_dup 4))]
17453 [(set_attr "type" "str")
17454 (set_attr "prefix_rep" "1")
17455 (set_attr "memory" "store")
17456 (set_attr "mode" "SI")])
17458 (define_insn "*rep_stosqi"
17459 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17460 (set (match_operand:SI 0 "register_operand" "=D")
17461 (plus:SI (match_operand:SI 3 "register_operand" "0")
17462 (match_operand:SI 4 "register_operand" "1")))
17463 (set (mem:BLK (match_dup 3))
17465 (use (match_operand:QI 2 "register_operand" "a"))
17466 (use (match_dup 4))]
17469 [(set_attr "type" "str")
17470 (set_attr "prefix_rep" "1")
17471 (set_attr "memory" "store")
17472 (set_attr "mode" "QI")])
17474 (define_insn "*rep_stosqi_rex64"
17475 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17476 (set (match_operand:DI 0 "register_operand" "=D")
17477 (plus:DI (match_operand:DI 3 "register_operand" "0")
17478 (match_operand:DI 4 "register_operand" "1")))
17479 (set (mem:BLK (match_dup 3))
17481 (use (match_operand:QI 2 "register_operand" "a"))
17482 (use (match_dup 4))]
17485 [(set_attr "type" "str")
17486 (set_attr "prefix_rep" "1")
17487 (set_attr "memory" "store")
17488 (set_attr "prefix_rex" "0")
17489 (set_attr "mode" "QI")])
17491 (define_expand "cmpstrnsi"
17492 [(set (match_operand:SI 0 "register_operand" "")
17493 (compare:SI (match_operand:BLK 1 "general_operand" "")
17494 (match_operand:BLK 2 "general_operand" "")))
17495 (use (match_operand 3 "general_operand" ""))
17496 (use (match_operand 4 "immediate_operand" ""))]
17499 rtx addr1, addr2, out, outlow, count, countreg, align;
17501 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17504 /* Can't use this if the user has appropriated esi or edi. */
17505 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
17510 out = gen_reg_rtx (SImode);
17512 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17513 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17514 if (addr1 != XEXP (operands[1], 0))
17515 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17516 if (addr2 != XEXP (operands[2], 0))
17517 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17519 count = operands[3];
17520 countreg = ix86_zero_extend_to_Pmode (count);
17522 /* %%% Iff we are testing strict equality, we can use known alignment
17523 to good advantage. This may be possible with combine, particularly
17524 once cc0 is dead. */
17525 align = operands[4];
17527 if (CONST_INT_P (count))
17529 if (INTVAL (count) == 0)
17531 emit_move_insn (operands[0], const0_rtx);
17534 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17535 operands[1], operands[2]));
17539 rtx (*cmp_insn)(rtx, rtx);
17542 cmp_insn = gen_cmpdi_1;
17544 cmp_insn = gen_cmpsi_1;
17545 emit_insn (cmp_insn (countreg, countreg));
17546 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17547 operands[1], operands[2]));
17550 outlow = gen_lowpart (QImode, out);
17551 emit_insn (gen_cmpintqi (outlow));
17552 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17554 if (operands[0] != out)
17555 emit_move_insn (operands[0], out);
17560 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17562 (define_expand "cmpintqi"
17563 [(set (match_dup 1)
17564 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17566 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17567 (parallel [(set (match_operand:QI 0 "register_operand" "")
17568 (minus:QI (match_dup 1)
17570 (clobber (reg:CC FLAGS_REG))])]
17572 "operands[1] = gen_reg_rtx (QImode);
17573 operands[2] = gen_reg_rtx (QImode);")
17575 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17576 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17578 (define_expand "cmpstrnqi_nz_1"
17579 [(parallel [(set (reg:CC FLAGS_REG)
17580 (compare:CC (match_operand 4 "memory_operand" "")
17581 (match_operand 5 "memory_operand" "")))
17582 (use (match_operand 2 "register_operand" ""))
17583 (use (match_operand:SI 3 "immediate_operand" ""))
17584 (clobber (match_operand 0 "register_operand" ""))
17585 (clobber (match_operand 1 "register_operand" ""))
17586 (clobber (match_dup 2))])]
17588 "ix86_current_function_needs_cld = 1;")
17590 (define_insn "*cmpstrnqi_nz_1"
17591 [(set (reg:CC FLAGS_REG)
17592 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17593 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17594 (use (match_operand:SI 6 "register_operand" "2"))
17595 (use (match_operand:SI 3 "immediate_operand" "i"))
17596 (clobber (match_operand:SI 0 "register_operand" "=S"))
17597 (clobber (match_operand:SI 1 "register_operand" "=D"))
17598 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17601 [(set_attr "type" "str")
17602 (set_attr "mode" "QI")
17603 (set_attr "prefix_rep" "1")])
17605 (define_insn "*cmpstrnqi_nz_rex_1"
17606 [(set (reg:CC FLAGS_REG)
17607 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17608 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17609 (use (match_operand:DI 6 "register_operand" "2"))
17610 (use (match_operand:SI 3 "immediate_operand" "i"))
17611 (clobber (match_operand:DI 0 "register_operand" "=S"))
17612 (clobber (match_operand:DI 1 "register_operand" "=D"))
17613 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17616 [(set_attr "type" "str")
17617 (set_attr "mode" "QI")
17618 (set_attr "prefix_rex" "0")
17619 (set_attr "prefix_rep" "1")])
17621 ;; The same, but the count is not known to not be zero.
17623 (define_expand "cmpstrnqi_1"
17624 [(parallel [(set (reg:CC FLAGS_REG)
17625 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17627 (compare:CC (match_operand 4 "memory_operand" "")
17628 (match_operand 5 "memory_operand" ""))
17630 (use (match_operand:SI 3 "immediate_operand" ""))
17631 (use (reg:CC FLAGS_REG))
17632 (clobber (match_operand 0 "register_operand" ""))
17633 (clobber (match_operand 1 "register_operand" ""))
17634 (clobber (match_dup 2))])]
17636 "ix86_current_function_needs_cld = 1;")
17638 (define_insn "*cmpstrnqi_1"
17639 [(set (reg:CC FLAGS_REG)
17640 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17642 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17643 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17645 (use (match_operand:SI 3 "immediate_operand" "i"))
17646 (use (reg:CC FLAGS_REG))
17647 (clobber (match_operand:SI 0 "register_operand" "=S"))
17648 (clobber (match_operand:SI 1 "register_operand" "=D"))
17649 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17652 [(set_attr "type" "str")
17653 (set_attr "mode" "QI")
17654 (set_attr "prefix_rep" "1")])
17656 (define_insn "*cmpstrnqi_rex_1"
17657 [(set (reg:CC FLAGS_REG)
17658 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17660 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17661 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17663 (use (match_operand:SI 3 "immediate_operand" "i"))
17664 (use (reg:CC FLAGS_REG))
17665 (clobber (match_operand:DI 0 "register_operand" "=S"))
17666 (clobber (match_operand:DI 1 "register_operand" "=D"))
17667 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17670 [(set_attr "type" "str")
17671 (set_attr "mode" "QI")
17672 (set_attr "prefix_rex" "0")
17673 (set_attr "prefix_rep" "1")])
17675 (define_expand "strlensi"
17676 [(set (match_operand:SI 0 "register_operand" "")
17677 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17678 (match_operand:QI 2 "immediate_operand" "")
17679 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17682 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17688 (define_expand "strlendi"
17689 [(set (match_operand:DI 0 "register_operand" "")
17690 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17691 (match_operand:QI 2 "immediate_operand" "")
17692 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17695 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17701 (define_expand "strlenqi_1"
17702 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17703 (clobber (match_operand 1 "register_operand" ""))
17704 (clobber (reg:CC FLAGS_REG))])]
17706 "ix86_current_function_needs_cld = 1;")
17708 (define_insn "*strlenqi_1"
17709 [(set (match_operand:SI 0 "register_operand" "=&c")
17710 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17711 (match_operand:QI 2 "register_operand" "a")
17712 (match_operand:SI 3 "immediate_operand" "i")
17713 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17714 (clobber (match_operand:SI 1 "register_operand" "=D"))
17715 (clobber (reg:CC FLAGS_REG))]
17718 [(set_attr "type" "str")
17719 (set_attr "mode" "QI")
17720 (set_attr "prefix_rep" "1")])
17722 (define_insn "*strlenqi_rex_1"
17723 [(set (match_operand:DI 0 "register_operand" "=&c")
17724 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17725 (match_operand:QI 2 "register_operand" "a")
17726 (match_operand:DI 3 "immediate_operand" "i")
17727 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17728 (clobber (match_operand:DI 1 "register_operand" "=D"))
17729 (clobber (reg:CC FLAGS_REG))]
17732 [(set_attr "type" "str")
17733 (set_attr "mode" "QI")
17734 (set_attr "prefix_rex" "0")
17735 (set_attr "prefix_rep" "1")])
17737 ;; Peephole optimizations to clean up after cmpstrn*. This should be
17738 ;; handled in combine, but it is not currently up to the task.
17739 ;; When used for their truth value, the cmpstrn* expanders generate
17748 ;; The intermediate three instructions are unnecessary.
17750 ;; This one handles cmpstrn*_nz_1...
17753 (set (reg:CC FLAGS_REG)
17754 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17755 (mem:BLK (match_operand 5 "register_operand" ""))))
17756 (use (match_operand 6 "register_operand" ""))
17757 (use (match_operand:SI 3 "immediate_operand" ""))
17758 (clobber (match_operand 0 "register_operand" ""))
17759 (clobber (match_operand 1 "register_operand" ""))
17760 (clobber (match_operand 2 "register_operand" ""))])
17761 (set (match_operand:QI 7 "register_operand" "")
17762 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17763 (set (match_operand:QI 8 "register_operand" "")
17764 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17765 (set (reg FLAGS_REG)
17766 (compare (match_dup 7) (match_dup 8)))
17768 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17770 (set (reg:CC FLAGS_REG)
17771 (compare:CC (mem:BLK (match_dup 4))
17772 (mem:BLK (match_dup 5))))
17773 (use (match_dup 6))
17774 (use (match_dup 3))
17775 (clobber (match_dup 0))
17776 (clobber (match_dup 1))
17777 (clobber (match_dup 2))])]
17780 ;; ...and this one handles cmpstrn*_1.
17783 (set (reg:CC FLAGS_REG)
17784 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17786 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17787 (mem:BLK (match_operand 5 "register_operand" "")))
17789 (use (match_operand:SI 3 "immediate_operand" ""))
17790 (use (reg:CC FLAGS_REG))
17791 (clobber (match_operand 0 "register_operand" ""))
17792 (clobber (match_operand 1 "register_operand" ""))
17793 (clobber (match_operand 2 "register_operand" ""))])
17794 (set (match_operand:QI 7 "register_operand" "")
17795 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17796 (set (match_operand:QI 8 "register_operand" "")
17797 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17798 (set (reg FLAGS_REG)
17799 (compare (match_dup 7) (match_dup 8)))
17801 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17803 (set (reg:CC FLAGS_REG)
17804 (if_then_else:CC (ne (match_dup 6)
17806 (compare:CC (mem:BLK (match_dup 4))
17807 (mem:BLK (match_dup 5)))
17809 (use (match_dup 3))
17810 (use (reg:CC FLAGS_REG))
17811 (clobber (match_dup 0))
17812 (clobber (match_dup 1))
17813 (clobber (match_dup 2))])]
17818 ;; Conditional move instructions.
17820 (define_expand "mov<mode>cc"
17821 [(set (match_operand:SWIM 0 "register_operand" "")
17822 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
17823 (match_operand:SWIM 2 "general_operand" "")
17824 (match_operand:SWIM 3 "general_operand" "")))]
17826 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17828 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17829 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17830 ;; So just document what we're doing explicitly.
17832 (define_expand "x86_mov<mode>cc_0_m1"
17834 [(set (match_operand:SWI48 0 "register_operand" "")
17835 (if_then_else:SWI48
17836 (match_operator:SWI48 2 "ix86_carry_flag_operator"
17837 [(match_operand 1 "flags_reg_operand" "")
17841 (clobber (reg:CC FLAGS_REG))])]
17845 (define_insn "*x86_mov<mode>cc_0_m1"
17846 [(set (match_operand:SWI48 0 "register_operand" "=r")
17847 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17848 [(reg FLAGS_REG) (const_int 0)])
17851 (clobber (reg:CC FLAGS_REG))]
17853 "sbb{<imodesuffix>}\t%0, %0"
17854 ; Since we don't have the proper number of operands for an alu insn,
17855 ; fill in all the blanks.
17856 [(set_attr "type" "alu")
17857 (set_attr "use_carry" "1")
17858 (set_attr "pent_pair" "pu")
17859 (set_attr "memory" "none")
17860 (set_attr "imm_disp" "false")
17861 (set_attr "mode" "<MODE>")
17862 (set_attr "length_immediate" "0")])
17864 (define_insn "*x86_mov<mode>cc_0_m1_se"
17865 [(set (match_operand:SWI48 0 "register_operand" "=r")
17866 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17867 [(reg FLAGS_REG) (const_int 0)])
17870 (clobber (reg:CC FLAGS_REG))]
17872 "sbb{<imodesuffix>}\t%0, %0"
17873 [(set_attr "type" "alu")
17874 (set_attr "use_carry" "1")
17875 (set_attr "pent_pair" "pu")
17876 (set_attr "memory" "none")
17877 (set_attr "imm_disp" "false")
17878 (set_attr "mode" "<MODE>")
17879 (set_attr "length_immediate" "0")])
17881 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17882 [(set (match_operand:SWI48 0 "register_operand" "=r")
17883 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17884 [(reg FLAGS_REG) (const_int 0)])))]
17886 "sbb{<imodesuffix>}\t%0, %0"
17887 [(set_attr "type" "alu")
17888 (set_attr "use_carry" "1")
17889 (set_attr "pent_pair" "pu")
17890 (set_attr "memory" "none")
17891 (set_attr "imm_disp" "false")
17892 (set_attr "mode" "<MODE>")
17893 (set_attr "length_immediate" "0")])
17895 (define_insn "*mov<mode>cc_noc"
17896 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17897 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17898 [(reg FLAGS_REG) (const_int 0)])
17899 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17900 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17901 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17903 cmov%O2%C1\t{%2, %0|%0, %2}
17904 cmov%O2%c1\t{%3, %0|%0, %3}"
17905 [(set_attr "type" "icmov")
17906 (set_attr "mode" "<MODE>")])
17908 (define_insn_and_split "*movqicc_noc"
17909 [(set (match_operand:QI 0 "register_operand" "=r,r")
17910 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17911 [(match_operand 4 "flags_reg_operand" "")
17913 (match_operand:QI 2 "register_operand" "r,0")
17914 (match_operand:QI 3 "register_operand" "0,r")))]
17915 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17917 "&& reload_completed"
17918 [(set (match_dup 0)
17919 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17922 "operands[0] = gen_lowpart (SImode, operands[0]);
17923 operands[2] = gen_lowpart (SImode, operands[2]);
17924 operands[3] = gen_lowpart (SImode, operands[3]);"
17925 [(set_attr "type" "icmov")
17926 (set_attr "mode" "SI")])
17928 (define_expand "mov<mode>cc"
17929 [(set (match_operand:X87MODEF 0 "register_operand" "")
17930 (if_then_else:X87MODEF
17931 (match_operand 1 "ix86_fp_comparison_operator" "")
17932 (match_operand:X87MODEF 2 "register_operand" "")
17933 (match_operand:X87MODEF 3 "register_operand" "")))]
17934 "(TARGET_80387 && TARGET_CMOVE)
17935 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17936 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17938 (define_insn "*movsfcc_1_387"
17939 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17940 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17941 [(reg FLAGS_REG) (const_int 0)])
17942 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17943 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17944 "TARGET_80387 && TARGET_CMOVE
17945 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17947 fcmov%F1\t{%2, %0|%0, %2}
17948 fcmov%f1\t{%3, %0|%0, %3}
17949 cmov%O2%C1\t{%2, %0|%0, %2}
17950 cmov%O2%c1\t{%3, %0|%0, %3}"
17951 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17952 (set_attr "mode" "SF,SF,SI,SI")])
17954 (define_insn "*movdfcc_1"
17955 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
17956 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17957 [(reg FLAGS_REG) (const_int 0)])
17958 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
17959 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
17960 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17961 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17963 fcmov%F1\t{%2, %0|%0, %2}
17964 fcmov%f1\t{%3, %0|%0, %3}
17967 [(set_attr "type" "fcmov,fcmov,multi,multi")
17968 (set_attr "mode" "DF")])
17970 (define_insn "*movdfcc_1_rex64"
17971 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
17972 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17973 [(reg FLAGS_REG) (const_int 0)])
17974 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
17975 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
17976 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17977 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17979 fcmov%F1\t{%2, %0|%0, %2}
17980 fcmov%f1\t{%3, %0|%0, %3}
17981 cmov%O2%C1\t{%2, %0|%0, %2}
17982 cmov%O2%c1\t{%3, %0|%0, %3}"
17983 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17984 (set_attr "mode" "DF")])
17987 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17988 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17989 [(match_operand 4 "flags_reg_operand" "")
17991 (match_operand:DF 2 "nonimmediate_operand" "")
17992 (match_operand:DF 3 "nonimmediate_operand" "")))]
17993 "!TARGET_64BIT && reload_completed"
17994 [(set (match_dup 2)
17995 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17999 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18002 "split_di (&operands[2], 2, &operands[5], &operands[7]);
18003 split_di (&operands[0], 1, &operands[2], &operands[3]);")
18005 (define_insn "*movxfcc_1"
18006 [(set (match_operand:XF 0 "register_operand" "=f,f")
18007 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18008 [(reg FLAGS_REG) (const_int 0)])
18009 (match_operand:XF 2 "register_operand" "f,0")
18010 (match_operand:XF 3 "register_operand" "0,f")))]
18011 "TARGET_80387 && TARGET_CMOVE"
18013 fcmov%F1\t{%2, %0|%0, %2}
18014 fcmov%f1\t{%3, %0|%0, %3}"
18015 [(set_attr "type" "fcmov")
18016 (set_attr "mode" "XF")])
18018 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18019 ;; the scalar versions to have only XMM registers as operands.
18021 ;; XOP conditional move
18022 (define_insn "*xop_pcmov_<mode>"
18023 [(set (match_operand:MODEF 0 "register_operand" "=x")
18024 (if_then_else:MODEF
18025 (match_operand:MODEF 1 "register_operand" "x")
18026 (match_operand:MODEF 2 "register_operand" "x")
18027 (match_operand:MODEF 3 "register_operand" "x")))]
18029 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18030 [(set_attr "type" "sse4arg")])
18032 ;; These versions of the min/max patterns are intentionally ignorant of
18033 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18034 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18035 ;; are undefined in this condition, we're certain this is correct.
18037 (define_insn "*avx_<code><mode>3"
18038 [(set (match_operand:MODEF 0 "register_operand" "=x")
18040 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
18041 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18042 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18043 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18044 [(set_attr "type" "sseadd")
18045 (set_attr "prefix" "vex")
18046 (set_attr "mode" "<MODE>")])
18048 (define_insn "<code><mode>3"
18049 [(set (match_operand:MODEF 0 "register_operand" "=x")
18051 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
18052 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18053 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18054 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
18055 [(set_attr "type" "sseadd")
18056 (set_attr "mode" "<MODE>")])
18058 ;; These versions of the min/max patterns implement exactly the operations
18059 ;; min = (op1 < op2 ? op1 : op2)
18060 ;; max = (!(op1 < op2) ? op1 : op2)
18061 ;; Their operands are not commutative, and thus they may be used in the
18062 ;; presence of -0.0 and NaN.
18064 (define_insn "*avx_ieee_smin<mode>3"
18065 [(set (match_operand:MODEF 0 "register_operand" "=x")
18067 [(match_operand:MODEF 1 "register_operand" "x")
18068 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18070 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18071 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18072 [(set_attr "type" "sseadd")
18073 (set_attr "prefix" "vex")
18074 (set_attr "mode" "<MODE>")])
18076 (define_insn "*ieee_smin<mode>3"
18077 [(set (match_operand:MODEF 0 "register_operand" "=x")
18079 [(match_operand:MODEF 1 "register_operand" "0")
18080 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18082 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18083 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
18084 [(set_attr "type" "sseadd")
18085 (set_attr "mode" "<MODE>")])
18087 (define_insn "*avx_ieee_smax<mode>3"
18088 [(set (match_operand:MODEF 0 "register_operand" "=x")
18090 [(match_operand:MODEF 1 "register_operand" "0")
18091 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18093 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18094 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18095 [(set_attr "type" "sseadd")
18096 (set_attr "prefix" "vex")
18097 (set_attr "mode" "<MODE>")])
18099 (define_insn "*ieee_smax<mode>3"
18100 [(set (match_operand:MODEF 0 "register_operand" "=x")
18102 [(match_operand:MODEF 1 "register_operand" "0")
18103 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18105 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18106 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
18107 [(set_attr "type" "sseadd")
18108 (set_attr "mode" "<MODE>")])
18110 ;; Make two stack loads independent:
18112 ;; fld %st(0) -> fld bb
18113 ;; fmul bb fmul %st(1), %st
18115 ;; Actually we only match the last two instructions for simplicity.
18117 [(set (match_operand 0 "fp_register_operand" "")
18118 (match_operand 1 "fp_register_operand" ""))
18120 (match_operator 2 "binary_fp_operator"
18122 (match_operand 3 "memory_operand" "")]))]
18123 "REGNO (operands[0]) != REGNO (operands[1])"
18124 [(set (match_dup 0) (match_dup 3))
18125 (set (match_dup 0) (match_dup 4))]
18127 ;; The % modifier is not operational anymore in peephole2's, so we have to
18128 ;; swap the operands manually in the case of addition and multiplication.
18129 "if (COMMUTATIVE_ARITH_P (operands[2]))
18130 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18131 operands[0], operands[1]);
18133 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18134 operands[1], operands[0]);")
18136 ;; Conditional addition patterns
18137 (define_expand "add<mode>cc"
18138 [(match_operand:SWI 0 "register_operand" "")
18139 (match_operand 1 "comparison_operator" "")
18140 (match_operand:SWI 2 "register_operand" "")
18141 (match_operand:SWI 3 "const_int_operand" "")]
18143 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18146 ;; Misc patterns (?)
18148 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18149 ;; Otherwise there will be nothing to keep
18151 ;; [(set (reg ebp) (reg esp))]
18152 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18153 ;; (clobber (eflags)]
18154 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18156 ;; in proper program order.
18157 (define_insn "pro_epilogue_adjust_stack_1"
18158 [(set (match_operand:SI 0 "register_operand" "=r,r")
18159 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18160 (match_operand:SI 2 "immediate_operand" "i,i")))
18161 (clobber (reg:CC FLAGS_REG))
18162 (clobber (mem:BLK (scratch)))]
18165 switch (get_attr_type (insn))
18168 return "mov{l}\t{%1, %0|%0, %1}";
18171 if (CONST_INT_P (operands[2])
18172 && (INTVAL (operands[2]) == 128
18173 || (INTVAL (operands[2]) < 0
18174 && INTVAL (operands[2]) != -128)))
18176 operands[2] = GEN_INT (-INTVAL (operands[2]));
18177 return "sub{l}\t{%2, %0|%0, %2}";
18179 return "add{l}\t{%2, %0|%0, %2}";
18182 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18183 return "lea{l}\t{%a2, %0|%0, %a2}";
18186 gcc_unreachable ();
18189 [(set (attr "type")
18190 (cond [(and (eq_attr "alternative" "0")
18191 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18192 (const_string "alu")
18193 (match_operand:SI 2 "const0_operand" "")
18194 (const_string "imov")
18196 (const_string "lea")))
18197 (set (attr "length_immediate")
18198 (cond [(eq_attr "type" "imov")
18200 (and (eq_attr "type" "alu")
18201 (match_operand 2 "const128_operand" ""))
18204 (const_string "*")))
18205 (set_attr "mode" "SI")])
18207 (define_insn "pro_epilogue_adjust_stack_rex64"
18208 [(set (match_operand:DI 0 "register_operand" "=r,r")
18209 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18210 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18211 (clobber (reg:CC FLAGS_REG))
18212 (clobber (mem:BLK (scratch)))]
18215 switch (get_attr_type (insn))
18218 return "mov{q}\t{%1, %0|%0, %1}";
18221 if (CONST_INT_P (operands[2])
18222 /* Avoid overflows. */
18223 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18224 && (INTVAL (operands[2]) == 128
18225 || (INTVAL (operands[2]) < 0
18226 && INTVAL (operands[2]) != -128)))
18228 operands[2] = GEN_INT (-INTVAL (operands[2]));
18229 return "sub{q}\t{%2, %0|%0, %2}";
18231 return "add{q}\t{%2, %0|%0, %2}";
18234 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18235 return "lea{q}\t{%a2, %0|%0, %a2}";
18238 gcc_unreachable ();
18241 [(set (attr "type")
18242 (cond [(and (eq_attr "alternative" "0")
18243 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18244 (const_string "alu")
18245 (match_operand:DI 2 "const0_operand" "")
18246 (const_string "imov")
18248 (const_string "lea")))
18249 (set (attr "length_immediate")
18250 (cond [(eq_attr "type" "imov")
18252 (and (eq_attr "type" "alu")
18253 (match_operand 2 "const128_operand" ""))
18256 (const_string "*")))
18257 (set_attr "mode" "DI")])
18259 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18260 [(set (match_operand:DI 0 "register_operand" "=r,r")
18261 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18262 (match_operand:DI 3 "immediate_operand" "i,i")))
18263 (use (match_operand:DI 2 "register_operand" "r,r"))
18264 (clobber (reg:CC FLAGS_REG))
18265 (clobber (mem:BLK (scratch)))]
18268 switch (get_attr_type (insn))
18271 return "add{q}\t{%2, %0|%0, %2}";
18274 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18275 return "lea{q}\t{%a2, %0|%0, %a2}";
18278 gcc_unreachable ();
18281 [(set_attr "type" "alu,lea")
18282 (set_attr "mode" "DI")])
18284 (define_insn "allocate_stack_worker_32"
18285 [(set (match_operand:SI 0 "register_operand" "=a")
18286 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
18287 UNSPECV_STACK_PROBE))
18288 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
18289 (clobber (reg:CC FLAGS_REG))]
18290 "!TARGET_64BIT && TARGET_STACK_PROBE"
18292 [(set_attr "type" "multi")
18293 (set_attr "length" "5")])
18295 (define_insn "allocate_stack_worker_64"
18296 [(set (match_operand:DI 0 "register_operand" "=a")
18297 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
18298 UNSPECV_STACK_PROBE))
18299 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
18300 (clobber (reg:DI R10_REG))
18301 (clobber (reg:DI R11_REG))
18302 (clobber (reg:CC FLAGS_REG))]
18303 "TARGET_64BIT && TARGET_STACK_PROBE"
18305 [(set_attr "type" "multi")
18306 (set_attr "length" "5")])
18308 (define_expand "allocate_stack"
18309 [(match_operand 0 "register_operand" "")
18310 (match_operand 1 "general_operand" "")]
18311 "TARGET_STACK_PROBE"
18315 #ifndef CHECK_STACK_LIMIT
18316 #define CHECK_STACK_LIMIT 0
18319 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18320 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18322 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
18323 stack_pointer_rtx, 0, OPTAB_DIRECT);
18324 if (x != stack_pointer_rtx)
18325 emit_move_insn (stack_pointer_rtx, x);
18329 x = copy_to_mode_reg (Pmode, operands[1]);
18331 x = gen_allocate_stack_worker_64 (x, x);
18333 x = gen_allocate_stack_worker_32 (x, x);
18337 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18341 ;; Use IOR for stack probes, this is shorter.
18342 (define_expand "probe_stack"
18343 [(match_operand 0 "memory_operand" "")]
18346 if (GET_MODE (operands[0]) == DImode)
18347 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
18349 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
18353 (define_expand "builtin_setjmp_receiver"
18354 [(label_ref (match_operand 0 "" ""))]
18355 "!TARGET_64BIT && flag_pic"
18361 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
18362 rtx label_rtx = gen_label_rtx ();
18363 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18364 xops[0] = xops[1] = picreg;
18365 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18366 ix86_expand_binary_operator (MINUS, SImode, xops);
18370 emit_insn (gen_set_got (pic_offset_table_rtx));
18374 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18377 [(set (match_operand 0 "register_operand" "")
18378 (match_operator 3 "promotable_binary_operator"
18379 [(match_operand 1 "register_operand" "")
18380 (match_operand 2 "aligned_operand" "")]))
18381 (clobber (reg:CC FLAGS_REG))]
18382 "! TARGET_PARTIAL_REG_STALL && reload_completed
18383 && ((GET_MODE (operands[0]) == HImode
18384 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18385 /* ??? next two lines just !satisfies_constraint_K (...) */
18386 || !CONST_INT_P (operands[2])
18387 || satisfies_constraint_K (operands[2])))
18388 || (GET_MODE (operands[0]) == QImode
18389 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18390 [(parallel [(set (match_dup 0)
18391 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18392 (clobber (reg:CC FLAGS_REG))])]
18393 "operands[0] = gen_lowpart (SImode, operands[0]);
18394 operands[1] = gen_lowpart (SImode, operands[1]);
18395 if (GET_CODE (operands[3]) != ASHIFT)
18396 operands[2] = gen_lowpart (SImode, operands[2]);
18397 PUT_MODE (operands[3], SImode);")
18399 ; Promote the QImode tests, as i386 has encoding of the AND
18400 ; instruction with 32-bit sign-extended immediate and thus the
18401 ; instruction size is unchanged, except in the %eax case for
18402 ; which it is increased by one byte, hence the ! optimize_size.
18404 [(set (match_operand 0 "flags_reg_operand" "")
18405 (match_operator 2 "compare_operator"
18406 [(and (match_operand 3 "aligned_operand" "")
18407 (match_operand 4 "const_int_operand" ""))
18409 (set (match_operand 1 "register_operand" "")
18410 (and (match_dup 3) (match_dup 4)))]
18411 "! TARGET_PARTIAL_REG_STALL && reload_completed
18412 && optimize_insn_for_speed_p ()
18413 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18414 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18415 /* Ensure that the operand will remain sign-extended immediate. */
18416 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18417 [(parallel [(set (match_dup 0)
18418 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18421 (and:SI (match_dup 3) (match_dup 4)))])]
18424 = gen_int_mode (INTVAL (operands[4])
18425 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18426 operands[1] = gen_lowpart (SImode, operands[1]);
18427 operands[3] = gen_lowpart (SImode, operands[3]);
18430 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18431 ; the TEST instruction with 32-bit sign-extended immediate and thus
18432 ; the instruction size would at least double, which is not what we
18433 ; want even with ! optimize_size.
18435 [(set (match_operand 0 "flags_reg_operand" "")
18436 (match_operator 1 "compare_operator"
18437 [(and (match_operand:HI 2 "aligned_operand" "")
18438 (match_operand:HI 3 "const_int_operand" ""))
18440 "! TARGET_PARTIAL_REG_STALL && reload_completed
18441 && ! TARGET_FAST_PREFIX
18442 && optimize_insn_for_speed_p ()
18443 /* Ensure that the operand will remain sign-extended immediate. */
18444 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18445 [(set (match_dup 0)
18446 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18450 = gen_int_mode (INTVAL (operands[3])
18451 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18452 operands[2] = gen_lowpart (SImode, operands[2]);
18456 [(set (match_operand 0 "register_operand" "")
18457 (neg (match_operand 1 "register_operand" "")))
18458 (clobber (reg:CC FLAGS_REG))]
18459 "! TARGET_PARTIAL_REG_STALL && reload_completed
18460 && (GET_MODE (operands[0]) == HImode
18461 || (GET_MODE (operands[0]) == QImode
18462 && (TARGET_PROMOTE_QImode
18463 || optimize_insn_for_size_p ())))"
18464 [(parallel [(set (match_dup 0)
18465 (neg:SI (match_dup 1)))
18466 (clobber (reg:CC FLAGS_REG))])]
18467 "operands[0] = gen_lowpart (SImode, operands[0]);
18468 operands[1] = gen_lowpart (SImode, operands[1]);")
18471 [(set (match_operand 0 "register_operand" "")
18472 (not (match_operand 1 "register_operand" "")))]
18473 "! TARGET_PARTIAL_REG_STALL && reload_completed
18474 && (GET_MODE (operands[0]) == HImode
18475 || (GET_MODE (operands[0]) == QImode
18476 && (TARGET_PROMOTE_QImode
18477 || optimize_insn_for_size_p ())))"
18478 [(set (match_dup 0)
18479 (not:SI (match_dup 1)))]
18480 "operands[0] = gen_lowpart (SImode, operands[0]);
18481 operands[1] = gen_lowpart (SImode, operands[1]);")
18484 [(set (match_operand 0 "register_operand" "")
18485 (if_then_else (match_operator 1 "comparison_operator"
18486 [(reg FLAGS_REG) (const_int 0)])
18487 (match_operand 2 "register_operand" "")
18488 (match_operand 3 "register_operand" "")))]
18489 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18490 && (GET_MODE (operands[0]) == HImode
18491 || (GET_MODE (operands[0]) == QImode
18492 && (TARGET_PROMOTE_QImode
18493 || optimize_insn_for_size_p ())))"
18494 [(set (match_dup 0)
18495 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18496 "operands[0] = gen_lowpart (SImode, operands[0]);
18497 operands[2] = gen_lowpart (SImode, operands[2]);
18498 operands[3] = gen_lowpart (SImode, operands[3]);")
18501 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18502 ;; transform a complex memory operation into two memory to register operations.
18504 ;; Don't push memory operands
18506 [(set (match_operand:SI 0 "push_operand" "")
18507 (match_operand:SI 1 "memory_operand" ""))
18508 (match_scratch:SI 2 "r")]
18509 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18510 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18511 [(set (match_dup 2) (match_dup 1))
18512 (set (match_dup 0) (match_dup 2))]
18516 [(set (match_operand:DI 0 "push_operand" "")
18517 (match_operand:DI 1 "memory_operand" ""))
18518 (match_scratch:DI 2 "r")]
18519 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18520 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18521 [(set (match_dup 2) (match_dup 1))
18522 (set (match_dup 0) (match_dup 2))]
18525 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18528 [(set (match_operand:SF 0 "push_operand" "")
18529 (match_operand:SF 1 "memory_operand" ""))
18530 (match_scratch:SF 2 "r")]
18531 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18532 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18533 [(set (match_dup 2) (match_dup 1))
18534 (set (match_dup 0) (match_dup 2))]
18538 [(set (match_operand:HI 0 "push_operand" "")
18539 (match_operand:HI 1 "memory_operand" ""))
18540 (match_scratch:HI 2 "r")]
18541 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18542 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18543 [(set (match_dup 2) (match_dup 1))
18544 (set (match_dup 0) (match_dup 2))]
18548 [(set (match_operand:QI 0 "push_operand" "")
18549 (match_operand:QI 1 "memory_operand" ""))
18550 (match_scratch:QI 2 "q")]
18551 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18552 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18553 [(set (match_dup 2) (match_dup 1))
18554 (set (match_dup 0) (match_dup 2))]
18557 ;; Don't move an immediate directly to memory when the instruction
18560 [(match_scratch:SI 1 "r")
18561 (set (match_operand:SI 0 "memory_operand" "")
18563 "optimize_insn_for_speed_p ()
18564 && ! TARGET_USE_MOV0
18565 && TARGET_SPLIT_LONG_MOVES
18566 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
18567 && peep2_regno_dead_p (0, FLAGS_REG)"
18568 [(parallel [(set (match_dup 1) (const_int 0))
18569 (clobber (reg:CC FLAGS_REG))])
18570 (set (match_dup 0) (match_dup 1))]
18574 [(match_scratch:HI 1 "r")
18575 (set (match_operand:HI 0 "memory_operand" "")
18577 "optimize_insn_for_speed_p ()
18578 && ! TARGET_USE_MOV0
18579 && TARGET_SPLIT_LONG_MOVES
18580 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
18581 && peep2_regno_dead_p (0, FLAGS_REG)"
18582 [(parallel [(set (match_dup 2) (const_int 0))
18583 (clobber (reg:CC FLAGS_REG))])
18584 (set (match_dup 0) (match_dup 1))]
18585 "operands[2] = gen_lowpart (SImode, operands[1]);")
18588 [(match_scratch:QI 1 "q")
18589 (set (match_operand:QI 0 "memory_operand" "")
18591 "optimize_insn_for_speed_p ()
18592 && ! TARGET_USE_MOV0
18593 && TARGET_SPLIT_LONG_MOVES
18594 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
18595 && peep2_regno_dead_p (0, FLAGS_REG)"
18596 [(parallel [(set (match_dup 2) (const_int 0))
18597 (clobber (reg:CC FLAGS_REG))])
18598 (set (match_dup 0) (match_dup 1))]
18599 "operands[2] = gen_lowpart (SImode, operands[1]);")
18602 [(match_scratch:SI 2 "r")
18603 (set (match_operand:SI 0 "memory_operand" "")
18604 (match_operand:SI 1 "immediate_operand" ""))]
18605 "optimize_insn_for_speed_p ()
18606 && TARGET_SPLIT_LONG_MOVES
18607 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
18608 [(set (match_dup 2) (match_dup 1))
18609 (set (match_dup 0) (match_dup 2))]
18613 [(match_scratch:HI 2 "r")
18614 (set (match_operand:HI 0 "memory_operand" "")
18615 (match_operand:HI 1 "immediate_operand" ""))]
18616 "optimize_insn_for_speed_p ()
18617 && TARGET_SPLIT_LONG_MOVES
18618 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
18619 [(set (match_dup 2) (match_dup 1))
18620 (set (match_dup 0) (match_dup 2))]
18624 [(match_scratch:QI 2 "q")
18625 (set (match_operand:QI 0 "memory_operand" "")
18626 (match_operand:QI 1 "immediate_operand" ""))]
18627 "optimize_insn_for_speed_p ()
18628 && TARGET_SPLIT_LONG_MOVES
18629 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
18630 [(set (match_dup 2) (match_dup 1))
18631 (set (match_dup 0) (match_dup 2))]
18634 ;; Don't compare memory with zero, load and use a test instead.
18636 [(set (match_operand 0 "flags_reg_operand" "")
18637 (match_operator 1 "compare_operator"
18638 [(match_operand:SI 2 "memory_operand" "")
18640 (match_scratch:SI 3 "r")]
18641 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18642 [(set (match_dup 3) (match_dup 2))
18643 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18646 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18647 ;; Don't split NOTs with a displacement operand, because resulting XOR
18648 ;; will not be pairable anyway.
18650 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18651 ;; represented using a modRM byte. The XOR replacement is long decoded,
18652 ;; so this split helps here as well.
18654 ;; Note: Can't do this as a regular split because we can't get proper
18655 ;; lifetime information then.
18658 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18659 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18660 "optimize_insn_for_speed_p ()
18661 && ((TARGET_NOT_UNPAIRABLE
18662 && (!MEM_P (operands[0])
18663 || !memory_displacement_operand (operands[0], SImode)))
18664 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
18665 && peep2_regno_dead_p (0, FLAGS_REG)"
18666 [(parallel [(set (match_dup 0)
18667 (xor:SI (match_dup 1) (const_int -1)))
18668 (clobber (reg:CC FLAGS_REG))])]
18672 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18673 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18674 "optimize_insn_for_speed_p ()
18675 && ((TARGET_NOT_UNPAIRABLE
18676 && (!MEM_P (operands[0])
18677 || !memory_displacement_operand (operands[0], HImode)))
18678 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
18679 && peep2_regno_dead_p (0, FLAGS_REG)"
18680 [(parallel [(set (match_dup 0)
18681 (xor:HI (match_dup 1) (const_int -1)))
18682 (clobber (reg:CC FLAGS_REG))])]
18686 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18687 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18688 "optimize_insn_for_speed_p ()
18689 && ((TARGET_NOT_UNPAIRABLE
18690 && (!MEM_P (operands[0])
18691 || !memory_displacement_operand (operands[0], QImode)))
18692 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
18693 && peep2_regno_dead_p (0, FLAGS_REG)"
18694 [(parallel [(set (match_dup 0)
18695 (xor:QI (match_dup 1) (const_int -1)))
18696 (clobber (reg:CC FLAGS_REG))])]
18699 ;; Non pairable "test imm, reg" instructions can be translated to
18700 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18701 ;; byte opcode instead of two, have a short form for byte operands),
18702 ;; so do it for other CPUs as well. Given that the value was dead,
18703 ;; this should not create any new dependencies. Pass on the sub-word
18704 ;; versions if we're concerned about partial register stalls.
18707 [(set (match_operand 0 "flags_reg_operand" "")
18708 (match_operator 1 "compare_operator"
18709 [(and:SI (match_operand:SI 2 "register_operand" "")
18710 (match_operand:SI 3 "immediate_operand" ""))
18712 "ix86_match_ccmode (insn, CCNOmode)
18713 && (true_regnum (operands[2]) != AX_REG
18714 || satisfies_constraint_K (operands[3]))
18715 && peep2_reg_dead_p (1, operands[2])"
18717 [(set (match_dup 0)
18718 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18721 (and:SI (match_dup 2) (match_dup 3)))])]
18724 ;; We don't need to handle HImode case, because it will be promoted to SImode
18725 ;; on ! TARGET_PARTIAL_REG_STALL
18728 [(set (match_operand 0 "flags_reg_operand" "")
18729 (match_operator 1 "compare_operator"
18730 [(and:QI (match_operand:QI 2 "register_operand" "")
18731 (match_operand:QI 3 "immediate_operand" ""))
18733 "! TARGET_PARTIAL_REG_STALL
18734 && ix86_match_ccmode (insn, CCNOmode)
18735 && true_regnum (operands[2]) != AX_REG
18736 && peep2_reg_dead_p (1, operands[2])"
18738 [(set (match_dup 0)
18739 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18742 (and:QI (match_dup 2) (match_dup 3)))])]
18746 [(set (match_operand 0 "flags_reg_operand" "")
18747 (match_operator 1 "compare_operator"
18750 (match_operand 2 "ext_register_operand" "")
18753 (match_operand 3 "const_int_operand" ""))
18755 "! TARGET_PARTIAL_REG_STALL
18756 && ix86_match_ccmode (insn, CCNOmode)
18757 && true_regnum (operands[2]) != AX_REG
18758 && peep2_reg_dead_p (1, operands[2])"
18759 [(parallel [(set (match_dup 0)
18768 (set (zero_extract:SI (match_dup 2)
18779 ;; Don't do logical operations with memory inputs.
18781 [(match_scratch:SI 2 "r")
18782 (parallel [(set (match_operand:SI 0 "register_operand" "")
18783 (match_operator:SI 3 "arith_or_logical_operator"
18785 (match_operand:SI 1 "memory_operand" "")]))
18786 (clobber (reg:CC FLAGS_REG))])]
18787 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
18788 [(set (match_dup 2) (match_dup 1))
18789 (parallel [(set (match_dup 0)
18790 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18791 (clobber (reg:CC FLAGS_REG))])]
18795 [(match_scratch:SI 2 "r")
18796 (parallel [(set (match_operand:SI 0 "register_operand" "")
18797 (match_operator:SI 3 "arith_or_logical_operator"
18798 [(match_operand:SI 1 "memory_operand" "")
18800 (clobber (reg:CC FLAGS_REG))])]
18801 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
18802 [(set (match_dup 2) (match_dup 1))
18803 (parallel [(set (match_dup 0)
18804 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18805 (clobber (reg:CC FLAGS_REG))])]
18808 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
18809 ;; refers to the destination of the load!
18812 [(set (match_operand:SI 0 "register_operand" "")
18813 (match_operand:SI 1 "register_operand" ""))
18814 (parallel [(set (match_dup 0)
18815 (match_operator:SI 3 "commutative_operator"
18817 (match_operand:SI 2 "memory_operand" "")]))
18818 (clobber (reg:CC FLAGS_REG))])]
18819 "REGNO (operands[0]) != REGNO (operands[1])
18820 && GENERAL_REGNO_P (REGNO (operands[0]))
18821 && GENERAL_REGNO_P (REGNO (operands[1]))"
18822 [(set (match_dup 0) (match_dup 4))
18823 (parallel [(set (match_dup 0)
18824 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18825 (clobber (reg:CC FLAGS_REG))])]
18826 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
18829 [(set (match_operand 0 "register_operand" "")
18830 (match_operand 1 "register_operand" ""))
18832 (match_operator 3 "commutative_operator"
18834 (match_operand 2 "memory_operand" "")]))]
18835 "REGNO (operands[0]) != REGNO (operands[1])
18836 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
18837 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
18838 [(set (match_dup 0) (match_dup 2))
18840 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
18843 ; Don't do logical operations with memory outputs
18845 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18846 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18847 ; the same decoder scheduling characteristics as the original.
18850 [(match_scratch:SI 2 "r")
18851 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18852 (match_operator:SI 3 "arith_or_logical_operator"
18854 (match_operand:SI 1 "nonmemory_operand" "")]))
18855 (clobber (reg:CC FLAGS_REG))])]
18856 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
18857 /* Do not split stack checking probes. */
18858 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
18859 [(set (match_dup 2) (match_dup 0))
18860 (parallel [(set (match_dup 2)
18861 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18862 (clobber (reg:CC FLAGS_REG))])
18863 (set (match_dup 0) (match_dup 2))]
18867 [(match_scratch:SI 2 "r")
18868 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18869 (match_operator:SI 3 "arith_or_logical_operator"
18870 [(match_operand:SI 1 "nonmemory_operand" "")
18872 (clobber (reg:CC FLAGS_REG))])]
18873 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
18874 /* Do not split stack checking probes. */
18875 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
18876 [(set (match_dup 2) (match_dup 0))
18877 (parallel [(set (match_dup 2)
18878 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18879 (clobber (reg:CC FLAGS_REG))])
18880 (set (match_dup 0) (match_dup 2))]
18883 ;; Attempt to always use XOR for zeroing registers.
18885 [(set (match_operand 0 "register_operand" "")
18886 (match_operand 1 "const0_operand" ""))]
18887 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18888 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18889 && GENERAL_REG_P (operands[0])
18890 && peep2_regno_dead_p (0, FLAGS_REG)"
18891 [(parallel [(set (match_dup 0) (const_int 0))
18892 (clobber (reg:CC FLAGS_REG))])]
18894 operands[0] = gen_lowpart (word_mode, operands[0]);
18898 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18900 "(GET_MODE (operands[0]) == QImode
18901 || GET_MODE (operands[0]) == HImode)
18902 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18903 && peep2_regno_dead_p (0, FLAGS_REG)"
18904 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18905 (clobber (reg:CC FLAGS_REG))])])
18907 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18909 [(set (match_operand 0 "register_operand" "")
18911 "(GET_MODE (operands[0]) == HImode
18912 || GET_MODE (operands[0]) == SImode
18913 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18914 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
18915 && peep2_regno_dead_p (0, FLAGS_REG)"
18916 [(parallel [(set (match_dup 0) (const_int -1))
18917 (clobber (reg:CC FLAGS_REG))])]
18918 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18921 ;; Attempt to convert simple leas to adds. These can be created by
18924 [(set (match_operand:SI 0 "register_operand" "")
18925 (plus:SI (match_dup 0)
18926 (match_operand:SI 1 "nonmemory_operand" "")))]
18927 "peep2_regno_dead_p (0, FLAGS_REG)"
18928 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18929 (clobber (reg:CC FLAGS_REG))])]
18933 [(set (match_operand:SI 0 "register_operand" "")
18934 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18935 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18936 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18937 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18938 (clobber (reg:CC FLAGS_REG))])]
18939 "operands[2] = gen_lowpart (SImode, operands[2]);")
18942 [(set (match_operand:DI 0 "register_operand" "")
18943 (plus:DI (match_dup 0)
18944 (match_operand:DI 1 "x86_64_general_operand" "")))]
18945 "peep2_regno_dead_p (0, FLAGS_REG)"
18946 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18947 (clobber (reg:CC FLAGS_REG))])]
18951 [(set (match_operand:SI 0 "register_operand" "")
18952 (mult:SI (match_dup 0)
18953 (match_operand:SI 1 "const_int_operand" "")))]
18954 "exact_log2 (INTVAL (operands[1])) >= 0
18955 && peep2_regno_dead_p (0, FLAGS_REG)"
18956 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18957 (clobber (reg:CC FLAGS_REG))])]
18958 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18961 [(set (match_operand:DI 0 "register_operand" "")
18962 (mult:DI (match_dup 0)
18963 (match_operand:DI 1 "const_int_operand" "")))]
18964 "exact_log2 (INTVAL (operands[1])) >= 0
18965 && peep2_regno_dead_p (0, FLAGS_REG)"
18966 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18967 (clobber (reg:CC FLAGS_REG))])]
18968 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18971 [(set (match_operand:SI 0 "register_operand" "")
18972 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18973 (match_operand:DI 2 "const_int_operand" "")) 0))]
18974 "exact_log2 (INTVAL (operands[2])) >= 0
18975 && REGNO (operands[0]) == REGNO (operands[1])
18976 && peep2_regno_dead_p (0, FLAGS_REG)"
18977 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18978 (clobber (reg:CC FLAGS_REG))])]
18979 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18981 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18982 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18983 ;; many CPUs it is also faster, since special hardware to avoid esp
18984 ;; dependencies is present.
18986 ;; While some of these conversions may be done using splitters, we use peepholes
18987 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18989 ;; Convert prologue esp subtractions to push.
18990 ;; We need register to push. In order to keep verify_flow_info happy we have
18992 ;; - use scratch and clobber it in order to avoid dependencies
18993 ;; - use already live register
18994 ;; We can't use the second way right now, since there is no reliable way how to
18995 ;; verify that given register is live. First choice will also most likely in
18996 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18997 ;; call clobbered registers are dead. We may want to use base pointer as an
18998 ;; alternative when no register is available later.
19001 [(match_scratch:SI 0 "r")
19002 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19003 (clobber (reg:CC FLAGS_REG))
19004 (clobber (mem:BLK (scratch)))])]
19005 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19006 [(clobber (match_dup 0))
19007 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19008 (clobber (mem:BLK (scratch)))])])
19011 [(match_scratch:SI 0 "r")
19012 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19013 (clobber (reg:CC FLAGS_REG))
19014 (clobber (mem:BLK (scratch)))])]
19015 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19016 [(clobber (match_dup 0))
19017 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19018 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19019 (clobber (mem:BLK (scratch)))])])
19021 ;; Convert esp subtractions to push.
19023 [(match_scratch:SI 0 "r")
19024 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19025 (clobber (reg:CC FLAGS_REG))])]
19026 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19027 [(clobber (match_dup 0))
19028 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19031 [(match_scratch:SI 0 "r")
19032 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19033 (clobber (reg:CC FLAGS_REG))])]
19034 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19035 [(clobber (match_dup 0))
19036 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19037 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19039 ;; Convert epilogue deallocator to pop.
19041 [(match_scratch:SI 0 "r")
19042 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19043 (clobber (reg:CC FLAGS_REG))
19044 (clobber (mem:BLK (scratch)))])]
19045 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19046 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19047 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19048 (clobber (mem:BLK (scratch)))])]
19051 ;; Two pops case is tricky, since pop causes dependency on destination register.
19052 ;; We use two registers if available.
19054 [(match_scratch:SI 0 "r")
19055 (match_scratch:SI 1 "r")
19056 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19057 (clobber (reg:CC FLAGS_REG))
19058 (clobber (mem:BLK (scratch)))])]
19059 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19060 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19061 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19062 (clobber (mem:BLK (scratch)))])
19063 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19064 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19068 [(match_scratch:SI 0 "r")
19069 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19070 (clobber (reg:CC FLAGS_REG))
19071 (clobber (mem:BLK (scratch)))])]
19072 "optimize_insn_for_size_p ()"
19073 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19074 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19075 (clobber (mem:BLK (scratch)))])
19076 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19077 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19080 ;; Convert esp additions to pop.
19082 [(match_scratch:SI 0 "r")
19083 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19084 (clobber (reg:CC FLAGS_REG))])]
19086 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19087 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19090 ;; Two pops case is tricky, since pop causes dependency on destination register.
19091 ;; We use two registers if available.
19093 [(match_scratch:SI 0 "r")
19094 (match_scratch:SI 1 "r")
19095 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19096 (clobber (reg:CC FLAGS_REG))])]
19098 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19099 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19100 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19101 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19105 [(match_scratch:SI 0 "r")
19106 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19107 (clobber (reg:CC FLAGS_REG))])]
19108 "optimize_insn_for_size_p ()"
19109 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19110 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19111 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19112 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19115 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19116 ;; required and register dies. Similarly for 128 to -128.
19118 [(set (match_operand 0 "flags_reg_operand" "")
19119 (match_operator 1 "compare_operator"
19120 [(match_operand 2 "register_operand" "")
19121 (match_operand 3 "const_int_operand" "")]))]
19122 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19123 && incdec_operand (operands[3], GET_MODE (operands[3])))
19124 || (!TARGET_FUSE_CMP_AND_BRANCH
19125 && INTVAL (operands[3]) == 128))
19126 && ix86_match_ccmode (insn, CCGCmode)
19127 && peep2_reg_dead_p (1, operands[2])"
19128 [(parallel [(set (match_dup 0)
19129 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19130 (clobber (match_dup 2))])]
19134 [(match_scratch:DI 0 "r")
19135 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19136 (clobber (reg:CC FLAGS_REG))
19137 (clobber (mem:BLK (scratch)))])]
19138 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19139 [(clobber (match_dup 0))
19140 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19141 (clobber (mem:BLK (scratch)))])])
19144 [(match_scratch:DI 0 "r")
19145 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19146 (clobber (reg:CC FLAGS_REG))
19147 (clobber (mem:BLK (scratch)))])]
19148 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19149 [(clobber (match_dup 0))
19150 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19151 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19152 (clobber (mem:BLK (scratch)))])])
19154 ;; Convert esp subtractions to push.
19156 [(match_scratch:DI 0 "r")
19157 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19158 (clobber (reg:CC FLAGS_REG))])]
19159 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19160 [(clobber (match_dup 0))
19161 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19164 [(match_scratch:DI 0 "r")
19165 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19166 (clobber (reg:CC FLAGS_REG))])]
19167 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19168 [(clobber (match_dup 0))
19169 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19170 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19172 ;; Convert epilogue deallocator to pop.
19174 [(match_scratch:DI 0 "r")
19175 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19176 (clobber (reg:CC FLAGS_REG))
19177 (clobber (mem:BLK (scratch)))])]
19178 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19179 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19180 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19181 (clobber (mem:BLK (scratch)))])]
19184 ;; Two pops case is tricky, since pop causes dependency on destination register.
19185 ;; We use two registers if available.
19187 [(match_scratch:DI 0 "r")
19188 (match_scratch:DI 1 "r")
19189 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19190 (clobber (reg:CC FLAGS_REG))
19191 (clobber (mem:BLK (scratch)))])]
19192 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19193 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19194 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19195 (clobber (mem:BLK (scratch)))])
19196 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19197 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19201 [(match_scratch:DI 0 "r")
19202 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19203 (clobber (reg:CC FLAGS_REG))
19204 (clobber (mem:BLK (scratch)))])]
19205 "optimize_insn_for_size_p ()"
19206 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19207 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19208 (clobber (mem:BLK (scratch)))])
19209 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19210 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19213 ;; Convert esp additions to pop.
19215 [(match_scratch:DI 0 "r")
19216 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19217 (clobber (reg:CC FLAGS_REG))])]
19219 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19220 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19223 ;; Two pops case is tricky, since pop causes dependency on destination register.
19224 ;; We use two registers if available.
19226 [(match_scratch:DI 0 "r")
19227 (match_scratch:DI 1 "r")
19228 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19229 (clobber (reg:CC FLAGS_REG))])]
19231 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19232 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19233 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19234 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19238 [(match_scratch:DI 0 "r")
19239 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19240 (clobber (reg:CC FLAGS_REG))])]
19241 "optimize_insn_for_size_p ()"
19242 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19243 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19244 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19245 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19248 ;; Convert imul by three, five and nine into lea
19251 [(set (match_operand:SI 0 "register_operand" "")
19252 (mult:SI (match_operand:SI 1 "register_operand" "")
19253 (match_operand:SI 2 "const_int_operand" "")))
19254 (clobber (reg:CC FLAGS_REG))])]
19255 "INTVAL (operands[2]) == 3
19256 || INTVAL (operands[2]) == 5
19257 || INTVAL (operands[2]) == 9"
19258 [(set (match_dup 0)
19259 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19261 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19265 [(set (match_operand:SI 0 "register_operand" "")
19266 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19267 (match_operand:SI 2 "const_int_operand" "")))
19268 (clobber (reg:CC FLAGS_REG))])]
19269 "optimize_insn_for_speed_p ()
19270 && (INTVAL (operands[2]) == 3
19271 || INTVAL (operands[2]) == 5
19272 || INTVAL (operands[2]) == 9)"
19273 [(set (match_dup 0) (match_dup 1))
19275 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19277 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19281 [(set (match_operand:DI 0 "register_operand" "")
19282 (mult:DI (match_operand:DI 1 "register_operand" "")
19283 (match_operand:DI 2 "const_int_operand" "")))
19284 (clobber (reg:CC FLAGS_REG))])]
19286 && (INTVAL (operands[2]) == 3
19287 || INTVAL (operands[2]) == 5
19288 || INTVAL (operands[2]) == 9)"
19289 [(set (match_dup 0)
19290 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19292 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19296 [(set (match_operand:DI 0 "register_operand" "")
19297 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19298 (match_operand:DI 2 "const_int_operand" "")))
19299 (clobber (reg:CC FLAGS_REG))])]
19301 && optimize_insn_for_speed_p ()
19302 && (INTVAL (operands[2]) == 3
19303 || INTVAL (operands[2]) == 5
19304 || INTVAL (operands[2]) == 9)"
19305 [(set (match_dup 0) (match_dup 1))
19307 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19309 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19311 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19312 ;; imul $32bit_imm, reg, reg is direct decoded.
19314 [(match_scratch:DI 3 "r")
19315 (parallel [(set (match_operand:DI 0 "register_operand" "")
19316 (mult:DI (match_operand:DI 1 "memory_operand" "")
19317 (match_operand:DI 2 "immediate_operand" "")))
19318 (clobber (reg:CC FLAGS_REG))])]
19319 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19320 && !satisfies_constraint_K (operands[2])"
19321 [(set (match_dup 3) (match_dup 1))
19322 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19323 (clobber (reg:CC FLAGS_REG))])]
19327 [(match_scratch:SI 3 "r")
19328 (parallel [(set (match_operand:SI 0 "register_operand" "")
19329 (mult:SI (match_operand:SI 1 "memory_operand" "")
19330 (match_operand:SI 2 "immediate_operand" "")))
19331 (clobber (reg:CC FLAGS_REG))])]
19332 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19333 && !satisfies_constraint_K (operands[2])"
19334 [(set (match_dup 3) (match_dup 1))
19335 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19336 (clobber (reg:CC FLAGS_REG))])]
19340 [(match_scratch:SI 3 "r")
19341 (parallel [(set (match_operand:DI 0 "register_operand" "")
19343 (mult:SI (match_operand:SI 1 "memory_operand" "")
19344 (match_operand:SI 2 "immediate_operand" ""))))
19345 (clobber (reg:CC FLAGS_REG))])]
19346 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19347 && !satisfies_constraint_K (operands[2])"
19348 [(set (match_dup 3) (match_dup 1))
19349 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19350 (clobber (reg:CC FLAGS_REG))])]
19353 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19354 ;; Convert it into imul reg, reg
19355 ;; It would be better to force assembler to encode instruction using long
19356 ;; immediate, but there is apparently no way to do so.
19358 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19359 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19360 (match_operand:DI 2 "const_int_operand" "")))
19361 (clobber (reg:CC FLAGS_REG))])
19362 (match_scratch:DI 3 "r")]
19363 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19364 && satisfies_constraint_K (operands[2])"
19365 [(set (match_dup 3) (match_dup 2))
19366 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19367 (clobber (reg:CC FLAGS_REG))])]
19369 if (!rtx_equal_p (operands[0], operands[1]))
19370 emit_move_insn (operands[0], operands[1]);
19374 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19375 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19376 (match_operand:SI 2 "const_int_operand" "")))
19377 (clobber (reg:CC FLAGS_REG))])
19378 (match_scratch:SI 3 "r")]
19379 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19380 && satisfies_constraint_K (operands[2])"
19381 [(set (match_dup 3) (match_dup 2))
19382 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19383 (clobber (reg:CC FLAGS_REG))])]
19385 if (!rtx_equal_p (operands[0], operands[1]))
19386 emit_move_insn (operands[0], operands[1]);
19390 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19391 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19392 (match_operand:HI 2 "immediate_operand" "")))
19393 (clobber (reg:CC FLAGS_REG))])
19394 (match_scratch:HI 3 "r")]
19395 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
19396 [(set (match_dup 3) (match_dup 2))
19397 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19398 (clobber (reg:CC FLAGS_REG))])]
19400 if (!rtx_equal_p (operands[0], operands[1]))
19401 emit_move_insn (operands[0], operands[1]);
19404 ;; After splitting up read-modify operations, array accesses with memory
19405 ;; operands might end up in form:
19407 ;; movl 4(%esp), %edx
19409 ;; instead of pre-splitting:
19411 ;; addl 4(%esp), %eax
19413 ;; movl 4(%esp), %edx
19414 ;; leal (%edx,%eax,4), %eax
19417 [(parallel [(set (match_operand 0 "register_operand" "")
19418 (ashift (match_operand 1 "register_operand" "")
19419 (match_operand 2 "const_int_operand" "")))
19420 (clobber (reg:CC FLAGS_REG))])
19421 (set (match_operand 3 "register_operand")
19422 (match_operand 4 "x86_64_general_operand" ""))
19423 (parallel [(set (match_operand 5 "register_operand" "")
19424 (plus (match_operand 6 "register_operand" "")
19425 (match_operand 7 "register_operand" "")))
19426 (clobber (reg:CC FLAGS_REG))])]
19427 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
19428 /* Validate MODE for lea. */
19429 && ((!TARGET_PARTIAL_REG_STALL
19430 && (GET_MODE (operands[0]) == QImode
19431 || GET_MODE (operands[0]) == HImode))
19432 || GET_MODE (operands[0]) == SImode
19433 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19434 /* We reorder load and the shift. */
19435 && !rtx_equal_p (operands[1], operands[3])
19436 && !reg_overlap_mentioned_p (operands[0], operands[4])
19437 /* Last PLUS must consist of operand 0 and 3. */
19438 && !rtx_equal_p (operands[0], operands[3])
19439 && (rtx_equal_p (operands[3], operands[6])
19440 || rtx_equal_p (operands[3], operands[7]))
19441 && (rtx_equal_p (operands[0], operands[6])
19442 || rtx_equal_p (operands[0], operands[7]))
19443 /* The intermediate operand 0 must die or be same as output. */
19444 && (rtx_equal_p (operands[0], operands[5])
19445 || peep2_reg_dead_p (3, operands[0]))"
19446 [(set (match_dup 3) (match_dup 4))
19447 (set (match_dup 0) (match_dup 1))]
19449 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
19450 int scale = 1 << INTVAL (operands[2]);
19451 rtx index = gen_lowpart (Pmode, operands[1]);
19452 rtx base = gen_lowpart (Pmode, operands[3]);
19453 rtx dest = gen_lowpart (mode, operands[5]);
19455 operands[1] = gen_rtx_PLUS (Pmode, base,
19456 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
19458 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19459 operands[0] = dest;
19462 ;; Call-value patterns last so that the wildcard operand does not
19463 ;; disrupt insn-recog's switch tables.
19465 (define_insn "*call_value_pop_0"
19466 [(set (match_operand 0 "" "")
19467 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19468 (match_operand:SI 2 "" "")))
19469 (set (reg:SI SP_REG)
19470 (plus:SI (reg:SI SP_REG)
19471 (match_operand:SI 3 "immediate_operand" "")))]
19474 if (SIBLING_CALL_P (insn))
19477 return "call\t%P1";
19479 [(set_attr "type" "callv")])
19481 (define_insn "*call_value_pop_1"
19482 [(set (match_operand 0 "" "")
19483 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
19484 (match_operand:SI 2 "" "")))
19485 (set (reg:SI SP_REG)
19486 (plus:SI (reg:SI SP_REG)
19487 (match_operand:SI 3 "immediate_operand" "i")))]
19488 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
19490 if (constant_call_address_operand (operands[1], Pmode))
19491 return "call\t%P1";
19492 return "call\t%A1";
19494 [(set_attr "type" "callv")])
19496 (define_insn "*sibcall_value_pop_1"
19497 [(set (match_operand 0 "" "")
19498 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
19499 (match_operand:SI 2 "" "")))
19500 (set (reg:SI SP_REG)
19501 (plus:SI (reg:SI SP_REG)
19502 (match_operand:SI 3 "immediate_operand" "i,i")))]
19503 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
19507 [(set_attr "type" "callv")])
19509 (define_insn "*call_value_0"
19510 [(set (match_operand 0 "" "")
19511 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19512 (match_operand:SI 2 "" "")))]
19515 if (SIBLING_CALL_P (insn))
19518 return "call\t%P1";
19520 [(set_attr "type" "callv")])
19522 (define_insn "*call_value_0_rex64"
19523 [(set (match_operand 0 "" "")
19524 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19525 (match_operand:DI 2 "const_int_operand" "")))]
19528 if (SIBLING_CALL_P (insn))
19531 return "call\t%P1";
19533 [(set_attr "type" "callv")])
19535 (define_insn "*call_value_0_rex64_ms_sysv"
19536 [(set (match_operand 0 "" "")
19537 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19538 (match_operand:DI 2 "const_int_operand" "")))
19539 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
19540 (clobber (reg:TI XMM6_REG))
19541 (clobber (reg:TI XMM7_REG))
19542 (clobber (reg:TI XMM8_REG))
19543 (clobber (reg:TI XMM9_REG))
19544 (clobber (reg:TI XMM10_REG))
19545 (clobber (reg:TI XMM11_REG))
19546 (clobber (reg:TI XMM12_REG))
19547 (clobber (reg:TI XMM13_REG))
19548 (clobber (reg:TI XMM14_REG))
19549 (clobber (reg:TI XMM15_REG))
19550 (clobber (reg:DI SI_REG))
19551 (clobber (reg:DI DI_REG))]
19552 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
19554 if (SIBLING_CALL_P (insn))
19557 return "call\t%P1";
19559 [(set_attr "type" "callv")])
19561 (define_insn "*call_value_1"
19562 [(set (match_operand 0 "" "")
19563 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
19564 (match_operand:SI 2 "" "")))]
19565 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
19567 if (constant_call_address_operand (operands[1], Pmode))
19568 return "call\t%P1";
19569 return "call\t%A1";
19571 [(set_attr "type" "callv")])
19573 (define_insn "*sibcall_value_1"
19574 [(set (match_operand 0 "" "")
19575 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
19576 (match_operand:SI 2 "" "")))]
19577 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
19581 [(set_attr "type" "callv")])
19583 (define_insn "*call_value_1_rex64"
19584 [(set (match_operand 0 "" "")
19585 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19586 (match_operand:DI 2 "" "")))]
19587 "TARGET_64BIT && !SIBLING_CALL_P (insn)
19588 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
19590 if (constant_call_address_operand (operands[1], Pmode))
19591 return "call\t%P1";
19592 return "call\t%A1";
19594 [(set_attr "type" "callv")])
19596 (define_insn "*call_value_1_rex64_ms_sysv"
19597 [(set (match_operand 0 "" "")
19598 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19599 (match_operand:DI 2 "" "")))
19600 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
19601 (clobber (reg:TI XMM6_REG))
19602 (clobber (reg:TI XMM7_REG))
19603 (clobber (reg:TI XMM8_REG))
19604 (clobber (reg:TI XMM9_REG))
19605 (clobber (reg:TI XMM10_REG))
19606 (clobber (reg:TI XMM11_REG))
19607 (clobber (reg:TI XMM12_REG))
19608 (clobber (reg:TI XMM13_REG))
19609 (clobber (reg:TI XMM14_REG))
19610 (clobber (reg:TI XMM15_REG))
19611 (clobber (reg:DI SI_REG))
19612 (clobber (reg:DI DI_REG))]
19613 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
19615 if (constant_call_address_operand (operands[1], Pmode))
19616 return "call\t%P1";
19617 return "call\t%A1";
19619 [(set_attr "type" "callv")])
19621 (define_insn "*call_value_1_rex64_large"
19622 [(set (match_operand 0 "" "")
19623 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
19624 (match_operand:DI 2 "" "")))]
19625 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
19627 [(set_attr "type" "callv")])
19629 (define_insn "*sibcall_value_1_rex64"
19630 [(set (match_operand 0 "" "")
19631 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
19632 (match_operand:DI 2 "" "")))]
19633 "TARGET_64BIT && SIBLING_CALL_P (insn)"
19637 [(set_attr "type" "callv")])
19639 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19640 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19641 ;; caught for use by garbage collectors and the like. Using an insn that
19642 ;; maps to SIGILL makes it more likely the program will rightfully die.
19643 ;; Keeping with tradition, "6" is in honor of #UD.
19644 (define_insn "trap"
19645 [(trap_if (const_int 1) (const_int 6))]
19647 { return ASM_SHORT "0x0b0f"; }
19648 [(set_attr "length" "2")])
19650 (define_expand "sse_prologue_save"
19651 [(parallel [(set (match_operand:BLK 0 "" "")
19652 (unspec:BLK [(reg:DI XMM0_REG)
19659 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
19660 (use (match_operand:DI 1 "register_operand" ""))
19661 (use (match_operand:DI 2 "immediate_operand" ""))
19662 (use (label_ref:DI (match_operand 3 "" "")))])]
19666 (define_insn "*sse_prologue_save_insn"
19667 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19668 (match_operand:DI 4 "const_int_operand" "n")))
19669 (unspec:BLK [(reg:DI XMM0_REG)
19676 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
19677 (use (match_operand:DI 1 "register_operand" "r"))
19678 (use (match_operand:DI 2 "const_int_operand" "i"))
19679 (use (label_ref:DI (match_operand 3 "" "X")))]
19681 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
19682 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19685 operands[0] = gen_rtx_MEM (Pmode,
19686 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19687 /* VEX instruction with a REX prefix will #UD. */
19688 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
19689 gcc_unreachable ();
19691 output_asm_insn ("jmp\t%A1", operands);
19692 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19694 operands[4] = adjust_address (operands[0], DImode, i*16);
19695 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19696 PUT_MODE (operands[4], TImode);
19697 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19698 output_asm_insn ("rex", operands);
19699 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
19701 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19702 CODE_LABEL_NUMBER (operands[3]));
19705 [(set_attr "type" "other")
19706 (set_attr "length_immediate" "0")
19707 (set_attr "length_address" "0")
19708 (set (attr "length")
19710 (eq (symbol_ref "TARGET_AVX") (const_int 0))
19711 (const_string "34")
19712 (const_string "42")))
19713 (set_attr "memory" "store")
19714 (set_attr "modrm" "0")
19715 (set_attr "prefix" "maybe_vex")
19716 (set_attr "mode" "DI")])
19718 (define_expand "prefetch"
19719 [(prefetch (match_operand 0 "address_operand" "")
19720 (match_operand:SI 1 "const_int_operand" "")
19721 (match_operand:SI 2 "const_int_operand" ""))]
19722 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19724 int rw = INTVAL (operands[1]);
19725 int locality = INTVAL (operands[2]);
19727 gcc_assert (rw == 0 || rw == 1);
19728 gcc_assert (locality >= 0 && locality <= 3);
19729 gcc_assert (GET_MODE (operands[0]) == Pmode
19730 || GET_MODE (operands[0]) == VOIDmode);
19732 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19733 supported by SSE counterpart or the SSE prefetch is not available
19734 (K6 machines). Otherwise use SSE prefetch as it allows specifying
19736 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19737 operands[2] = GEN_INT (3);
19739 operands[1] = const0_rtx;
19742 (define_insn "*prefetch_sse"
19743 [(prefetch (match_operand:SI 0 "address_operand" "p")
19745 (match_operand:SI 1 "const_int_operand" ""))]
19746 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19748 static const char * const patterns[4] = {
19749 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19752 int locality = INTVAL (operands[1]);
19753 gcc_assert (locality >= 0 && locality <= 3);
19755 return patterns[locality];
19757 [(set_attr "type" "sse")
19758 (set_attr "atom_sse_attr" "prefetch")
19759 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
19760 (set_attr "memory" "none")])
19762 (define_insn "*prefetch_sse_rex"
19763 [(prefetch (match_operand:DI 0 "address_operand" "p")
19765 (match_operand:SI 1 "const_int_operand" ""))]
19766 "TARGET_PREFETCH_SSE && TARGET_64BIT"
19768 static const char * const patterns[4] = {
19769 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19772 int locality = INTVAL (operands[1]);
19773 gcc_assert (locality >= 0 && locality <= 3);
19775 return patterns[locality];
19777 [(set_attr "type" "sse")
19778 (set_attr "atom_sse_attr" "prefetch")
19779 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
19780 (set_attr "memory" "none")])
19782 (define_insn "*prefetch_3dnow"
19783 [(prefetch (match_operand:SI 0 "address_operand" "p")
19784 (match_operand:SI 1 "const_int_operand" "n")
19786 "TARGET_3DNOW && !TARGET_64BIT"
19788 if (INTVAL (operands[1]) == 0)
19789 return "prefetch\t%a0";
19791 return "prefetchw\t%a0";
19793 [(set_attr "type" "mmx")
19794 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
19795 (set_attr "memory" "none")])
19797 (define_insn "*prefetch_3dnow_rex"
19798 [(prefetch (match_operand:DI 0 "address_operand" "p")
19799 (match_operand:SI 1 "const_int_operand" "n")
19801 "TARGET_3DNOW && TARGET_64BIT"
19803 if (INTVAL (operands[1]) == 0)
19804 return "prefetch\t%a0";
19806 return "prefetchw\t%a0";
19808 [(set_attr "type" "mmx")
19809 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
19810 (set_attr "memory" "none")])
19812 (define_expand "stack_protect_set"
19813 [(match_operand 0 "memory_operand" "")
19814 (match_operand 1 "memory_operand" "")]
19817 #ifdef TARGET_THREAD_SSP_OFFSET
19819 emit_insn (gen_stack_tls_protect_set_di (operands[0],
19820 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19822 emit_insn (gen_stack_tls_protect_set_si (operands[0],
19823 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19826 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
19828 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
19833 (define_insn "stack_protect_set_si"
19834 [(set (match_operand:SI 0 "memory_operand" "=m")
19835 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19836 (set (match_scratch:SI 2 "=&r") (const_int 0))
19837 (clobber (reg:CC FLAGS_REG))]
19839 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
19840 [(set_attr "type" "multi")])
19842 (define_insn "stack_protect_set_di"
19843 [(set (match_operand:DI 0 "memory_operand" "=m")
19844 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19845 (set (match_scratch:DI 2 "=&r") (const_int 0))
19846 (clobber (reg:CC FLAGS_REG))]
19848 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19849 [(set_attr "type" "multi")])
19851 (define_insn "stack_tls_protect_set_si"
19852 [(set (match_operand:SI 0 "memory_operand" "=m")
19853 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
19854 (set (match_scratch:SI 2 "=&r") (const_int 0))
19855 (clobber (reg:CC FLAGS_REG))]
19857 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
19858 [(set_attr "type" "multi")])
19860 (define_insn "stack_tls_protect_set_di"
19861 [(set (match_operand:DI 0 "memory_operand" "=m")
19862 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
19863 (set (match_scratch:DI 2 "=&r") (const_int 0))
19864 (clobber (reg:CC FLAGS_REG))]
19867 /* The kernel uses a different segment register for performance reasons; a
19868 system call would not have to trash the userspace segment register,
19869 which would be expensive */
19870 if (ix86_cmodel != CM_KERNEL)
19871 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
19873 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
19875 [(set_attr "type" "multi")])
19877 (define_expand "stack_protect_test"
19878 [(match_operand 0 "memory_operand" "")
19879 (match_operand 1 "memory_operand" "")
19880 (match_operand 2 "" "")]
19883 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19885 #ifdef TARGET_THREAD_SSP_OFFSET
19887 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
19888 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19890 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
19891 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19894 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
19896 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
19899 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19900 flags, const0_rtx, operands[2]));
19904 (define_insn "stack_protect_test_si"
19905 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19906 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
19907 (match_operand:SI 2 "memory_operand" "m")]
19909 (clobber (match_scratch:SI 3 "=&r"))]
19911 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
19912 [(set_attr "type" "multi")])
19914 (define_insn "stack_protect_test_di"
19915 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19916 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
19917 (match_operand:DI 2 "memory_operand" "m")]
19919 (clobber (match_scratch:DI 3 "=&r"))]
19921 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
19922 [(set_attr "type" "multi")])
19924 (define_insn "stack_tls_protect_test_si"
19925 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19926 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
19927 (match_operand:SI 2 "const_int_operand" "i")]
19928 UNSPEC_SP_TLS_TEST))
19929 (clobber (match_scratch:SI 3 "=r"))]
19931 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
19932 [(set_attr "type" "multi")])
19934 (define_insn "stack_tls_protect_test_di"
19935 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19936 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
19937 (match_operand:DI 2 "const_int_operand" "i")]
19938 UNSPEC_SP_TLS_TEST))
19939 (clobber (match_scratch:DI 3 "=r"))]
19942 /* The kernel uses a different segment register for performance reasons; a
19943 system call would not have to trash the userspace segment register,
19944 which would be expensive */
19945 if (ix86_cmodel != CM_KERNEL)
19946 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
19948 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
19950 [(set_attr "type" "multi")])
19952 (define_insn "sse4_2_crc32<mode>"
19953 [(set (match_operand:SI 0 "register_operand" "=r")
19955 [(match_operand:SI 1 "register_operand" "0")
19956 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19958 "TARGET_SSE4_2 || TARGET_CRC32"
19959 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19960 [(set_attr "type" "sselog1")
19961 (set_attr "prefix_rep" "1")
19962 (set_attr "prefix_extra" "1")
19963 (set (attr "prefix_data16")
19964 (if_then_else (match_operand:HI 2 "" "")
19966 (const_string "*")))
19967 (set (attr "prefix_rex")
19968 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
19970 (const_string "*")))
19971 (set_attr "mode" "SI")])
19973 (define_insn "sse4_2_crc32di"
19974 [(set (match_operand:DI 0 "register_operand" "=r")
19976 [(match_operand:DI 1 "register_operand" "0")
19977 (match_operand:DI 2 "nonimmediate_operand" "rm")]
19979 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19980 "crc32{q}\t{%2, %0|%0, %2}"
19981 [(set_attr "type" "sselog1")
19982 (set_attr "prefix_rep" "1")
19983 (set_attr "prefix_extra" "1")
19984 (set_attr "mode" "DI")])
19986 (define_expand "rdpmc"
19987 [(match_operand:DI 0 "register_operand" "")
19988 (match_operand:SI 1 "register_operand" "")]
19991 rtx reg = gen_reg_rtx (DImode);
19994 /* Force operand 1 into ECX. */
19995 rtx ecx = gen_rtx_REG (SImode, CX_REG);
19996 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
19997 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
20002 rtvec vec = rtvec_alloc (2);
20003 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20004 rtx upper = gen_reg_rtx (DImode);
20005 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20006 gen_rtvec (1, const0_rtx),
20008 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
20009 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20011 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20012 NULL, 1, OPTAB_DIRECT);
20013 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20017 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
20018 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20022 (define_insn "*rdpmc"
20023 [(set (match_operand:DI 0 "register_operand" "=A")
20024 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20028 [(set_attr "type" "other")
20029 (set_attr "length" "2")])
20031 (define_insn "*rdpmc_rex64"
20032 [(set (match_operand:DI 0 "register_operand" "=a")
20033 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20035 (set (match_operand:DI 1 "register_operand" "=d")
20036 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
20039 [(set_attr "type" "other")
20040 (set_attr "length" "2")])
20042 (define_expand "rdtsc"
20043 [(set (match_operand:DI 0 "register_operand" "")
20044 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20049 rtvec vec = rtvec_alloc (2);
20050 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20051 rtx upper = gen_reg_rtx (DImode);
20052 rtx lower = gen_reg_rtx (DImode);
20053 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
20054 gen_rtvec (1, const0_rtx),
20056 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
20057 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
20059 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20060 NULL, 1, OPTAB_DIRECT);
20061 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
20063 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
20068 (define_insn "*rdtsc"
20069 [(set (match_operand:DI 0 "register_operand" "=A")
20070 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20073 [(set_attr "type" "other")
20074 (set_attr "length" "2")])
20076 (define_insn "*rdtsc_rex64"
20077 [(set (match_operand:DI 0 "register_operand" "=a")
20078 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20079 (set (match_operand:DI 1 "register_operand" "=d")
20080 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20083 [(set_attr "type" "other")
20084 (set_attr "length" "2")])
20086 (define_expand "rdtscp"
20087 [(match_operand:DI 0 "register_operand" "")
20088 (match_operand:SI 1 "memory_operand" "")]
20091 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20092 gen_rtvec (1, const0_rtx),
20094 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
20095 gen_rtvec (1, const0_rtx),
20097 rtx reg = gen_reg_rtx (DImode);
20098 rtx tmp = gen_reg_rtx (SImode);
20102 rtvec vec = rtvec_alloc (3);
20103 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20104 rtx upper = gen_reg_rtx (DImode);
20105 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20106 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20107 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
20109 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20110 NULL, 1, OPTAB_DIRECT);
20111 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20116 rtvec vec = rtvec_alloc (2);
20117 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20118 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20119 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
20122 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20123 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
20127 (define_insn "*rdtscp"
20128 [(set (match_operand:DI 0 "register_operand" "=A")
20129 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20130 (set (match_operand:SI 1 "register_operand" "=c")
20131 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20134 [(set_attr "type" "other")
20135 (set_attr "length" "3")])
20137 (define_insn "*rdtscp_rex64"
20138 [(set (match_operand:DI 0 "register_operand" "=a")
20139 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20140 (set (match_operand:DI 1 "register_operand" "=d")
20141 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20142 (set (match_operand:SI 2 "register_operand" "=c")
20143 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20146 [(set_attr "type" "other")
20147 (set_attr "length" "3")])
20149 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20151 ;; LWP instructions
20153 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20155 (define_expand "lwp_llwpcb"
20156 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
20157 UNSPECV_LLWP_INTRINSIC)]
20161 (define_insn "*lwp_llwpcb<mode>1"
20162 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20163 UNSPECV_LLWP_INTRINSIC)]
20166 [(set_attr "type" "lwp")
20167 (set_attr "mode" "<MODE>")
20168 (set_attr "length" "5")])
20170 (define_expand "lwp_slwpcb"
20171 [(set (match_operand 0 "register_operand" "=r")
20172 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20176 emit_insn (gen_lwp_slwpcbdi (operands[0]));
20178 emit_insn (gen_lwp_slwpcbsi (operands[0]));
20182 (define_insn "lwp_slwpcb<mode>"
20183 [(set (match_operand:P 0 "register_operand" "=r")
20184 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20187 [(set_attr "type" "lwp")
20188 (set_attr "mode" "<MODE>")
20189 (set_attr "length" "5")])
20191 (define_expand "lwp_lwpval<mode>3"
20192 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
20193 (match_operand:SI 2 "nonimmediate_operand" "rm")
20194 (match_operand:SI 3 "const_int_operand" "i")]
20195 UNSPECV_LWPVAL_INTRINSIC)]
20197 "/* Avoid unused variable warning. */
20200 (define_insn "*lwp_lwpval<mode>3_1"
20201 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20202 (match_operand:SI 1 "nonimmediate_operand" "rm")
20203 (match_operand:SI 2 "const_int_operand" "i")]
20204 UNSPECV_LWPVAL_INTRINSIC)]
20206 "lwpval\t{%2, %1, %0|%0, %1, %2}"
20207 [(set_attr "type" "lwp")
20208 (set_attr "mode" "<MODE>")
20209 (set (attr "length")
20210 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20212 (define_expand "lwp_lwpins<mode>3"
20213 [(set (reg:CCC FLAGS_REG)
20214 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
20215 (match_operand:SI 2 "nonimmediate_operand" "rm")
20216 (match_operand:SI 3 "const_int_operand" "i")]
20217 UNSPECV_LWPINS_INTRINSIC))
20218 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
20219 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20223 (define_insn "*lwp_lwpins<mode>3_1"
20224 [(set (reg:CCC FLAGS_REG)
20225 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20226 (match_operand:SI 1 "nonimmediate_operand" "rm")
20227 (match_operand:SI 2 "const_int_operand" "i")]
20228 UNSPECV_LWPINS_INTRINSIC))]
20230 "lwpins\t{%2, %1, %0|%0, %1, %2}"
20231 [(set_attr "type" "lwp")
20232 (set_attr "mode" "<MODE>")
20233 (set (attr "length")
20234 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20238 (include "sync.md")