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
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 ;; E,e -- likewise, but for compare-and-branch fused insn.
34 ;; F,f -- likewise, but for floating-point.
35 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
37 ;; R -- print the prefix for register names.
38 ;; z -- print the opcode suffix for the size of the current operand.
39 ;; Z -- likewise, with special suffixes for x87 instructions.
40 ;; * -- print a star (in certain assembler syntax)
41 ;; A -- print an absolute memory reference.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
67 [; Relocation specifiers
78 (UNSPEC_MACHOPIC_OFFSET 10)
81 (UNSPEC_STACK_ALLOC 11)
83 (UNSPEC_SSE_PROLOGUE_SAVE 13)
87 (UNSPEC_SET_GOT_OFFSET 17)
88 (UNSPEC_MEMORY_BLOCKAGE 18)
93 (UNSPEC_TLS_LD_BASE 22)
96 ; Other random patterns
101 (UNSPEC_ADD_CARRY 34)
104 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
105 (UNSPEC_TRUNC_NOOP 39)
107 ; For SSE/MMX support:
108 (UNSPEC_FIX_NOTRUNC 40)
125 (UNSPEC_MS_TO_SYSV_CALL 48)
127 ; Generic math support
129 (UNSPEC_IEEE_MIN 51) ; not commutative
130 (UNSPEC_IEEE_MAX 52) ; not commutative
145 (UNSPEC_FRNDINT_FLOOR 70)
146 (UNSPEC_FRNDINT_CEIL 71)
147 (UNSPEC_FRNDINT_TRUNC 72)
148 (UNSPEC_FRNDINT_MASK_PM 73)
149 (UNSPEC_FIST_FLOOR 74)
150 (UNSPEC_FIST_CEIL 75)
152 ; x87 Double output FP
153 (UNSPEC_SINCOS_COS 80)
154 (UNSPEC_SINCOS_SIN 81)
155 (UNSPEC_XTRACT_FRACT 84)
156 (UNSPEC_XTRACT_EXP 85)
157 (UNSPEC_FSCALE_FRACT 86)
158 (UNSPEC_FSCALE_EXP 87)
170 (UNSPEC_SP_TLS_SET 102)
171 (UNSPEC_SP_TLS_TEST 103)
181 (UNSPEC_INSERTQI 132)
186 (UNSPEC_INSERTPS 135)
188 (UNSPEC_MOVNTDQA 137)
190 (UNSPEC_PHMINPOSUW 139)
196 (UNSPEC_PCMPESTR 144)
197 (UNSPEC_PCMPISTR 145)
200 (UNSPEC_FMA4_INTRINSIC 150)
201 (UNSPEC_FMA4_FMADDSUB 151)
202 (UNSPEC_FMA4_FMSUBADD 152)
203 (UNSPEC_XOP_UNSIGNED_CMP 151)
204 (UNSPEC_XOP_TRUEFALSE 152)
205 (UNSPEC_XOP_PERMUTE 153)
210 (UNSPEC_AESENCLAST 160)
212 (UNSPEC_AESDECLAST 162)
214 (UNSPEC_AESKEYGENASSIST 164)
222 (UNSPEC_VPERMIL2F128 168)
223 (UNSPEC_MASKLOAD 169)
224 (UNSPEC_MASKSTORE 170)
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 ;; Half mode for double word integer modes.
775 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
776 (DI "TARGET_64BIT")])
778 ;; Double word integer modes.
779 (define_mode_attr DWI [(SI "DI") (DI "TI")])
780 (define_mode_attr dwi [(SI "di") (DI "ti")])
782 ;; Instruction suffix for integer modes.
783 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
785 ;; Register class for integer modes.
786 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
788 ;; Immediate operand constraint for integer modes.
789 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
791 ;; General operand constraint for word modes.
792 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
794 ;; Immediate operand constraint for double integer modes.
795 (define_mode_attr di [(SI "iF") (DI "e")])
797 ;; General operand predicate for integer modes.
798 (define_mode_attr general_operand
799 [(QI "general_operand")
800 (HI "general_operand")
801 (SI "general_operand")
802 (DI "x86_64_general_operand")
803 (TI "x86_64_general_operand")])
805 ;; General sign/zero extend operand predicate for integer modes.
806 (define_mode_attr general_szext_operand
807 [(QI "general_operand")
808 (HI "general_operand")
809 (SI "general_operand")
810 (DI "x86_64_szext_general_operand")])
812 ;; SSE and x87 SFmode and DFmode floating point modes
813 (define_mode_iterator MODEF [SF DF])
815 ;; All x87 floating point modes
816 (define_mode_iterator X87MODEF [SF DF XF])
818 ;; All integer modes handled by x87 fisttp operator.
819 (define_mode_iterator X87MODEI [HI SI DI])
821 ;; All integer modes handled by integer x87 operators.
822 (define_mode_iterator X87MODEI12 [HI SI])
824 ;; All integer modes handled by SSE cvtts?2si* operators.
825 (define_mode_iterator SSEMODEI24 [SI DI])
827 ;; SSE asm suffix for floating point modes
828 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
830 ;; SSE vector mode corresponding to a scalar mode
831 (define_mode_attr ssevecmode
832 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
834 ;; Instruction suffix for REX 64bit operators.
835 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
837 ;; This mode iterator allows :P to be used for patterns that operate on
838 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
839 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
841 ;; Scheduling descriptions
843 (include "pentium.md")
846 (include "athlon.md")
851 ;; Operand and operator predicates and constraints
853 (include "predicates.md")
854 (include "constraints.md")
857 ;; Compare and branch/compare and store instructions.
859 (define_expand "cbranch<mode>4"
860 [(set (reg:CC FLAGS_REG)
861 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
862 (match_operand:SDWIM 2 "<general_operand>" "")))
863 (set (pc) (if_then_else
864 (match_operator 0 "comparison_operator"
865 [(reg:CC FLAGS_REG) (const_int 0)])
866 (label_ref (match_operand 3 "" ""))
870 if (MEM_P (operands[1]) && MEM_P (operands[2]))
871 operands[1] = force_reg (<MODE>mode, operands[1]);
872 ix86_compare_op0 = operands[1];
873 ix86_compare_op1 = operands[2];
874 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
878 (define_expand "cstore<mode>4"
879 [(set (reg:CC FLAGS_REG)
880 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
881 (match_operand:SWIM 3 "<general_operand>" "")))
882 (set (match_operand:QI 0 "register_operand" "")
883 (match_operator 1 "comparison_operator"
884 [(reg:CC FLAGS_REG) (const_int 0)]))]
887 if (MEM_P (operands[2]) && MEM_P (operands[3]))
888 operands[2] = force_reg (<MODE>mode, operands[2]);
889 ix86_compare_op0 = operands[2];
890 ix86_compare_op1 = operands[3];
891 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
895 (define_expand "cmp<mode>_1"
896 [(set (reg:CC FLAGS_REG)
897 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
898 (match_operand:SWI48 1 "<general_operand>" "")))]
902 (define_insn "*cmp<mode>_ccno_1"
903 [(set (reg FLAGS_REG)
904 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
905 (match_operand:SWI 1 "const0_operand" "")))]
906 "ix86_match_ccmode (insn, CCNOmode)"
908 test{<imodesuffix>}\t%0, %0
909 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
910 [(set_attr "type" "test,icmp")
911 (set_attr "length_immediate" "0,1")
912 (set_attr "mode" "<MODE>")])
914 (define_insn "*cmp<mode>_1"
915 [(set (reg FLAGS_REG)
916 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
917 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
918 "ix86_match_ccmode (insn, CCmode)"
919 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
920 [(set_attr "type" "icmp")
921 (set_attr "mode" "<MODE>")])
923 (define_insn "*cmp<mode>_minus_1"
924 [(set (reg FLAGS_REG)
926 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
927 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
929 "ix86_match_ccmode (insn, CCGOCmode)"
930 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
931 [(set_attr "type" "icmp")
932 (set_attr "mode" "<MODE>")])
934 (define_insn "*cmpqi_ext_1"
935 [(set (reg FLAGS_REG)
937 (match_operand:QI 0 "general_operand" "Qm")
940 (match_operand 1 "ext_register_operand" "Q")
943 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
944 "cmp{b}\t{%h1, %0|%0, %h1}"
945 [(set_attr "type" "icmp")
946 (set_attr "mode" "QI")])
948 (define_insn "*cmpqi_ext_1_rex64"
949 [(set (reg FLAGS_REG)
951 (match_operand:QI 0 "register_operand" "Q")
954 (match_operand 1 "ext_register_operand" "Q")
957 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
958 "cmp{b}\t{%h1, %0|%0, %h1}"
959 [(set_attr "type" "icmp")
960 (set_attr "mode" "QI")])
962 (define_insn "*cmpqi_ext_2"
963 [(set (reg FLAGS_REG)
967 (match_operand 0 "ext_register_operand" "Q")
970 (match_operand:QI 1 "const0_operand" "")))]
971 "ix86_match_ccmode (insn, CCNOmode)"
973 [(set_attr "type" "test")
974 (set_attr "length_immediate" "0")
975 (set_attr "mode" "QI")])
977 (define_expand "cmpqi_ext_3"
978 [(set (reg:CC FLAGS_REG)
982 (match_operand 0 "ext_register_operand" "")
985 (match_operand:QI 1 "immediate_operand" "")))]
989 (define_insn "*cmpqi_ext_3_insn"
990 [(set (reg FLAGS_REG)
994 (match_operand 0 "ext_register_operand" "Q")
997 (match_operand:QI 1 "general_operand" "Qmn")))]
998 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
999 "cmp{b}\t{%1, %h0|%h0, %1}"
1000 [(set_attr "type" "icmp")
1001 (set_attr "modrm" "1")
1002 (set_attr "mode" "QI")])
1004 (define_insn "*cmpqi_ext_3_insn_rex64"
1005 [(set (reg FLAGS_REG)
1009 (match_operand 0 "ext_register_operand" "Q")
1012 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1013 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1014 "cmp{b}\t{%1, %h0|%h0, %1}"
1015 [(set_attr "type" "icmp")
1016 (set_attr "modrm" "1")
1017 (set_attr "mode" "QI")])
1019 (define_insn "*cmpqi_ext_4"
1020 [(set (reg FLAGS_REG)
1024 (match_operand 0 "ext_register_operand" "Q")
1029 (match_operand 1 "ext_register_operand" "Q")
1031 (const_int 8)) 0)))]
1032 "ix86_match_ccmode (insn, CCmode)"
1033 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1034 [(set_attr "type" "icmp")
1035 (set_attr "mode" "QI")])
1037 ;; These implement float point compares.
1038 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1039 ;; which would allow mix and match FP modes on the compares. Which is what
1040 ;; the old patterns did, but with many more of them.
1042 (define_expand "cbranchxf4"
1043 [(set (reg:CC FLAGS_REG)
1044 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1045 (match_operand:XF 2 "nonmemory_operand" "")))
1046 (set (pc) (if_then_else
1047 (match_operator 0 "ix86_fp_comparison_operator"
1050 (label_ref (match_operand 3 "" ""))
1054 ix86_compare_op0 = operands[1];
1055 ix86_compare_op1 = operands[2];
1056 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1060 (define_expand "cstorexf4"
1061 [(set (reg:CC FLAGS_REG)
1062 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1063 (match_operand:XF 3 "nonmemory_operand" "")))
1064 (set (match_operand:QI 0 "register_operand" "")
1065 (match_operator 1 "ix86_fp_comparison_operator"
1070 ix86_compare_op0 = operands[2];
1071 ix86_compare_op1 = operands[3];
1072 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1076 (define_expand "cbranch<mode>4"
1077 [(set (reg:CC FLAGS_REG)
1078 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1079 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1080 (set (pc) (if_then_else
1081 (match_operator 0 "ix86_fp_comparison_operator"
1084 (label_ref (match_operand 3 "" ""))
1086 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1088 ix86_compare_op0 = operands[1];
1089 ix86_compare_op1 = operands[2];
1090 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1094 (define_expand "cstore<mode>4"
1095 [(set (reg:CC FLAGS_REG)
1096 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1097 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1098 (set (match_operand:QI 0 "register_operand" "")
1099 (match_operator 1 "ix86_fp_comparison_operator"
1102 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1104 ix86_compare_op0 = operands[2];
1105 ix86_compare_op1 = operands[3];
1106 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1110 (define_expand "cbranchcc4"
1111 [(set (pc) (if_then_else
1112 (match_operator 0 "comparison_operator"
1113 [(match_operand 1 "flags_reg_operand" "")
1114 (match_operand 2 "const0_operand" "")])
1115 (label_ref (match_operand 3 "" ""))
1119 ix86_compare_op0 = operands[1];
1120 ix86_compare_op1 = operands[2];
1121 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1125 (define_expand "cstorecc4"
1126 [(set (match_operand:QI 0 "register_operand" "")
1127 (match_operator 1 "comparison_operator"
1128 [(match_operand 2 "flags_reg_operand" "")
1129 (match_operand 3 "const0_operand" "")]))]
1132 ix86_compare_op0 = operands[2];
1133 ix86_compare_op1 = operands[3];
1134 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1139 ;; FP compares, step 1:
1140 ;; Set the FP condition codes.
1142 ;; CCFPmode compare with exceptions
1143 ;; CCFPUmode compare with no exceptions
1145 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1146 ;; used to manage the reg stack popping would not be preserved.
1148 (define_insn "*cmpfp_0"
1149 [(set (match_operand:HI 0 "register_operand" "=a")
1152 (match_operand 1 "register_operand" "f")
1153 (match_operand 2 "const0_operand" ""))]
1155 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1156 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1157 "* return output_fp_compare (insn, operands, 0, 0);"
1158 [(set_attr "type" "multi")
1159 (set_attr "unit" "i387")
1161 (cond [(match_operand:SF 1 "" "")
1163 (match_operand:DF 1 "" "")
1166 (const_string "XF")))])
1168 (define_insn_and_split "*cmpfp_0_cc"
1169 [(set (reg:CCFP FLAGS_REG)
1171 (match_operand 1 "register_operand" "f")
1172 (match_operand 2 "const0_operand" "")))
1173 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1174 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1175 && TARGET_SAHF && !TARGET_CMOVE
1176 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1178 "&& reload_completed"
1181 [(compare:CCFP (match_dup 1)(match_dup 2))]
1183 (set (reg:CC FLAGS_REG)
1184 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1186 [(set_attr "type" "multi")
1187 (set_attr "unit" "i387")
1189 (cond [(match_operand:SF 1 "" "")
1191 (match_operand:DF 1 "" "")
1194 (const_string "XF")))])
1196 (define_insn "*cmpfp_xf"
1197 [(set (match_operand:HI 0 "register_operand" "=a")
1200 (match_operand:XF 1 "register_operand" "f")
1201 (match_operand:XF 2 "register_operand" "f"))]
1204 "* return output_fp_compare (insn, operands, 0, 0);"
1205 [(set_attr "type" "multi")
1206 (set_attr "unit" "i387")
1207 (set_attr "mode" "XF")])
1209 (define_insn_and_split "*cmpfp_xf_cc"
1210 [(set (reg:CCFP FLAGS_REG)
1212 (match_operand:XF 1 "register_operand" "f")
1213 (match_operand:XF 2 "register_operand" "f")))
1214 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1216 && TARGET_SAHF && !TARGET_CMOVE"
1218 "&& reload_completed"
1221 [(compare:CCFP (match_dup 1)(match_dup 2))]
1223 (set (reg:CC FLAGS_REG)
1224 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1226 [(set_attr "type" "multi")
1227 (set_attr "unit" "i387")
1228 (set_attr "mode" "XF")])
1230 (define_insn "*cmpfp_<mode>"
1231 [(set (match_operand:HI 0 "register_operand" "=a")
1234 (match_operand:MODEF 1 "register_operand" "f")
1235 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1238 "* return output_fp_compare (insn, operands, 0, 0);"
1239 [(set_attr "type" "multi")
1240 (set_attr "unit" "i387")
1241 (set_attr "mode" "<MODE>")])
1243 (define_insn_and_split "*cmpfp_<mode>_cc"
1244 [(set (reg:CCFP FLAGS_REG)
1246 (match_operand:MODEF 1 "register_operand" "f")
1247 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1248 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1250 && TARGET_SAHF && !TARGET_CMOVE"
1252 "&& reload_completed"
1255 [(compare:CCFP (match_dup 1)(match_dup 2))]
1257 (set (reg:CC FLAGS_REG)
1258 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1260 [(set_attr "type" "multi")
1261 (set_attr "unit" "i387")
1262 (set_attr "mode" "<MODE>")])
1264 (define_insn "*cmpfp_u"
1265 [(set (match_operand:HI 0 "register_operand" "=a")
1268 (match_operand 1 "register_operand" "f")
1269 (match_operand 2 "register_operand" "f"))]
1271 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1272 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1273 "* return output_fp_compare (insn, operands, 0, 1);"
1274 [(set_attr "type" "multi")
1275 (set_attr "unit" "i387")
1277 (cond [(match_operand:SF 1 "" "")
1279 (match_operand:DF 1 "" "")
1282 (const_string "XF")))])
1284 (define_insn_and_split "*cmpfp_u_cc"
1285 [(set (reg:CCFPU FLAGS_REG)
1287 (match_operand 1 "register_operand" "f")
1288 (match_operand 2 "register_operand" "f")))
1289 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1290 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1291 && TARGET_SAHF && !TARGET_CMOVE
1292 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1294 "&& reload_completed"
1297 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1299 (set (reg:CC FLAGS_REG)
1300 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1302 [(set_attr "type" "multi")
1303 (set_attr "unit" "i387")
1305 (cond [(match_operand:SF 1 "" "")
1307 (match_operand:DF 1 "" "")
1310 (const_string "XF")))])
1312 (define_insn "*cmpfp_<mode>"
1313 [(set (match_operand:HI 0 "register_operand" "=a")
1316 (match_operand 1 "register_operand" "f")
1317 (match_operator 3 "float_operator"
1318 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1320 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1321 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1322 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1323 "* return output_fp_compare (insn, operands, 0, 0);"
1324 [(set_attr "type" "multi")
1325 (set_attr "unit" "i387")
1326 (set_attr "fp_int_src" "true")
1327 (set_attr "mode" "<MODE>")])
1329 (define_insn_and_split "*cmpfp_<mode>_cc"
1330 [(set (reg:CCFP FLAGS_REG)
1332 (match_operand 1 "register_operand" "f")
1333 (match_operator 3 "float_operator"
1334 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1335 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1336 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1337 && TARGET_SAHF && !TARGET_CMOVE
1338 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1339 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1341 "&& reload_completed"
1346 (match_op_dup 3 [(match_dup 2)]))]
1348 (set (reg:CC FLAGS_REG)
1349 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1351 [(set_attr "type" "multi")
1352 (set_attr "unit" "i387")
1353 (set_attr "fp_int_src" "true")
1354 (set_attr "mode" "<MODE>")])
1356 ;; FP compares, step 2
1357 ;; Move the fpsw to ax.
1359 (define_insn "x86_fnstsw_1"
1360 [(set (match_operand:HI 0 "register_operand" "=a")
1361 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1364 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1365 (set_attr "mode" "SI")
1366 (set_attr "unit" "i387")])
1368 ;; FP compares, step 3
1369 ;; Get ax into flags, general case.
1371 (define_insn "x86_sahf_1"
1372 [(set (reg:CC FLAGS_REG)
1373 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1377 #ifdef HAVE_AS_IX86_SAHF
1380 return ASM_BYTE "0x9e";
1383 [(set_attr "length" "1")
1384 (set_attr "athlon_decode" "vector")
1385 (set_attr "amdfam10_decode" "direct")
1386 (set_attr "mode" "SI")])
1388 ;; Pentium Pro can do steps 1 through 3 in one go.
1389 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1390 (define_insn "*cmpfp_i_mixed"
1391 [(set (reg:CCFP FLAGS_REG)
1392 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1393 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1394 "TARGET_MIX_SSE_I387
1395 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1396 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1397 "* return output_fp_compare (insn, operands, 1, 0);"
1398 [(set_attr "type" "fcmp,ssecomi")
1399 (set_attr "prefix" "orig,maybe_vex")
1401 (if_then_else (match_operand:SF 1 "" "")
1403 (const_string "DF")))
1404 (set (attr "prefix_rep")
1405 (if_then_else (eq_attr "type" "ssecomi")
1407 (const_string "*")))
1408 (set (attr "prefix_data16")
1409 (cond [(eq_attr "type" "fcmp")
1411 (eq_attr "mode" "DF")
1414 (const_string "0")))
1415 (set_attr "athlon_decode" "vector")
1416 (set_attr "amdfam10_decode" "direct")])
1418 (define_insn "*cmpfp_i_sse"
1419 [(set (reg:CCFP FLAGS_REG)
1420 (compare:CCFP (match_operand 0 "register_operand" "x")
1421 (match_operand 1 "nonimmediate_operand" "xm")))]
1423 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1424 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1425 "* return output_fp_compare (insn, operands, 1, 0);"
1426 [(set_attr "type" "ssecomi")
1427 (set_attr "prefix" "maybe_vex")
1429 (if_then_else (match_operand:SF 1 "" "")
1431 (const_string "DF")))
1432 (set_attr "prefix_rep" "0")
1433 (set (attr "prefix_data16")
1434 (if_then_else (eq_attr "mode" "DF")
1436 (const_string "0")))
1437 (set_attr "athlon_decode" "vector")
1438 (set_attr "amdfam10_decode" "direct")])
1440 (define_insn "*cmpfp_i_i387"
1441 [(set (reg:CCFP FLAGS_REG)
1442 (compare:CCFP (match_operand 0 "register_operand" "f")
1443 (match_operand 1 "register_operand" "f")))]
1444 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1446 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1447 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1448 "* return output_fp_compare (insn, operands, 1, 0);"
1449 [(set_attr "type" "fcmp")
1451 (cond [(match_operand:SF 1 "" "")
1453 (match_operand:DF 1 "" "")
1456 (const_string "XF")))
1457 (set_attr "athlon_decode" "vector")
1458 (set_attr "amdfam10_decode" "direct")])
1460 (define_insn "*cmpfp_iu_mixed"
1461 [(set (reg:CCFPU FLAGS_REG)
1462 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1463 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1464 "TARGET_MIX_SSE_I387
1465 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1466 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1467 "* return output_fp_compare (insn, operands, 1, 1);"
1468 [(set_attr "type" "fcmp,ssecomi")
1469 (set_attr "prefix" "orig,maybe_vex")
1471 (if_then_else (match_operand:SF 1 "" "")
1473 (const_string "DF")))
1474 (set (attr "prefix_rep")
1475 (if_then_else (eq_attr "type" "ssecomi")
1477 (const_string "*")))
1478 (set (attr "prefix_data16")
1479 (cond [(eq_attr "type" "fcmp")
1481 (eq_attr "mode" "DF")
1484 (const_string "0")))
1485 (set_attr "athlon_decode" "vector")
1486 (set_attr "amdfam10_decode" "direct")])
1488 (define_insn "*cmpfp_iu_sse"
1489 [(set (reg:CCFPU FLAGS_REG)
1490 (compare:CCFPU (match_operand 0 "register_operand" "x")
1491 (match_operand 1 "nonimmediate_operand" "xm")))]
1493 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1494 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1495 "* return output_fp_compare (insn, operands, 1, 1);"
1496 [(set_attr "type" "ssecomi")
1497 (set_attr "prefix" "maybe_vex")
1499 (if_then_else (match_operand:SF 1 "" "")
1501 (const_string "DF")))
1502 (set_attr "prefix_rep" "0")
1503 (set (attr "prefix_data16")
1504 (if_then_else (eq_attr "mode" "DF")
1506 (const_string "0")))
1507 (set_attr "athlon_decode" "vector")
1508 (set_attr "amdfam10_decode" "direct")])
1510 (define_insn "*cmpfp_iu_387"
1511 [(set (reg:CCFPU FLAGS_REG)
1512 (compare:CCFPU (match_operand 0 "register_operand" "f")
1513 (match_operand 1 "register_operand" "f")))]
1514 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1516 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1517 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1518 "* return output_fp_compare (insn, operands, 1, 1);"
1519 [(set_attr "type" "fcmp")
1521 (cond [(match_operand:SF 1 "" "")
1523 (match_operand:DF 1 "" "")
1526 (const_string "XF")))
1527 (set_attr "athlon_decode" "vector")
1528 (set_attr "amdfam10_decode" "direct")])
1530 ;; Move instructions.
1532 ;; General case of fullword move.
1534 (define_expand "movsi"
1535 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1536 (match_operand:SI 1 "general_operand" ""))]
1538 "ix86_expand_move (SImode, operands); DONE;")
1540 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1543 ;; %%% We don't use a post-inc memory reference because x86 is not a
1544 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1545 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1546 ;; targets without our curiosities, and it is just as easy to represent
1547 ;; this differently.
1549 (define_insn "*pushsi2"
1550 [(set (match_operand:SI 0 "push_operand" "=<")
1551 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1554 [(set_attr "type" "push")
1555 (set_attr "mode" "SI")])
1557 ;; For 64BIT abi we always round up to 8 bytes.
1558 (define_insn "*pushsi2_rex64"
1559 [(set (match_operand:SI 0 "push_operand" "=X")
1560 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1563 [(set_attr "type" "push")
1564 (set_attr "mode" "SI")])
1566 (define_insn "*pushsi2_prologue"
1567 [(set (match_operand:SI 0 "push_operand" "=<")
1568 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1569 (clobber (mem:BLK (scratch)))]
1572 [(set_attr "type" "push")
1573 (set_attr "mode" "SI")])
1575 (define_insn "*popsi1_epilogue"
1576 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1577 (mem:SI (reg:SI SP_REG)))
1578 (set (reg:SI SP_REG)
1579 (plus:SI (reg:SI SP_REG) (const_int 4)))
1580 (clobber (mem:BLK (scratch)))]
1583 [(set_attr "type" "pop")
1584 (set_attr "mode" "SI")])
1586 (define_insn "popsi1"
1587 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1588 (mem:SI (reg:SI SP_REG)))
1589 (set (reg:SI SP_REG)
1590 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1593 [(set_attr "type" "pop")
1594 (set_attr "mode" "SI")])
1596 (define_insn "*movsi_xor"
1597 [(set (match_operand:SI 0 "register_operand" "=r")
1598 (match_operand:SI 1 "const0_operand" ""))
1599 (clobber (reg:CC FLAGS_REG))]
1602 [(set_attr "type" "alu1")
1603 (set_attr "mode" "SI")
1604 (set_attr "length_immediate" "0")])
1606 (define_insn "*movsi_or"
1607 [(set (match_operand:SI 0 "register_operand" "=r")
1608 (match_operand:SI 1 "immediate_operand" "i"))
1609 (clobber (reg:CC FLAGS_REG))]
1611 && operands[1] == constm1_rtx"
1613 operands[1] = constm1_rtx;
1614 return "or{l}\t{%1, %0|%0, %1}";
1616 [(set_attr "type" "alu1")
1617 (set_attr "mode" "SI")
1618 (set_attr "length_immediate" "1")])
1620 (define_insn "*movsi_1"
1621 [(set (match_operand:SI 0 "nonimmediate_operand"
1622 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1623 (match_operand:SI 1 "general_operand"
1624 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1625 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1627 switch (get_attr_type (insn))
1630 if (get_attr_mode (insn) == MODE_TI)
1631 return "%vpxor\t%0, %d0";
1632 return "%vxorps\t%0, %d0";
1635 switch (get_attr_mode (insn))
1638 return "%vmovdqa\t{%1, %0|%0, %1}";
1640 return "%vmovaps\t{%1, %0|%0, %1}";
1642 return "%vmovd\t{%1, %0|%0, %1}";
1644 return "%vmovss\t{%1, %0|%0, %1}";
1650 return "pxor\t%0, %0";
1653 if (get_attr_mode (insn) == MODE_DI)
1654 return "movq\t{%1, %0|%0, %1}";
1655 return "movd\t{%1, %0|%0, %1}";
1658 return "lea{l}\t{%1, %0|%0, %1}";
1661 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1662 return "mov{l}\t{%1, %0|%0, %1}";
1666 (cond [(eq_attr "alternative" "2")
1667 (const_string "mmx")
1668 (eq_attr "alternative" "3,4,5")
1669 (const_string "mmxmov")
1670 (eq_attr "alternative" "6")
1671 (const_string "sselog1")
1672 (eq_attr "alternative" "7,8,9,10,11")
1673 (const_string "ssemov")
1674 (match_operand:DI 1 "pic_32bit_operand" "")
1675 (const_string "lea")
1677 (const_string "imov")))
1678 (set (attr "prefix")
1679 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1680 (const_string "orig")
1681 (const_string "maybe_vex")))
1682 (set (attr "prefix_data16")
1683 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1685 (const_string "*")))
1687 (cond [(eq_attr "alternative" "2,3")
1689 (eq_attr "alternative" "6,7")
1691 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1692 (const_string "V4SF")
1693 (const_string "TI"))
1694 (and (eq_attr "alternative" "8,9,10,11")
1695 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1698 (const_string "SI")))])
1700 ;; Stores and loads of ax to arbitrary constant address.
1701 ;; We fake an second form of instruction to force reload to load address
1702 ;; into register when rax is not available
1703 (define_insn "*movabssi_1_rex64"
1704 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1705 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1706 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1708 movabs{l}\t{%1, %P0|%P0, %1}
1709 mov{l}\t{%1, %a0|%a0, %1}"
1710 [(set_attr "type" "imov")
1711 (set_attr "modrm" "0,*")
1712 (set_attr "length_address" "8,0")
1713 (set_attr "length_immediate" "0,*")
1714 (set_attr "memory" "store")
1715 (set_attr "mode" "SI")])
1717 (define_insn "*movabssi_2_rex64"
1718 [(set (match_operand:SI 0 "register_operand" "=a,r")
1719 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1720 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1722 movabs{l}\t{%P1, %0|%0, %P1}
1723 mov{l}\t{%a1, %0|%0, %a1}"
1724 [(set_attr "type" "imov")
1725 (set_attr "modrm" "0,*")
1726 (set_attr "length_address" "8,0")
1727 (set_attr "length_immediate" "0")
1728 (set_attr "memory" "load")
1729 (set_attr "mode" "SI")])
1731 (define_insn "*swapsi"
1732 [(set (match_operand:SI 0 "register_operand" "+r")
1733 (match_operand:SI 1 "register_operand" "+r"))
1738 [(set_attr "type" "imov")
1739 (set_attr "mode" "SI")
1740 (set_attr "pent_pair" "np")
1741 (set_attr "athlon_decode" "vector")
1742 (set_attr "amdfam10_decode" "double")])
1744 (define_expand "movhi"
1745 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1746 (match_operand:HI 1 "general_operand" ""))]
1748 "ix86_expand_move (HImode, operands); DONE;")
1750 (define_insn "*pushhi2"
1751 [(set (match_operand:HI 0 "push_operand" "=X")
1752 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1755 [(set_attr "type" "push")
1756 (set_attr "mode" "SI")])
1758 ;; For 64BIT abi we always round up to 8 bytes.
1759 (define_insn "*pushhi2_rex64"
1760 [(set (match_operand:HI 0 "push_operand" "=X")
1761 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1764 [(set_attr "type" "push")
1765 (set_attr "mode" "DI")])
1767 (define_insn "*movhi_1"
1768 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1769 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1770 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1772 switch (get_attr_type (insn))
1775 /* movzwl is faster than movw on p2 due to partial word stalls,
1776 though not as fast as an aligned movl. */
1777 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1779 if (get_attr_mode (insn) == MODE_SI)
1780 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1782 return "mov{w}\t{%1, %0|%0, %1}";
1786 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1787 (const_string "imov")
1788 (and (eq_attr "alternative" "0")
1789 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1791 (eq (symbol_ref "TARGET_HIMODE_MATH")
1793 (const_string "imov")
1794 (and (eq_attr "alternative" "1,2")
1795 (match_operand:HI 1 "aligned_operand" ""))
1796 (const_string "imov")
1797 (and (ne (symbol_ref "TARGET_MOVX")
1799 (eq_attr "alternative" "0,2"))
1800 (const_string "imovx")
1802 (const_string "imov")))
1804 (cond [(eq_attr "type" "imovx")
1806 (and (eq_attr "alternative" "1,2")
1807 (match_operand:HI 1 "aligned_operand" ""))
1809 (and (eq_attr "alternative" "0")
1810 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1812 (eq (symbol_ref "TARGET_HIMODE_MATH")
1816 (const_string "HI")))])
1818 ;; Stores and loads of ax to arbitrary constant address.
1819 ;; We fake an second form of instruction to force reload to load address
1820 ;; into register when rax is not available
1821 (define_insn "*movabshi_1_rex64"
1822 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1823 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1824 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1826 movabs{w}\t{%1, %P0|%P0, %1}
1827 mov{w}\t{%1, %a0|%a0, %1}"
1828 [(set_attr "type" "imov")
1829 (set_attr "modrm" "0,*")
1830 (set_attr "length_address" "8,0")
1831 (set_attr "length_immediate" "0,*")
1832 (set_attr "memory" "store")
1833 (set_attr "mode" "HI")])
1835 (define_insn "*movabshi_2_rex64"
1836 [(set (match_operand:HI 0 "register_operand" "=a,r")
1837 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1838 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1840 movabs{w}\t{%P1, %0|%0, %P1}
1841 mov{w}\t{%a1, %0|%0, %a1}"
1842 [(set_attr "type" "imov")
1843 (set_attr "modrm" "0,*")
1844 (set_attr "length_address" "8,0")
1845 (set_attr "length_immediate" "0")
1846 (set_attr "memory" "load")
1847 (set_attr "mode" "HI")])
1849 (define_insn "*swaphi_1"
1850 [(set (match_operand:HI 0 "register_operand" "+r")
1851 (match_operand:HI 1 "register_operand" "+r"))
1854 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1856 [(set_attr "type" "imov")
1857 (set_attr "mode" "SI")
1858 (set_attr "pent_pair" "np")
1859 (set_attr "athlon_decode" "vector")
1860 (set_attr "amdfam10_decode" "double")])
1862 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1863 (define_insn "*swaphi_2"
1864 [(set (match_operand:HI 0 "register_operand" "+r")
1865 (match_operand:HI 1 "register_operand" "+r"))
1868 "TARGET_PARTIAL_REG_STALL"
1870 [(set_attr "type" "imov")
1871 (set_attr "mode" "HI")
1872 (set_attr "pent_pair" "np")
1873 (set_attr "athlon_decode" "vector")])
1875 (define_expand "movstricthi"
1876 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1877 (match_operand:HI 1 "general_operand" ""))]
1880 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1882 /* Don't generate memory->memory moves, go through a register */
1883 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1884 operands[1] = force_reg (HImode, operands[1]);
1887 (define_insn "*movstricthi_1"
1888 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1889 (match_operand:HI 1 "general_operand" "rn,m"))]
1890 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1891 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1892 "mov{w}\t{%1, %0|%0, %1}"
1893 [(set_attr "type" "imov")
1894 (set_attr "mode" "HI")])
1896 (define_insn "*movstricthi_xor"
1897 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1898 (match_operand:HI 1 "const0_operand" ""))
1899 (clobber (reg:CC FLAGS_REG))]
1902 [(set_attr "type" "alu1")
1903 (set_attr "mode" "HI")
1904 (set_attr "length_immediate" "0")])
1906 (define_expand "movqi"
1907 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1908 (match_operand:QI 1 "general_operand" ""))]
1910 "ix86_expand_move (QImode, operands); DONE;")
1912 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1913 ;; "push a byte". But actually we use pushl, which has the effect
1914 ;; of rounding the amount pushed up to a word.
1916 (define_insn "*pushqi2"
1917 [(set (match_operand:QI 0 "push_operand" "=X")
1918 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1921 [(set_attr "type" "push")
1922 (set_attr "mode" "SI")])
1924 ;; For 64BIT abi we always round up to 8 bytes.
1925 (define_insn "*pushqi2_rex64"
1926 [(set (match_operand:QI 0 "push_operand" "=X")
1927 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1930 [(set_attr "type" "push")
1931 (set_attr "mode" "DI")])
1933 ;; Situation is quite tricky about when to choose full sized (SImode) move
1934 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1935 ;; partial register dependency machines (such as AMD Athlon), where QImode
1936 ;; moves issue extra dependency and for partial register stalls machines
1937 ;; that don't use QImode patterns (and QImode move cause stall on the next
1940 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1941 ;; register stall machines with, where we use QImode instructions, since
1942 ;; partial register stall can be caused there. Then we use movzx.
1943 (define_insn "*movqi_1"
1944 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1945 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1946 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1948 switch (get_attr_type (insn))
1951 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1952 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1954 if (get_attr_mode (insn) == MODE_SI)
1955 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1957 return "mov{b}\t{%1, %0|%0, %1}";
1961 (cond [(and (eq_attr "alternative" "5")
1962 (not (match_operand:QI 1 "aligned_operand" "")))
1963 (const_string "imovx")
1964 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1965 (const_string "imov")
1966 (and (eq_attr "alternative" "3")
1967 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1969 (eq (symbol_ref "TARGET_QIMODE_MATH")
1971 (const_string "imov")
1972 (eq_attr "alternative" "3,5")
1973 (const_string "imovx")
1974 (and (ne (symbol_ref "TARGET_MOVX")
1976 (eq_attr "alternative" "2"))
1977 (const_string "imovx")
1979 (const_string "imov")))
1981 (cond [(eq_attr "alternative" "3,4,5")
1983 (eq_attr "alternative" "6")
1985 (eq_attr "type" "imovx")
1987 (and (eq_attr "type" "imov")
1988 (and (eq_attr "alternative" "0,1")
1989 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1991 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1993 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1996 ;; Avoid partial register stalls when not using QImode arithmetic
1997 (and (eq_attr "type" "imov")
1998 (and (eq_attr "alternative" "0,1")
1999 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2001 (eq (symbol_ref "TARGET_QIMODE_MATH")
2005 (const_string "QI")))])
2007 (define_insn "*swapqi_1"
2008 [(set (match_operand:QI 0 "register_operand" "+r")
2009 (match_operand:QI 1 "register_operand" "+r"))
2012 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2014 [(set_attr "type" "imov")
2015 (set_attr "mode" "SI")
2016 (set_attr "pent_pair" "np")
2017 (set_attr "athlon_decode" "vector")
2018 (set_attr "amdfam10_decode" "vector")])
2020 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2021 (define_insn "*swapqi_2"
2022 [(set (match_operand:QI 0 "register_operand" "+q")
2023 (match_operand:QI 1 "register_operand" "+q"))
2026 "TARGET_PARTIAL_REG_STALL"
2028 [(set_attr "type" "imov")
2029 (set_attr "mode" "QI")
2030 (set_attr "pent_pair" "np")
2031 (set_attr "athlon_decode" "vector")])
2033 (define_expand "movstrictqi"
2034 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2035 (match_operand:QI 1 "general_operand" ""))]
2038 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2040 /* Don't generate memory->memory moves, go through a register. */
2041 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2042 operands[1] = force_reg (QImode, operands[1]);
2045 (define_insn "*movstrictqi_1"
2046 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2047 (match_operand:QI 1 "general_operand" "*qn,m"))]
2048 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2049 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2050 "mov{b}\t{%1, %0|%0, %1}"
2051 [(set_attr "type" "imov")
2052 (set_attr "mode" "QI")])
2054 (define_insn "*movstrictqi_xor"
2055 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2056 (match_operand:QI 1 "const0_operand" ""))
2057 (clobber (reg:CC FLAGS_REG))]
2060 [(set_attr "type" "alu1")
2061 (set_attr "mode" "QI")
2062 (set_attr "length_immediate" "0")])
2064 (define_insn "*movsi_extv_1"
2065 [(set (match_operand:SI 0 "register_operand" "=R")
2066 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2070 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2071 [(set_attr "type" "imovx")
2072 (set_attr "mode" "SI")])
2074 (define_insn "*movhi_extv_1"
2075 [(set (match_operand:HI 0 "register_operand" "=R")
2076 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2080 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2081 [(set_attr "type" "imovx")
2082 (set_attr "mode" "SI")])
2084 (define_insn "*movqi_extv_1"
2085 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2086 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2091 switch (get_attr_type (insn))
2094 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2096 return "mov{b}\t{%h1, %0|%0, %h1}";
2100 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2101 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2102 (ne (symbol_ref "TARGET_MOVX")
2104 (const_string "imovx")
2105 (const_string "imov")))
2107 (if_then_else (eq_attr "type" "imovx")
2109 (const_string "QI")))])
2111 (define_insn "*movqi_extv_1_rex64"
2112 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2113 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2118 switch (get_attr_type (insn))
2121 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2123 return "mov{b}\t{%h1, %0|%0, %h1}";
2127 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2128 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2129 (ne (symbol_ref "TARGET_MOVX")
2131 (const_string "imovx")
2132 (const_string "imov")))
2134 (if_then_else (eq_attr "type" "imovx")
2136 (const_string "QI")))])
2138 ;; Stores and loads of ax to arbitrary constant address.
2139 ;; We fake an second form of instruction to force reload to load address
2140 ;; into register when rax is not available
2141 (define_insn "*movabsqi_1_rex64"
2142 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2143 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2144 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2146 movabs{b}\t{%1, %P0|%P0, %1}
2147 mov{b}\t{%1, %a0|%a0, %1}"
2148 [(set_attr "type" "imov")
2149 (set_attr "modrm" "0,*")
2150 (set_attr "length_address" "8,0")
2151 (set_attr "length_immediate" "0,*")
2152 (set_attr "memory" "store")
2153 (set_attr "mode" "QI")])
2155 (define_insn "*movabsqi_2_rex64"
2156 [(set (match_operand:QI 0 "register_operand" "=a,r")
2157 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2158 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2160 movabs{b}\t{%P1, %0|%0, %P1}
2161 mov{b}\t{%a1, %0|%0, %a1}"
2162 [(set_attr "type" "imov")
2163 (set_attr "modrm" "0,*")
2164 (set_attr "length_address" "8,0")
2165 (set_attr "length_immediate" "0")
2166 (set_attr "memory" "load")
2167 (set_attr "mode" "QI")])
2169 (define_insn "*movdi_extzv_1"
2170 [(set (match_operand:DI 0 "register_operand" "=R")
2171 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2175 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2176 [(set_attr "type" "imovx")
2177 (set_attr "mode" "SI")])
2179 (define_insn "*movsi_extzv_1"
2180 [(set (match_operand:SI 0 "register_operand" "=R")
2181 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2185 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2186 [(set_attr "type" "imovx")
2187 (set_attr "mode" "SI")])
2189 (define_insn "*movqi_extzv_2"
2190 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2191 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2196 switch (get_attr_type (insn))
2199 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2201 return "mov{b}\t{%h1, %0|%0, %h1}";
2205 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2206 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2207 (ne (symbol_ref "TARGET_MOVX")
2209 (const_string "imovx")
2210 (const_string "imov")))
2212 (if_then_else (eq_attr "type" "imovx")
2214 (const_string "QI")))])
2216 (define_insn "*movqi_extzv_2_rex64"
2217 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2218 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2223 switch (get_attr_type (insn))
2226 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2228 return "mov{b}\t{%h1, %0|%0, %h1}";
2232 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2233 (ne (symbol_ref "TARGET_MOVX")
2235 (const_string "imovx")
2236 (const_string "imov")))
2238 (if_then_else (eq_attr "type" "imovx")
2240 (const_string "QI")))])
2242 (define_insn "movsi_insv_1"
2243 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2246 (match_operand:SI 1 "general_operand" "Qmn"))]
2248 "mov{b}\t{%b1, %h0|%h0, %b1}"
2249 [(set_attr "type" "imov")
2250 (set_attr "mode" "QI")])
2252 (define_insn "*movsi_insv_1_rex64"
2253 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2256 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2258 "mov{b}\t{%b1, %h0|%h0, %b1}"
2259 [(set_attr "type" "imov")
2260 (set_attr "mode" "QI")])
2262 (define_insn "movdi_insv_1_rex64"
2263 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2266 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2268 "mov{b}\t{%b1, %h0|%h0, %b1}"
2269 [(set_attr "type" "imov")
2270 (set_attr "mode" "QI")])
2272 (define_insn "*movqi_insv_2"
2273 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2276 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2279 "mov{b}\t{%h1, %h0|%h0, %h1}"
2280 [(set_attr "type" "imov")
2281 (set_attr "mode" "QI")])
2283 (define_expand "movdi"
2284 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2285 (match_operand:DI 1 "general_operand" ""))]
2287 "ix86_expand_move (DImode, operands); DONE;")
2289 (define_insn "*pushdi"
2290 [(set (match_operand:DI 0 "push_operand" "=<")
2291 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2295 (define_insn "*pushdi2_rex64"
2296 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2297 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2302 [(set_attr "type" "push,multi")
2303 (set_attr "mode" "DI")])
2305 ;; Convert impossible pushes of immediate to existing instructions.
2306 ;; First try to get scratch register and go through it. In case this
2307 ;; fails, push sign extended lower part first and then overwrite
2308 ;; upper part by 32bit move.
2310 [(match_scratch:DI 2 "r")
2311 (set (match_operand:DI 0 "push_operand" "")
2312 (match_operand:DI 1 "immediate_operand" ""))]
2313 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2314 && !x86_64_immediate_operand (operands[1], DImode)"
2315 [(set (match_dup 2) (match_dup 1))
2316 (set (match_dup 0) (match_dup 2))]
2319 ;; We need to define this as both peepholer and splitter for case
2320 ;; peephole2 pass is not run.
2321 ;; "&& 1" is needed to keep it from matching the previous pattern.
2323 [(set (match_operand:DI 0 "push_operand" "")
2324 (match_operand:DI 1 "immediate_operand" ""))]
2325 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2326 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2327 [(set (match_dup 0) (match_dup 1))
2328 (set (match_dup 2) (match_dup 3))]
2329 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2330 operands[1] = gen_lowpart (DImode, operands[2]);
2331 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2336 [(set (match_operand:DI 0 "push_operand" "")
2337 (match_operand:DI 1 "immediate_operand" ""))]
2338 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2339 ? epilogue_completed : reload_completed)
2340 && !symbolic_operand (operands[1], DImode)
2341 && !x86_64_immediate_operand (operands[1], DImode)"
2342 [(set (match_dup 0) (match_dup 1))
2343 (set (match_dup 2) (match_dup 3))]
2344 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2345 operands[1] = gen_lowpart (DImode, operands[2]);
2346 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2350 (define_insn "*pushdi2_prologue_rex64"
2351 [(set (match_operand:DI 0 "push_operand" "=<")
2352 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2353 (clobber (mem:BLK (scratch)))]
2356 [(set_attr "type" "push")
2357 (set_attr "mode" "DI")])
2359 (define_insn "*popdi1_epilogue_rex64"
2360 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2361 (mem:DI (reg:DI SP_REG)))
2362 (set (reg:DI SP_REG)
2363 (plus:DI (reg:DI SP_REG) (const_int 8)))
2364 (clobber (mem:BLK (scratch)))]
2367 [(set_attr "type" "pop")
2368 (set_attr "mode" "DI")])
2370 (define_insn "popdi1"
2371 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2372 (mem:DI (reg:DI SP_REG)))
2373 (set (reg:DI SP_REG)
2374 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2377 [(set_attr "type" "pop")
2378 (set_attr "mode" "DI")])
2380 (define_insn "*movdi_xor_rex64"
2381 [(set (match_operand:DI 0 "register_operand" "=r")
2382 (match_operand:DI 1 "const0_operand" ""))
2383 (clobber (reg:CC FLAGS_REG))]
2385 && reload_completed"
2387 [(set_attr "type" "alu1")
2388 (set_attr "mode" "SI")
2389 (set_attr "length_immediate" "0")])
2391 (define_insn "*movdi_or_rex64"
2392 [(set (match_operand:DI 0 "register_operand" "=r")
2393 (match_operand:DI 1 "const_int_operand" "i"))
2394 (clobber (reg:CC FLAGS_REG))]
2397 && operands[1] == constm1_rtx"
2399 operands[1] = constm1_rtx;
2400 return "or{q}\t{%1, %0|%0, %1}";
2402 [(set_attr "type" "alu1")
2403 (set_attr "mode" "DI")
2404 (set_attr "length_immediate" "1")])
2406 (define_insn "*movdi_2"
2407 [(set (match_operand:DI 0 "nonimmediate_operand"
2408 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2409 (match_operand:DI 1 "general_operand"
2410 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2411 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2416 movq\t{%1, %0|%0, %1}
2417 movq\t{%1, %0|%0, %1}
2419 %vmovq\t{%1, %0|%0, %1}
2420 %vmovdqa\t{%1, %0|%0, %1}
2421 %vmovq\t{%1, %0|%0, %1}
2423 movlps\t{%1, %0|%0, %1}
2424 movaps\t{%1, %0|%0, %1}
2425 movlps\t{%1, %0|%0, %1}"
2426 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2427 (set (attr "prefix")
2428 (if_then_else (eq_attr "alternative" "5,6,7,8")
2429 (const_string "vex")
2430 (const_string "orig")))
2431 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2434 [(set (match_operand:DI 0 "push_operand" "")
2435 (match_operand:DI 1 "general_operand" ""))]
2436 "!TARGET_64BIT && reload_completed
2437 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2439 "ix86_split_long_move (operands); DONE;")
2441 ;; %%% This multiword shite has got to go.
2443 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2444 (match_operand:DI 1 "general_operand" ""))]
2445 "!TARGET_64BIT && reload_completed
2446 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2447 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2449 "ix86_split_long_move (operands); DONE;")
2451 (define_insn "*movdi_1_rex64"
2452 [(set (match_operand:DI 0 "nonimmediate_operand"
2453 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2454 (match_operand:DI 1 "general_operand"
2455 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2456 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2458 switch (get_attr_type (insn))
2461 if (SSE_REG_P (operands[0]))
2462 return "movq2dq\t{%1, %0|%0, %1}";
2464 return "movdq2q\t{%1, %0|%0, %1}";
2469 if (get_attr_mode (insn) == MODE_TI)
2470 return "vmovdqa\t{%1, %0|%0, %1}";
2472 return "vmovq\t{%1, %0|%0, %1}";
2475 if (get_attr_mode (insn) == MODE_TI)
2476 return "movdqa\t{%1, %0|%0, %1}";
2480 /* Moves from and into integer register is done using movd
2481 opcode with REX prefix. */
2482 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2483 return "movd\t{%1, %0|%0, %1}";
2484 return "movq\t{%1, %0|%0, %1}";
2487 return "%vpxor\t%0, %d0";
2490 return "pxor\t%0, %0";
2496 return "lea{q}\t{%a1, %0|%0, %a1}";
2499 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2500 if (get_attr_mode (insn) == MODE_SI)
2501 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2502 else if (which_alternative == 2)
2503 return "movabs{q}\t{%1, %0|%0, %1}";
2505 return "mov{q}\t{%1, %0|%0, %1}";
2509 (cond [(eq_attr "alternative" "5")
2510 (const_string "mmx")
2511 (eq_attr "alternative" "6,7,8,9,10")
2512 (const_string "mmxmov")
2513 (eq_attr "alternative" "11")
2514 (const_string "sselog1")
2515 (eq_attr "alternative" "12,13,14,15,16")
2516 (const_string "ssemov")
2517 (eq_attr "alternative" "17,18")
2518 (const_string "ssecvt")
2519 (eq_attr "alternative" "4")
2520 (const_string "multi")
2521 (match_operand:DI 1 "pic_32bit_operand" "")
2522 (const_string "lea")
2524 (const_string "imov")))
2527 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2529 (const_string "*")))
2530 (set (attr "length_immediate")
2532 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2534 (const_string "*")))
2535 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2536 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2537 (set (attr "prefix")
2538 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2539 (const_string "maybe_vex")
2540 (const_string "orig")))
2541 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2543 ;; Stores and loads of ax to arbitrary constant address.
2544 ;; We fake an second form of instruction to force reload to load address
2545 ;; into register when rax is not available
2546 (define_insn "*movabsdi_1_rex64"
2547 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2548 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2549 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2551 movabs{q}\t{%1, %P0|%P0, %1}
2552 mov{q}\t{%1, %a0|%a0, %1}"
2553 [(set_attr "type" "imov")
2554 (set_attr "modrm" "0,*")
2555 (set_attr "length_address" "8,0")
2556 (set_attr "length_immediate" "0,*")
2557 (set_attr "memory" "store")
2558 (set_attr "mode" "DI")])
2560 (define_insn "*movabsdi_2_rex64"
2561 [(set (match_operand:DI 0 "register_operand" "=a,r")
2562 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2563 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2565 movabs{q}\t{%P1, %0|%0, %P1}
2566 mov{q}\t{%a1, %0|%0, %a1}"
2567 [(set_attr "type" "imov")
2568 (set_attr "modrm" "0,*")
2569 (set_attr "length_address" "8,0")
2570 (set_attr "length_immediate" "0")
2571 (set_attr "memory" "load")
2572 (set_attr "mode" "DI")])
2574 ;; Convert impossible stores of immediate to existing instructions.
2575 ;; First try to get scratch register and go through it. In case this
2576 ;; fails, move by 32bit parts.
2578 [(match_scratch:DI 2 "r")
2579 (set (match_operand:DI 0 "memory_operand" "")
2580 (match_operand:DI 1 "immediate_operand" ""))]
2581 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2582 && !x86_64_immediate_operand (operands[1], DImode)"
2583 [(set (match_dup 2) (match_dup 1))
2584 (set (match_dup 0) (match_dup 2))]
2587 ;; We need to define this as both peepholer and splitter for case
2588 ;; peephole2 pass is not run.
2589 ;; "&& 1" is needed to keep it from matching the previous pattern.
2591 [(set (match_operand:DI 0 "memory_operand" "")
2592 (match_operand:DI 1 "immediate_operand" ""))]
2593 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2594 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2595 [(set (match_dup 2) (match_dup 3))
2596 (set (match_dup 4) (match_dup 5))]
2597 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2600 [(set (match_operand:DI 0 "memory_operand" "")
2601 (match_operand:DI 1 "immediate_operand" ""))]
2602 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2603 ? epilogue_completed : reload_completed)
2604 && !symbolic_operand (operands[1], DImode)
2605 && !x86_64_immediate_operand (operands[1], DImode)"
2606 [(set (match_dup 2) (match_dup 3))
2607 (set (match_dup 4) (match_dup 5))]
2608 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2610 (define_insn "*swapdi_rex64"
2611 [(set (match_operand:DI 0 "register_operand" "+r")
2612 (match_operand:DI 1 "register_operand" "+r"))
2617 [(set_attr "type" "imov")
2618 (set_attr "mode" "DI")
2619 (set_attr "pent_pair" "np")
2620 (set_attr "athlon_decode" "vector")
2621 (set_attr "amdfam10_decode" "double")])
2623 (define_expand "movoi"
2624 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2625 (match_operand:OI 1 "general_operand" ""))]
2627 "ix86_expand_move (OImode, operands); DONE;")
2629 (define_insn "*movoi_internal"
2630 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2631 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2633 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2635 switch (which_alternative)
2638 return "vxorps\t%0, %0, %0";
2641 if (misaligned_operand (operands[0], OImode)
2642 || misaligned_operand (operands[1], OImode))
2643 return "vmovdqu\t{%1, %0|%0, %1}";
2645 return "vmovdqa\t{%1, %0|%0, %1}";
2650 [(set_attr "type" "sselog1,ssemov,ssemov")
2651 (set_attr "prefix" "vex")
2652 (set_attr "mode" "OI")])
2654 (define_expand "movti"
2655 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2656 (match_operand:TI 1 "nonimmediate_operand" ""))]
2657 "TARGET_SSE || TARGET_64BIT"
2660 ix86_expand_move (TImode, operands);
2661 else if (push_operand (operands[0], TImode))
2662 ix86_expand_push (TImode, operands[1]);
2664 ix86_expand_vector_move (TImode, operands);
2668 (define_insn "*movti_internal"
2669 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2670 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2671 "TARGET_SSE && !TARGET_64BIT
2672 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2674 switch (which_alternative)
2677 if (get_attr_mode (insn) == MODE_V4SF)
2678 return "%vxorps\t%0, %d0";
2680 return "%vpxor\t%0, %d0";
2683 /* TDmode values are passed as TImode on the stack. Moving them
2684 to stack may result in unaligned memory access. */
2685 if (misaligned_operand (operands[0], TImode)
2686 || misaligned_operand (operands[1], TImode))
2688 if (get_attr_mode (insn) == MODE_V4SF)
2689 return "%vmovups\t{%1, %0|%0, %1}";
2691 return "%vmovdqu\t{%1, %0|%0, %1}";
2695 if (get_attr_mode (insn) == MODE_V4SF)
2696 return "%vmovaps\t{%1, %0|%0, %1}";
2698 return "%vmovdqa\t{%1, %0|%0, %1}";
2704 [(set_attr "type" "sselog1,ssemov,ssemov")
2705 (set_attr "prefix" "maybe_vex")
2707 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2708 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2709 (const_string "V4SF")
2710 (and (eq_attr "alternative" "2")
2711 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2713 (const_string "V4SF")]
2714 (const_string "TI")))])
2716 (define_insn "*movti_rex64"
2717 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2718 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2720 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2722 switch (which_alternative)
2728 if (get_attr_mode (insn) == MODE_V4SF)
2729 return "%vxorps\t%0, %d0";
2731 return "%vpxor\t%0, %d0";
2734 /* TDmode values are passed as TImode on the stack. Moving them
2735 to stack may result in unaligned memory access. */
2736 if (misaligned_operand (operands[0], TImode)
2737 || misaligned_operand (operands[1], TImode))
2739 if (get_attr_mode (insn) == MODE_V4SF)
2740 return "%vmovups\t{%1, %0|%0, %1}";
2742 return "%vmovdqu\t{%1, %0|%0, %1}";
2746 if (get_attr_mode (insn) == MODE_V4SF)
2747 return "%vmovaps\t{%1, %0|%0, %1}";
2749 return "%vmovdqa\t{%1, %0|%0, %1}";
2755 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2756 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2758 (cond [(eq_attr "alternative" "2,3")
2760 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2762 (const_string "V4SF")
2763 (const_string "TI"))
2764 (eq_attr "alternative" "4")
2766 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2768 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2770 (const_string "V4SF")
2771 (const_string "TI"))]
2772 (const_string "DI")))])
2775 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2776 (match_operand:TI 1 "general_operand" ""))]
2777 "reload_completed && !SSE_REG_P (operands[0])
2778 && !SSE_REG_P (operands[1])"
2780 "ix86_split_long_move (operands); DONE;")
2782 ;; This expands to what emit_move_complex would generate if we didn't
2783 ;; have a movti pattern. Having this avoids problems with reload on
2784 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2785 ;; to have around all the time.
2786 (define_expand "movcdi"
2787 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2788 (match_operand:CDI 1 "general_operand" ""))]
2791 if (push_operand (operands[0], CDImode))
2792 emit_move_complex_push (CDImode, operands[0], operands[1]);
2794 emit_move_complex_parts (operands[0], operands[1]);
2798 (define_expand "movsf"
2799 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2800 (match_operand:SF 1 "general_operand" ""))]
2802 "ix86_expand_move (SFmode, operands); DONE;")
2804 (define_insn "*pushsf"
2805 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2806 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2809 /* Anything else should be already split before reg-stack. */
2810 gcc_assert (which_alternative == 1);
2811 return "push{l}\t%1";
2813 [(set_attr "type" "multi,push,multi")
2814 (set_attr "unit" "i387,*,*")
2815 (set_attr "mode" "SF,SI,SF")])
2817 (define_insn "*pushsf_rex64"
2818 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2819 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2822 /* Anything else should be already split before reg-stack. */
2823 gcc_assert (which_alternative == 1);
2824 return "push{q}\t%q1";
2826 [(set_attr "type" "multi,push,multi")
2827 (set_attr "unit" "i387,*,*")
2828 (set_attr "mode" "SF,DI,SF")])
2831 [(set (match_operand:SF 0 "push_operand" "")
2832 (match_operand:SF 1 "memory_operand" ""))]
2834 && MEM_P (operands[1])
2835 && (operands[2] = find_constant_src (insn))"
2839 ;; %%% Kill this when call knows how to work this out.
2841 [(set (match_operand:SF 0 "push_operand" "")
2842 (match_operand:SF 1 "any_fp_register_operand" ""))]
2844 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2845 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2848 [(set (match_operand:SF 0 "push_operand" "")
2849 (match_operand:SF 1 "any_fp_register_operand" ""))]
2851 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2852 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2854 (define_insn "*movsf_1"
2855 [(set (match_operand:SF 0 "nonimmediate_operand"
2856 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2857 (match_operand:SF 1 "general_operand"
2858 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2859 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2860 && (reload_in_progress || reload_completed
2861 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2862 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2863 && standard_80387_constant_p (operands[1]))
2864 || GET_CODE (operands[1]) != CONST_DOUBLE
2865 || memory_operand (operands[0], SFmode))"
2867 switch (which_alternative)
2871 return output_387_reg_move (insn, operands);
2874 return standard_80387_constant_opcode (operands[1]);
2878 return "mov{l}\t{%1, %0|%0, %1}";
2880 if (get_attr_mode (insn) == MODE_TI)
2881 return "%vpxor\t%0, %d0";
2883 return "%vxorps\t%0, %d0";
2885 if (get_attr_mode (insn) == MODE_V4SF)
2886 return "%vmovaps\t{%1, %0|%0, %1}";
2888 return "%vmovss\t{%1, %d0|%d0, %1}";
2891 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2892 : "vmovss\t{%1, %0|%0, %1}";
2894 return "movss\t{%1, %0|%0, %1}";
2896 return "%vmovss\t{%1, %0|%0, %1}";
2898 case 9: case 10: case 14: case 15:
2899 return "movd\t{%1, %0|%0, %1}";
2901 return "%vmovd\t{%1, %0|%0, %1}";
2904 return "movq\t{%1, %0|%0, %1}";
2910 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2911 (set (attr "prefix")
2912 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2913 (const_string "maybe_vex")
2914 (const_string "orig")))
2916 (cond [(eq_attr "alternative" "3,4,9,10")
2918 (eq_attr "alternative" "5")
2920 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2922 (ne (symbol_ref "TARGET_SSE2")
2924 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2927 (const_string "V4SF"))
2928 /* For architectures resolving dependencies on
2929 whole SSE registers use APS move to break dependency
2930 chains, otherwise use short move to avoid extra work.
2932 Do the same for architectures resolving dependencies on
2933 the parts. While in DF mode it is better to always handle
2934 just register parts, the SF mode is different due to lack
2935 of instructions to load just part of the register. It is
2936 better to maintain the whole registers in single format
2937 to avoid problems on using packed logical operations. */
2938 (eq_attr "alternative" "6")
2940 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2942 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2944 (const_string "V4SF")
2945 (const_string "SF"))
2946 (eq_attr "alternative" "11")
2947 (const_string "DI")]
2948 (const_string "SF")))])
2950 (define_insn "*swapsf"
2951 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2952 (match_operand:SF 1 "fp_register_operand" "+f"))
2955 "reload_completed || TARGET_80387"
2957 if (STACK_TOP_P (operands[0]))
2962 [(set_attr "type" "fxch")
2963 (set_attr "mode" "SF")])
2965 (define_expand "movdf"
2966 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2967 (match_operand:DF 1 "general_operand" ""))]
2969 "ix86_expand_move (DFmode, operands); DONE;")
2971 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2972 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2973 ;; On the average, pushdf using integers can be still shorter. Allow this
2974 ;; pattern for optimize_size too.
2976 (define_insn "*pushdf_nointeger"
2977 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2978 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2979 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2981 /* This insn should be already split before reg-stack. */
2984 [(set_attr "type" "multi")
2985 (set_attr "unit" "i387,*,*,*")
2986 (set_attr "mode" "DF,SI,SI,DF")])
2988 (define_insn "*pushdf_integer"
2989 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2990 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2991 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2993 /* This insn should be already split before reg-stack. */
2996 [(set_attr "type" "multi")
2997 (set_attr "unit" "i387,*,*")
2998 (set_attr "mode" "DF,SI,DF")])
3000 ;; %%% Kill this when call knows how to work this out.
3002 [(set (match_operand:DF 0 "push_operand" "")
3003 (match_operand:DF 1 "any_fp_register_operand" ""))]
3005 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3006 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3010 [(set (match_operand:DF 0 "push_operand" "")
3011 (match_operand:DF 1 "general_operand" ""))]
3014 "ix86_split_long_move (operands); DONE;")
3016 ;; Moving is usually shorter when only FP registers are used. This separate
3017 ;; movdf pattern avoids the use of integer registers for FP operations
3018 ;; when optimizing for size.
3020 (define_insn "*movdf_nointeger"
3021 [(set (match_operand:DF 0 "nonimmediate_operand"
3022 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3023 (match_operand:DF 1 "general_operand"
3024 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3025 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3026 && ((optimize_function_for_size_p (cfun)
3027 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3028 && (reload_in_progress || reload_completed
3029 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3030 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3031 && optimize_function_for_size_p (cfun)
3032 && !memory_operand (operands[0], DFmode)
3033 && standard_80387_constant_p (operands[1]))
3034 || GET_CODE (operands[1]) != CONST_DOUBLE
3035 || ((optimize_function_for_size_p (cfun)
3036 || !TARGET_MEMORY_MISMATCH_STALL
3037 || reload_in_progress || reload_completed)
3038 && memory_operand (operands[0], DFmode)))"
3040 switch (which_alternative)
3044 return output_387_reg_move (insn, operands);
3047 return standard_80387_constant_opcode (operands[1]);
3053 switch (get_attr_mode (insn))
3056 return "%vxorps\t%0, %d0";
3058 return "%vxorpd\t%0, %d0";
3060 return "%vpxor\t%0, %d0";
3067 switch (get_attr_mode (insn))
3070 return "%vmovaps\t{%1, %0|%0, %1}";
3072 return "%vmovapd\t{%1, %0|%0, %1}";
3074 return "%vmovdqa\t{%1, %0|%0, %1}";
3076 return "%vmovq\t{%1, %0|%0, %1}";
3080 if (REG_P (operands[0]) && REG_P (operands[1]))
3081 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3083 return "vmovsd\t{%1, %0|%0, %1}";
3086 return "movsd\t{%1, %0|%0, %1}";
3090 if (REG_P (operands[0]))
3091 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3093 return "vmovlpd\t{%1, %0|%0, %1}";
3096 return "movlpd\t{%1, %0|%0, %1}";
3100 if (REG_P (operands[0]))
3101 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3103 return "vmovlps\t{%1, %0|%0, %1}";
3106 return "movlps\t{%1, %0|%0, %1}";
3115 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3116 (set (attr "prefix")
3117 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3118 (const_string "orig")
3119 (const_string "maybe_vex")))
3120 (set (attr "prefix_data16")
3121 (if_then_else (eq_attr "mode" "V1DF")
3123 (const_string "*")))
3125 (cond [(eq_attr "alternative" "0,1,2")
3127 (eq_attr "alternative" "3,4")
3130 /* For SSE1, we have many fewer alternatives. */
3131 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3132 (cond [(eq_attr "alternative" "5,6")
3133 (const_string "V4SF")
3135 (const_string "V2SF"))
3137 /* xorps is one byte shorter. */
3138 (eq_attr "alternative" "5")
3139 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3141 (const_string "V4SF")
3142 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3146 (const_string "V2DF"))
3148 /* For architectures resolving dependencies on
3149 whole SSE registers use APD move to break dependency
3150 chains, otherwise use short move to avoid extra work.
3152 movaps encodes one byte shorter. */
3153 (eq_attr "alternative" "6")
3155 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3157 (const_string "V4SF")
3158 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3160 (const_string "V2DF")
3162 (const_string "DF"))
3163 /* For architectures resolving dependencies on register
3164 parts we may avoid extra work to zero out upper part
3166 (eq_attr "alternative" "7")
3168 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3170 (const_string "V1DF")
3171 (const_string "DF"))
3173 (const_string "DF")))])
3175 (define_insn "*movdf_integer_rex64"
3176 [(set (match_operand:DF 0 "nonimmediate_operand"
3177 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3178 (match_operand:DF 1 "general_operand"
3179 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3180 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3181 && (reload_in_progress || reload_completed
3182 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3183 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3184 && optimize_function_for_size_p (cfun)
3185 && standard_80387_constant_p (operands[1]))
3186 || GET_CODE (operands[1]) != CONST_DOUBLE
3187 || memory_operand (operands[0], DFmode))"
3189 switch (which_alternative)
3193 return output_387_reg_move (insn, operands);
3196 return standard_80387_constant_opcode (operands[1]);
3203 switch (get_attr_mode (insn))
3206 return "%vxorps\t%0, %d0";
3208 return "%vxorpd\t%0, %d0";
3210 return "%vpxor\t%0, %d0";
3217 switch (get_attr_mode (insn))
3220 return "%vmovaps\t{%1, %0|%0, %1}";
3222 return "%vmovapd\t{%1, %0|%0, %1}";
3224 return "%vmovdqa\t{%1, %0|%0, %1}";
3226 return "%vmovq\t{%1, %0|%0, %1}";
3230 if (REG_P (operands[0]) && REG_P (operands[1]))
3231 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3233 return "vmovsd\t{%1, %0|%0, %1}";
3236 return "movsd\t{%1, %0|%0, %1}";
3238 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3240 return "%vmovlps\t{%1, %d0|%d0, %1}";
3247 return "%vmovd\t{%1, %0|%0, %1}";
3253 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3254 (set (attr "prefix")
3255 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3256 (const_string "orig")
3257 (const_string "maybe_vex")))
3258 (set (attr "prefix_data16")
3259 (if_then_else (eq_attr "mode" "V1DF")
3261 (const_string "*")))
3263 (cond [(eq_attr "alternative" "0,1,2")
3265 (eq_attr "alternative" "3,4,9,10")
3268 /* For SSE1, we have many fewer alternatives. */
3269 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3270 (cond [(eq_attr "alternative" "5,6")
3271 (const_string "V4SF")
3273 (const_string "V2SF"))
3275 /* xorps is one byte shorter. */
3276 (eq_attr "alternative" "5")
3277 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3279 (const_string "V4SF")
3280 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3284 (const_string "V2DF"))
3286 /* For architectures resolving dependencies on
3287 whole SSE registers use APD move to break dependency
3288 chains, otherwise use short move to avoid extra work.
3290 movaps encodes one byte shorter. */
3291 (eq_attr "alternative" "6")
3293 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3295 (const_string "V4SF")
3296 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3298 (const_string "V2DF")
3300 (const_string "DF"))
3301 /* For architectures resolving dependencies on register
3302 parts we may avoid extra work to zero out upper part
3304 (eq_attr "alternative" "7")
3306 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3308 (const_string "V1DF")
3309 (const_string "DF"))
3311 (const_string "DF")))])
3313 (define_insn "*movdf_integer"
3314 [(set (match_operand:DF 0 "nonimmediate_operand"
3315 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3316 (match_operand:DF 1 "general_operand"
3317 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3318 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3319 && optimize_function_for_speed_p (cfun)
3320 && TARGET_INTEGER_DFMODE_MOVES
3321 && (reload_in_progress || reload_completed
3322 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3323 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3324 && optimize_function_for_size_p (cfun)
3325 && standard_80387_constant_p (operands[1]))
3326 || GET_CODE (operands[1]) != CONST_DOUBLE
3327 || memory_operand (operands[0], DFmode))"
3329 switch (which_alternative)
3333 return output_387_reg_move (insn, operands);
3336 return standard_80387_constant_opcode (operands[1]);
3343 switch (get_attr_mode (insn))
3346 return "xorps\t%0, %0";
3348 return "xorpd\t%0, %0";
3350 return "pxor\t%0, %0";
3357 switch (get_attr_mode (insn))
3360 return "movaps\t{%1, %0|%0, %1}";
3362 return "movapd\t{%1, %0|%0, %1}";
3364 return "movdqa\t{%1, %0|%0, %1}";
3366 return "movq\t{%1, %0|%0, %1}";
3368 return "movsd\t{%1, %0|%0, %1}";
3370 return "movlpd\t{%1, %0|%0, %1}";
3372 return "movlps\t{%1, %0|%0, %1}";
3381 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3382 (set (attr "prefix_data16")
3383 (if_then_else (eq_attr "mode" "V1DF")
3385 (const_string "*")))
3387 (cond [(eq_attr "alternative" "0,1,2")
3389 (eq_attr "alternative" "3,4")
3392 /* For SSE1, we have many fewer alternatives. */
3393 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3394 (cond [(eq_attr "alternative" "5,6")
3395 (const_string "V4SF")
3397 (const_string "V2SF"))
3399 /* xorps is one byte shorter. */
3400 (eq_attr "alternative" "5")
3401 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3403 (const_string "V4SF")
3404 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3408 (const_string "V2DF"))
3410 /* For architectures resolving dependencies on
3411 whole SSE registers use APD move to break dependency
3412 chains, otherwise use short move to avoid extra work.
3414 movaps encodes one byte shorter. */
3415 (eq_attr "alternative" "6")
3417 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3419 (const_string "V4SF")
3420 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3422 (const_string "V2DF")
3424 (const_string "DF"))
3425 /* For architectures resolving dependencies on register
3426 parts we may avoid extra work to zero out upper part
3428 (eq_attr "alternative" "7")
3430 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3432 (const_string "V1DF")
3433 (const_string "DF"))
3435 (const_string "DF")))])
3438 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3439 (match_operand:DF 1 "general_operand" ""))]
3441 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3442 && ! (ANY_FP_REG_P (operands[0]) ||
3443 (GET_CODE (operands[0]) == SUBREG
3444 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3445 && ! (ANY_FP_REG_P (operands[1]) ||
3446 (GET_CODE (operands[1]) == SUBREG
3447 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3449 "ix86_split_long_move (operands); DONE;")
3451 (define_insn "*swapdf"
3452 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3453 (match_operand:DF 1 "fp_register_operand" "+f"))
3456 "reload_completed || TARGET_80387"
3458 if (STACK_TOP_P (operands[0]))
3463 [(set_attr "type" "fxch")
3464 (set_attr "mode" "DF")])
3466 (define_expand "movxf"
3467 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3468 (match_operand:XF 1 "general_operand" ""))]
3470 "ix86_expand_move (XFmode, operands); DONE;")
3472 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3473 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3474 ;; Pushing using integer instructions is longer except for constants
3475 ;; and direct memory references.
3476 ;; (assuming that any given constant is pushed only once, but this ought to be
3477 ;; handled elsewhere).
3479 (define_insn "*pushxf_nointeger"
3480 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3481 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3482 "optimize_function_for_size_p (cfun)"
3484 /* This insn should be already split before reg-stack. */
3487 [(set_attr "type" "multi")
3488 (set_attr "unit" "i387,*,*")
3489 (set_attr "mode" "XF,SI,SI")])
3491 (define_insn "*pushxf_integer"
3492 [(set (match_operand:XF 0 "push_operand" "=<,<")
3493 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3494 "optimize_function_for_speed_p (cfun)"
3496 /* This insn should be already split before reg-stack. */
3499 [(set_attr "type" "multi")
3500 (set_attr "unit" "i387,*")
3501 (set_attr "mode" "XF,SI")])
3504 [(set (match_operand 0 "push_operand" "")
3505 (match_operand 1 "general_operand" ""))]
3507 && (GET_MODE (operands[0]) == XFmode
3508 || GET_MODE (operands[0]) == DFmode)
3509 && !ANY_FP_REG_P (operands[1])"
3511 "ix86_split_long_move (operands); DONE;")
3514 [(set (match_operand:XF 0 "push_operand" "")
3515 (match_operand:XF 1 "any_fp_register_operand" ""))]
3517 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3518 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3519 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3521 ;; Do not use integer registers when optimizing for size
3522 (define_insn "*movxf_nointeger"
3523 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3524 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3525 "optimize_function_for_size_p (cfun)
3526 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3527 && (reload_in_progress || reload_completed
3528 || standard_80387_constant_p (operands[1])
3529 || GET_CODE (operands[1]) != CONST_DOUBLE
3530 || memory_operand (operands[0], XFmode))"
3532 switch (which_alternative)
3536 return output_387_reg_move (insn, operands);
3539 return standard_80387_constant_opcode (operands[1]);
3547 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3548 (set_attr "mode" "XF,XF,XF,SI,SI")])
3550 (define_insn "*movxf_integer"
3551 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3552 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3553 "optimize_function_for_speed_p (cfun)
3554 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3555 && (reload_in_progress || reload_completed
3556 || GET_CODE (operands[1]) != CONST_DOUBLE
3557 || memory_operand (operands[0], XFmode))"
3559 switch (which_alternative)
3563 return output_387_reg_move (insn, operands);
3566 return standard_80387_constant_opcode (operands[1]);
3575 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3576 (set_attr "mode" "XF,XF,XF,SI,SI")])
3578 (define_expand "movtf"
3579 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3580 (match_operand:TF 1 "nonimmediate_operand" ""))]
3583 ix86_expand_move (TFmode, operands);
3587 (define_insn "*movtf_internal"
3588 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3589 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3591 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3593 switch (which_alternative)
3597 if (get_attr_mode (insn) == MODE_V4SF)
3598 return "%vmovaps\t{%1, %0|%0, %1}";
3600 return "%vmovdqa\t{%1, %0|%0, %1}";
3602 if (get_attr_mode (insn) == MODE_V4SF)
3603 return "%vxorps\t%0, %d0";
3605 return "%vpxor\t%0, %d0";
3613 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3614 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3616 (cond [(eq_attr "alternative" "0,2")
3618 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3620 (const_string "V4SF")
3621 (const_string "TI"))
3622 (eq_attr "alternative" "1")
3624 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3626 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3628 (const_string "V4SF")
3629 (const_string "TI"))]
3630 (const_string "DI")))])
3632 (define_insn "*pushtf_sse"
3633 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3634 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3637 /* This insn should be already split before reg-stack. */
3640 [(set_attr "type" "multi")
3641 (set_attr "unit" "sse,*,*")
3642 (set_attr "mode" "TF,SI,SI")])
3645 [(set (match_operand:TF 0 "push_operand" "")
3646 (match_operand:TF 1 "general_operand" ""))]
3647 "TARGET_SSE2 && reload_completed
3648 && !SSE_REG_P (operands[1])"
3650 "ix86_split_long_move (operands); DONE;")
3653 [(set (match_operand:TF 0 "push_operand" "")
3654 (match_operand:TF 1 "any_fp_register_operand" ""))]
3656 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3657 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3661 [(set (match_operand 0 "nonimmediate_operand" "")
3662 (match_operand 1 "general_operand" ""))]
3664 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3665 && GET_MODE (operands[0]) == XFmode
3666 && ! (ANY_FP_REG_P (operands[0]) ||
3667 (GET_CODE (operands[0]) == SUBREG
3668 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3669 && ! (ANY_FP_REG_P (operands[1]) ||
3670 (GET_CODE (operands[1]) == SUBREG
3671 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3673 "ix86_split_long_move (operands); DONE;")
3676 [(set (match_operand 0 "register_operand" "")
3677 (match_operand 1 "memory_operand" ""))]
3679 && MEM_P (operands[1])
3680 && (GET_MODE (operands[0]) == TFmode
3681 || GET_MODE (operands[0]) == XFmode
3682 || GET_MODE (operands[0]) == SFmode
3683 || GET_MODE (operands[0]) == DFmode)
3684 && (operands[2] = find_constant_src (insn))"
3685 [(set (match_dup 0) (match_dup 2))]
3687 rtx c = operands[2];
3688 rtx r = operands[0];
3690 if (GET_CODE (r) == SUBREG)
3695 if (!standard_sse_constant_p (c))
3698 else if (FP_REG_P (r))
3700 if (!standard_80387_constant_p (c))
3703 else if (MMX_REG_P (r))
3708 [(set (match_operand 0 "register_operand" "")
3709 (float_extend (match_operand 1 "memory_operand" "")))]
3711 && MEM_P (operands[1])
3712 && (GET_MODE (operands[0]) == TFmode
3713 || GET_MODE (operands[0]) == XFmode
3714 || GET_MODE (operands[0]) == SFmode
3715 || GET_MODE (operands[0]) == DFmode)
3716 && (operands[2] = find_constant_src (insn))"
3717 [(set (match_dup 0) (match_dup 2))]
3719 rtx c = operands[2];
3720 rtx r = operands[0];
3722 if (GET_CODE (r) == SUBREG)
3727 if (!standard_sse_constant_p (c))
3730 else if (FP_REG_P (r))
3732 if (!standard_80387_constant_p (c))
3735 else if (MMX_REG_P (r))
3739 (define_insn "swapxf"
3740 [(set (match_operand:XF 0 "register_operand" "+f")
3741 (match_operand:XF 1 "register_operand" "+f"))
3746 if (STACK_TOP_P (operands[0]))
3751 [(set_attr "type" "fxch")
3752 (set_attr "mode" "XF")])
3754 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3756 [(set (match_operand:X87MODEF 0 "register_operand" "")
3757 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3758 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3759 && (standard_80387_constant_p (operands[1]) == 8
3760 || standard_80387_constant_p (operands[1]) == 9)"
3761 [(set (match_dup 0)(match_dup 1))
3763 (neg:X87MODEF (match_dup 0)))]
3767 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3768 if (real_isnegzero (&r))
3769 operands[1] = CONST0_RTX (<MODE>mode);
3771 operands[1] = CONST1_RTX (<MODE>mode);
3775 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3776 (match_operand:TF 1 "general_operand" ""))]
3778 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3780 "ix86_split_long_move (operands); DONE;")
3782 ;; Zero extension instructions
3784 (define_expand "zero_extendhisi2"
3785 [(set (match_operand:SI 0 "register_operand" "")
3786 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3789 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3791 operands[1] = force_reg (HImode, operands[1]);
3792 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3797 (define_insn "zero_extendhisi2_and"
3798 [(set (match_operand:SI 0 "register_operand" "=r")
3799 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3800 (clobber (reg:CC FLAGS_REG))]
3801 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3803 [(set_attr "type" "alu1")
3804 (set_attr "mode" "SI")])
3807 [(set (match_operand:SI 0 "register_operand" "")
3808 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3809 (clobber (reg:CC FLAGS_REG))]
3810 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3811 && optimize_function_for_speed_p (cfun)"
3812 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3813 (clobber (reg:CC FLAGS_REG))])]
3816 (define_insn "*zero_extendhisi2_movzwl"
3817 [(set (match_operand:SI 0 "register_operand" "=r")
3818 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3819 "!TARGET_ZERO_EXTEND_WITH_AND
3820 || optimize_function_for_size_p (cfun)"
3821 "movz{wl|x}\t{%1, %0|%0, %1}"
3822 [(set_attr "type" "imovx")
3823 (set_attr "mode" "SI")])
3825 (define_expand "zero_extendqihi2"
3827 [(set (match_operand:HI 0 "register_operand" "")
3828 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3829 (clobber (reg:CC FLAGS_REG))])]
3833 (define_insn "*zero_extendqihi2_and"
3834 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3835 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3836 (clobber (reg:CC FLAGS_REG))]
3837 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3839 [(set_attr "type" "alu1")
3840 (set_attr "mode" "HI")])
3842 (define_insn "*zero_extendqihi2_movzbw_and"
3843 [(set (match_operand:HI 0 "register_operand" "=r,r")
3844 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3845 (clobber (reg:CC FLAGS_REG))]
3846 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3848 [(set_attr "type" "imovx,alu1")
3849 (set_attr "mode" "HI")])
3851 ; zero extend to SImode here to avoid partial register stalls
3852 (define_insn "*zero_extendqihi2_movzbl"
3853 [(set (match_operand:HI 0 "register_operand" "=r")
3854 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3855 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3856 && reload_completed"
3857 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3858 [(set_attr "type" "imovx")
3859 (set_attr "mode" "SI")])
3861 ;; For the movzbw case strip only the clobber
3863 [(set (match_operand:HI 0 "register_operand" "")
3864 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3865 (clobber (reg:CC FLAGS_REG))]
3867 && (!TARGET_ZERO_EXTEND_WITH_AND
3868 || optimize_function_for_size_p (cfun))
3869 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3870 [(set (match_operand:HI 0 "register_operand" "")
3871 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3873 ;; When source and destination does not overlap, clear destination
3874 ;; first and then do the movb
3876 [(set (match_operand:HI 0 "register_operand" "")
3877 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3878 (clobber (reg:CC FLAGS_REG))]
3880 && ANY_QI_REG_P (operands[0])
3881 && (TARGET_ZERO_EXTEND_WITH_AND
3882 && optimize_function_for_speed_p (cfun))
3883 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3884 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3886 operands[2] = gen_lowpart (QImode, operands[0]);
3887 ix86_expand_clear (operands[0]);
3890 ;; Rest is handled by single and.
3892 [(set (match_operand:HI 0 "register_operand" "")
3893 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3894 (clobber (reg:CC FLAGS_REG))]
3896 && true_regnum (operands[0]) == true_regnum (operands[1])"
3897 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3898 (clobber (reg:CC FLAGS_REG))])]
3901 (define_expand "zero_extendqisi2"
3903 [(set (match_operand:SI 0 "register_operand" "")
3904 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3905 (clobber (reg:CC FLAGS_REG))])]
3909 (define_insn "*zero_extendqisi2_and"
3910 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3911 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3912 (clobber (reg:CC FLAGS_REG))]
3913 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3915 [(set_attr "type" "alu1")
3916 (set_attr "mode" "SI")])
3918 (define_insn "*zero_extendqisi2_movzbl_and"
3919 [(set (match_operand:SI 0 "register_operand" "=r,r")
3920 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3921 (clobber (reg:CC FLAGS_REG))]
3922 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3924 [(set_attr "type" "imovx,alu1")
3925 (set_attr "mode" "SI")])
3927 (define_insn "*zero_extendqisi2_movzbl"
3928 [(set (match_operand:SI 0 "register_operand" "=r")
3929 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3930 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3931 && reload_completed"
3932 "movz{bl|x}\t{%1, %0|%0, %1}"
3933 [(set_attr "type" "imovx")
3934 (set_attr "mode" "SI")])
3936 ;; For the movzbl case strip only the clobber
3938 [(set (match_operand:SI 0 "register_operand" "")
3939 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3940 (clobber (reg:CC FLAGS_REG))]
3942 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3943 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3945 (zero_extend:SI (match_dup 1)))])
3947 ;; When source and destination does not overlap, clear destination
3948 ;; first and then do the movb
3950 [(set (match_operand:SI 0 "register_operand" "")
3951 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3952 (clobber (reg:CC FLAGS_REG))]
3954 && ANY_QI_REG_P (operands[0])
3955 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3956 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3957 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3958 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3960 operands[2] = gen_lowpart (QImode, operands[0]);
3961 ix86_expand_clear (operands[0]);
3964 ;; Rest is handled by single and.
3966 [(set (match_operand:SI 0 "register_operand" "")
3967 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3968 (clobber (reg:CC FLAGS_REG))]
3970 && true_regnum (operands[0]) == true_regnum (operands[1])"
3971 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3972 (clobber (reg:CC FLAGS_REG))])]
3975 ;; %%% Kill me once multi-word ops are sane.
3976 (define_expand "zero_extendsidi2"
3977 [(set (match_operand:DI 0 "register_operand" "")
3978 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3983 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3988 (define_insn "zero_extendsidi2_32"
3989 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3991 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3992 (clobber (reg:CC FLAGS_REG))]
3998 movd\t{%1, %0|%0, %1}
3999 movd\t{%1, %0|%0, %1}
4000 %vmovd\t{%1, %0|%0, %1}
4001 %vmovd\t{%1, %0|%0, %1}"
4002 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4003 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4004 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4006 (define_insn "zero_extendsidi2_rex64"
4007 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4009 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4012 mov\t{%k1, %k0|%k0, %k1}
4014 movd\t{%1, %0|%0, %1}
4015 movd\t{%1, %0|%0, %1}
4016 %vmovd\t{%1, %0|%0, %1}
4017 %vmovd\t{%1, %0|%0, %1}"
4018 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4019 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4020 (set_attr "prefix_0f" "0,*,*,*,*,*")
4021 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4024 [(set (match_operand:DI 0 "memory_operand" "")
4025 (zero_extend:DI (match_dup 0)))]
4027 [(set (match_dup 4) (const_int 0))]
4028 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4031 [(set (match_operand:DI 0 "register_operand" "")
4032 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4033 (clobber (reg:CC FLAGS_REG))]
4034 "!TARGET_64BIT && reload_completed
4035 && true_regnum (operands[0]) == true_regnum (operands[1])"
4036 [(set (match_dup 4) (const_int 0))]
4037 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4040 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4041 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4042 (clobber (reg:CC FLAGS_REG))]
4043 "!TARGET_64BIT && reload_completed
4044 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4045 [(set (match_dup 3) (match_dup 1))
4046 (set (match_dup 4) (const_int 0))]
4047 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4049 (define_insn "zero_extendhidi2"
4050 [(set (match_operand:DI 0 "register_operand" "=r")
4051 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4053 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4054 [(set_attr "type" "imovx")
4055 (set_attr "mode" "SI")])
4057 (define_insn "zero_extendqidi2"
4058 [(set (match_operand:DI 0 "register_operand" "=r")
4059 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4061 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4062 [(set_attr "type" "imovx")
4063 (set_attr "mode" "SI")])
4065 ;; Sign extension instructions
4067 (define_expand "extendsidi2"
4068 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4069 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4070 (clobber (reg:CC FLAGS_REG))
4071 (clobber (match_scratch:SI 2 ""))])]
4076 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4081 (define_insn "*extendsidi2_1"
4082 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4083 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4084 (clobber (reg:CC FLAGS_REG))
4085 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4089 (define_insn "extendsidi2_rex64"
4090 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4091 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4095 movs{lq|x}\t{%1, %0|%0, %1}"
4096 [(set_attr "type" "imovx")
4097 (set_attr "mode" "DI")
4098 (set_attr "prefix_0f" "0")
4099 (set_attr "modrm" "0,1")])
4101 (define_insn "extendhidi2"
4102 [(set (match_operand:DI 0 "register_operand" "=r")
4103 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4105 "movs{wq|x}\t{%1, %0|%0, %1}"
4106 [(set_attr "type" "imovx")
4107 (set_attr "mode" "DI")])
4109 (define_insn "extendqidi2"
4110 [(set (match_operand:DI 0 "register_operand" "=r")
4111 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4113 "movs{bq|x}\t{%1, %0|%0, %1}"
4114 [(set_attr "type" "imovx")
4115 (set_attr "mode" "DI")])
4117 ;; Extend to memory case when source register does die.
4119 [(set (match_operand:DI 0 "memory_operand" "")
4120 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4121 (clobber (reg:CC FLAGS_REG))
4122 (clobber (match_operand:SI 2 "register_operand" ""))]
4124 && dead_or_set_p (insn, operands[1])
4125 && !reg_mentioned_p (operands[1], operands[0]))"
4126 [(set (match_dup 3) (match_dup 1))
4127 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4128 (clobber (reg:CC FLAGS_REG))])
4129 (set (match_dup 4) (match_dup 1))]
4130 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4132 ;; Extend to memory case when source register does not die.
4134 [(set (match_operand:DI 0 "memory_operand" "")
4135 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4136 (clobber (reg:CC FLAGS_REG))
4137 (clobber (match_operand:SI 2 "register_operand" ""))]
4141 split_di (&operands[0], 1, &operands[3], &operands[4]);
4143 emit_move_insn (operands[3], operands[1]);
4145 /* Generate a cltd if possible and doing so it profitable. */
4146 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4147 && true_regnum (operands[1]) == AX_REG
4148 && true_regnum (operands[2]) == DX_REG)
4150 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4154 emit_move_insn (operands[2], operands[1]);
4155 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4157 emit_move_insn (operands[4], operands[2]);
4161 ;; Extend to register case. Optimize case where source and destination
4162 ;; registers match and cases where we can use cltd.
4164 [(set (match_operand:DI 0 "register_operand" "")
4165 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4166 (clobber (reg:CC FLAGS_REG))
4167 (clobber (match_scratch:SI 2 ""))]
4171 split_di (&operands[0], 1, &operands[3], &operands[4]);
4173 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4174 emit_move_insn (operands[3], operands[1]);
4176 /* Generate a cltd if possible and doing so it profitable. */
4177 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4178 && true_regnum (operands[3]) == AX_REG)
4180 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4184 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4185 emit_move_insn (operands[4], operands[1]);
4187 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4191 (define_insn "extendhisi2"
4192 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4193 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4196 switch (get_attr_prefix_0f (insn))
4199 return "{cwtl|cwde}";
4201 return "movs{wl|x}\t{%1, %0|%0, %1}";
4204 [(set_attr "type" "imovx")
4205 (set_attr "mode" "SI")
4206 (set (attr "prefix_0f")
4207 ;; movsx is short decodable while cwtl is vector decoded.
4208 (if_then_else (and (eq_attr "cpu" "!k6")
4209 (eq_attr "alternative" "0"))
4211 (const_string "1")))
4213 (if_then_else (eq_attr "prefix_0f" "0")
4215 (const_string "1")))])
4217 (define_insn "*extendhisi2_zext"
4218 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4220 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4223 switch (get_attr_prefix_0f (insn))
4226 return "{cwtl|cwde}";
4228 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4231 [(set_attr "type" "imovx")
4232 (set_attr "mode" "SI")
4233 (set (attr "prefix_0f")
4234 ;; movsx is short decodable while cwtl is vector decoded.
4235 (if_then_else (and (eq_attr "cpu" "!k6")
4236 (eq_attr "alternative" "0"))
4238 (const_string "1")))
4240 (if_then_else (eq_attr "prefix_0f" "0")
4242 (const_string "1")))])
4244 (define_insn "extendqihi2"
4245 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4246 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4249 switch (get_attr_prefix_0f (insn))
4252 return "{cbtw|cbw}";
4254 return "movs{bw|x}\t{%1, %0|%0, %1}";
4257 [(set_attr "type" "imovx")
4258 (set_attr "mode" "HI")
4259 (set (attr "prefix_0f")
4260 ;; movsx is short decodable while cwtl is vector decoded.
4261 (if_then_else (and (eq_attr "cpu" "!k6")
4262 (eq_attr "alternative" "0"))
4264 (const_string "1")))
4266 (if_then_else (eq_attr "prefix_0f" "0")
4268 (const_string "1")))])
4270 (define_insn "extendqisi2"
4271 [(set (match_operand:SI 0 "register_operand" "=r")
4272 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4274 "movs{bl|x}\t{%1, %0|%0, %1}"
4275 [(set_attr "type" "imovx")
4276 (set_attr "mode" "SI")])
4278 (define_insn "*extendqisi2_zext"
4279 [(set (match_operand:DI 0 "register_operand" "=r")
4281 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4283 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4284 [(set_attr "type" "imovx")
4285 (set_attr "mode" "SI")])
4287 ;; Conversions between float and double.
4289 ;; These are all no-ops in the model used for the 80387. So just
4292 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4293 (define_insn "*dummy_extendsfdf2"
4294 [(set (match_operand:DF 0 "push_operand" "=<")
4295 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4300 [(set (match_operand:DF 0 "push_operand" "")
4301 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4303 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4304 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4306 (define_insn "*dummy_extendsfxf2"
4307 [(set (match_operand:XF 0 "push_operand" "=<")
4308 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4313 [(set (match_operand:XF 0 "push_operand" "")
4314 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4316 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4317 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4318 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4321 [(set (match_operand:XF 0 "push_operand" "")
4322 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4324 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4325 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4326 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4328 (define_expand "extendsfdf2"
4329 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4330 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4331 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4333 /* ??? Needed for compress_float_constant since all fp constants
4334 are LEGITIMATE_CONSTANT_P. */
4335 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4337 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4338 && standard_80387_constant_p (operands[1]) > 0)
4340 operands[1] = simplify_const_unary_operation
4341 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4342 emit_move_insn_1 (operands[0], operands[1]);
4345 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4349 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4351 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4353 We do the conversion post reload to avoid producing of 128bit spills
4354 that might lead to ICE on 32bit target. The sequence unlikely combine
4357 [(set (match_operand:DF 0 "register_operand" "")
4359 (match_operand:SF 1 "nonimmediate_operand" "")))]
4360 "TARGET_USE_VECTOR_FP_CONVERTS
4361 && optimize_insn_for_speed_p ()
4362 && reload_completed && SSE_REG_P (operands[0])"
4367 (parallel [(const_int 0) (const_int 1)]))))]
4369 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4370 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4371 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4372 Try to avoid move when unpacking can be done in source. */
4373 if (REG_P (operands[1]))
4375 /* If it is unsafe to overwrite upper half of source, we need
4376 to move to destination and unpack there. */
4377 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4378 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4379 && true_regnum (operands[0]) != true_regnum (operands[1]))
4381 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4382 emit_move_insn (tmp, operands[1]);
4385 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4386 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4390 emit_insn (gen_vec_setv4sf_0 (operands[3],
4391 CONST0_RTX (V4SFmode), operands[1]));
4394 (define_insn "*extendsfdf2_mixed"
4395 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4397 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4398 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4400 switch (which_alternative)
4404 return output_387_reg_move (insn, operands);
4407 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4413 [(set_attr "type" "fmov,fmov,ssecvt")
4414 (set_attr "prefix" "orig,orig,maybe_vex")
4415 (set_attr "mode" "SF,XF,DF")])
4417 (define_insn "*extendsfdf2_sse"
4418 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4419 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4420 "TARGET_SSE2 && TARGET_SSE_MATH"
4421 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4422 [(set_attr "type" "ssecvt")
4423 (set_attr "prefix" "maybe_vex")
4424 (set_attr "mode" "DF")])
4426 (define_insn "*extendsfdf2_i387"
4427 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4428 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4430 "* return output_387_reg_move (insn, operands);"
4431 [(set_attr "type" "fmov")
4432 (set_attr "mode" "SF,XF")])
4434 (define_expand "extend<mode>xf2"
4435 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4436 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4439 /* ??? Needed for compress_float_constant since all fp constants
4440 are LEGITIMATE_CONSTANT_P. */
4441 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4443 if (standard_80387_constant_p (operands[1]) > 0)
4445 operands[1] = simplify_const_unary_operation
4446 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4447 emit_move_insn_1 (operands[0], operands[1]);
4450 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4454 (define_insn "*extend<mode>xf2_i387"
4455 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4457 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4459 "* return output_387_reg_move (insn, operands);"
4460 [(set_attr "type" "fmov")
4461 (set_attr "mode" "<MODE>,XF")])
4463 ;; %%% This seems bad bad news.
4464 ;; This cannot output into an f-reg because there is no way to be sure
4465 ;; of truncating in that case. Otherwise this is just like a simple move
4466 ;; insn. So we pretend we can output to a reg in order to get better
4467 ;; register preferencing, but we really use a stack slot.
4469 ;; Conversion from DFmode to SFmode.
4471 (define_expand "truncdfsf2"
4472 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4474 (match_operand:DF 1 "nonimmediate_operand" "")))]
4475 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4477 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4479 else if (flag_unsafe_math_optimizations)
4483 enum ix86_stack_slot slot = (virtuals_instantiated
4486 rtx temp = assign_386_stack_local (SFmode, slot);
4487 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4492 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4494 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4496 We do the conversion post reload to avoid producing of 128bit spills
4497 that might lead to ICE on 32bit target. The sequence unlikely combine
4500 [(set (match_operand:SF 0 "register_operand" "")
4502 (match_operand:DF 1 "nonimmediate_operand" "")))]
4503 "TARGET_USE_VECTOR_FP_CONVERTS
4504 && optimize_insn_for_speed_p ()
4505 && reload_completed && SSE_REG_P (operands[0])"
4508 (float_truncate:V2SF
4512 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4513 operands[3] = CONST0_RTX (V2SFmode);
4514 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4515 /* Use movsd for loading from memory, unpcklpd for registers.
4516 Try to avoid move when unpacking can be done in source, or SSE3
4517 movddup is available. */
4518 if (REG_P (operands[1]))
4521 && true_regnum (operands[0]) != true_regnum (operands[1])
4522 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4523 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4525 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4526 emit_move_insn (tmp, operands[1]);
4529 else if (!TARGET_SSE3)
4530 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4531 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4534 emit_insn (gen_sse2_loadlpd (operands[4],
4535 CONST0_RTX (V2DFmode), operands[1]));
4538 (define_expand "truncdfsf2_with_temp"
4539 [(parallel [(set (match_operand:SF 0 "" "")
4540 (float_truncate:SF (match_operand:DF 1 "" "")))
4541 (clobber (match_operand:SF 2 "" ""))])]
4544 (define_insn "*truncdfsf_fast_mixed"
4545 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4547 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4548 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4550 switch (which_alternative)
4553 return output_387_reg_move (insn, operands);
4555 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4560 [(set_attr "type" "fmov,ssecvt")
4561 (set_attr "prefix" "orig,maybe_vex")
4562 (set_attr "mode" "SF")])
4564 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4565 ;; because nothing we do here is unsafe.
4566 (define_insn "*truncdfsf_fast_sse"
4567 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4569 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4570 "TARGET_SSE2 && TARGET_SSE_MATH"
4571 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4572 [(set_attr "type" "ssecvt")
4573 (set_attr "prefix" "maybe_vex")
4574 (set_attr "mode" "SF")])
4576 (define_insn "*truncdfsf_fast_i387"
4577 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4579 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4580 "TARGET_80387 && flag_unsafe_math_optimizations"
4581 "* return output_387_reg_move (insn, operands);"
4582 [(set_attr "type" "fmov")
4583 (set_attr "mode" "SF")])
4585 (define_insn "*truncdfsf_mixed"
4586 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4588 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4589 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4590 "TARGET_MIX_SSE_I387"
4592 switch (which_alternative)
4595 return output_387_reg_move (insn, operands);
4597 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4603 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4604 (set_attr "unit" "*,*,i387,i387,i387")
4605 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4606 (set_attr "mode" "SF")])
4608 (define_insn "*truncdfsf_i387"
4609 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4611 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4612 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4615 switch (which_alternative)
4618 return output_387_reg_move (insn, operands);
4624 [(set_attr "type" "fmov,multi,multi,multi")
4625 (set_attr "unit" "*,i387,i387,i387")
4626 (set_attr "mode" "SF")])
4628 (define_insn "*truncdfsf2_i387_1"
4629 [(set (match_operand:SF 0 "memory_operand" "=m")
4631 (match_operand:DF 1 "register_operand" "f")))]
4633 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4634 && !TARGET_MIX_SSE_I387"
4635 "* return output_387_reg_move (insn, operands);"
4636 [(set_attr "type" "fmov")
4637 (set_attr "mode" "SF")])
4640 [(set (match_operand:SF 0 "register_operand" "")
4642 (match_operand:DF 1 "fp_register_operand" "")))
4643 (clobber (match_operand 2 "" ""))]
4645 [(set (match_dup 2) (match_dup 1))
4646 (set (match_dup 0) (match_dup 2))]
4648 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4651 ;; Conversion from XFmode to {SF,DF}mode
4653 (define_expand "truncxf<mode>2"
4654 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4655 (float_truncate:MODEF
4656 (match_operand:XF 1 "register_operand" "")))
4657 (clobber (match_dup 2))])]
4660 if (flag_unsafe_math_optimizations)
4662 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4663 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4664 if (reg != operands[0])
4665 emit_move_insn (operands[0], reg);
4670 enum ix86_stack_slot slot = (virtuals_instantiated
4673 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4677 (define_insn "*truncxfsf2_mixed"
4678 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4680 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4681 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4684 gcc_assert (!which_alternative);
4685 return output_387_reg_move (insn, operands);
4687 [(set_attr "type" "fmov,multi,multi,multi")
4688 (set_attr "unit" "*,i387,i387,i387")
4689 (set_attr "mode" "SF")])
4691 (define_insn "*truncxfdf2_mixed"
4692 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4694 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4695 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4698 gcc_assert (!which_alternative);
4699 return output_387_reg_move (insn, operands);
4701 [(set_attr "type" "fmov,multi,multi,multi")
4702 (set_attr "unit" "*,i387,i387,i387")
4703 (set_attr "mode" "DF")])
4705 (define_insn "truncxf<mode>2_i387_noop"
4706 [(set (match_operand:MODEF 0 "register_operand" "=f")
4707 (float_truncate:MODEF
4708 (match_operand:XF 1 "register_operand" "f")))]
4709 "TARGET_80387 && flag_unsafe_math_optimizations"
4710 "* return output_387_reg_move (insn, operands);"
4711 [(set_attr "type" "fmov")
4712 (set_attr "mode" "<MODE>")])
4714 (define_insn "*truncxf<mode>2_i387"
4715 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4716 (float_truncate:MODEF
4717 (match_operand:XF 1 "register_operand" "f")))]
4719 "* return output_387_reg_move (insn, operands);"
4720 [(set_attr "type" "fmov")
4721 (set_attr "mode" "<MODE>")])
4724 [(set (match_operand:MODEF 0 "register_operand" "")
4725 (float_truncate:MODEF
4726 (match_operand:XF 1 "register_operand" "")))
4727 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4728 "TARGET_80387 && reload_completed"
4729 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4730 (set (match_dup 0) (match_dup 2))]
4734 [(set (match_operand:MODEF 0 "memory_operand" "")
4735 (float_truncate:MODEF
4736 (match_operand:XF 1 "register_operand" "")))
4737 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4739 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4742 ;; Signed conversion to DImode.
4744 (define_expand "fix_truncxfdi2"
4745 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4746 (fix:DI (match_operand:XF 1 "register_operand" "")))
4747 (clobber (reg:CC FLAGS_REG))])]
4752 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4757 (define_expand "fix_trunc<mode>di2"
4758 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4759 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4760 (clobber (reg:CC FLAGS_REG))])]
4761 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4764 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4766 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4769 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4771 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4772 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4773 if (out != operands[0])
4774 emit_move_insn (operands[0], out);
4779 ;; Signed conversion to SImode.
4781 (define_expand "fix_truncxfsi2"
4782 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4783 (fix:SI (match_operand:XF 1 "register_operand" "")))
4784 (clobber (reg:CC FLAGS_REG))])]
4789 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4794 (define_expand "fix_trunc<mode>si2"
4795 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4796 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4797 (clobber (reg:CC FLAGS_REG))])]
4798 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4801 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4803 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4806 if (SSE_FLOAT_MODE_P (<MODE>mode))
4808 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4809 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4810 if (out != operands[0])
4811 emit_move_insn (operands[0], out);
4816 ;; Signed conversion to HImode.
4818 (define_expand "fix_trunc<mode>hi2"
4819 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4820 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4821 (clobber (reg:CC FLAGS_REG))])]
4823 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4827 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4832 ;; Unsigned conversion to SImode.
4834 (define_expand "fixuns_trunc<mode>si2"
4836 [(set (match_operand:SI 0 "register_operand" "")
4838 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4840 (clobber (match_scratch:<ssevecmode> 3 ""))
4841 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4842 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4844 enum machine_mode mode = <MODE>mode;
4845 enum machine_mode vecmode = <ssevecmode>mode;
4846 REAL_VALUE_TYPE TWO31r;
4849 if (optimize_insn_for_size_p ())
4852 real_ldexp (&TWO31r, &dconst1, 31);
4853 two31 = const_double_from_real_value (TWO31r, mode);
4854 two31 = ix86_build_const_vector (mode, true, two31);
4855 operands[2] = force_reg (vecmode, two31);
4858 (define_insn_and_split "*fixuns_trunc<mode>_1"
4859 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4861 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4862 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4863 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4864 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4865 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4866 && optimize_function_for_speed_p (cfun)"
4868 "&& reload_completed"
4871 ix86_split_convert_uns_si_sse (operands);
4875 ;; Unsigned conversion to HImode.
4876 ;; Without these patterns, we'll try the unsigned SI conversion which
4877 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4879 (define_expand "fixuns_trunc<mode>hi2"
4881 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4882 (set (match_operand:HI 0 "nonimmediate_operand" "")
4883 (subreg:HI (match_dup 2) 0))]
4884 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4885 "operands[2] = gen_reg_rtx (SImode);")
4887 ;; When SSE is available, it is always faster to use it!
4888 (define_insn "fix_trunc<mode>di_sse"
4889 [(set (match_operand:DI 0 "register_operand" "=r,r")
4890 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4891 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4892 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4893 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4894 [(set_attr "type" "sseicvt")
4895 (set_attr "prefix" "maybe_vex")
4896 (set_attr "prefix_rex" "1")
4897 (set_attr "mode" "<MODE>")
4898 (set_attr "athlon_decode" "double,vector")
4899 (set_attr "amdfam10_decode" "double,double")])
4901 (define_insn "fix_trunc<mode>si_sse"
4902 [(set (match_operand:SI 0 "register_operand" "=r,r")
4903 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4904 "SSE_FLOAT_MODE_P (<MODE>mode)
4905 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4906 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4907 [(set_attr "type" "sseicvt")
4908 (set_attr "prefix" "maybe_vex")
4909 (set_attr "mode" "<MODE>")
4910 (set_attr "athlon_decode" "double,vector")
4911 (set_attr "amdfam10_decode" "double,double")])
4913 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4915 [(set (match_operand:MODEF 0 "register_operand" "")
4916 (match_operand:MODEF 1 "memory_operand" ""))
4917 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4918 (fix:SSEMODEI24 (match_dup 0)))]
4919 "TARGET_SHORTEN_X87_SSE
4920 && peep2_reg_dead_p (2, operands[0])"
4921 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4924 ;; Avoid vector decoded forms of the instruction.
4926 [(match_scratch:DF 2 "Y2")
4927 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4928 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4929 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4930 [(set (match_dup 2) (match_dup 1))
4931 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4935 [(match_scratch:SF 2 "x")
4936 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4937 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4938 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4939 [(set (match_dup 2) (match_dup 1))
4940 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4943 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4944 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4945 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4946 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4948 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4949 && (TARGET_64BIT || <MODE>mode != DImode))
4951 && can_create_pseudo_p ()"
4956 if (memory_operand (operands[0], VOIDmode))
4957 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4960 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4961 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4967 [(set_attr "type" "fisttp")
4968 (set_attr "mode" "<MODE>")])
4970 (define_insn "fix_trunc<mode>_i387_fisttp"
4971 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4972 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4973 (clobber (match_scratch:XF 2 "=&1f"))]
4974 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4976 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4977 && (TARGET_64BIT || <MODE>mode != DImode))
4978 && TARGET_SSE_MATH)"
4979 "* return output_fix_trunc (insn, operands, 1);"
4980 [(set_attr "type" "fisttp")
4981 (set_attr "mode" "<MODE>")])
4983 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4984 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4985 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4986 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4987 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4988 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4990 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4991 && (TARGET_64BIT || <MODE>mode != DImode))
4992 && TARGET_SSE_MATH)"
4994 [(set_attr "type" "fisttp")
4995 (set_attr "mode" "<MODE>")])
4998 [(set (match_operand:X87MODEI 0 "register_operand" "")
4999 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5000 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5001 (clobber (match_scratch 3 ""))]
5003 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5004 (clobber (match_dup 3))])
5005 (set (match_dup 0) (match_dup 2))]
5009 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5010 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5011 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5012 (clobber (match_scratch 3 ""))]
5014 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5015 (clobber (match_dup 3))])]
5018 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5019 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5020 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5021 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5022 ;; function in i386.c.
5023 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5024 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5025 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5026 (clobber (reg:CC FLAGS_REG))]
5027 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5029 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5030 && (TARGET_64BIT || <MODE>mode != DImode))
5031 && can_create_pseudo_p ()"
5036 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5038 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5039 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5040 if (memory_operand (operands[0], VOIDmode))
5041 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5042 operands[2], operands[3]));
5045 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5046 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5047 operands[2], operands[3],
5052 [(set_attr "type" "fistp")
5053 (set_attr "i387_cw" "trunc")
5054 (set_attr "mode" "<MODE>")])
5056 (define_insn "fix_truncdi_i387"
5057 [(set (match_operand:DI 0 "memory_operand" "=m")
5058 (fix:DI (match_operand 1 "register_operand" "f")))
5059 (use (match_operand:HI 2 "memory_operand" "m"))
5060 (use (match_operand:HI 3 "memory_operand" "m"))
5061 (clobber (match_scratch:XF 4 "=&1f"))]
5062 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5064 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5065 "* return output_fix_trunc (insn, operands, 0);"
5066 [(set_attr "type" "fistp")
5067 (set_attr "i387_cw" "trunc")
5068 (set_attr "mode" "DI")])
5070 (define_insn "fix_truncdi_i387_with_temp"
5071 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5072 (fix:DI (match_operand 1 "register_operand" "f,f")))
5073 (use (match_operand:HI 2 "memory_operand" "m,m"))
5074 (use (match_operand:HI 3 "memory_operand" "m,m"))
5075 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5076 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5077 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5079 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5081 [(set_attr "type" "fistp")
5082 (set_attr "i387_cw" "trunc")
5083 (set_attr "mode" "DI")])
5086 [(set (match_operand:DI 0 "register_operand" "")
5087 (fix:DI (match_operand 1 "register_operand" "")))
5088 (use (match_operand:HI 2 "memory_operand" ""))
5089 (use (match_operand:HI 3 "memory_operand" ""))
5090 (clobber (match_operand:DI 4 "memory_operand" ""))
5091 (clobber (match_scratch 5 ""))]
5093 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5096 (clobber (match_dup 5))])
5097 (set (match_dup 0) (match_dup 4))]
5101 [(set (match_operand:DI 0 "memory_operand" "")
5102 (fix:DI (match_operand 1 "register_operand" "")))
5103 (use (match_operand:HI 2 "memory_operand" ""))
5104 (use (match_operand:HI 3 "memory_operand" ""))
5105 (clobber (match_operand:DI 4 "memory_operand" ""))
5106 (clobber (match_scratch 5 ""))]
5108 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5111 (clobber (match_dup 5))])]
5114 (define_insn "fix_trunc<mode>_i387"
5115 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5116 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5117 (use (match_operand:HI 2 "memory_operand" "m"))
5118 (use (match_operand:HI 3 "memory_operand" "m"))]
5119 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5121 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5122 "* return output_fix_trunc (insn, operands, 0);"
5123 [(set_attr "type" "fistp")
5124 (set_attr "i387_cw" "trunc")
5125 (set_attr "mode" "<MODE>")])
5127 (define_insn "fix_trunc<mode>_i387_with_temp"
5128 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5129 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5130 (use (match_operand:HI 2 "memory_operand" "m,m"))
5131 (use (match_operand:HI 3 "memory_operand" "m,m"))
5132 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5133 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5135 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5137 [(set_attr "type" "fistp")
5138 (set_attr "i387_cw" "trunc")
5139 (set_attr "mode" "<MODE>")])
5142 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5143 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5144 (use (match_operand:HI 2 "memory_operand" ""))
5145 (use (match_operand:HI 3 "memory_operand" ""))
5146 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5148 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5150 (use (match_dup 3))])
5151 (set (match_dup 0) (match_dup 4))]
5155 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5156 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5157 (use (match_operand:HI 2 "memory_operand" ""))
5158 (use (match_operand:HI 3 "memory_operand" ""))
5159 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5161 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5163 (use (match_dup 3))])]
5166 (define_insn "x86_fnstcw_1"
5167 [(set (match_operand:HI 0 "memory_operand" "=m")
5168 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5171 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5172 (set_attr "mode" "HI")
5173 (set_attr "unit" "i387")])
5175 (define_insn "x86_fldcw_1"
5176 [(set (reg:HI FPCR_REG)
5177 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5180 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5181 (set_attr "mode" "HI")
5182 (set_attr "unit" "i387")
5183 (set_attr "athlon_decode" "vector")
5184 (set_attr "amdfam10_decode" "vector")])
5186 ;; Conversion between fixed point and floating point.
5188 ;; Even though we only accept memory inputs, the backend _really_
5189 ;; wants to be able to do this between registers.
5191 (define_expand "floathi<mode>2"
5192 [(set (match_operand:X87MODEF 0 "register_operand" "")
5193 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5195 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5196 || TARGET_MIX_SSE_I387)"
5199 ;; Pre-reload splitter to add memory clobber to the pattern.
5200 (define_insn_and_split "*floathi<mode>2_1"
5201 [(set (match_operand:X87MODEF 0 "register_operand" "")
5202 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5204 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5205 || TARGET_MIX_SSE_I387)
5206 && can_create_pseudo_p ()"
5209 [(parallel [(set (match_dup 0)
5210 (float:X87MODEF (match_dup 1)))
5211 (clobber (match_dup 2))])]
5212 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5214 (define_insn "*floathi<mode>2_i387_with_temp"
5215 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5216 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5217 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5219 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5220 || TARGET_MIX_SSE_I387)"
5222 [(set_attr "type" "fmov,multi")
5223 (set_attr "mode" "<MODE>")
5224 (set_attr "unit" "*,i387")
5225 (set_attr "fp_int_src" "true")])
5227 (define_insn "*floathi<mode>2_i387"
5228 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5229 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5231 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5232 || TARGET_MIX_SSE_I387)"
5234 [(set_attr "type" "fmov")
5235 (set_attr "mode" "<MODE>")
5236 (set_attr "fp_int_src" "true")])
5239 [(set (match_operand:X87MODEF 0 "register_operand" "")
5240 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5241 (clobber (match_operand:HI 2 "memory_operand" ""))]
5243 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5244 || TARGET_MIX_SSE_I387)
5245 && reload_completed"
5246 [(set (match_dup 2) (match_dup 1))
5247 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5251 [(set (match_operand:X87MODEF 0 "register_operand" "")
5252 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5253 (clobber (match_operand:HI 2 "memory_operand" ""))]
5255 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5256 || TARGET_MIX_SSE_I387)
5257 && reload_completed"
5258 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5261 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5262 [(set (match_operand:X87MODEF 0 "register_operand" "")
5264 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5266 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5267 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5269 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5270 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5271 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5273 rtx reg = gen_reg_rtx (XFmode);
5276 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5278 if (<X87MODEF:MODE>mode == SFmode)
5279 insn = gen_truncxfsf2 (operands[0], reg);
5280 else if (<X87MODEF:MODE>mode == DFmode)
5281 insn = gen_truncxfdf2 (operands[0], reg);
5290 ;; Pre-reload splitter to add memory clobber to the pattern.
5291 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5292 [(set (match_operand:X87MODEF 0 "register_operand" "")
5293 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5295 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5296 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5297 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5298 || TARGET_MIX_SSE_I387))
5299 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5300 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5301 && ((<SSEMODEI24:MODE>mode == SImode
5302 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5303 && optimize_function_for_speed_p (cfun)
5304 && flag_trapping_math)
5305 || !(TARGET_INTER_UNIT_CONVERSIONS
5306 || optimize_function_for_size_p (cfun)))))
5307 && can_create_pseudo_p ()"
5310 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5311 (clobber (match_dup 2))])]
5313 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5315 /* Avoid store forwarding (partial memory) stall penalty
5316 by passing DImode value through XMM registers. */
5317 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5318 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5319 && optimize_function_for_speed_p (cfun))
5321 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5328 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5329 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5331 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5332 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5333 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5334 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5336 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5337 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5338 (set_attr "unit" "*,i387,*,*,*")
5339 (set_attr "athlon_decode" "*,*,double,direct,double")
5340 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5341 (set_attr "fp_int_src" "true")])
5343 (define_insn "*floatsi<mode>2_vector_mixed"
5344 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5345 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5346 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5347 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5351 [(set_attr "type" "fmov,sseicvt")
5352 (set_attr "mode" "<MODE>,<ssevecmode>")
5353 (set_attr "unit" "i387,*")
5354 (set_attr "athlon_decode" "*,direct")
5355 (set_attr "amdfam10_decode" "*,double")
5356 (set_attr "fp_int_src" "true")])
5358 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5359 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5361 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5362 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5363 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5364 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5366 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5367 (set_attr "mode" "<MODEF:MODE>")
5368 (set_attr "unit" "*,i387,*,*")
5369 (set_attr "athlon_decode" "*,*,double,direct")
5370 (set_attr "amdfam10_decode" "*,*,vector,double")
5371 (set_attr "fp_int_src" "true")])
5374 [(set (match_operand:MODEF 0 "register_operand" "")
5375 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5376 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5377 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5378 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5379 && TARGET_INTER_UNIT_CONVERSIONS
5381 && (SSE_REG_P (operands[0])
5382 || (GET_CODE (operands[0]) == SUBREG
5383 && SSE_REG_P (operands[0])))"
5384 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5388 [(set (match_operand:MODEF 0 "register_operand" "")
5389 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5390 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5391 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5392 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5393 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5395 && (SSE_REG_P (operands[0])
5396 || (GET_CODE (operands[0]) == SUBREG
5397 && SSE_REG_P (operands[0])))"
5398 [(set (match_dup 2) (match_dup 1))
5399 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5402 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5403 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5405 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5406 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5407 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5408 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5411 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5412 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5413 [(set_attr "type" "fmov,sseicvt,sseicvt")
5414 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5415 (set_attr "mode" "<MODEF:MODE>")
5416 (set (attr "prefix_rex")
5418 (and (eq_attr "prefix" "maybe_vex")
5419 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5421 (const_string "*")))
5422 (set_attr "unit" "i387,*,*")
5423 (set_attr "athlon_decode" "*,double,direct")
5424 (set_attr "amdfam10_decode" "*,vector,double")
5425 (set_attr "fp_int_src" "true")])
5427 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5428 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5430 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5431 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5432 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5433 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5436 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5437 [(set_attr "type" "fmov,sseicvt")
5438 (set_attr "prefix" "orig,maybe_vex")
5439 (set_attr "mode" "<MODEF:MODE>")
5440 (set (attr "prefix_rex")
5442 (and (eq_attr "prefix" "maybe_vex")
5443 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5445 (const_string "*")))
5446 (set_attr "athlon_decode" "*,direct")
5447 (set_attr "amdfam10_decode" "*,double")
5448 (set_attr "fp_int_src" "true")])
5450 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5451 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5453 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5454 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5455 "TARGET_SSE2 && TARGET_SSE_MATH
5456 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5458 [(set_attr "type" "sseicvt")
5459 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5460 (set_attr "athlon_decode" "double,direct,double")
5461 (set_attr "amdfam10_decode" "vector,double,double")
5462 (set_attr "fp_int_src" "true")])
5464 (define_insn "*floatsi<mode>2_vector_sse"
5465 [(set (match_operand:MODEF 0 "register_operand" "=x")
5466 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5467 "TARGET_SSE2 && TARGET_SSE_MATH
5468 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5470 [(set_attr "type" "sseicvt")
5471 (set_attr "mode" "<MODE>")
5472 (set_attr "athlon_decode" "direct")
5473 (set_attr "amdfam10_decode" "double")
5474 (set_attr "fp_int_src" "true")])
5477 [(set (match_operand:MODEF 0 "register_operand" "")
5478 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5479 (clobber (match_operand:SI 2 "memory_operand" ""))]
5480 "TARGET_SSE2 && TARGET_SSE_MATH
5481 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5483 && (SSE_REG_P (operands[0])
5484 || (GET_CODE (operands[0]) == SUBREG
5485 && SSE_REG_P (operands[0])))"
5488 rtx op1 = operands[1];
5490 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5492 if (GET_CODE (op1) == SUBREG)
5493 op1 = SUBREG_REG (op1);
5495 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5497 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5498 emit_insn (gen_sse2_loadld (operands[4],
5499 CONST0_RTX (V4SImode), operands[1]));
5501 /* We can ignore possible trapping value in the
5502 high part of SSE register for non-trapping math. */
5503 else if (SSE_REG_P (op1) && !flag_trapping_math)
5504 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5507 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5508 emit_move_insn (operands[2], operands[1]);
5509 emit_insn (gen_sse2_loadld (operands[4],
5510 CONST0_RTX (V4SImode), operands[2]));
5513 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5518 [(set (match_operand:MODEF 0 "register_operand" "")
5519 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5520 (clobber (match_operand:SI 2 "memory_operand" ""))]
5521 "TARGET_SSE2 && TARGET_SSE_MATH
5522 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5524 && (SSE_REG_P (operands[0])
5525 || (GET_CODE (operands[0]) == SUBREG
5526 && SSE_REG_P (operands[0])))"
5529 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5531 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5533 emit_insn (gen_sse2_loadld (operands[4],
5534 CONST0_RTX (V4SImode), operands[1]));
5536 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5541 [(set (match_operand:MODEF 0 "register_operand" "")
5542 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5543 "TARGET_SSE2 && TARGET_SSE_MATH
5544 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5546 && (SSE_REG_P (operands[0])
5547 || (GET_CODE (operands[0]) == SUBREG
5548 && SSE_REG_P (operands[0])))"
5551 rtx op1 = operands[1];
5553 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5555 if (GET_CODE (op1) == SUBREG)
5556 op1 = SUBREG_REG (op1);
5558 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5560 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5561 emit_insn (gen_sse2_loadld (operands[4],
5562 CONST0_RTX (V4SImode), operands[1]));
5564 /* We can ignore possible trapping value in the
5565 high part of SSE register for non-trapping math. */
5566 else if (SSE_REG_P (op1) && !flag_trapping_math)
5567 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5571 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5576 [(set (match_operand:MODEF 0 "register_operand" "")
5577 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5578 "TARGET_SSE2 && TARGET_SSE_MATH
5579 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5581 && (SSE_REG_P (operands[0])
5582 || (GET_CODE (operands[0]) == SUBREG
5583 && SSE_REG_P (operands[0])))"
5586 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5588 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5590 emit_insn (gen_sse2_loadld (operands[4],
5591 CONST0_RTX (V4SImode), operands[1]));
5593 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5597 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5598 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5600 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5601 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5602 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5603 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5605 [(set_attr "type" "sseicvt")
5606 (set_attr "mode" "<MODEF:MODE>")
5607 (set_attr "athlon_decode" "double,direct")
5608 (set_attr "amdfam10_decode" "vector,double")
5609 (set_attr "fp_int_src" "true")])
5611 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5612 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5614 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5615 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5616 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5617 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5618 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5619 [(set_attr "type" "sseicvt")
5620 (set_attr "prefix" "maybe_vex")
5621 (set_attr "mode" "<MODEF:MODE>")
5622 (set (attr "prefix_rex")
5624 (and (eq_attr "prefix" "maybe_vex")
5625 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5627 (const_string "*")))
5628 (set_attr "athlon_decode" "double,direct")
5629 (set_attr "amdfam10_decode" "vector,double")
5630 (set_attr "fp_int_src" "true")])
5633 [(set (match_operand:MODEF 0 "register_operand" "")
5634 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5635 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5636 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5637 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5638 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5640 && (SSE_REG_P (operands[0])
5641 || (GET_CODE (operands[0]) == SUBREG
5642 && SSE_REG_P (operands[0])))"
5643 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5646 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5647 [(set (match_operand:MODEF 0 "register_operand" "=x")
5649 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5650 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5651 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5652 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5653 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5654 [(set_attr "type" "sseicvt")
5655 (set_attr "prefix" "maybe_vex")
5656 (set_attr "mode" "<MODEF:MODE>")
5657 (set (attr "prefix_rex")
5659 (and (eq_attr "prefix" "maybe_vex")
5660 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5662 (const_string "*")))
5663 (set_attr "athlon_decode" "direct")
5664 (set_attr "amdfam10_decode" "double")
5665 (set_attr "fp_int_src" "true")])
5668 [(set (match_operand:MODEF 0 "register_operand" "")
5669 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5670 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5671 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5672 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5673 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5675 && (SSE_REG_P (operands[0])
5676 || (GET_CODE (operands[0]) == SUBREG
5677 && SSE_REG_P (operands[0])))"
5678 [(set (match_dup 2) (match_dup 1))
5679 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5683 [(set (match_operand:MODEF 0 "register_operand" "")
5684 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5685 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5686 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5687 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5689 && (SSE_REG_P (operands[0])
5690 || (GET_CODE (operands[0]) == SUBREG
5691 && SSE_REG_P (operands[0])))"
5692 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5695 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5696 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5698 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5699 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5701 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5705 [(set_attr "type" "fmov,multi")
5706 (set_attr "mode" "<X87MODEF:MODE>")
5707 (set_attr "unit" "*,i387")
5708 (set_attr "fp_int_src" "true")])
5710 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5711 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5713 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5715 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5717 [(set_attr "type" "fmov")
5718 (set_attr "mode" "<X87MODEF:MODE>")
5719 (set_attr "fp_int_src" "true")])
5722 [(set (match_operand:X87MODEF 0 "register_operand" "")
5723 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5724 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5726 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5728 && FP_REG_P (operands[0])"
5729 [(set (match_dup 2) (match_dup 1))
5730 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5734 [(set (match_operand:X87MODEF 0 "register_operand" "")
5735 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5736 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5738 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5740 && FP_REG_P (operands[0])"
5741 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5744 ;; Avoid store forwarding (partial memory) stall penalty
5745 ;; by passing DImode value through XMM registers. */
5747 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5748 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5750 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5751 (clobber (match_scratch:V4SI 3 "=X,x"))
5752 (clobber (match_scratch:V4SI 4 "=X,x"))
5753 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5754 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5755 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5756 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5758 [(set_attr "type" "multi")
5759 (set_attr "mode" "<X87MODEF:MODE>")
5760 (set_attr "unit" "i387")
5761 (set_attr "fp_int_src" "true")])
5764 [(set (match_operand:X87MODEF 0 "register_operand" "")
5765 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5766 (clobber (match_scratch:V4SI 3 ""))
5767 (clobber (match_scratch:V4SI 4 ""))
5768 (clobber (match_operand:DI 2 "memory_operand" ""))]
5769 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5770 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5771 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5773 && FP_REG_P (operands[0])"
5774 [(set (match_dup 2) (match_dup 3))
5775 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5777 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5778 Assemble the 64-bit DImode value in an xmm register. */
5779 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5780 gen_rtx_SUBREG (SImode, operands[1], 0)));
5781 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5782 gen_rtx_SUBREG (SImode, operands[1], 4)));
5783 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5786 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5790 [(set (match_operand:X87MODEF 0 "register_operand" "")
5791 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5792 (clobber (match_scratch:V4SI 3 ""))
5793 (clobber (match_scratch:V4SI 4 ""))
5794 (clobber (match_operand:DI 2 "memory_operand" ""))]
5795 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5796 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5797 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5799 && FP_REG_P (operands[0])"
5800 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5803 ;; Avoid store forwarding (partial memory) stall penalty by extending
5804 ;; SImode value to DImode through XMM register instead of pushing two
5805 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5806 ;; targets benefit from this optimization. Also note that fild
5807 ;; loads from memory only.
5809 (define_insn "*floatunssi<mode>2_1"
5810 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5811 (unsigned_float:X87MODEF
5812 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5813 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5814 (clobber (match_scratch:SI 3 "=X,x"))]
5816 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5819 [(set_attr "type" "multi")
5820 (set_attr "mode" "<MODE>")])
5823 [(set (match_operand:X87MODEF 0 "register_operand" "")
5824 (unsigned_float:X87MODEF
5825 (match_operand:SI 1 "register_operand" "")))
5826 (clobber (match_operand:DI 2 "memory_operand" ""))
5827 (clobber (match_scratch:SI 3 ""))]
5829 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5831 && reload_completed"
5832 [(set (match_dup 2) (match_dup 1))
5834 (float:X87MODEF (match_dup 2)))]
5835 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5838 [(set (match_operand:X87MODEF 0 "register_operand" "")
5839 (unsigned_float:X87MODEF
5840 (match_operand:SI 1 "memory_operand" "")))
5841 (clobber (match_operand:DI 2 "memory_operand" ""))
5842 (clobber (match_scratch:SI 3 ""))]
5844 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5846 && reload_completed"
5847 [(set (match_dup 2) (match_dup 3))
5849 (float:X87MODEF (match_dup 2)))]
5851 emit_move_insn (operands[3], operands[1]);
5852 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5855 (define_expand "floatunssi<mode>2"
5857 [(set (match_operand:X87MODEF 0 "register_operand" "")
5858 (unsigned_float:X87MODEF
5859 (match_operand:SI 1 "nonimmediate_operand" "")))
5860 (clobber (match_dup 2))
5861 (clobber (match_scratch:SI 3 ""))])]
5863 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5865 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5867 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5869 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5874 enum ix86_stack_slot slot = (virtuals_instantiated
5877 operands[2] = assign_386_stack_local (DImode, slot);
5881 (define_expand "floatunsdisf2"
5882 [(use (match_operand:SF 0 "register_operand" ""))
5883 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5884 "TARGET_64BIT && TARGET_SSE_MATH"
5885 "x86_emit_floatuns (operands); DONE;")
5887 (define_expand "floatunsdidf2"
5888 [(use (match_operand:DF 0 "register_operand" ""))
5889 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5890 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5891 && TARGET_SSE2 && TARGET_SSE_MATH"
5894 x86_emit_floatuns (operands);
5896 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5902 (define_expand "add<mode>3"
5903 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5904 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5905 (match_operand:SDWIM 2 "<general_operand>" "")))]
5907 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5909 (define_insn_and_split "*add<dwi>3_doubleword"
5910 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5912 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5913 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5914 (clobber (reg:CC FLAGS_REG))]
5915 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5918 [(parallel [(set (reg:CC FLAGS_REG)
5919 (unspec:CC [(match_dup 1) (match_dup 2)]
5922 (plus:DWIH (match_dup 1) (match_dup 2)))])
5923 (parallel [(set (match_dup 3)
5927 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5929 (clobber (reg:CC FLAGS_REG))])]
5930 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5932 (define_insn "*add<mode>3_cc"
5933 [(set (reg:CC FLAGS_REG)
5935 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5936 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5938 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5939 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5940 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5941 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5942 [(set_attr "type" "alu")
5943 (set_attr "mode" "<MODE>")])
5945 (define_insn "addqi3_cc"
5946 [(set (reg:CC FLAGS_REG)
5948 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5949 (match_operand:QI 2 "general_operand" "qn,qm")]
5951 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5952 (plus:QI (match_dup 1) (match_dup 2)))]
5953 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5954 "add{b}\t{%2, %0|%0, %2}"
5955 [(set_attr "type" "alu")
5956 (set_attr "mode" "QI")])
5958 (define_insn "*lea_1"
5959 [(set (match_operand:DWIH 0 "register_operand" "=r")
5960 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5962 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5963 [(set_attr "type" "lea")
5964 (set_attr "mode" "<MODE>")])
5966 (define_insn "*lea_2"
5967 [(set (match_operand:SI 0 "register_operand" "=r")
5968 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5970 "lea{l}\t{%a1, %0|%0, %a1}"
5971 [(set_attr "type" "lea")
5972 (set_attr "mode" "SI")])
5974 (define_insn "*lea_2_zext"
5975 [(set (match_operand:DI 0 "register_operand" "=r")
5977 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5979 "lea{l}\t{%a1, %k0|%k0, %a1}"
5980 [(set_attr "type" "lea")
5981 (set_attr "mode" "SI")])
5983 (define_insn "*add<mode>_1"
5984 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5986 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5987 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5988 (clobber (reg:CC FLAGS_REG))]
5989 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5991 switch (get_attr_type (insn))
5994 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5995 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5998 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5999 if (operands[2] == const1_rtx)
6000 return "inc{<imodesuffix>}\t%0";
6003 gcc_assert (operands[2] == constm1_rtx);
6004 return "dec{<imodesuffix>}\t%0";
6008 /* Use add as much as possible to replace lea for AGU optimization. */
6009 if (which_alternative == 2 && TARGET_OPT_AGU)
6010 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6012 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6014 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6015 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6016 if (CONST_INT_P (operands[2])
6017 /* Avoid overflows. */
6018 && (<MODE>mode != DImode
6019 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6020 && (INTVAL (operands[2]) == 128
6021 || (INTVAL (operands[2]) < 0
6022 && INTVAL (operands[2]) != -128)))
6024 operands[2] = GEN_INT (-INTVAL (operands[2]));
6025 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6027 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6031 (cond [(and (eq_attr "alternative" "2")
6032 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6033 (const_string "lea")
6034 (eq_attr "alternative" "3")
6035 (const_string "lea")
6036 ; Current assemblers are broken and do not allow @GOTOFF in
6037 ; ought but a memory context.
6038 (match_operand:SWI48 2 "pic_symbolic_operand" "")
6039 (const_string "lea")
6040 (match_operand:SWI48 2 "incdec_operand" "")
6041 (const_string "incdec")
6043 (const_string "alu")))
6044 (set (attr "length_immediate")
6046 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6048 (const_string "*")))
6049 (set_attr "mode" "<MODE>")])
6051 ;; It may seem that nonimmediate operand is proper one for operand 1.
6052 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6053 ;; we take care in ix86_binary_operator_ok to not allow two memory
6054 ;; operands so proper swapping will be done in reload. This allow
6055 ;; patterns constructed from addsi_1 to match.
6057 (define_insn "*addsi_1_zext"
6058 [(set (match_operand:DI 0 "register_operand" "=r,r")
6060 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6061 (match_operand:SI 2 "general_operand" "g,li"))))
6062 (clobber (reg:CC FLAGS_REG))]
6063 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6065 switch (get_attr_type (insn))
6068 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6069 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6072 if (operands[2] == const1_rtx)
6073 return "inc{l}\t%k0";
6076 gcc_assert (operands[2] == constm1_rtx);
6077 return "dec{l}\t%k0";
6081 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6082 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6083 if (CONST_INT_P (operands[2])
6084 && (INTVAL (operands[2]) == 128
6085 || (INTVAL (operands[2]) < 0
6086 && INTVAL (operands[2]) != -128)))
6088 operands[2] = GEN_INT (-INTVAL (operands[2]));
6089 return "sub{l}\t{%2, %k0|%k0, %2}";
6091 return "add{l}\t{%2, %k0|%k0, %2}";
6095 (cond [(eq_attr "alternative" "1")
6096 (const_string "lea")
6097 ; Current assemblers are broken and do not allow @GOTOFF in
6098 ; ought but a memory context.
6099 (match_operand:SI 2 "pic_symbolic_operand" "")
6100 (const_string "lea")
6101 (match_operand:SI 2 "incdec_operand" "")
6102 (const_string "incdec")
6104 (const_string "alu")))
6105 (set (attr "length_immediate")
6107 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6109 (const_string "*")))
6110 (set_attr "mode" "SI")])
6112 (define_insn "*addhi_1"
6113 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6114 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6115 (match_operand:HI 2 "general_operand" "rn,rm")))
6116 (clobber (reg:CC FLAGS_REG))]
6117 "TARGET_PARTIAL_REG_STALL
6118 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6120 switch (get_attr_type (insn))
6123 if (operands[2] == const1_rtx)
6124 return "inc{w}\t%0";
6127 gcc_assert (operands[2] == constm1_rtx);
6128 return "dec{w}\t%0";
6132 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6133 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6134 if (CONST_INT_P (operands[2])
6135 && (INTVAL (operands[2]) == 128
6136 || (INTVAL (operands[2]) < 0
6137 && INTVAL (operands[2]) != -128)))
6139 operands[2] = GEN_INT (-INTVAL (operands[2]));
6140 return "sub{w}\t{%2, %0|%0, %2}";
6142 return "add{w}\t{%2, %0|%0, %2}";
6146 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6147 (const_string "incdec")
6148 (const_string "alu")))
6149 (set (attr "length_immediate")
6151 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6153 (const_string "*")))
6154 (set_attr "mode" "HI")])
6156 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6157 ;; type optimizations enabled by define-splits. This is not important
6158 ;; for PII, and in fact harmful because of partial register stalls.
6160 (define_insn "*addhi_1_lea"
6161 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6162 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6163 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6164 (clobber (reg:CC FLAGS_REG))]
6165 "!TARGET_PARTIAL_REG_STALL
6166 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6168 switch (get_attr_type (insn))
6173 if (operands[2] == const1_rtx)
6174 return "inc{w}\t%0";
6177 gcc_assert (operands[2] == constm1_rtx);
6178 return "dec{w}\t%0";
6182 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6183 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6184 if (CONST_INT_P (operands[2])
6185 && (INTVAL (operands[2]) == 128
6186 || (INTVAL (operands[2]) < 0
6187 && INTVAL (operands[2]) != -128)))
6189 operands[2] = GEN_INT (-INTVAL (operands[2]));
6190 return "sub{w}\t{%2, %0|%0, %2}";
6192 return "add{w}\t{%2, %0|%0, %2}";
6196 (if_then_else (eq_attr "alternative" "2")
6197 (const_string "lea")
6198 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6199 (const_string "incdec")
6200 (const_string "alu"))))
6201 (set (attr "length_immediate")
6203 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6205 (const_string "*")))
6206 (set_attr "mode" "HI,HI,SI")])
6208 (define_insn "*addqi_1"
6209 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6210 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6211 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6212 (clobber (reg:CC FLAGS_REG))]
6213 "TARGET_PARTIAL_REG_STALL
6214 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6216 int widen = (which_alternative == 2);
6217 switch (get_attr_type (insn))
6220 if (operands[2] == const1_rtx)
6221 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6224 gcc_assert (operands[2] == constm1_rtx);
6225 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6229 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6230 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6231 if (CONST_INT_P (operands[2])
6232 && (INTVAL (operands[2]) == 128
6233 || (INTVAL (operands[2]) < 0
6234 && INTVAL (operands[2]) != -128)))
6236 operands[2] = GEN_INT (-INTVAL (operands[2]));
6238 return "sub{l}\t{%2, %k0|%k0, %2}";
6240 return "sub{b}\t{%2, %0|%0, %2}";
6243 return "add{l}\t{%k2, %k0|%k0, %k2}";
6245 return "add{b}\t{%2, %0|%0, %2}";
6249 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6250 (const_string "incdec")
6251 (const_string "alu")))
6252 (set (attr "length_immediate")
6254 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6256 (const_string "*")))
6257 (set_attr "mode" "QI,QI,SI")])
6259 ;; %%% Potential partial reg stall on alternative 2. What to do?
6260 (define_insn "*addqi_1_lea"
6261 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6262 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6263 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6264 (clobber (reg:CC FLAGS_REG))]
6265 "!TARGET_PARTIAL_REG_STALL
6266 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6268 int widen = (which_alternative == 2);
6269 switch (get_attr_type (insn))
6274 if (operands[2] == const1_rtx)
6275 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6278 gcc_assert (operands[2] == constm1_rtx);
6279 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6283 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6284 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6285 if (CONST_INT_P (operands[2])
6286 && (INTVAL (operands[2]) == 128
6287 || (INTVAL (operands[2]) < 0
6288 && INTVAL (operands[2]) != -128)))
6290 operands[2] = GEN_INT (-INTVAL (operands[2]));
6292 return "sub{l}\t{%2, %k0|%k0, %2}";
6294 return "sub{b}\t{%2, %0|%0, %2}";
6297 return "add{l}\t{%k2, %k0|%k0, %k2}";
6299 return "add{b}\t{%2, %0|%0, %2}";
6303 (if_then_else (eq_attr "alternative" "3")
6304 (const_string "lea")
6305 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6306 (const_string "incdec")
6307 (const_string "alu"))))
6308 (set (attr "length_immediate")
6310 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6312 (const_string "*")))
6313 (set_attr "mode" "QI,QI,SI,SI")])
6315 (define_insn "*addqi_1_slp"
6316 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6317 (plus:QI (match_dup 0)
6318 (match_operand:QI 1 "general_operand" "qn,qnm")))
6319 (clobber (reg:CC FLAGS_REG))]
6320 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6321 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6323 switch (get_attr_type (insn))
6326 if (operands[1] == const1_rtx)
6327 return "inc{b}\t%0";
6330 gcc_assert (operands[1] == constm1_rtx);
6331 return "dec{b}\t%0";
6335 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6336 if (CONST_INT_P (operands[1])
6337 && INTVAL (operands[1]) < 0)
6339 operands[1] = GEN_INT (-INTVAL (operands[1]));
6340 return "sub{b}\t{%1, %0|%0, %1}";
6342 return "add{b}\t{%1, %0|%0, %1}";
6346 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6347 (const_string "incdec")
6348 (const_string "alu1")))
6349 (set (attr "memory")
6350 (if_then_else (match_operand 1 "memory_operand" "")
6351 (const_string "load")
6352 (const_string "none")))
6353 (set_attr "mode" "QI")])
6355 (define_insn "*add<mode>_2"
6356 [(set (reg FLAGS_REG)
6359 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6360 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6362 (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6363 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6364 "ix86_match_ccmode (insn, CCGOCmode)
6365 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6366 /* Current assemblers are broken and do not allow @GOTOFF in
6367 ought but a memory context. */
6368 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6370 switch (get_attr_type (insn))
6373 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6374 if (operands[2] == const1_rtx)
6375 return "inc{<imodesuffix>}\t%0";
6378 gcc_assert (operands[2] == constm1_rtx);
6379 return "dec{<imodesuffix>}\t%0";
6383 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6384 /* ???? In DImode, we ought to handle there the 32bit case too
6385 - do we need new constraint? */
6386 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6387 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6388 if (CONST_INT_P (operands[2])
6389 /* Avoid overflows. */
6390 && (<MODE>mode != DImode
6391 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6392 && (INTVAL (operands[2]) == 128
6393 || (INTVAL (operands[2]) < 0
6394 && INTVAL (operands[2]) != -128)))
6396 operands[2] = GEN_INT (-INTVAL (operands[2]));
6397 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6399 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6403 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6404 (const_string "incdec")
6405 (const_string "alu")))
6406 (set (attr "length_immediate")
6408 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6410 (const_string "*")))
6411 (set_attr "mode" "<MODE>")])
6413 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6414 (define_insn "*addsi_2_zext"
6415 [(set (reg FLAGS_REG)
6417 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6418 (match_operand:SI 2 "general_operand" "g"))
6420 (set (match_operand:DI 0 "register_operand" "=r")
6421 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6422 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6423 && ix86_binary_operator_ok (PLUS, SImode, operands)
6424 /* Current assemblers are broken and do not allow @GOTOFF in
6425 ought but a memory context. */
6426 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6428 switch (get_attr_type (insn))
6431 if (operands[2] == const1_rtx)
6432 return "inc{l}\t%k0";
6435 gcc_assert (operands[2] == constm1_rtx);
6436 return "dec{l}\t%k0";
6440 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6441 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6442 if (CONST_INT_P (operands[2])
6443 && (INTVAL (operands[2]) == 128
6444 || (INTVAL (operands[2]) < 0
6445 && INTVAL (operands[2]) != -128)))
6447 operands[2] = GEN_INT (-INTVAL (operands[2]));
6448 return "sub{l}\t{%2, %k0|%k0, %2}";
6450 return "add{l}\t{%2, %k0|%k0, %2}";
6454 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6455 (const_string "incdec")
6456 (const_string "alu")))
6457 (set (attr "length_immediate")
6459 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6461 (const_string "*")))
6462 (set_attr "mode" "SI")])
6464 (define_insn "*addhi_2"
6465 [(set (reg FLAGS_REG)
6467 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6468 (match_operand:HI 2 "general_operand" "rmn,rn"))
6470 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6471 (plus:HI (match_dup 1) (match_dup 2)))]
6472 "ix86_match_ccmode (insn, CCGOCmode)
6473 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6475 switch (get_attr_type (insn))
6478 if (operands[2] == const1_rtx)
6479 return "inc{w}\t%0";
6482 gcc_assert (operands[2] == constm1_rtx);
6483 return "dec{w}\t%0";
6487 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6488 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6489 if (CONST_INT_P (operands[2])
6490 && (INTVAL (operands[2]) == 128
6491 || (INTVAL (operands[2]) < 0
6492 && INTVAL (operands[2]) != -128)))
6494 operands[2] = GEN_INT (-INTVAL (operands[2]));
6495 return "sub{w}\t{%2, %0|%0, %2}";
6497 return "add{w}\t{%2, %0|%0, %2}";
6501 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6502 (const_string "incdec")
6503 (const_string "alu")))
6504 (set (attr "length_immediate")
6506 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6508 (const_string "*")))
6509 (set_attr "mode" "HI")])
6511 (define_insn "*addqi_2"
6512 [(set (reg FLAGS_REG)
6514 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6515 (match_operand:QI 2 "general_operand" "qmn,qn"))
6517 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6518 (plus:QI (match_dup 1) (match_dup 2)))]
6519 "ix86_match_ccmode (insn, CCGOCmode)
6520 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6522 switch (get_attr_type (insn))
6525 if (operands[2] == const1_rtx)
6526 return "inc{b}\t%0";
6529 gcc_assert (operands[2] == constm1_rtx
6530 || (CONST_INT_P (operands[2])
6531 && INTVAL (operands[2]) == 255));
6532 return "dec{b}\t%0";
6536 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6537 if (CONST_INT_P (operands[2])
6538 && INTVAL (operands[2]) < 0)
6540 operands[2] = GEN_INT (-INTVAL (operands[2]));
6541 return "sub{b}\t{%2, %0|%0, %2}";
6543 return "add{b}\t{%2, %0|%0, %2}";
6547 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6548 (const_string "incdec")
6549 (const_string "alu")))
6550 (set_attr "mode" "QI")])
6552 (define_insn "*add<mode>_3"
6553 [(set (reg FLAGS_REG)
6555 (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6556 (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6557 (clobber (match_scratch:SWI48 0 "=r"))]
6558 "ix86_match_ccmode (insn, CCZmode)
6559 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6560 /* Current assemblers are broken and do not allow @GOTOFF in
6561 ought but a memory context. */
6562 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6564 switch (get_attr_type (insn))
6567 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6568 if (operands[2] == const1_rtx)
6569 return "inc{<imodesuffix>}\t%0";
6572 gcc_assert (operands[2] == constm1_rtx);
6573 return "dec{<imodesuffix>}\t%0";
6577 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6578 /* ???? In DImode, we ought to handle there the 32bit case too
6579 - do we need new constraint? */
6580 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6581 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6582 if (CONST_INT_P (operands[2])
6583 /* Avoid overflows. */
6584 && (<MODE>mode != DImode
6585 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6586 && (INTVAL (operands[2]) == 128
6587 || (INTVAL (operands[2]) < 0
6588 && INTVAL (operands[2]) != -128)))
6590 operands[2] = GEN_INT (-INTVAL (operands[2]));
6591 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6593 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6597 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6598 (const_string "incdec")
6599 (const_string "alu")))
6600 (set (attr "length_immediate")
6602 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6604 (const_string "*")))
6605 (set_attr "mode" "<MODE>")])
6607 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6608 (define_insn "*addsi_3_zext"
6609 [(set (reg FLAGS_REG)
6611 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6612 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6613 (set (match_operand:DI 0 "register_operand" "=r")
6614 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6615 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6616 && ix86_binary_operator_ok (PLUS, SImode, operands)
6617 /* Current assemblers are broken and do not allow @GOTOFF in
6618 ought but a memory context. */
6619 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6621 switch (get_attr_type (insn))
6624 if (operands[2] == const1_rtx)
6625 return "inc{l}\t%k0";
6628 gcc_assert (operands[2] == constm1_rtx);
6629 return "dec{l}\t%k0";
6633 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6634 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6635 if (CONST_INT_P (operands[2])
6636 && (INTVAL (operands[2]) == 128
6637 || (INTVAL (operands[2]) < 0
6638 && INTVAL (operands[2]) != -128)))
6640 operands[2] = GEN_INT (-INTVAL (operands[2]));
6641 return "sub{l}\t{%2, %k0|%k0, %2}";
6643 return "add{l}\t{%2, %k0|%k0, %2}";
6647 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6648 (const_string "incdec")
6649 (const_string "alu")))
6650 (set (attr "length_immediate")
6652 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6654 (const_string "*")))
6655 (set_attr "mode" "SI")])
6657 (define_insn "*addhi_3"
6658 [(set (reg FLAGS_REG)
6660 (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6661 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6662 (clobber (match_scratch:HI 0 "=r"))]
6663 "ix86_match_ccmode (insn, CCZmode)
6664 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6666 switch (get_attr_type (insn))
6669 if (operands[2] == const1_rtx)
6670 return "inc{w}\t%0";
6673 gcc_assert (operands[2] == constm1_rtx);
6674 return "dec{w}\t%0";
6678 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6679 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6680 if (CONST_INT_P (operands[2])
6681 && (INTVAL (operands[2]) == 128
6682 || (INTVAL (operands[2]) < 0
6683 && INTVAL (operands[2]) != -128)))
6685 operands[2] = GEN_INT (-INTVAL (operands[2]));
6686 return "sub{w}\t{%2, %0|%0, %2}";
6688 return "add{w}\t{%2, %0|%0, %2}";
6692 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6693 (const_string "incdec")
6694 (const_string "alu")))
6695 (set (attr "length_immediate")
6697 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6699 (const_string "*")))
6700 (set_attr "mode" "HI")])
6702 (define_insn "*addqi_3"
6703 [(set (reg FLAGS_REG)
6705 (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6706 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6707 (clobber (match_scratch:QI 0 "=q"))]
6708 "ix86_match_ccmode (insn, CCZmode)
6709 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6711 switch (get_attr_type (insn))
6714 if (operands[2] == const1_rtx)
6715 return "inc{b}\t%0";
6718 gcc_assert (operands[2] == constm1_rtx
6719 || (CONST_INT_P (operands[2])
6720 && INTVAL (operands[2]) == 255));
6721 return "dec{b}\t%0";
6725 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6726 if (CONST_INT_P (operands[2])
6727 && INTVAL (operands[2]) < 0)
6729 operands[2] = GEN_INT (-INTVAL (operands[2]));
6730 return "sub{b}\t{%2, %0|%0, %2}";
6732 return "add{b}\t{%2, %0|%0, %2}";
6736 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6737 (const_string "incdec")
6738 (const_string "alu")))
6739 (set_attr "mode" "QI")])
6741 ; For comparisons against 1, -1 and 128, we may generate better code
6742 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6743 ; is matched then. We can't accept general immediate, because for
6744 ; case of overflows, the result is messed up.
6745 ; This pattern also don't hold of 0x8000000000000000, since the value
6746 ; overflows when negated.
6747 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6748 ; only for comparisons not depending on it.
6750 (define_insn "*adddi_4"
6751 [(set (reg FLAGS_REG)
6753 (match_operand:DI 1 "nonimmediate_operand" "0")
6754 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6755 (clobber (match_scratch:DI 0 "=rm"))]
6757 && ix86_match_ccmode (insn, CCGCmode)"
6759 switch (get_attr_type (insn))
6762 if (operands[2] == constm1_rtx)
6763 return "inc{q}\t%0";
6766 gcc_assert (operands[2] == const1_rtx);
6767 return "dec{q}\t%0";
6771 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6772 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6773 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6774 if ((INTVAL (operands[2]) == -128
6775 || (INTVAL (operands[2]) > 0
6776 && INTVAL (operands[2]) != 128))
6777 /* Avoid overflows. */
6778 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6779 return "sub{q}\t{%2, %0|%0, %2}";
6780 operands[2] = GEN_INT (-INTVAL (operands[2]));
6781 return "add{q}\t{%2, %0|%0, %2}";
6785 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6786 (const_string "incdec")
6787 (const_string "alu")))
6788 (set (attr "length_immediate")
6790 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6792 (const_string "*")))
6793 (set_attr "mode" "DI")])
6795 ; For comparisons against 1, -1 and 128, we may generate better code
6796 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6797 ; is matched then. We can't accept general immediate, because for
6798 ; case of overflows, the result is messed up.
6799 ; This pattern also don't hold of 0x80000000, since the value overflows
6801 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6802 ; only for comparisons not depending on it.
6804 (define_insn "*addsi_4"
6805 [(set (reg FLAGS_REG)
6807 (match_operand:SI 1 "nonimmediate_operand" "0")
6808 (match_operand:SI 2 "const_int_operand" "n")))
6809 (clobber (match_scratch:SI 0 "=rm"))]
6810 "ix86_match_ccmode (insn, CCGCmode)
6811 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6813 switch (get_attr_type (insn))
6816 if (operands[2] == constm1_rtx)
6817 return "inc{l}\t%0";
6820 gcc_assert (operands[2] == const1_rtx);
6821 return "dec{l}\t%0";
6825 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6826 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6827 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6828 if ((INTVAL (operands[2]) == -128
6829 || (INTVAL (operands[2]) > 0
6830 && INTVAL (operands[2]) != 128)))
6831 return "sub{l}\t{%2, %0|%0, %2}";
6832 operands[2] = GEN_INT (-INTVAL (operands[2]));
6833 return "add{l}\t{%2, %0|%0, %2}";
6837 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6838 (const_string "incdec")
6839 (const_string "alu")))
6840 (set (attr "length_immediate")
6842 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6844 (const_string "*")))
6845 (set_attr "mode" "SI")])
6847 ; See comments above addsi_4 for details.
6849 (define_insn "*addhi_4"
6850 [(set (reg FLAGS_REG)
6852 (match_operand:HI 1 "nonimmediate_operand" "0")
6853 (match_operand:HI 2 "const_int_operand" "n")))
6854 (clobber (match_scratch:HI 0 "=rm"))]
6855 "ix86_match_ccmode (insn, CCGCmode)
6856 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6858 switch (get_attr_type (insn))
6861 if (operands[2] == constm1_rtx)
6862 return "inc{w}\t%0";
6865 gcc_assert (operands[2] == const1_rtx);
6866 return "dec{w}\t%0";
6870 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6871 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6872 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6873 if ((INTVAL (operands[2]) == -128
6874 || (INTVAL (operands[2]) > 0
6875 && INTVAL (operands[2]) != 128)))
6876 return "sub{w}\t{%2, %0|%0, %2}";
6877 operands[2] = GEN_INT (-INTVAL (operands[2]));
6878 return "add{w}\t{%2, %0|%0, %2}";
6882 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6883 (const_string "incdec")
6884 (const_string "alu")))
6885 (set (attr "length_immediate")
6887 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6889 (const_string "*")))
6890 (set_attr "mode" "HI")])
6892 ; See comments above addsi_4 for details.
6894 (define_insn "*addqi_4"
6895 [(set (reg FLAGS_REG)
6897 (match_operand:QI 1 "nonimmediate_operand" "0")
6898 (match_operand:QI 2 "const_int_operand" "n")))
6899 (clobber (match_scratch:QI 0 "=qm"))]
6900 "ix86_match_ccmode (insn, CCGCmode)
6901 && (INTVAL (operands[2]) & 0xff) != 0x80"
6903 switch (get_attr_type (insn))
6906 if (operands[2] == constm1_rtx
6907 || (CONST_INT_P (operands[2])
6908 && INTVAL (operands[2]) == 255))
6909 return "inc{b}\t%0";
6912 gcc_assert (operands[2] == const1_rtx);
6913 return "dec{b}\t%0";
6917 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6918 if (INTVAL (operands[2]) < 0)
6920 operands[2] = GEN_INT (-INTVAL (operands[2]));
6921 return "add{b}\t{%2, %0|%0, %2}";
6923 return "sub{b}\t{%2, %0|%0, %2}";
6927 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6928 (const_string "incdec")
6929 (const_string "alu")))
6930 (set_attr "mode" "QI")])
6932 (define_insn "*add<mode>_5"
6933 [(set (reg FLAGS_REG)
6936 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6937 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6939 (clobber (match_scratch:SWI48 0 "=r"))]
6940 "ix86_match_ccmode (insn, CCGOCmode)
6941 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6942 /* Current assemblers are broken and do not allow @GOTOFF in
6943 ought but a memory context. */
6944 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6946 switch (get_attr_type (insn))
6949 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6950 if (operands[2] == const1_rtx)
6951 return "inc{<imodesuffix>}\t%0";
6954 gcc_assert (operands[2] == constm1_rtx);
6955 return "dec{<imodesuffix>}\t%0";
6959 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6960 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6961 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6962 if (CONST_INT_P (operands[2])
6963 /* Avoid overflows. */
6964 && (<MODE>mode != DImode
6965 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6966 && (INTVAL (operands[2]) == 128
6967 || (INTVAL (operands[2]) < 0
6968 && INTVAL (operands[2]) != -128)))
6970 operands[2] = GEN_INT (-INTVAL (operands[2]));
6971 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6973 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6977 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6978 (const_string "incdec")
6979 (const_string "alu")))
6980 (set (attr "length_immediate")
6982 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6984 (const_string "*")))
6985 (set_attr "mode" "<MODE>")])
6987 (define_insn "*addhi_5"
6988 [(set (reg FLAGS_REG)
6990 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6991 (match_operand:HI 2 "general_operand" "rmn"))
6993 (clobber (match_scratch:HI 0 "=r"))]
6994 "ix86_match_ccmode (insn, CCGOCmode)
6995 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6997 switch (get_attr_type (insn))
7000 if (operands[2] == const1_rtx)
7001 return "inc{w}\t%0";
7004 gcc_assert (operands[2] == constm1_rtx);
7005 return "dec{w}\t%0";
7009 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7010 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7011 if (CONST_INT_P (operands[2])
7012 && (INTVAL (operands[2]) == 128
7013 || (INTVAL (operands[2]) < 0
7014 && INTVAL (operands[2]) != -128)))
7016 operands[2] = GEN_INT (-INTVAL (operands[2]));
7017 return "sub{w}\t{%2, %0|%0, %2}";
7019 return "add{w}\t{%2, %0|%0, %2}";
7023 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7024 (const_string "incdec")
7025 (const_string "alu")))
7026 (set (attr "length_immediate")
7028 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7030 (const_string "*")))
7031 (set_attr "mode" "HI")])
7033 (define_insn "*addqi_5"
7034 [(set (reg FLAGS_REG)
7036 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7037 (match_operand:QI 2 "general_operand" "qmn"))
7039 (clobber (match_scratch:QI 0 "=q"))]
7040 "ix86_match_ccmode (insn, CCGOCmode)
7041 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7043 switch (get_attr_type (insn))
7046 if (operands[2] == const1_rtx)
7047 return "inc{b}\t%0";
7050 gcc_assert (operands[2] == constm1_rtx
7051 || (CONST_INT_P (operands[2])
7052 && INTVAL (operands[2]) == 255));
7053 return "dec{b}\t%0";
7057 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
7058 if (CONST_INT_P (operands[2])
7059 && INTVAL (operands[2]) < 0)
7061 operands[2] = GEN_INT (-INTVAL (operands[2]));
7062 return "sub{b}\t{%2, %0|%0, %2}";
7064 return "add{b}\t{%2, %0|%0, %2}";
7068 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7069 (const_string "incdec")
7070 (const_string "alu")))
7071 (set_attr "mode" "QI")])
7073 (define_insn "*addqi_ext_1_rex64"
7074 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7079 (match_operand 1 "ext_register_operand" "0")
7082 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7083 (clobber (reg:CC FLAGS_REG))]
7086 switch (get_attr_type (insn))
7089 if (operands[2] == const1_rtx)
7090 return "inc{b}\t%h0";
7093 gcc_assert (operands[2] == constm1_rtx
7094 || (CONST_INT_P (operands[2])
7095 && INTVAL (operands[2]) == 255));
7096 return "dec{b}\t%h0";
7100 return "add{b}\t{%2, %h0|%h0, %2}";
7104 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7105 (const_string "incdec")
7106 (const_string "alu")))
7107 (set_attr "modrm" "1")
7108 (set_attr "mode" "QI")])
7110 (define_insn "addqi_ext_1"
7111 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7116 (match_operand 1 "ext_register_operand" "0")
7119 (match_operand:QI 2 "general_operand" "Qmn")))
7120 (clobber (reg:CC FLAGS_REG))]
7123 switch (get_attr_type (insn))
7126 if (operands[2] == const1_rtx)
7127 return "inc{b}\t%h0";
7130 gcc_assert (operands[2] == constm1_rtx
7131 || (CONST_INT_P (operands[2])
7132 && INTVAL (operands[2]) == 255));
7133 return "dec{b}\t%h0";
7137 return "add{b}\t{%2, %h0|%h0, %2}";
7141 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7142 (const_string "incdec")
7143 (const_string "alu")))
7144 (set_attr "modrm" "1")
7145 (set_attr "mode" "QI")])
7147 (define_insn "*addqi_ext_2"
7148 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7153 (match_operand 1 "ext_register_operand" "%0")
7157 (match_operand 2 "ext_register_operand" "Q")
7160 (clobber (reg:CC FLAGS_REG))]
7162 "add{b}\t{%h2, %h0|%h0, %h2}"
7163 [(set_attr "type" "alu")
7164 (set_attr "mode" "QI")])
7166 ;; The lea patterns for non-Pmodes needs to be matched by
7167 ;; several insns converted to real lea by splitters.
7169 (define_insn_and_split "*lea_general_1"
7170 [(set (match_operand 0 "register_operand" "=r")
7171 (plus (plus (match_operand 1 "index_register_operand" "l")
7172 (match_operand 2 "register_operand" "r"))
7173 (match_operand 3 "immediate_operand" "i")))]
7174 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7175 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7176 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7177 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7178 && GET_MODE (operands[0]) == GET_MODE (operands[2])
7179 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7180 || GET_MODE (operands[3]) == VOIDmode)"
7182 "&& reload_completed"
7186 operands[0] = gen_lowpart (SImode, operands[0]);
7187 operands[1] = gen_lowpart (Pmode, operands[1]);
7188 operands[2] = gen_lowpart (Pmode, operands[2]);
7189 operands[3] = gen_lowpart (Pmode, operands[3]);
7190 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7192 if (Pmode != SImode)
7193 pat = gen_rtx_SUBREG (SImode, pat, 0);
7194 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7197 [(set_attr "type" "lea")
7198 (set_attr "mode" "SI")])
7200 (define_insn_and_split "*lea_general_1_zext"
7201 [(set (match_operand:DI 0 "register_operand" "=r")
7204 (match_operand:SI 1 "index_register_operand" "l")
7205 (match_operand:SI 2 "register_operand" "r"))
7206 (match_operand:SI 3 "immediate_operand" "i"))))]
7209 "&& reload_completed"
7211 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7213 (match_dup 3)) 0)))]
7215 operands[1] = gen_lowpart (Pmode, operands[1]);
7216 operands[2] = gen_lowpart (Pmode, operands[2]);
7217 operands[3] = gen_lowpart (Pmode, operands[3]);
7219 [(set_attr "type" "lea")
7220 (set_attr "mode" "SI")])
7222 (define_insn_and_split "*lea_general_2"
7223 [(set (match_operand 0 "register_operand" "=r")
7224 (plus (mult (match_operand 1 "index_register_operand" "l")
7225 (match_operand 2 "const248_operand" "i"))
7226 (match_operand 3 "nonmemory_operand" "ri")))]
7227 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7228 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7229 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7230 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7231 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7232 || GET_MODE (operands[3]) == VOIDmode)"
7234 "&& reload_completed"
7238 operands[0] = gen_lowpart (SImode, operands[0]);
7239 operands[1] = gen_lowpart (Pmode, operands[1]);
7240 operands[3] = gen_lowpart (Pmode, operands[3]);
7241 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7243 if (Pmode != SImode)
7244 pat = gen_rtx_SUBREG (SImode, pat, 0);
7245 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7248 [(set_attr "type" "lea")
7249 (set_attr "mode" "SI")])
7251 (define_insn_and_split "*lea_general_2_zext"
7252 [(set (match_operand:DI 0 "register_operand" "=r")
7255 (match_operand:SI 1 "index_register_operand" "l")
7256 (match_operand:SI 2 "const248_operand" "n"))
7257 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7260 "&& reload_completed"
7262 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7264 (match_dup 3)) 0)))]
7266 operands[1] = gen_lowpart (Pmode, operands[1]);
7267 operands[3] = gen_lowpart (Pmode, operands[3]);
7269 [(set_attr "type" "lea")
7270 (set_attr "mode" "SI")])
7272 (define_insn_and_split "*lea_general_3"
7273 [(set (match_operand 0 "register_operand" "=r")
7274 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7275 (match_operand 2 "const248_operand" "i"))
7276 (match_operand 3 "register_operand" "r"))
7277 (match_operand 4 "immediate_operand" "i")))]
7278 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7279 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7280 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7281 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7282 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7284 "&& reload_completed"
7288 operands[0] = gen_lowpart (SImode, operands[0]);
7289 operands[1] = gen_lowpart (Pmode, operands[1]);
7290 operands[3] = gen_lowpart (Pmode, operands[3]);
7291 operands[4] = gen_lowpart (Pmode, operands[4]);
7292 pat = gen_rtx_PLUS (Pmode,
7293 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7297 if (Pmode != SImode)
7298 pat = gen_rtx_SUBREG (SImode, pat, 0);
7299 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7302 [(set_attr "type" "lea")
7303 (set_attr "mode" "SI")])
7305 (define_insn_and_split "*lea_general_3_zext"
7306 [(set (match_operand:DI 0 "register_operand" "=r")
7310 (match_operand:SI 1 "index_register_operand" "l")
7311 (match_operand:SI 2 "const248_operand" "n"))
7312 (match_operand:SI 3 "register_operand" "r"))
7313 (match_operand:SI 4 "immediate_operand" "i"))))]
7316 "&& reload_completed"
7318 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7321 (match_dup 4)) 0)))]
7323 operands[1] = gen_lowpart (Pmode, operands[1]);
7324 operands[3] = gen_lowpart (Pmode, operands[3]);
7325 operands[4] = gen_lowpart (Pmode, operands[4]);
7327 [(set_attr "type" "lea")
7328 (set_attr "mode" "SI")])
7330 ;; Convert lea to the lea pattern to avoid flags dependency.
7332 [(set (match_operand:DI 0 "register_operand" "")
7333 (plus:DI (match_operand:DI 1 "register_operand" "")
7334 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7335 (clobber (reg:CC FLAGS_REG))]
7336 "TARGET_64BIT && reload_completed
7337 && ix86_lea_for_add_ok (PLUS, insn, operands)"
7339 (plus:DI (match_dup 1)
7343 ;; Convert lea to the lea pattern to avoid flags dependency.
7345 [(set (match_operand 0 "register_operand" "")
7346 (plus (match_operand 1 "register_operand" "")
7347 (match_operand 2 "nonmemory_operand" "")))
7348 (clobber (reg:CC FLAGS_REG))]
7349 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
7353 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7354 may confuse gen_lowpart. */
7355 if (GET_MODE (operands[0]) != Pmode)
7357 operands[1] = gen_lowpart (Pmode, operands[1]);
7358 operands[2] = gen_lowpart (Pmode, operands[2]);
7360 operands[0] = gen_lowpart (SImode, operands[0]);
7361 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7362 if (Pmode != SImode)
7363 pat = gen_rtx_SUBREG (SImode, pat, 0);
7364 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7368 ;; Convert lea to the lea pattern to avoid flags dependency.
7370 [(set (match_operand:DI 0 "register_operand" "")
7372 (plus:SI (match_operand:SI 1 "register_operand" "")
7373 (match_operand:SI 2 "nonmemory_operand" ""))))
7374 (clobber (reg:CC FLAGS_REG))]
7375 "TARGET_64BIT && reload_completed
7376 && true_regnum (operands[0]) != true_regnum (operands[1])"
7378 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7380 operands[1] = gen_lowpart (Pmode, operands[1]);
7381 operands[2] = gen_lowpart (Pmode, operands[2]);
7384 ;; Subtract instructions
7386 (define_expand "sub<mode>3"
7387 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7388 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7389 (match_operand:SDWIM 2 "<general_operand>" "")))]
7391 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7393 (define_insn_and_split "*sub<dwi>3_doubleword"
7394 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7396 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7397 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7398 (clobber (reg:CC FLAGS_REG))]
7399 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7402 [(parallel [(set (reg:CC FLAGS_REG)
7403 (compare:CC (match_dup 1) (match_dup 2)))
7405 (minus:DWIH (match_dup 1) (match_dup 2)))])
7406 (parallel [(set (match_dup 3)
7410 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7412 (clobber (reg:CC FLAGS_REG))])]
7413 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7415 (define_insn "*sub<mode>_1"
7416 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7418 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7419 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7420 (clobber (reg:CC FLAGS_REG))]
7421 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7422 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7423 [(set_attr "type" "alu")
7424 (set_attr "mode" "<MODE>")])
7426 (define_insn "*subsi_1_zext"
7427 [(set (match_operand:DI 0 "register_operand" "=r")
7429 (minus:SI (match_operand:SI 1 "register_operand" "0")
7430 (match_operand:SI 2 "general_operand" "g"))))
7431 (clobber (reg:CC FLAGS_REG))]
7432 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7433 "sub{l}\t{%2, %k0|%k0, %2}"
7434 [(set_attr "type" "alu")
7435 (set_attr "mode" "SI")])
7437 (define_insn "*subqi_1_slp"
7438 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7439 (minus:QI (match_dup 0)
7440 (match_operand:QI 1 "general_operand" "qn,qm")))
7441 (clobber (reg:CC FLAGS_REG))]
7442 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7443 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7444 "sub{b}\t{%1, %0|%0, %1}"
7445 [(set_attr "type" "alu1")
7446 (set_attr "mode" "QI")])
7448 (define_insn "*sub<mode>_2"
7449 [(set (reg FLAGS_REG)
7452 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7453 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7455 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7456 (minus:SWI (match_dup 1) (match_dup 2)))]
7457 "ix86_match_ccmode (insn, CCGOCmode)
7458 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7459 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7460 [(set_attr "type" "alu")
7461 (set_attr "mode" "<MODE>")])
7463 (define_insn "*subsi_2_zext"
7464 [(set (reg FLAGS_REG)
7466 (minus:SI (match_operand:SI 1 "register_operand" "0")
7467 (match_operand:SI 2 "general_operand" "g"))
7469 (set (match_operand:DI 0 "register_operand" "=r")
7471 (minus:SI (match_dup 1)
7473 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7474 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7475 "sub{l}\t{%2, %k0|%k0, %2}"
7476 [(set_attr "type" "alu")
7477 (set_attr "mode" "SI")])
7479 (define_insn "*sub<mode>_3"
7480 [(set (reg FLAGS_REG)
7481 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7482 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7483 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7484 (minus:SWI (match_dup 1) (match_dup 2)))]
7485 "ix86_match_ccmode (insn, CCmode)
7486 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7487 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7488 [(set_attr "type" "alu")
7489 (set_attr "mode" "<MODE>")])
7491 (define_insn "*subsi_3_zext"
7492 [(set (reg FLAGS_REG)
7493 (compare (match_operand:SI 1 "register_operand" "0")
7494 (match_operand:SI 2 "general_operand" "g")))
7495 (set (match_operand:DI 0 "register_operand" "=r")
7497 (minus:SI (match_dup 1)
7499 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7500 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7501 "sub{l}\t{%2, %1|%1, %2}"
7502 [(set_attr "type" "alu")
7503 (set_attr "mode" "SI")])
7505 ;; Add with carry and subtract with borrow
7507 (define_expand "<plusminus_insn><mode>3_carry"
7509 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7511 (match_operand:SWI 1 "nonimmediate_operand" "")
7512 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7513 [(match_operand 3 "flags_reg_operand" "")
7515 (match_operand:SWI 2 "<general_operand>" ""))))
7516 (clobber (reg:CC FLAGS_REG))])]
7517 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7520 (define_insn "*<plusminus_insn><mode>3_carry"
7521 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7523 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7525 (match_operator 3 "ix86_carry_flag_operator"
7526 [(reg FLAGS_REG) (const_int 0)])
7527 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7528 (clobber (reg:CC FLAGS_REG))]
7529 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7530 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7531 [(set_attr "type" "alu")
7532 (set_attr "use_carry" "1")
7533 (set_attr "pent_pair" "pu")
7534 (set_attr "mode" "<MODE>")])
7536 (define_insn "*addsi3_carry_zext"
7537 [(set (match_operand:DI 0 "register_operand" "=r")
7539 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7540 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7541 [(reg FLAGS_REG) (const_int 0)])
7542 (match_operand:SI 2 "general_operand" "g")))))
7543 (clobber (reg:CC FLAGS_REG))]
7544 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7545 "adc{l}\t{%2, %k0|%k0, %2}"
7546 [(set_attr "type" "alu")
7547 (set_attr "use_carry" "1")
7548 (set_attr "pent_pair" "pu")
7549 (set_attr "mode" "SI")])
7551 (define_insn "*subsi3_carry_zext"
7552 [(set (match_operand:DI 0 "register_operand" "=r")
7554 (minus:SI (match_operand:SI 1 "register_operand" "0")
7555 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7556 [(reg FLAGS_REG) (const_int 0)])
7557 (match_operand:SI 2 "general_operand" "g")))))
7558 (clobber (reg:CC FLAGS_REG))]
7559 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7560 "sbb{l}\t{%2, %k0|%k0, %2}"
7561 [(set_attr "type" "alu")
7562 (set_attr "pent_pair" "pu")
7563 (set_attr "mode" "SI")])
7565 ;; Overflow setting add and subtract instructions
7567 (define_insn "*add<mode>3_cconly_overflow"
7568 [(set (reg:CCC FLAGS_REG)
7571 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7572 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7574 (clobber (match_scratch:SWI 0 "=<r>"))]
7575 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7576 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7577 [(set_attr "type" "alu")
7578 (set_attr "mode" "<MODE>")])
7580 (define_insn "*sub<mode>3_cconly_overflow"
7581 [(set (reg:CCC FLAGS_REG)
7584 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7585 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7588 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7589 [(set_attr "type" "icmp")
7590 (set_attr "mode" "<MODE>")])
7592 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7593 [(set (reg:CCC FLAGS_REG)
7596 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7597 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7599 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7600 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7601 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7602 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7603 [(set_attr "type" "alu")
7604 (set_attr "mode" "<MODE>")])
7606 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7607 [(set (reg:CCC FLAGS_REG)
7610 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7611 (match_operand:SI 2 "general_operand" "g"))
7613 (set (match_operand:DI 0 "register_operand" "=r")
7614 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7615 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7616 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7617 [(set_attr "type" "alu")
7618 (set_attr "mode" "SI")])
7620 ;; The patterns that match these are at the end of this file.
7622 (define_expand "<plusminus_insn>xf3"
7623 [(set (match_operand:XF 0 "register_operand" "")
7625 (match_operand:XF 1 "register_operand" "")
7626 (match_operand:XF 2 "register_operand" "")))]
7630 (define_expand "<plusminus_insn><mode>3"
7631 [(set (match_operand:MODEF 0 "register_operand" "")
7633 (match_operand:MODEF 1 "register_operand" "")
7634 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7635 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7636 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7639 ;; Multiply instructions
7641 (define_expand "mul<mode>3"
7642 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7644 (match_operand:SWIM248 1 "register_operand" "")
7645 (match_operand:SWIM248 2 "<general_operand>" "")))
7646 (clobber (reg:CC FLAGS_REG))])]
7650 (define_expand "mulqi3"
7651 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7653 (match_operand:QI 1 "register_operand" "")
7654 (match_operand:QI 2 "nonimmediate_operand" "")))
7655 (clobber (reg:CC FLAGS_REG))])]
7656 "TARGET_QIMODE_MATH"
7660 ;; IMUL reg32/64, reg32/64, imm8 Direct
7661 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7662 ;; IMUL reg32/64, reg32/64, imm32 Direct
7663 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7664 ;; IMUL reg32/64, reg32/64 Direct
7665 ;; IMUL reg32/64, mem32/64 Direct
7667 (define_insn "*mul<mode>3_1"
7668 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7670 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7671 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7672 (clobber (reg:CC FLAGS_REG))]
7673 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7675 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7676 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7677 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7678 [(set_attr "type" "imul")
7679 (set_attr "prefix_0f" "0,0,1")
7680 (set (attr "athlon_decode")
7681 (cond [(eq_attr "cpu" "athlon")
7682 (const_string "vector")
7683 (eq_attr "alternative" "1")
7684 (const_string "vector")
7685 (and (eq_attr "alternative" "2")
7686 (match_operand 1 "memory_operand" ""))
7687 (const_string "vector")]
7688 (const_string "direct")))
7689 (set (attr "amdfam10_decode")
7690 (cond [(and (eq_attr "alternative" "0,1")
7691 (match_operand 1 "memory_operand" ""))
7692 (const_string "vector")]
7693 (const_string "direct")))
7694 (set_attr "mode" "<MODE>")])
7696 (define_insn "*mulsi3_1_zext"
7697 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7699 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7700 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7701 (clobber (reg:CC FLAGS_REG))]
7703 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7705 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7706 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7707 imul{l}\t{%2, %k0|%k0, %2}"
7708 [(set_attr "type" "imul")
7709 (set_attr "prefix_0f" "0,0,1")
7710 (set (attr "athlon_decode")
7711 (cond [(eq_attr "cpu" "athlon")
7712 (const_string "vector")
7713 (eq_attr "alternative" "1")
7714 (const_string "vector")
7715 (and (eq_attr "alternative" "2")
7716 (match_operand 1 "memory_operand" ""))
7717 (const_string "vector")]
7718 (const_string "direct")))
7719 (set (attr "amdfam10_decode")
7720 (cond [(and (eq_attr "alternative" "0,1")
7721 (match_operand 1 "memory_operand" ""))
7722 (const_string "vector")]
7723 (const_string "direct")))
7724 (set_attr "mode" "SI")])
7727 ;; IMUL reg16, reg16, imm8 VectorPath
7728 ;; IMUL reg16, mem16, imm8 VectorPath
7729 ;; IMUL reg16, reg16, imm16 VectorPath
7730 ;; IMUL reg16, mem16, imm16 VectorPath
7731 ;; IMUL reg16, reg16 Direct
7732 ;; IMUL reg16, mem16 Direct
7734 (define_insn "*mulhi3_1"
7735 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7736 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7737 (match_operand:HI 2 "general_operand" "K,n,mr")))
7738 (clobber (reg:CC FLAGS_REG))]
7740 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7742 imul{w}\t{%2, %1, %0|%0, %1, %2}
7743 imul{w}\t{%2, %1, %0|%0, %1, %2}
7744 imul{w}\t{%2, %0|%0, %2}"
7745 [(set_attr "type" "imul")
7746 (set_attr "prefix_0f" "0,0,1")
7747 (set (attr "athlon_decode")
7748 (cond [(eq_attr "cpu" "athlon")
7749 (const_string "vector")
7750 (eq_attr "alternative" "1,2")
7751 (const_string "vector")]
7752 (const_string "direct")))
7753 (set (attr "amdfam10_decode")
7754 (cond [(eq_attr "alternative" "0,1")
7755 (const_string "vector")]
7756 (const_string "direct")))
7757 (set_attr "mode" "HI")])
7763 (define_insn "*mulqi3_1"
7764 [(set (match_operand:QI 0 "register_operand" "=a")
7765 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7766 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7767 (clobber (reg:CC FLAGS_REG))]
7769 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7771 [(set_attr "type" "imul")
7772 (set_attr "length_immediate" "0")
7773 (set (attr "athlon_decode")
7774 (if_then_else (eq_attr "cpu" "athlon")
7775 (const_string "vector")
7776 (const_string "direct")))
7777 (set_attr "amdfam10_decode" "direct")
7778 (set_attr "mode" "QI")])
7780 (define_expand "<u>mul<mode><dwi>3"
7781 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7784 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7786 (match_operand:DWIH 2 "register_operand" ""))))
7787 (clobber (reg:CC FLAGS_REG))])]
7791 (define_expand "<u>mulqihi3"
7792 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7795 (match_operand:QI 1 "nonimmediate_operand" ""))
7797 (match_operand:QI 2 "register_operand" ""))))
7798 (clobber (reg:CC FLAGS_REG))])]
7799 "TARGET_QIMODE_MATH"
7802 (define_insn "*<u>mul<mode><dwi>3_1"
7803 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7806 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7808 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7809 (clobber (reg:CC FLAGS_REG))]
7810 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7811 "<sgnprefix>mul{<imodesuffix>}\t%2"
7812 [(set_attr "type" "imul")
7813 (set_attr "length_immediate" "0")
7814 (set (attr "athlon_decode")
7815 (if_then_else (eq_attr "cpu" "athlon")
7816 (const_string "vector")
7817 (const_string "double")))
7818 (set_attr "amdfam10_decode" "double")
7819 (set_attr "mode" "<MODE>")])
7821 (define_insn "*<u>mulqihi3_1"
7822 [(set (match_operand:HI 0 "register_operand" "=a")
7825 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7827 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7828 (clobber (reg:CC FLAGS_REG))]
7830 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7831 "<sgnprefix>mul{b}\t%2"
7832 [(set_attr "type" "imul")
7833 (set_attr "length_immediate" "0")
7834 (set (attr "athlon_decode")
7835 (if_then_else (eq_attr "cpu" "athlon")
7836 (const_string "vector")
7837 (const_string "direct")))
7838 (set_attr "amdfam10_decode" "direct")
7839 (set_attr "mode" "QI")])
7841 (define_expand "<s>mul<mode>3_highpart"
7842 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7847 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7849 (match_operand:SWI48 2 "register_operand" "")))
7851 (clobber (match_scratch:SWI48 3 ""))
7852 (clobber (reg:CC FLAGS_REG))])]
7854 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7856 (define_insn "*<s>muldi3_highpart_1"
7857 [(set (match_operand:DI 0 "register_operand" "=d")
7862 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7864 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7866 (clobber (match_scratch:DI 3 "=1"))
7867 (clobber (reg:CC FLAGS_REG))]
7869 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7870 "<sgnprefix>mul{q}\t%2"
7871 [(set_attr "type" "imul")
7872 (set_attr "length_immediate" "0")
7873 (set (attr "athlon_decode")
7874 (if_then_else (eq_attr "cpu" "athlon")
7875 (const_string "vector")
7876 (const_string "double")))
7877 (set_attr "amdfam10_decode" "double")
7878 (set_attr "mode" "DI")])
7880 (define_insn "*<s>mulsi3_highpart_1"
7881 [(set (match_operand:SI 0 "register_operand" "=d")
7886 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7888 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7890 (clobber (match_scratch:SI 3 "=1"))
7891 (clobber (reg:CC FLAGS_REG))]
7892 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7893 "<sgnprefix>mul{l}\t%2"
7894 [(set_attr "type" "imul")
7895 (set_attr "length_immediate" "0")
7896 (set (attr "athlon_decode")
7897 (if_then_else (eq_attr "cpu" "athlon")
7898 (const_string "vector")
7899 (const_string "double")))
7900 (set_attr "amdfam10_decode" "double")
7901 (set_attr "mode" "SI")])
7903 (define_insn "*<s>mulsi3_highpart_zext"
7904 [(set (match_operand:DI 0 "register_operand" "=d")
7905 (zero_extend:DI (truncate:SI
7907 (mult:DI (any_extend:DI
7908 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7910 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7912 (clobber (match_scratch:SI 3 "=1"))
7913 (clobber (reg:CC FLAGS_REG))]
7915 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7916 "<sgnprefix>mul{l}\t%2"
7917 [(set_attr "type" "imul")
7918 (set_attr "length_immediate" "0")
7919 (set (attr "athlon_decode")
7920 (if_then_else (eq_attr "cpu" "athlon")
7921 (const_string "vector")
7922 (const_string "double")))
7923 (set_attr "amdfam10_decode" "double")
7924 (set_attr "mode" "SI")])
7926 ;; The patterns that match these are at the end of this file.
7928 (define_expand "mulxf3"
7929 [(set (match_operand:XF 0 "register_operand" "")
7930 (mult:XF (match_operand:XF 1 "register_operand" "")
7931 (match_operand:XF 2 "register_operand" "")))]
7935 (define_expand "mul<mode>3"
7936 [(set (match_operand:MODEF 0 "register_operand" "")
7937 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7938 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7939 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7940 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7943 ;; Divide instructions
7945 (define_insn "<u>divqi3"
7946 [(set (match_operand:QI 0 "register_operand" "=a")
7948 (match_operand:HI 1 "register_operand" "0")
7949 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7950 (clobber (reg:CC FLAGS_REG))]
7951 "TARGET_QIMODE_MATH"
7952 "<sgnprefix>div{b}\t%2"
7953 [(set_attr "type" "idiv")
7954 (set_attr "mode" "QI")])
7956 ;; The patterns that match these are at the end of this file.
7958 (define_expand "divxf3"
7959 [(set (match_operand:XF 0 "register_operand" "")
7960 (div:XF (match_operand:XF 1 "register_operand" "")
7961 (match_operand:XF 2 "register_operand" "")))]
7965 (define_expand "divdf3"
7966 [(set (match_operand:DF 0 "register_operand" "")
7967 (div:DF (match_operand:DF 1 "register_operand" "")
7968 (match_operand:DF 2 "nonimmediate_operand" "")))]
7969 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7970 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7973 (define_expand "divsf3"
7974 [(set (match_operand:SF 0 "register_operand" "")
7975 (div:SF (match_operand:SF 1 "register_operand" "")
7976 (match_operand:SF 2 "nonimmediate_operand" "")))]
7977 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7980 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7981 && flag_finite_math_only && !flag_trapping_math
7982 && flag_unsafe_math_optimizations)
7984 ix86_emit_swdivsf (operands[0], operands[1],
7985 operands[2], SFmode);
7990 ;; Divmod instructions.
7992 (define_expand "divmod<mode>4"
7993 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7995 (match_operand:SWIM248 1 "register_operand" "")
7996 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7997 (set (match_operand:SWIM248 3 "register_operand" "")
7998 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7999 (clobber (reg:CC FLAGS_REG))])]
8003 (define_insn_and_split "*divmod<mode>4"
8004 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8005 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8006 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8007 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8008 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8009 (clobber (reg:CC FLAGS_REG))]
8012 "&& reload_completed"
8013 [(parallel [(set (match_dup 1)
8014 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8015 (clobber (reg:CC FLAGS_REG))])
8016 (parallel [(set (match_dup 0)
8017 (div:SWIM248 (match_dup 2) (match_dup 3)))
8019 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8021 (clobber (reg:CC FLAGS_REG))])]
8023 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
8025 if (<MODE>mode != HImode
8026 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8027 operands[4] = operands[2];
8030 /* Avoid use of cltd in favor of a mov+shift. */
8031 emit_move_insn (operands[1], operands[2]);
8032 operands[4] = operands[1];
8035 [(set_attr "type" "multi")
8036 (set_attr "mode" "<MODE>")])
8038 (define_insn "*divmod<mode>4_noext"
8039 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8040 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8041 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8042 (set (match_operand:SWIM248 1 "register_operand" "=d")
8043 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8044 (use (match_operand:SWIM248 4 "register_operand" "1"))
8045 (clobber (reg:CC FLAGS_REG))]
8047 "idiv{<imodesuffix>}\t%3"
8048 [(set_attr "type" "idiv")
8049 (set_attr "mode" "<MODE>")])
8051 (define_expand "udivmod<mode>4"
8052 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8054 (match_operand:SWIM248 1 "register_operand" "")
8055 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8056 (set (match_operand:SWIM248 3 "register_operand" "")
8057 (umod:SWIM248 (match_dup 1) (match_dup 2)))
8058 (clobber (reg:CC FLAGS_REG))])]
8062 (define_insn_and_split "*udivmod<mode>4"
8063 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8064 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8065 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8066 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8067 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8068 (clobber (reg:CC FLAGS_REG))]
8071 "&& reload_completed"
8072 [(set (match_dup 1) (const_int 0))
8073 (parallel [(set (match_dup 0)
8074 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8076 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8078 (clobber (reg:CC FLAGS_REG))])]
8080 [(set_attr "type" "multi")
8081 (set_attr "mode" "<MODE>")])
8083 (define_insn "*udivmod<mode>4_noext"
8084 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8085 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8086 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8087 (set (match_operand:SWIM248 1 "register_operand" "=d")
8088 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8089 (use (match_operand:SWIM248 4 "register_operand" "1"))
8090 (clobber (reg:CC FLAGS_REG))]
8092 "div{<imodesuffix>}\t%3"
8093 [(set_attr "type" "idiv")
8094 (set_attr "mode" "<MODE>")])
8096 ;; We cannot use div/idiv for double division, because it causes
8097 ;; "division by zero" on the overflow and that's not what we expect
8098 ;; from truncate. Because true (non truncating) double division is
8099 ;; never generated, we can't create this insn anyway.
8102 ; [(set (match_operand:SI 0 "register_operand" "=a")
8104 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8106 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8107 ; (set (match_operand:SI 3 "register_operand" "=d")
8109 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8110 ; (clobber (reg:CC FLAGS_REG))]
8112 ; "div{l}\t{%2, %0|%0, %2}"
8113 ; [(set_attr "type" "idiv")])
8115 ;;- Logical AND instructions
8117 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8118 ;; Note that this excludes ah.
8120 (define_expand "testsi_ccno_1"
8121 [(set (reg:CCNO FLAGS_REG)
8123 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8124 (match_operand:SI 1 "nonmemory_operand" ""))
8129 (define_expand "testqi_ccz_1"
8130 [(set (reg:CCZ FLAGS_REG)
8131 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8132 (match_operand:QI 1 "nonmemory_operand" ""))
8137 (define_insn "*testdi_1"
8138 [(set (reg FLAGS_REG)
8141 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8142 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8144 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8145 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8147 test{l}\t{%k1, %k0|%k0, %k1}
8148 test{l}\t{%k1, %k0|%k0, %k1}
8149 test{q}\t{%1, %0|%0, %1}
8150 test{q}\t{%1, %0|%0, %1}
8151 test{q}\t{%1, %0|%0, %1}"
8152 [(set_attr "type" "test")
8153 (set_attr "modrm" "0,1,0,1,1")
8154 (set_attr "mode" "SI,SI,DI,DI,DI")])
8156 (define_insn "*testqi_1_maybe_si"
8157 [(set (reg FLAGS_REG)
8160 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8161 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8163 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8164 && ix86_match_ccmode (insn,
8165 CONST_INT_P (operands[1])
8166 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8168 if (which_alternative == 3)
8170 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8171 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8172 return "test{l}\t{%1, %k0|%k0, %1}";
8174 return "test{b}\t{%1, %0|%0, %1}";
8176 [(set_attr "type" "test")
8177 (set_attr "modrm" "0,1,1,1")
8178 (set_attr "mode" "QI,QI,QI,SI")
8179 (set_attr "pent_pair" "uv,np,uv,np")])
8181 (define_insn "*test<mode>_1"
8182 [(set (reg FLAGS_REG)
8185 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8186 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8188 "ix86_match_ccmode (insn, CCNOmode)
8189 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8190 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8191 [(set_attr "type" "test")
8192 (set_attr "modrm" "0,1,1")
8193 (set_attr "mode" "<MODE>")
8194 (set_attr "pent_pair" "uv,np,uv")])
8196 (define_expand "testqi_ext_ccno_0"
8197 [(set (reg:CCNO FLAGS_REG)
8201 (match_operand 0 "ext_register_operand" "")
8204 (match_operand 1 "const_int_operand" ""))
8209 (define_insn "*testqi_ext_0"
8210 [(set (reg FLAGS_REG)
8214 (match_operand 0 "ext_register_operand" "Q")
8217 (match_operand 1 "const_int_operand" "n"))
8219 "ix86_match_ccmode (insn, CCNOmode)"
8220 "test{b}\t{%1, %h0|%h0, %1}"
8221 [(set_attr "type" "test")
8222 (set_attr "mode" "QI")
8223 (set_attr "length_immediate" "1")
8224 (set_attr "modrm" "1")
8225 (set_attr "pent_pair" "np")])
8227 (define_insn "*testqi_ext_1_rex64"
8228 [(set (reg FLAGS_REG)
8232 (match_operand 0 "ext_register_operand" "Q")
8236 (match_operand:QI 1 "register_operand" "Q")))
8238 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8239 "test{b}\t{%1, %h0|%h0, %1}"
8240 [(set_attr "type" "test")
8241 (set_attr "mode" "QI")])
8243 (define_insn "*testqi_ext_1"
8244 [(set (reg FLAGS_REG)
8248 (match_operand 0 "ext_register_operand" "Q")
8252 (match_operand:QI 1 "general_operand" "Qm")))
8254 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8255 "test{b}\t{%1, %h0|%h0, %1}"
8256 [(set_attr "type" "test")
8257 (set_attr "mode" "QI")])
8259 (define_insn "*testqi_ext_2"
8260 [(set (reg FLAGS_REG)
8264 (match_operand 0 "ext_register_operand" "Q")
8268 (match_operand 1 "ext_register_operand" "Q")
8272 "ix86_match_ccmode (insn, CCNOmode)"
8273 "test{b}\t{%h1, %h0|%h0, %h1}"
8274 [(set_attr "type" "test")
8275 (set_attr "mode" "QI")])
8277 (define_insn "*testqi_ext_3_rex64"
8278 [(set (reg FLAGS_REG)
8279 (compare (zero_extract:DI
8280 (match_operand 0 "nonimmediate_operand" "rm")
8281 (match_operand:DI 1 "const_int_operand" "")
8282 (match_operand:DI 2 "const_int_operand" ""))
8285 && ix86_match_ccmode (insn, CCNOmode)
8286 && INTVAL (operands[1]) > 0
8287 && INTVAL (operands[2]) >= 0
8288 /* Ensure that resulting mask is zero or sign extended operand. */
8289 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8290 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8291 && INTVAL (operands[1]) > 32))
8292 && (GET_MODE (operands[0]) == SImode
8293 || GET_MODE (operands[0]) == DImode
8294 || GET_MODE (operands[0]) == HImode
8295 || GET_MODE (operands[0]) == QImode)"
8298 ;; Combine likes to form bit extractions for some tests. Humor it.
8299 (define_insn "*testqi_ext_3"
8300 [(set (reg FLAGS_REG)
8301 (compare (zero_extract:SI
8302 (match_operand 0 "nonimmediate_operand" "rm")
8303 (match_operand:SI 1 "const_int_operand" "")
8304 (match_operand:SI 2 "const_int_operand" ""))
8306 "ix86_match_ccmode (insn, CCNOmode)
8307 && INTVAL (operands[1]) > 0
8308 && INTVAL (operands[2]) >= 0
8309 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8310 && (GET_MODE (operands[0]) == SImode
8311 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8312 || GET_MODE (operands[0]) == HImode
8313 || GET_MODE (operands[0]) == QImode)"
8317 [(set (match_operand 0 "flags_reg_operand" "")
8318 (match_operator 1 "compare_operator"
8320 (match_operand 2 "nonimmediate_operand" "")
8321 (match_operand 3 "const_int_operand" "")
8322 (match_operand 4 "const_int_operand" ""))
8324 "ix86_match_ccmode (insn, CCNOmode)"
8325 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8327 rtx val = operands[2];
8328 HOST_WIDE_INT len = INTVAL (operands[3]);
8329 HOST_WIDE_INT pos = INTVAL (operands[4]);
8331 enum machine_mode mode, submode;
8333 mode = GET_MODE (val);
8336 /* ??? Combine likes to put non-volatile mem extractions in QImode
8337 no matter the size of the test. So find a mode that works. */
8338 if (! MEM_VOLATILE_P (val))
8340 mode = smallest_mode_for_size (pos + len, MODE_INT);
8341 val = adjust_address (val, mode, 0);
8344 else if (GET_CODE (val) == SUBREG
8345 && (submode = GET_MODE (SUBREG_REG (val)),
8346 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8347 && pos + len <= GET_MODE_BITSIZE (submode)
8348 && GET_MODE_CLASS (submode) == MODE_INT)
8350 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8352 val = SUBREG_REG (val);
8354 else if (mode == HImode && pos + len <= 8)
8356 /* Small HImode tests can be converted to QImode. */
8358 val = gen_lowpart (QImode, val);
8361 if (len == HOST_BITS_PER_WIDE_INT)
8364 mask = ((HOST_WIDE_INT)1 << len) - 1;
8367 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8370 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8371 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8372 ;; this is relatively important trick.
8373 ;; Do the conversion only post-reload to avoid limiting of the register class
8376 [(set (match_operand 0 "flags_reg_operand" "")
8377 (match_operator 1 "compare_operator"
8378 [(and (match_operand 2 "register_operand" "")
8379 (match_operand 3 "const_int_operand" ""))
8382 && QI_REG_P (operands[2])
8383 && GET_MODE (operands[2]) != QImode
8384 && ((ix86_match_ccmode (insn, CCZmode)
8385 && !(INTVAL (operands[3]) & ~(255 << 8)))
8386 || (ix86_match_ccmode (insn, CCNOmode)
8387 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8390 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8393 "operands[2] = gen_lowpart (SImode, operands[2]);
8394 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8397 [(set (match_operand 0 "flags_reg_operand" "")
8398 (match_operator 1 "compare_operator"
8399 [(and (match_operand 2 "nonimmediate_operand" "")
8400 (match_operand 3 "const_int_operand" ""))
8403 && GET_MODE (operands[2]) != QImode
8404 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8405 && ((ix86_match_ccmode (insn, CCZmode)
8406 && !(INTVAL (operands[3]) & ~255))
8407 || (ix86_match_ccmode (insn, CCNOmode)
8408 && !(INTVAL (operands[3]) & ~127)))"
8410 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8412 "operands[2] = gen_lowpart (QImode, operands[2]);
8413 operands[3] = gen_lowpart (QImode, operands[3]);")
8415 ;; %%% This used to optimize known byte-wide and operations to memory,
8416 ;; and sometimes to QImode registers. If this is considered useful,
8417 ;; it should be done with splitters.
8419 (define_expand "and<mode>3"
8420 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8421 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8422 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8424 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8426 (define_insn "*anddi_1"
8427 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8429 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8430 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8431 (clobber (reg:CC FLAGS_REG))]
8432 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8434 switch (get_attr_type (insn))
8438 enum machine_mode mode;
8440 gcc_assert (CONST_INT_P (operands[2]));
8441 if (INTVAL (operands[2]) == 0xff)
8445 gcc_assert (INTVAL (operands[2]) == 0xffff);
8449 operands[1] = gen_lowpart (mode, operands[1]);
8451 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8453 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8457 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8458 if (get_attr_mode (insn) == MODE_SI)
8459 return "and{l}\t{%k2, %k0|%k0, %k2}";
8461 return "and{q}\t{%2, %0|%0, %2}";
8464 [(set_attr "type" "alu,alu,alu,imovx")
8465 (set_attr "length_immediate" "*,*,*,0")
8466 (set (attr "prefix_rex")
8468 (and (eq_attr "type" "imovx")
8469 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8470 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8472 (const_string "*")))
8473 (set_attr "mode" "SI,DI,DI,SI")])
8475 (define_insn "*andsi_1"
8476 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8477 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8478 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8479 (clobber (reg:CC FLAGS_REG))]
8480 "ix86_binary_operator_ok (AND, SImode, operands)"
8482 switch (get_attr_type (insn))
8486 enum machine_mode mode;
8488 gcc_assert (CONST_INT_P (operands[2]));
8489 if (INTVAL (operands[2]) == 0xff)
8493 gcc_assert (INTVAL (operands[2]) == 0xffff);
8497 operands[1] = gen_lowpart (mode, operands[1]);
8499 return "movz{bl|x}\t{%1, %0|%0, %1}";
8501 return "movz{wl|x}\t{%1, %0|%0, %1}";
8505 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8506 return "and{l}\t{%2, %0|%0, %2}";
8509 [(set_attr "type" "alu,alu,imovx")
8510 (set (attr "prefix_rex")
8512 (and (eq_attr "type" "imovx")
8513 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8514 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8516 (const_string "*")))
8517 (set_attr "length_immediate" "*,*,0")
8518 (set_attr "mode" "SI")])
8520 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8521 (define_insn "*andsi_1_zext"
8522 [(set (match_operand:DI 0 "register_operand" "=r")
8524 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8525 (match_operand:SI 2 "general_operand" "g"))))
8526 (clobber (reg:CC FLAGS_REG))]
8527 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8528 "and{l}\t{%2, %k0|%k0, %2}"
8529 [(set_attr "type" "alu")
8530 (set_attr "mode" "SI")])
8532 (define_insn "*andhi_1"
8533 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8534 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8535 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8536 (clobber (reg:CC FLAGS_REG))]
8537 "ix86_binary_operator_ok (AND, HImode, operands)"
8539 switch (get_attr_type (insn))
8542 gcc_assert (CONST_INT_P (operands[2]));
8543 gcc_assert (INTVAL (operands[2]) == 0xff);
8544 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8547 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8549 return "and{w}\t{%2, %0|%0, %2}";
8552 [(set_attr "type" "alu,alu,imovx")
8553 (set_attr "length_immediate" "*,*,0")
8554 (set (attr "prefix_rex")
8556 (and (eq_attr "type" "imovx")
8557 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8559 (const_string "*")))
8560 (set_attr "mode" "HI,HI,SI")])
8562 ;; %%% Potential partial reg stall on alternative 2. What to do?
8563 (define_insn "*andqi_1"
8564 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8565 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8566 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8567 (clobber (reg:CC FLAGS_REG))]
8568 "ix86_binary_operator_ok (AND, QImode, operands)"
8570 and{b}\t{%2, %0|%0, %2}
8571 and{b}\t{%2, %0|%0, %2}
8572 and{l}\t{%k2, %k0|%k0, %k2}"
8573 [(set_attr "type" "alu")
8574 (set_attr "mode" "QI,QI,SI")])
8576 (define_insn "*andqi_1_slp"
8577 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8578 (and:QI (match_dup 0)
8579 (match_operand:QI 1 "general_operand" "qn,qmn")))
8580 (clobber (reg:CC FLAGS_REG))]
8581 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8582 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8583 "and{b}\t{%1, %0|%0, %1}"
8584 [(set_attr "type" "alu1")
8585 (set_attr "mode" "QI")])
8588 [(set (match_operand 0 "register_operand" "")
8590 (const_int -65536)))
8591 (clobber (reg:CC FLAGS_REG))]
8592 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8593 || optimize_function_for_size_p (cfun)"
8594 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8595 "operands[1] = gen_lowpart (HImode, operands[0]);")
8598 [(set (match_operand 0 "ext_register_operand" "")
8601 (clobber (reg:CC FLAGS_REG))]
8602 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8603 && reload_completed"
8604 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8605 "operands[1] = gen_lowpart (QImode, operands[0]);")
8608 [(set (match_operand 0 "ext_register_operand" "")
8610 (const_int -65281)))
8611 (clobber (reg:CC FLAGS_REG))]
8612 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8613 && reload_completed"
8614 [(parallel [(set (zero_extract:SI (match_dup 0)
8618 (zero_extract:SI (match_dup 0)
8621 (zero_extract:SI (match_dup 0)
8624 (clobber (reg:CC FLAGS_REG))])]
8625 "operands[0] = gen_lowpart (SImode, operands[0]);")
8627 (define_insn "*anddi_2"
8628 [(set (reg FLAGS_REG)
8631 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8632 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8634 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8635 (and:DI (match_dup 1) (match_dup 2)))]
8636 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8637 && ix86_binary_operator_ok (AND, DImode, operands)"
8639 and{l}\t{%k2, %k0|%k0, %k2}
8640 and{q}\t{%2, %0|%0, %2}
8641 and{q}\t{%2, %0|%0, %2}"
8642 [(set_attr "type" "alu")
8643 (set_attr "mode" "SI,DI,DI")])
8645 (define_insn "*andqi_2_maybe_si"
8646 [(set (reg FLAGS_REG)
8648 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8649 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8651 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8652 (and:QI (match_dup 1) (match_dup 2)))]
8653 "ix86_binary_operator_ok (AND, QImode, operands)
8654 && ix86_match_ccmode (insn,
8655 CONST_INT_P (operands[2])
8656 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8658 if (which_alternative == 2)
8660 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8661 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8662 return "and{l}\t{%2, %k0|%k0, %2}";
8664 return "and{b}\t{%2, %0|%0, %2}";
8666 [(set_attr "type" "alu")
8667 (set_attr "mode" "QI,QI,SI")])
8669 (define_insn "*and<mode>_2"
8670 [(set (reg FLAGS_REG)
8671 (compare (and:SWI124
8672 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8673 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8675 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8676 (and:SWI124 (match_dup 1) (match_dup 2)))]
8677 "ix86_match_ccmode (insn, CCNOmode)
8678 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8679 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8680 [(set_attr "type" "alu")
8681 (set_attr "mode" "<MODE>")])
8683 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8684 (define_insn "*andsi_2_zext"
8685 [(set (reg FLAGS_REG)
8687 (match_operand:SI 1 "nonimmediate_operand" "%0")
8688 (match_operand:SI 2 "general_operand" "g"))
8690 (set (match_operand:DI 0 "register_operand" "=r")
8691 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8692 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8693 && ix86_binary_operator_ok (AND, SImode, operands)"
8694 "and{l}\t{%2, %k0|%k0, %2}"
8695 [(set_attr "type" "alu")
8696 (set_attr "mode" "SI")])
8698 (define_insn "*andqi_2_slp"
8699 [(set (reg FLAGS_REG)
8701 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8702 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8704 (set (strict_low_part (match_dup 0))
8705 (and:QI (match_dup 0) (match_dup 1)))]
8706 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8707 && ix86_match_ccmode (insn, CCNOmode)
8708 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8709 "and{b}\t{%1, %0|%0, %1}"
8710 [(set_attr "type" "alu1")
8711 (set_attr "mode" "QI")])
8713 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8714 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8715 ;; for a QImode operand, which of course failed.
8716 (define_insn "andqi_ext_0"
8717 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8722 (match_operand 1 "ext_register_operand" "0")
8725 (match_operand 2 "const_int_operand" "n")))
8726 (clobber (reg:CC FLAGS_REG))]
8728 "and{b}\t{%2, %h0|%h0, %2}"
8729 [(set_attr "type" "alu")
8730 (set_attr "length_immediate" "1")
8731 (set_attr "modrm" "1")
8732 (set_attr "mode" "QI")])
8734 ;; Generated by peephole translating test to and. This shows up
8735 ;; often in fp comparisons.
8736 (define_insn "*andqi_ext_0_cc"
8737 [(set (reg FLAGS_REG)
8741 (match_operand 1 "ext_register_operand" "0")
8744 (match_operand 2 "const_int_operand" "n"))
8746 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8755 "ix86_match_ccmode (insn, CCNOmode)"
8756 "and{b}\t{%2, %h0|%h0, %2}"
8757 [(set_attr "type" "alu")
8758 (set_attr "length_immediate" "1")
8759 (set_attr "modrm" "1")
8760 (set_attr "mode" "QI")])
8762 (define_insn "*andqi_ext_1_rex64"
8763 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8768 (match_operand 1 "ext_register_operand" "0")
8772 (match_operand 2 "ext_register_operand" "Q"))))
8773 (clobber (reg:CC FLAGS_REG))]
8775 "and{b}\t{%2, %h0|%h0, %2}"
8776 [(set_attr "type" "alu")
8777 (set_attr "length_immediate" "0")
8778 (set_attr "mode" "QI")])
8780 (define_insn "*andqi_ext_1"
8781 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8786 (match_operand 1 "ext_register_operand" "0")
8790 (match_operand:QI 2 "general_operand" "Qm"))))
8791 (clobber (reg:CC FLAGS_REG))]
8793 "and{b}\t{%2, %h0|%h0, %2}"
8794 [(set_attr "type" "alu")
8795 (set_attr "length_immediate" "0")
8796 (set_attr "mode" "QI")])
8798 (define_insn "*andqi_ext_2"
8799 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8804 (match_operand 1 "ext_register_operand" "%0")
8808 (match_operand 2 "ext_register_operand" "Q")
8811 (clobber (reg:CC FLAGS_REG))]
8813 "and{b}\t{%h2, %h0|%h0, %h2}"
8814 [(set_attr "type" "alu")
8815 (set_attr "length_immediate" "0")
8816 (set_attr "mode" "QI")])
8818 ;; Convert wide AND instructions with immediate operand to shorter QImode
8819 ;; equivalents when possible.
8820 ;; Don't do the splitting with memory operands, since it introduces risk
8821 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8822 ;; for size, but that can (should?) be handled by generic code instead.
8824 [(set (match_operand 0 "register_operand" "")
8825 (and (match_operand 1 "register_operand" "")
8826 (match_operand 2 "const_int_operand" "")))
8827 (clobber (reg:CC FLAGS_REG))]
8829 && QI_REG_P (operands[0])
8830 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8831 && !(~INTVAL (operands[2]) & ~(255 << 8))
8832 && GET_MODE (operands[0]) != QImode"
8833 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8834 (and:SI (zero_extract:SI (match_dup 1)
8835 (const_int 8) (const_int 8))
8837 (clobber (reg:CC FLAGS_REG))])]
8838 "operands[0] = gen_lowpart (SImode, operands[0]);
8839 operands[1] = gen_lowpart (SImode, operands[1]);
8840 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8842 ;; Since AND can be encoded with sign extended immediate, this is only
8843 ;; profitable when 7th bit is not set.
8845 [(set (match_operand 0 "register_operand" "")
8846 (and (match_operand 1 "general_operand" "")
8847 (match_operand 2 "const_int_operand" "")))
8848 (clobber (reg:CC FLAGS_REG))]
8850 && ANY_QI_REG_P (operands[0])
8851 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8852 && !(~INTVAL (operands[2]) & ~255)
8853 && !(INTVAL (operands[2]) & 128)
8854 && GET_MODE (operands[0]) != QImode"
8855 [(parallel [(set (strict_low_part (match_dup 0))
8856 (and:QI (match_dup 1)
8858 (clobber (reg:CC FLAGS_REG))])]
8859 "operands[0] = gen_lowpart (QImode, operands[0]);
8860 operands[1] = gen_lowpart (QImode, operands[1]);
8861 operands[2] = gen_lowpart (QImode, operands[2]);")
8863 ;; Logical inclusive and exclusive OR instructions
8865 ;; %%% This used to optimize known byte-wide and operations to memory.
8866 ;; If this is considered useful, it should be done with splitters.
8868 (define_expand "<code><mode>3"
8869 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8870 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8871 (match_operand:SWIM 2 "<general_operand>" "")))]
8873 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8875 (define_insn "*<code><mode>_1"
8876 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8878 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8879 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8880 (clobber (reg:CC FLAGS_REG))]
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 ;; %%% Potential partial reg stall on alternative 2. What to do?
8887 (define_insn "*<code>qi_1"
8888 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8889 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8890 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8891 (clobber (reg:CC FLAGS_REG))]
8892 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8894 <logicprefix>{b}\t{%2, %0|%0, %2}
8895 <logicprefix>{b}\t{%2, %0|%0, %2}
8896 <logicprefix>{l}\t{%k2, %k0|%k0, %k2}"
8897 [(set_attr "type" "alu")
8898 (set_attr "mode" "QI,QI,SI")])
8900 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8901 (define_insn "*<code>si_1_zext"
8902 [(set (match_operand:DI 0 "register_operand" "=r")
8904 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8905 (match_operand:SI 2 "general_operand" "g"))))
8906 (clobber (reg:CC FLAGS_REG))]
8907 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8908 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8909 [(set_attr "type" "alu")
8910 (set_attr "mode" "SI")])
8912 (define_insn "*<code>si_1_zext_imm"
8913 [(set (match_operand:DI 0 "register_operand" "=r")
8915 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8916 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8917 (clobber (reg:CC FLAGS_REG))]
8918 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8919 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8920 [(set_attr "type" "alu")
8921 (set_attr "mode" "SI")])
8923 (define_insn "*<code>qi_1_slp"
8924 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8925 (any_or:QI (match_dup 0)
8926 (match_operand:QI 1 "general_operand" "qmn,qn")))
8927 (clobber (reg:CC FLAGS_REG))]
8928 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8929 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8930 "<logicprefix>{b}\t{%1, %0|%0, %1}"
8931 [(set_attr "type" "alu1")
8932 (set_attr "mode" "QI")])
8934 (define_insn "*<code><mode>_2"
8935 [(set (reg FLAGS_REG)
8936 (compare (any_or:SWI
8937 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8938 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8940 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8941 (any_or:SWI (match_dup 1) (match_dup 2)))]
8942 "ix86_match_ccmode (insn, CCNOmode)
8943 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8944 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8945 [(set_attr "type" "alu")
8946 (set_attr "mode" "<MODE>")])
8948 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8949 ;; ??? Special case for immediate operand is missing - it is tricky.
8950 (define_insn "*<code>si_2_zext"
8951 [(set (reg FLAGS_REG)
8952 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8953 (match_operand:SI 2 "general_operand" "g"))
8955 (set (match_operand:DI 0 "register_operand" "=r")
8956 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8957 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8958 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8959 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8960 [(set_attr "type" "alu")
8961 (set_attr "mode" "SI")])
8963 (define_insn "*<code>si_2_zext_imm"
8964 [(set (reg FLAGS_REG)
8966 (match_operand:SI 1 "nonimmediate_operand" "%0")
8967 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8969 (set (match_operand:DI 0 "register_operand" "=r")
8970 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8971 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8972 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8973 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8974 [(set_attr "type" "alu")
8975 (set_attr "mode" "SI")])
8977 (define_insn "*<code>qi_2_slp"
8978 [(set (reg FLAGS_REG)
8979 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8980 (match_operand:QI 1 "general_operand" "qmn,qn"))
8982 (set (strict_low_part (match_dup 0))
8983 (any_or:QI (match_dup 0) (match_dup 1)))]
8984 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8985 && ix86_match_ccmode (insn, CCNOmode)
8986 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8987 "<logicprefix>{b}\t{%1, %0|%0, %1}"
8988 [(set_attr "type" "alu1")
8989 (set_attr "mode" "QI")])
8991 (define_insn "*<code><mode>_3"
8992 [(set (reg FLAGS_REG)
8993 (compare (any_or:SWI
8994 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8995 (match_operand:SWI 2 "<general_operand>" "<g>"))
8997 (clobber (match_scratch:SWI 0 "=<r>"))]
8998 "ix86_match_ccmode (insn, CCNOmode)
8999 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9000 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
9001 [(set_attr "type" "alu")
9002 (set_attr "mode" "<MODE>")])
9004 (define_insn "*<code>qi_ext_0"
9005 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9010 (match_operand 1 "ext_register_operand" "0")
9013 (match_operand 2 "const_int_operand" "n")))
9014 (clobber (reg:CC FLAGS_REG))]
9015 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9016 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
9017 [(set_attr "type" "alu")
9018 (set_attr "length_immediate" "1")
9019 (set_attr "modrm" "1")
9020 (set_attr "mode" "QI")])
9022 (define_insn "*<code>qi_ext_1_rex64"
9023 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9028 (match_operand 1 "ext_register_operand" "0")
9032 (match_operand 2 "ext_register_operand" "Q"))))
9033 (clobber (reg:CC FLAGS_REG))]
9035 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9036 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
9037 [(set_attr "type" "alu")
9038 (set_attr "length_immediate" "0")
9039 (set_attr "mode" "QI")])
9041 (define_insn "*<code>qi_ext_1"
9042 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9047 (match_operand 1 "ext_register_operand" "0")
9051 (match_operand:QI 2 "general_operand" "Qm"))))
9052 (clobber (reg:CC FLAGS_REG))]
9054 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9055 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
9056 [(set_attr "type" "alu")
9057 (set_attr "length_immediate" "0")
9058 (set_attr "mode" "QI")])
9060 (define_insn "*<code>qi_ext_2"
9061 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9065 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9068 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9071 (clobber (reg:CC FLAGS_REG))]
9072 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9073 "<logicprefix>{b}\t{%h2, %h0|%h0, %h2}"
9074 [(set_attr "type" "alu")
9075 (set_attr "length_immediate" "0")
9076 (set_attr "mode" "QI")])
9079 [(set (match_operand 0 "register_operand" "")
9080 (any_or (match_operand 1 "register_operand" "")
9081 (match_operand 2 "const_int_operand" "")))
9082 (clobber (reg:CC FLAGS_REG))]
9084 && QI_REG_P (operands[0])
9085 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9086 && !(INTVAL (operands[2]) & ~(255 << 8))
9087 && GET_MODE (operands[0]) != QImode"
9088 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9089 (any_or:SI (zero_extract:SI (match_dup 1)
9090 (const_int 8) (const_int 8))
9092 (clobber (reg:CC FLAGS_REG))])]
9093 "operands[0] = gen_lowpart (SImode, operands[0]);
9094 operands[1] = gen_lowpart (SImode, operands[1]);
9095 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9097 ;; Since OR can be encoded with sign extended immediate, this is only
9098 ;; profitable when 7th bit is set.
9100 [(set (match_operand 0 "register_operand" "")
9101 (any_or (match_operand 1 "general_operand" "")
9102 (match_operand 2 "const_int_operand" "")))
9103 (clobber (reg:CC FLAGS_REG))]
9105 && ANY_QI_REG_P (operands[0])
9106 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9107 && !(INTVAL (operands[2]) & ~255)
9108 && (INTVAL (operands[2]) & 128)
9109 && GET_MODE (operands[0]) != QImode"
9110 [(parallel [(set (strict_low_part (match_dup 0))
9111 (any_or:QI (match_dup 1)
9113 (clobber (reg:CC FLAGS_REG))])]
9114 "operands[0] = gen_lowpart (QImode, operands[0]);
9115 operands[1] = gen_lowpart (QImode, operands[1]);
9116 operands[2] = gen_lowpart (QImode, operands[2]);")
9118 (define_expand "xorqi_cc_ext_1"
9120 (set (reg:CCNO FLAGS_REG)
9124 (match_operand 1 "ext_register_operand" "")
9127 (match_operand:QI 2 "general_operand" ""))
9129 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9141 (define_insn "*xorqi_cc_ext_1_rex64"
9142 [(set (reg FLAGS_REG)
9146 (match_operand 1 "ext_register_operand" "0")
9149 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9151 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9160 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9161 "xor{b}\t{%2, %h0|%h0, %2}"
9162 [(set_attr "type" "alu")
9163 (set_attr "modrm" "1")
9164 (set_attr "mode" "QI")])
9166 (define_insn "*xorqi_cc_ext_1"
9167 [(set (reg FLAGS_REG)
9171 (match_operand 1 "ext_register_operand" "0")
9174 (match_operand:QI 2 "general_operand" "qmn"))
9176 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9185 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9186 "xor{b}\t{%2, %h0|%h0, %2}"
9187 [(set_attr "type" "alu")
9188 (set_attr "modrm" "1")
9189 (set_attr "mode" "QI")])
9191 ;; Negation instructions
9193 (define_expand "neg<mode>2"
9194 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9195 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9197 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9199 (define_insn_and_split "*neg<dwi>2_doubleword"
9200 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9201 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9202 (clobber (reg:CC FLAGS_REG))]
9203 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9207 [(set (reg:CCZ FLAGS_REG)
9208 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9209 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9212 (plus:DWIH (match_dup 3)
9213 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9215 (clobber (reg:CC FLAGS_REG))])
9218 (neg:DWIH (match_dup 2)))
9219 (clobber (reg:CC FLAGS_REG))])]
9220 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9222 (define_insn "*neg<mode>2_1"
9223 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9224 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9225 (clobber (reg:CC FLAGS_REG))]
9226 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9227 "neg{<imodesuffix>}\t%0"
9228 [(set_attr "type" "negnot")
9229 (set_attr "mode" "<MODE>")])
9231 ;; Combine is quite creative about this pattern.
9232 (define_insn "*negsi2_1_zext"
9233 [(set (match_operand:DI 0 "register_operand" "=r")
9235 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9238 (clobber (reg:CC FLAGS_REG))]
9239 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9241 [(set_attr "type" "negnot")
9242 (set_attr "mode" "SI")])
9244 ;; The problem with neg is that it does not perform (compare x 0),
9245 ;; it really performs (compare 0 x), which leaves us with the zero
9246 ;; flag being the only useful item.
9248 (define_insn "*neg<mode>2_cmpz"
9249 [(set (reg:CCZ FLAGS_REG)
9251 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9253 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9254 (neg:SWI (match_dup 1)))]
9255 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9256 "neg{<imodesuffix>}\t%0"
9257 [(set_attr "type" "negnot")
9258 (set_attr "mode" "<MODE>")])
9260 (define_insn "*negsi2_cmpz_zext"
9261 [(set (reg:CCZ FLAGS_REG)
9265 (match_operand:DI 1 "register_operand" "0")
9269 (set (match_operand:DI 0 "register_operand" "=r")
9270 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9273 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9275 [(set_attr "type" "negnot")
9276 (set_attr "mode" "SI")])
9278 ;; Changing of sign for FP values is doable using integer unit too.
9280 (define_expand "<code><mode>2"
9281 [(set (match_operand:X87MODEF 0 "register_operand" "")
9282 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9283 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9284 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9286 (define_insn "*absneg<mode>2_mixed"
9287 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9288 (match_operator:MODEF 3 "absneg_operator"
9289 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9290 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9291 (clobber (reg:CC FLAGS_REG))]
9292 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9295 (define_insn "*absneg<mode>2_sse"
9296 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9297 (match_operator:MODEF 3 "absneg_operator"
9298 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9299 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9300 (clobber (reg:CC FLAGS_REG))]
9301 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9304 (define_insn "*absneg<mode>2_i387"
9305 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9306 (match_operator:X87MODEF 3 "absneg_operator"
9307 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9308 (use (match_operand 2 "" ""))
9309 (clobber (reg:CC FLAGS_REG))]
9310 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9313 (define_expand "<code>tf2"
9314 [(set (match_operand:TF 0 "register_operand" "")
9315 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9317 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9319 (define_insn "*absnegtf2_sse"
9320 [(set (match_operand:TF 0 "register_operand" "=x,x")
9321 (match_operator:TF 3 "absneg_operator"
9322 [(match_operand:TF 1 "register_operand" "0,x")]))
9323 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9324 (clobber (reg:CC FLAGS_REG))]
9328 ;; Splitters for fp abs and neg.
9331 [(set (match_operand 0 "fp_register_operand" "")
9332 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9333 (use (match_operand 2 "" ""))
9334 (clobber (reg:CC FLAGS_REG))]
9336 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9339 [(set (match_operand 0 "register_operand" "")
9340 (match_operator 3 "absneg_operator"
9341 [(match_operand 1 "register_operand" "")]))
9342 (use (match_operand 2 "nonimmediate_operand" ""))
9343 (clobber (reg:CC FLAGS_REG))]
9344 "reload_completed && SSE_REG_P (operands[0])"
9345 [(set (match_dup 0) (match_dup 3))]
9347 enum machine_mode mode = GET_MODE (operands[0]);
9348 enum machine_mode vmode = GET_MODE (operands[2]);
9351 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9352 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9353 if (operands_match_p (operands[0], operands[2]))
9356 operands[1] = operands[2];
9359 if (GET_CODE (operands[3]) == ABS)
9360 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9362 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9367 [(set (match_operand:SF 0 "register_operand" "")
9368 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9369 (use (match_operand:V4SF 2 "" ""))
9370 (clobber (reg:CC FLAGS_REG))]
9372 [(parallel [(set (match_dup 0) (match_dup 1))
9373 (clobber (reg:CC FLAGS_REG))])]
9376 operands[0] = gen_lowpart (SImode, operands[0]);
9377 if (GET_CODE (operands[1]) == ABS)
9379 tmp = gen_int_mode (0x7fffffff, SImode);
9380 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9384 tmp = gen_int_mode (0x80000000, SImode);
9385 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9391 [(set (match_operand:DF 0 "register_operand" "")
9392 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9393 (use (match_operand 2 "" ""))
9394 (clobber (reg:CC FLAGS_REG))]
9396 [(parallel [(set (match_dup 0) (match_dup 1))
9397 (clobber (reg:CC FLAGS_REG))])]
9402 tmp = gen_lowpart (DImode, operands[0]);
9403 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9406 if (GET_CODE (operands[1]) == ABS)
9409 tmp = gen_rtx_NOT (DImode, tmp);
9413 operands[0] = gen_highpart (SImode, operands[0]);
9414 if (GET_CODE (operands[1]) == ABS)
9416 tmp = gen_int_mode (0x7fffffff, SImode);
9417 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9421 tmp = gen_int_mode (0x80000000, SImode);
9422 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9429 [(set (match_operand:XF 0 "register_operand" "")
9430 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9431 (use (match_operand 2 "" ""))
9432 (clobber (reg:CC FLAGS_REG))]
9434 [(parallel [(set (match_dup 0) (match_dup 1))
9435 (clobber (reg:CC FLAGS_REG))])]
9438 operands[0] = gen_rtx_REG (SImode,
9439 true_regnum (operands[0])
9440 + (TARGET_64BIT ? 1 : 2));
9441 if (GET_CODE (operands[1]) == ABS)
9443 tmp = GEN_INT (0x7fff);
9444 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9448 tmp = GEN_INT (0x8000);
9449 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9454 ;; Conditionalize these after reload. If they match before reload, we
9455 ;; lose the clobber and ability to use integer instructions.
9457 (define_insn "*<code><mode>2_1"
9458 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9459 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9461 && (reload_completed
9462 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9464 [(set_attr "type" "fsgn")
9465 (set_attr "mode" "<MODE>")])
9467 (define_insn "*<code>extendsfdf2"
9468 [(set (match_operand:DF 0 "register_operand" "=f")
9469 (absneg:DF (float_extend:DF
9470 (match_operand:SF 1 "register_operand" "0"))))]
9471 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9473 [(set_attr "type" "fsgn")
9474 (set_attr "mode" "DF")])
9476 (define_insn "*<code>extendsfxf2"
9477 [(set (match_operand:XF 0 "register_operand" "=f")
9478 (absneg:XF (float_extend:XF
9479 (match_operand:SF 1 "register_operand" "0"))))]
9482 [(set_attr "type" "fsgn")
9483 (set_attr "mode" "XF")])
9485 (define_insn "*<code>extenddfxf2"
9486 [(set (match_operand:XF 0 "register_operand" "=f")
9487 (absneg:XF (float_extend:XF
9488 (match_operand:DF 1 "register_operand" "0"))))]
9491 [(set_attr "type" "fsgn")
9492 (set_attr "mode" "XF")])
9494 ;; Copysign instructions
9496 (define_mode_iterator CSGNMODE [SF DF TF])
9497 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9499 (define_expand "copysign<mode>3"
9500 [(match_operand:CSGNMODE 0 "register_operand" "")
9501 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9502 (match_operand:CSGNMODE 2 "register_operand" "")]
9503 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9504 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9506 ix86_expand_copysign (operands);
9510 (define_insn_and_split "copysign<mode>3_const"
9511 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9513 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9514 (match_operand:CSGNMODE 2 "register_operand" "0")
9515 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9517 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9518 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9520 "&& reload_completed"
9523 ix86_split_copysign_const (operands);
9527 (define_insn "copysign<mode>3_var"
9528 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9530 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9531 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9532 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9533 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9535 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9536 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9537 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9541 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9543 [(match_operand:CSGNMODE 2 "register_operand" "")
9544 (match_operand:CSGNMODE 3 "register_operand" "")
9545 (match_operand:<CSGNVMODE> 4 "" "")
9546 (match_operand:<CSGNVMODE> 5 "" "")]
9548 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9549 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9550 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9551 && reload_completed"
9554 ix86_split_copysign_var (operands);
9558 ;; One complement instructions
9560 (define_expand "one_cmpl<mode>2"
9561 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9562 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9564 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9566 (define_insn "*one_cmpl<mode>2_1"
9567 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9568 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9569 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9570 "not{<imodesuffix>}\t%0"
9571 [(set_attr "type" "negnot")
9572 (set_attr "mode" "<MODE>")])
9574 ;; %%% Potential partial reg stall on alternative 1. What to do?
9575 (define_insn "*one_cmplqi2_1"
9576 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9577 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9578 "ix86_unary_operator_ok (NOT, QImode, operands)"
9582 [(set_attr "type" "negnot")
9583 (set_attr "mode" "QI,SI")])
9585 ;; ??? Currently never generated - xor is used instead.
9586 (define_insn "*one_cmplsi2_1_zext"
9587 [(set (match_operand:DI 0 "register_operand" "=r")
9589 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9590 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9592 [(set_attr "type" "negnot")
9593 (set_attr "mode" "SI")])
9595 (define_insn "*one_cmpl<mode>2_2"
9596 [(set (reg FLAGS_REG)
9597 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9599 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9600 (not:SWI (match_dup 1)))]
9601 "ix86_match_ccmode (insn, CCNOmode)
9602 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9604 [(set_attr "type" "alu1")
9605 (set_attr "mode" "<MODE>")])
9608 [(set (match_operand 0 "flags_reg_operand" "")
9609 (match_operator 2 "compare_operator"
9610 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9612 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9613 (not:SWI (match_dup 3)))]
9614 "ix86_match_ccmode (insn, CCNOmode)"
9615 [(parallel [(set (match_dup 0)
9616 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9619 (xor:SWI (match_dup 3) (const_int -1)))])]
9622 ;; ??? Currently never generated - xor is used instead.
9623 (define_insn "*one_cmplsi2_2_zext"
9624 [(set (reg FLAGS_REG)
9625 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9627 (set (match_operand:DI 0 "register_operand" "=r")
9628 (zero_extend:DI (not:SI (match_dup 1))))]
9629 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9630 && ix86_unary_operator_ok (NOT, SImode, operands)"
9632 [(set_attr "type" "alu1")
9633 (set_attr "mode" "SI")])
9636 [(set (match_operand 0 "flags_reg_operand" "")
9637 (match_operator 2 "compare_operator"
9638 [(not:SI (match_operand:SI 3 "register_operand" ""))
9640 (set (match_operand:DI 1 "register_operand" "")
9641 (zero_extend:DI (not:SI (match_dup 3))))]
9642 "ix86_match_ccmode (insn, CCNOmode)"
9643 [(parallel [(set (match_dup 0)
9644 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9647 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9650 ;; Arithmetic shift instructions
9652 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9653 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9654 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9655 ;; from the assembler input.
9657 ;; This instruction shifts the target reg/mem as usual, but instead of
9658 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9659 ;; is a left shift double, bits are taken from the high order bits of
9660 ;; reg, else if the insn is a shift right double, bits are taken from the
9661 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9662 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9664 ;; Since sh[lr]d does not change the `reg' operand, that is done
9665 ;; separately, making all shifts emit pairs of shift double and normal
9666 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9667 ;; support a 63 bit shift, each shift where the count is in a reg expands
9668 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9670 ;; If the shift count is a constant, we need never emit more than one
9671 ;; shift pair, instead using moves and sign extension for counts greater
9674 (define_expand "ashlti3"
9675 [(set (match_operand:TI 0 "register_operand" "")
9676 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
9677 (match_operand:QI 2 "nonmemory_operand" "")))]
9679 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
9681 (define_insn "*ashlti3_1"
9682 [(set (match_operand:TI 0 "register_operand" "=&r,r")
9683 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
9684 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
9685 (clobber (reg:CC FLAGS_REG))]
9688 [(set_attr "type" "multi")])
9691 [(match_scratch:DI 3 "r")
9692 (parallel [(set (match_operand:TI 0 "register_operand" "")
9693 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9694 (match_operand:QI 2 "nonmemory_operand" "")))
9695 (clobber (reg:CC FLAGS_REG))])
9699 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
9702 [(set (match_operand:TI 0 "register_operand" "")
9703 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9704 (match_operand:QI 2 "nonmemory_operand" "")))
9705 (clobber (reg:CC FLAGS_REG))]
9706 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9707 ? epilogue_completed : reload_completed)"
9709 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
9711 (define_insn "x86_64_shld"
9712 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9713 (ior:DI (ashift:DI (match_dup 0)
9714 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9715 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9716 (minus:QI (const_int 64) (match_dup 2)))))
9717 (clobber (reg:CC FLAGS_REG))]
9719 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9720 [(set_attr "type" "ishift")
9721 (set_attr "prefix_0f" "1")
9722 (set_attr "mode" "DI")
9723 (set_attr "athlon_decode" "vector")
9724 (set_attr "amdfam10_decode" "vector")])
9726 (define_expand "x86_64_shift_adj_1"
9727 [(set (reg:CCZ FLAGS_REG)
9728 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9731 (set (match_operand:DI 0 "register_operand" "")
9732 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9733 (match_operand:DI 1 "register_operand" "")
9736 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9737 (match_operand:DI 3 "register_operand" "r")
9742 (define_expand "x86_64_shift_adj_2"
9743 [(use (match_operand:DI 0 "register_operand" ""))
9744 (use (match_operand:DI 1 "register_operand" ""))
9745 (use (match_operand:QI 2 "register_operand" ""))]
9748 rtx label = gen_label_rtx ();
9751 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
9753 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9754 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9755 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9756 gen_rtx_LABEL_REF (VOIDmode, label),
9758 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9759 JUMP_LABEL (tmp) = label;
9761 emit_move_insn (operands[0], operands[1]);
9762 ix86_expand_clear (operands[1]);
9765 LABEL_NUSES (label) = 1;
9770 (define_expand "ashldi3"
9771 [(set (match_operand:DI 0 "shiftdi_operand" "")
9772 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
9773 (match_operand:QI 2 "nonmemory_operand" "")))]
9775 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
9777 (define_insn "*ashldi3_1_rex64"
9778 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9779 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
9780 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
9781 (clobber (reg:CC FLAGS_REG))]
9782 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9784 switch (get_attr_type (insn))
9787 gcc_assert (operands[2] == const1_rtx);
9788 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9789 return "add{q}\t%0, %0";
9792 gcc_assert (CONST_INT_P (operands[2]));
9793 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
9794 operands[1] = gen_rtx_MULT (DImode, operands[1],
9795 GEN_INT (1 << INTVAL (operands[2])));
9796 return "lea{q}\t{%a1, %0|%0, %a1}";
9799 if (REG_P (operands[2]))
9800 return "sal{q}\t{%b2, %0|%0, %b2}";
9801 else if (operands[2] == const1_rtx
9802 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9803 return "sal{q}\t%0";
9805 return "sal{q}\t{%2, %0|%0, %2}";
9809 (cond [(eq_attr "alternative" "1")
9810 (const_string "lea")
9811 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9813 (match_operand 0 "register_operand" ""))
9814 (match_operand 2 "const1_operand" ""))
9815 (const_string "alu")
9817 (const_string "ishift")))
9818 (set (attr "length_immediate")
9820 (ior (eq_attr "type" "alu")
9821 (and (eq_attr "type" "ishift")
9822 (and (match_operand 2 "const1_operand" "")
9823 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9826 (const_string "*")))
9827 (set_attr "mode" "DI")])
9829 ;; Convert lea to the lea pattern to avoid flags dependency.
9831 [(set (match_operand:DI 0 "register_operand" "")
9832 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9833 (match_operand:QI 2 "immediate_operand" "")))
9834 (clobber (reg:CC FLAGS_REG))]
9835 "TARGET_64BIT && reload_completed
9836 && true_regnum (operands[0]) != true_regnum (operands[1])"
9838 (mult:DI (match_dup 1)
9840 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9842 ;; This pattern can't accept a variable shift count, since shifts by
9843 ;; zero don't affect the flags. We assume that shifts by constant
9844 ;; zero are optimized away.
9845 (define_insn "*ashldi3_cmp_rex64"
9846 [(set (reg FLAGS_REG)
9848 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
9849 (match_operand:QI 2 "const_1_to_63_operand" "J"))
9851 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9852 (ashift:DI (match_dup 1) (match_dup 2)))]
9854 && (optimize_function_for_size_p (cfun)
9855 || !TARGET_PARTIAL_FLAG_REG_STALL
9856 || (operands[2] == const1_rtx
9858 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9859 && ix86_match_ccmode (insn, CCGOCmode)
9860 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9862 switch (get_attr_type (insn))
9865 gcc_assert (operands[2] == const1_rtx);
9866 return "add{q}\t%0, %0";
9869 if (REG_P (operands[2]))
9870 return "sal{q}\t{%b2, %0|%0, %b2}";
9871 else if (operands[2] == const1_rtx
9872 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9873 return "sal{q}\t%0";
9875 return "sal{q}\t{%2, %0|%0, %2}";
9879 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9881 (match_operand 0 "register_operand" ""))
9882 (match_operand 2 "const1_operand" ""))
9883 (const_string "alu")
9885 (const_string "ishift")))
9886 (set (attr "length_immediate")
9888 (ior (eq_attr "type" "alu")
9889 (and (eq_attr "type" "ishift")
9890 (and (match_operand 2 "const1_operand" "")
9891 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9894 (const_string "*")))
9895 (set_attr "mode" "DI")])
9897 (define_insn "*ashldi3_cconly_rex64"
9898 [(set (reg FLAGS_REG)
9900 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
9901 (match_operand:QI 2 "const_1_to_63_operand" "J"))
9903 (clobber (match_scratch:DI 0 "=r"))]
9905 && (optimize_function_for_size_p (cfun)
9906 || !TARGET_PARTIAL_FLAG_REG_STALL
9907 || (operands[2] == const1_rtx
9909 || TARGET_DOUBLE_WITH_ADD)))
9910 && ix86_match_ccmode (insn, CCGOCmode)
9911 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9913 switch (get_attr_type (insn))
9916 gcc_assert (operands[2] == const1_rtx);
9917 return "add{q}\t%0, %0";
9920 if (REG_P (operands[2]))
9921 return "sal{q}\t{%b2, %0|%0, %b2}";
9922 else if (operands[2] == const1_rtx
9923 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9924 return "sal{q}\t%0";
9926 return "sal{q}\t{%2, %0|%0, %2}";
9930 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9932 (match_operand 0 "register_operand" ""))
9933 (match_operand 2 "const1_operand" ""))
9934 (const_string "alu")
9936 (const_string "ishift")))
9937 (set (attr "length_immediate")
9939 (ior (eq_attr "type" "alu")
9940 (and (eq_attr "type" "ishift")
9941 (and (match_operand 2 "const1_operand" "")
9942 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9945 (const_string "*")))
9946 (set_attr "mode" "DI")])
9948 (define_insn "*ashldi3_1"
9949 [(set (match_operand:DI 0 "register_operand" "=&r,r")
9950 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
9951 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
9952 (clobber (reg:CC FLAGS_REG))]
9955 [(set_attr "type" "multi")])
9957 ;; By default we don't ask for a scratch register, because when DImode
9958 ;; values are manipulated, registers are already at a premium. But if
9959 ;; we have one handy, we won't turn it away.
9961 [(match_scratch:SI 3 "r")
9962 (parallel [(set (match_operand:DI 0 "register_operand" "")
9963 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
9964 (match_operand:QI 2 "nonmemory_operand" "")))
9965 (clobber (reg:CC FLAGS_REG))])
9967 "!TARGET_64BIT && TARGET_CMOVE"
9969 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
9972 [(set (match_operand:DI 0 "register_operand" "")
9973 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
9974 (match_operand:QI 2 "nonmemory_operand" "")))
9975 (clobber (reg:CC FLAGS_REG))]
9976 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9977 ? epilogue_completed : reload_completed)"
9979 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
9981 (define_insn "x86_shld"
9982 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9983 (ior:SI (ashift:SI (match_dup 0)
9984 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9985 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9986 (minus:QI (const_int 32) (match_dup 2)))))
9987 (clobber (reg:CC FLAGS_REG))]
9989 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9990 [(set_attr "type" "ishift")
9991 (set_attr "prefix_0f" "1")
9992 (set_attr "mode" "SI")
9993 (set_attr "pent_pair" "np")
9994 (set_attr "athlon_decode" "vector")
9995 (set_attr "amdfam10_decode" "vector")])
9997 (define_expand "x86_shift_adj_1"
9998 [(set (reg:CCZ FLAGS_REG)
9999 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10002 (set (match_operand:SI 0 "register_operand" "")
10003 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10004 (match_operand:SI 1 "register_operand" "")
10007 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10008 (match_operand:SI 3 "register_operand" "r")
10013 (define_expand "x86_shift_adj_2"
10014 [(use (match_operand:SI 0 "register_operand" ""))
10015 (use (match_operand:SI 1 "register_operand" ""))
10016 (use (match_operand:QI 2 "register_operand" ""))]
10019 rtx label = gen_label_rtx ();
10022 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10024 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10025 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10026 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10027 gen_rtx_LABEL_REF (VOIDmode, label),
10029 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10030 JUMP_LABEL (tmp) = label;
10032 emit_move_insn (operands[0], operands[1]);
10033 ix86_expand_clear (operands[1]);
10035 emit_label (label);
10036 LABEL_NUSES (label) = 1;
10041 (define_expand "ashlsi3"
10042 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10043 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10044 (match_operand:QI 2 "nonmemory_operand" "")))]
10046 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10048 (define_insn "*ashlsi3_1"
10049 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10050 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10051 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10052 (clobber (reg:CC FLAGS_REG))]
10053 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10055 switch (get_attr_type (insn))
10058 gcc_assert (operands[2] == const1_rtx);
10059 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10060 return "add{l}\t%0, %0";
10066 if (REG_P (operands[2]))
10067 return "sal{l}\t{%b2, %0|%0, %b2}";
10068 else if (operands[2] == const1_rtx
10069 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10070 return "sal{l}\t%0";
10072 return "sal{l}\t{%2, %0|%0, %2}";
10075 [(set (attr "type")
10076 (cond [(eq_attr "alternative" "1")
10077 (const_string "lea")
10078 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10080 (match_operand 0 "register_operand" ""))
10081 (match_operand 2 "const1_operand" ""))
10082 (const_string "alu")
10084 (const_string "ishift")))
10085 (set (attr "length_immediate")
10087 (ior (eq_attr "type" "alu")
10088 (and (eq_attr "type" "ishift")
10089 (and (match_operand 2 "const1_operand" "")
10090 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10093 (const_string "*")))
10094 (set_attr "mode" "SI")])
10096 ;; Convert lea to the lea pattern to avoid flags dependency.
10098 [(set (match_operand 0 "register_operand" "")
10099 (ashift (match_operand 1 "index_register_operand" "")
10100 (match_operand:QI 2 "const_int_operand" "")))
10101 (clobber (reg:CC FLAGS_REG))]
10103 && true_regnum (operands[0]) != true_regnum (operands[1])
10104 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10108 enum machine_mode mode = GET_MODE (operands[0]);
10110 if (GET_MODE_SIZE (mode) < 4)
10111 operands[0] = gen_lowpart (SImode, operands[0]);
10113 operands[1] = gen_lowpart (Pmode, operands[1]);
10114 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10116 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10117 if (Pmode != SImode)
10118 pat = gen_rtx_SUBREG (SImode, pat, 0);
10119 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10123 ;; Rare case of shifting RSP is handled by generating move and shift
10125 [(set (match_operand 0 "register_operand" "")
10126 (ashift (match_operand 1 "register_operand" "")
10127 (match_operand:QI 2 "const_int_operand" "")))
10128 (clobber (reg:CC FLAGS_REG))]
10130 && true_regnum (operands[0]) != true_regnum (operands[1])"
10134 emit_move_insn (operands[0], operands[1]);
10135 pat = gen_rtx_SET (VOIDmode, operands[0],
10136 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10137 operands[0], operands[2]));
10138 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10139 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10143 (define_insn "*ashlsi3_1_zext"
10144 [(set (match_operand:DI 0 "register_operand" "=r,r")
10145 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10146 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10147 (clobber (reg:CC FLAGS_REG))]
10148 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10150 switch (get_attr_type (insn))
10153 gcc_assert (operands[2] == const1_rtx);
10154 return "add{l}\t%k0, %k0";
10160 if (REG_P (operands[2]))
10161 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10162 else if (operands[2] == const1_rtx
10163 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10164 return "sal{l}\t%k0";
10166 return "sal{l}\t{%2, %k0|%k0, %2}";
10169 [(set (attr "type")
10170 (cond [(eq_attr "alternative" "1")
10171 (const_string "lea")
10172 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10174 (match_operand 2 "const1_operand" ""))
10175 (const_string "alu")
10177 (const_string "ishift")))
10178 (set (attr "length_immediate")
10180 (ior (eq_attr "type" "alu")
10181 (and (eq_attr "type" "ishift")
10182 (and (match_operand 2 "const1_operand" "")
10183 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10186 (const_string "*")))
10187 (set_attr "mode" "SI")])
10189 ;; Convert lea to the lea pattern to avoid flags dependency.
10191 [(set (match_operand:DI 0 "register_operand" "")
10192 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10193 (match_operand:QI 2 "const_int_operand" ""))))
10194 (clobber (reg:CC FLAGS_REG))]
10195 "TARGET_64BIT && reload_completed
10196 && true_regnum (operands[0]) != true_regnum (operands[1])"
10197 [(set (match_dup 0) (zero_extend:DI
10198 (subreg:SI (mult:SI (match_dup 1)
10199 (match_dup 2)) 0)))]
10201 operands[1] = gen_lowpart (Pmode, operands[1]);
10202 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10205 ;; This pattern can't accept a variable shift count, since shifts by
10206 ;; zero don't affect the flags. We assume that shifts by constant
10207 ;; zero are optimized away.
10208 (define_insn "*ashlsi3_cmp"
10209 [(set (reg FLAGS_REG)
10211 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10212 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10214 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10215 (ashift:SI (match_dup 1) (match_dup 2)))]
10216 "(optimize_function_for_size_p (cfun)
10217 || !TARGET_PARTIAL_FLAG_REG_STALL
10218 || (operands[2] == const1_rtx
10220 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10221 && ix86_match_ccmode (insn, CCGOCmode)
10222 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10224 switch (get_attr_type (insn))
10227 gcc_assert (operands[2] == const1_rtx);
10228 return "add{l}\t%0, %0";
10231 if (REG_P (operands[2]))
10232 return "sal{l}\t{%b2, %0|%0, %b2}";
10233 else if (operands[2] == const1_rtx
10234 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10235 return "sal{l}\t%0";
10237 return "sal{l}\t{%2, %0|%0, %2}";
10240 [(set (attr "type")
10241 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10243 (match_operand 0 "register_operand" ""))
10244 (match_operand 2 "const1_operand" ""))
10245 (const_string "alu")
10247 (const_string "ishift")))
10248 (set (attr "length_immediate")
10250 (ior (eq_attr "type" "alu")
10251 (and (eq_attr "type" "ishift")
10252 (and (match_operand 2 "const1_operand" "")
10253 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10256 (const_string "*")))
10257 (set_attr "mode" "SI")])
10259 (define_insn "*ashlsi3_cconly"
10260 [(set (reg FLAGS_REG)
10262 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10263 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10265 (clobber (match_scratch:SI 0 "=r"))]
10266 "(optimize_function_for_size_p (cfun)
10267 || !TARGET_PARTIAL_FLAG_REG_STALL
10268 || (operands[2] == const1_rtx
10270 || TARGET_DOUBLE_WITH_ADD)))
10271 && ix86_match_ccmode (insn, CCGOCmode)
10272 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10274 switch (get_attr_type (insn))
10277 gcc_assert (operands[2] == const1_rtx);
10278 return "add{l}\t%0, %0";
10281 if (REG_P (operands[2]))
10282 return "sal{l}\t{%b2, %0|%0, %b2}";
10283 else if (operands[2] == const1_rtx
10284 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10285 return "sal{l}\t%0";
10287 return "sal{l}\t{%2, %0|%0, %2}";
10290 [(set (attr "type")
10291 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10293 (match_operand 0 "register_operand" ""))
10294 (match_operand 2 "const1_operand" ""))
10295 (const_string "alu")
10297 (const_string "ishift")))
10298 (set (attr "length_immediate")
10300 (ior (eq_attr "type" "alu")
10301 (and (eq_attr "type" "ishift")
10302 (and (match_operand 2 "const1_operand" "")
10303 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10306 (const_string "*")))
10307 (set_attr "mode" "SI")])
10309 (define_insn "*ashlsi3_cmp_zext"
10310 [(set (reg FLAGS_REG)
10312 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10313 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10315 (set (match_operand:DI 0 "register_operand" "=r")
10316 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10318 && (optimize_function_for_size_p (cfun)
10319 || !TARGET_PARTIAL_FLAG_REG_STALL
10320 || (operands[2] == const1_rtx
10322 || TARGET_DOUBLE_WITH_ADD)))
10323 && ix86_match_ccmode (insn, CCGOCmode)
10324 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10326 switch (get_attr_type (insn))
10329 gcc_assert (operands[2] == const1_rtx);
10330 return "add{l}\t%k0, %k0";
10333 if (REG_P (operands[2]))
10334 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10335 else if (operands[2] == const1_rtx
10336 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10337 return "sal{l}\t%k0";
10339 return "sal{l}\t{%2, %k0|%k0, %2}";
10342 [(set (attr "type")
10343 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10345 (match_operand 2 "const1_operand" ""))
10346 (const_string "alu")
10348 (const_string "ishift")))
10349 (set (attr "length_immediate")
10351 (ior (eq_attr "type" "alu")
10352 (and (eq_attr "type" "ishift")
10353 (and (match_operand 2 "const1_operand" "")
10354 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10357 (const_string "*")))
10358 (set_attr "mode" "SI")])
10360 (define_expand "ashlhi3"
10361 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10362 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10363 (match_operand:QI 2 "nonmemory_operand" "")))]
10364 "TARGET_HIMODE_MATH"
10365 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10367 (define_insn "*ashlhi3_1_lea"
10368 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10369 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10370 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10371 (clobber (reg:CC FLAGS_REG))]
10372 "!TARGET_PARTIAL_REG_STALL
10373 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10375 switch (get_attr_type (insn))
10380 gcc_assert (operands[2] == const1_rtx);
10381 return "add{w}\t%0, %0";
10384 if (REG_P (operands[2]))
10385 return "sal{w}\t{%b2, %0|%0, %b2}";
10386 else if (operands[2] == const1_rtx
10387 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10388 return "sal{w}\t%0";
10390 return "sal{w}\t{%2, %0|%0, %2}";
10393 [(set (attr "type")
10394 (cond [(eq_attr "alternative" "1")
10395 (const_string "lea")
10396 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10398 (match_operand 0 "register_operand" ""))
10399 (match_operand 2 "const1_operand" ""))
10400 (const_string "alu")
10402 (const_string "ishift")))
10403 (set (attr "length_immediate")
10405 (ior (eq_attr "type" "alu")
10406 (and (eq_attr "type" "ishift")
10407 (and (match_operand 2 "const1_operand" "")
10408 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10411 (const_string "*")))
10412 (set_attr "mode" "HI,SI")])
10414 (define_insn "*ashlhi3_1"
10415 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10416 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10417 (match_operand:QI 2 "nonmemory_operand" "cI")))
10418 (clobber (reg:CC FLAGS_REG))]
10419 "TARGET_PARTIAL_REG_STALL
10420 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10422 switch (get_attr_type (insn))
10425 gcc_assert (operands[2] == const1_rtx);
10426 return "add{w}\t%0, %0";
10429 if (REG_P (operands[2]))
10430 return "sal{w}\t{%b2, %0|%0, %b2}";
10431 else if (operands[2] == const1_rtx
10432 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10433 return "sal{w}\t%0";
10435 return "sal{w}\t{%2, %0|%0, %2}";
10438 [(set (attr "type")
10439 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10441 (match_operand 0 "register_operand" ""))
10442 (match_operand 2 "const1_operand" ""))
10443 (const_string "alu")
10445 (const_string "ishift")))
10446 (set (attr "length_immediate")
10448 (ior (eq_attr "type" "alu")
10449 (and (eq_attr "type" "ishift")
10450 (and (match_operand 2 "const1_operand" "")
10451 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10454 (const_string "*")))
10455 (set_attr "mode" "HI")])
10457 ;; This pattern can't accept a variable shift count, since shifts by
10458 ;; zero don't affect the flags. We assume that shifts by constant
10459 ;; zero are optimized away.
10460 (define_insn "*ashlhi3_cmp"
10461 [(set (reg FLAGS_REG)
10463 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10464 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10466 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10467 (ashift:HI (match_dup 1) (match_dup 2)))]
10468 "(optimize_function_for_size_p (cfun)
10469 || !TARGET_PARTIAL_FLAG_REG_STALL
10470 || (operands[2] == const1_rtx
10472 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10473 && ix86_match_ccmode (insn, CCGOCmode)
10474 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10476 switch (get_attr_type (insn))
10479 gcc_assert (operands[2] == const1_rtx);
10480 return "add{w}\t%0, %0";
10483 if (REG_P (operands[2]))
10484 return "sal{w}\t{%b2, %0|%0, %b2}";
10485 else if (operands[2] == const1_rtx
10486 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10487 return "sal{w}\t%0";
10489 return "sal{w}\t{%2, %0|%0, %2}";
10492 [(set (attr "type")
10493 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10495 (match_operand 0 "register_operand" ""))
10496 (match_operand 2 "const1_operand" ""))
10497 (const_string "alu")
10499 (const_string "ishift")))
10500 (set (attr "length_immediate")
10502 (ior (eq_attr "type" "alu")
10503 (and (eq_attr "type" "ishift")
10504 (and (match_operand 2 "const1_operand" "")
10505 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10508 (const_string "*")))
10509 (set_attr "mode" "HI")])
10511 (define_insn "*ashlhi3_cconly"
10512 [(set (reg FLAGS_REG)
10514 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10515 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10517 (clobber (match_scratch:HI 0 "=r"))]
10518 "(optimize_function_for_size_p (cfun)
10519 || !TARGET_PARTIAL_FLAG_REG_STALL
10520 || (operands[2] == const1_rtx
10522 || TARGET_DOUBLE_WITH_ADD)))
10523 && ix86_match_ccmode (insn, CCGOCmode)
10524 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10526 switch (get_attr_type (insn))
10529 gcc_assert (operands[2] == const1_rtx);
10530 return "add{w}\t%0, %0";
10533 if (REG_P (operands[2]))
10534 return "sal{w}\t{%b2, %0|%0, %b2}";
10535 else if (operands[2] == const1_rtx
10536 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10537 return "sal{w}\t%0";
10539 return "sal{w}\t{%2, %0|%0, %2}";
10542 [(set (attr "type")
10543 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10545 (match_operand 0 "register_operand" ""))
10546 (match_operand 2 "const1_operand" ""))
10547 (const_string "alu")
10549 (const_string "ishift")))
10550 (set (attr "length_immediate")
10552 (ior (eq_attr "type" "alu")
10553 (and (eq_attr "type" "ishift")
10554 (and (match_operand 2 "const1_operand" "")
10555 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10558 (const_string "*")))
10559 (set_attr "mode" "HI")])
10561 (define_expand "ashlqi3"
10562 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10563 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10564 (match_operand:QI 2 "nonmemory_operand" "")))]
10565 "TARGET_QIMODE_MATH"
10566 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10568 ;; %%% Potential partial reg stall on alternative 2. What to do?
10570 (define_insn "*ashlqi3_1_lea"
10571 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10572 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10573 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10574 (clobber (reg:CC FLAGS_REG))]
10575 "!TARGET_PARTIAL_REG_STALL
10576 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10578 switch (get_attr_type (insn))
10583 gcc_assert (operands[2] == const1_rtx);
10584 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10585 return "add{l}\t%k0, %k0";
10587 return "add{b}\t%0, %0";
10590 if (REG_P (operands[2]))
10592 if (get_attr_mode (insn) == MODE_SI)
10593 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10595 return "sal{b}\t{%b2, %0|%0, %b2}";
10597 else if (operands[2] == const1_rtx
10598 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10600 if (get_attr_mode (insn) == MODE_SI)
10601 return "sal{l}\t%0";
10603 return "sal{b}\t%0";
10607 if (get_attr_mode (insn) == MODE_SI)
10608 return "sal{l}\t{%2, %k0|%k0, %2}";
10610 return "sal{b}\t{%2, %0|%0, %2}";
10614 [(set (attr "type")
10615 (cond [(eq_attr "alternative" "2")
10616 (const_string "lea")
10617 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10619 (match_operand 0 "register_operand" ""))
10620 (match_operand 2 "const1_operand" ""))
10621 (const_string "alu")
10623 (const_string "ishift")))
10624 (set (attr "length_immediate")
10626 (ior (eq_attr "type" "alu")
10627 (and (eq_attr "type" "ishift")
10628 (and (match_operand 2 "const1_operand" "")
10629 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10632 (const_string "*")))
10633 (set_attr "mode" "QI,SI,SI")])
10635 (define_insn "*ashlqi3_1"
10636 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10637 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10638 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10639 (clobber (reg:CC FLAGS_REG))]
10640 "TARGET_PARTIAL_REG_STALL
10641 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10643 switch (get_attr_type (insn))
10646 gcc_assert (operands[2] == const1_rtx);
10647 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10648 return "add{l}\t%k0, %k0";
10650 return "add{b}\t%0, %0";
10653 if (REG_P (operands[2]))
10655 if (get_attr_mode (insn) == MODE_SI)
10656 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10658 return "sal{b}\t{%b2, %0|%0, %b2}";
10660 else if (operands[2] == const1_rtx
10661 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10663 if (get_attr_mode (insn) == MODE_SI)
10664 return "sal{l}\t%0";
10666 return "sal{b}\t%0";
10670 if (get_attr_mode (insn) == MODE_SI)
10671 return "sal{l}\t{%2, %k0|%k0, %2}";
10673 return "sal{b}\t{%2, %0|%0, %2}";
10677 [(set (attr "type")
10678 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10680 (match_operand 0 "register_operand" ""))
10681 (match_operand 2 "const1_operand" ""))
10682 (const_string "alu")
10684 (const_string "ishift")))
10685 (set (attr "length_immediate")
10687 (ior (eq_attr "type" "alu")
10688 (and (eq_attr "type" "ishift")
10689 (and (match_operand 2 "const1_operand" "")
10690 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10693 (const_string "*")))
10694 (set_attr "mode" "QI,SI")])
10696 ;; This pattern can't accept a variable shift count, since shifts by
10697 ;; zero don't affect the flags. We assume that shifts by constant
10698 ;; zero are optimized away.
10699 (define_insn "*ashlqi3_cmp"
10700 [(set (reg FLAGS_REG)
10702 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10703 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10705 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10706 (ashift:QI (match_dup 1) (match_dup 2)))]
10707 "(optimize_function_for_size_p (cfun)
10708 || !TARGET_PARTIAL_FLAG_REG_STALL
10709 || (operands[2] == const1_rtx
10711 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10712 && ix86_match_ccmode (insn, CCGOCmode)
10713 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10715 switch (get_attr_type (insn))
10718 gcc_assert (operands[2] == const1_rtx);
10719 return "add{b}\t%0, %0";
10722 if (REG_P (operands[2]))
10723 return "sal{b}\t{%b2, %0|%0, %b2}";
10724 else if (operands[2] == const1_rtx
10725 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10726 return "sal{b}\t%0";
10728 return "sal{b}\t{%2, %0|%0, %2}";
10731 [(set (attr "type")
10732 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10734 (match_operand 0 "register_operand" ""))
10735 (match_operand 2 "const1_operand" ""))
10736 (const_string "alu")
10738 (const_string "ishift")))
10739 (set (attr "length_immediate")
10741 (ior (eq_attr "type" "alu")
10742 (and (eq_attr "type" "ishift")
10743 (and (match_operand 2 "const1_operand" "")
10744 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10747 (const_string "*")))
10748 (set_attr "mode" "QI")])
10750 (define_insn "*ashlqi3_cconly"
10751 [(set (reg FLAGS_REG)
10753 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10754 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10756 (clobber (match_scratch:QI 0 "=q"))]
10757 "(optimize_function_for_size_p (cfun)
10758 || !TARGET_PARTIAL_FLAG_REG_STALL
10759 || (operands[2] == const1_rtx
10761 || TARGET_DOUBLE_WITH_ADD)))
10762 && ix86_match_ccmode (insn, CCGOCmode)
10763 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10765 switch (get_attr_type (insn))
10768 gcc_assert (operands[2] == const1_rtx);
10769 return "add{b}\t%0, %0";
10772 if (REG_P (operands[2]))
10773 return "sal{b}\t{%b2, %0|%0, %b2}";
10774 else if (operands[2] == const1_rtx
10775 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10776 return "sal{b}\t%0";
10778 return "sal{b}\t{%2, %0|%0, %2}";
10781 [(set (attr "type")
10782 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10784 (match_operand 0 "register_operand" ""))
10785 (match_operand 2 "const1_operand" ""))
10786 (const_string "alu")
10788 (const_string "ishift")))
10789 (set (attr "length_immediate")
10791 (ior (eq_attr "type" "alu")
10792 (and (eq_attr "type" "ishift")
10793 (and (match_operand 2 "const1_operand" "")
10794 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10797 (const_string "*")))
10798 (set_attr "mode" "QI")])
10800 ;; See comment above `ashldi3' about how this works.
10802 (define_expand "ashrti3"
10803 [(set (match_operand:TI 0 "register_operand" "")
10804 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10805 (match_operand:QI 2 "nonmemory_operand" "")))]
10807 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
10809 (define_insn "*ashrti3_1"
10810 [(set (match_operand:TI 0 "register_operand" "=r")
10811 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
10812 (match_operand:QI 2 "nonmemory_operand" "Oc")))
10813 (clobber (reg:CC FLAGS_REG))]
10816 [(set_attr "type" "multi")])
10819 [(match_scratch:DI 3 "r")
10820 (parallel [(set (match_operand:TI 0 "register_operand" "")
10821 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10822 (match_operand:QI 2 "nonmemory_operand" "")))
10823 (clobber (reg:CC FLAGS_REG))])
10827 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
10830 [(set (match_operand:TI 0 "register_operand" "")
10831 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10832 (match_operand:QI 2 "nonmemory_operand" "")))
10833 (clobber (reg:CC FLAGS_REG))]
10834 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10835 ? epilogue_completed : reload_completed)"
10837 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
10839 (define_insn "x86_64_shrd"
10840 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10841 (ior:DI (ashiftrt:DI (match_dup 0)
10842 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10843 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10844 (minus:QI (const_int 64) (match_dup 2)))))
10845 (clobber (reg:CC FLAGS_REG))]
10847 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10848 [(set_attr "type" "ishift")
10849 (set_attr "prefix_0f" "1")
10850 (set_attr "mode" "DI")
10851 (set_attr "athlon_decode" "vector")
10852 (set_attr "amdfam10_decode" "vector")])
10854 (define_expand "ashrdi3"
10855 [(set (match_operand:DI 0 "shiftdi_operand" "")
10856 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10857 (match_operand:QI 2 "nonmemory_operand" "")))]
10859 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10861 (define_expand "x86_64_shift_adj_3"
10862 [(use (match_operand:DI 0 "register_operand" ""))
10863 (use (match_operand:DI 1 "register_operand" ""))
10864 (use (match_operand:QI 2 "register_operand" ""))]
10867 rtx label = gen_label_rtx ();
10870 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10872 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10873 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10874 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10875 gen_rtx_LABEL_REF (VOIDmode, label),
10877 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10878 JUMP_LABEL (tmp) = label;
10880 emit_move_insn (operands[0], operands[1]);
10881 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
10883 emit_label (label);
10884 LABEL_NUSES (label) = 1;
10889 (define_insn "ashrdi3_63_rex64"
10890 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10891 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10892 (match_operand:DI 2 "const_int_operand" "i,i")))
10893 (clobber (reg:CC FLAGS_REG))]
10894 "TARGET_64BIT && INTVAL (operands[2]) == 63
10895 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10896 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10899 sar{q}\t{%2, %0|%0, %2}"
10900 [(set_attr "type" "imovx,ishift")
10901 (set_attr "prefix_0f" "0,*")
10902 (set_attr "length_immediate" "0,*")
10903 (set_attr "modrm" "0,1")
10904 (set_attr "mode" "DI")])
10906 (define_insn "*ashrdi3_1_one_bit_rex64"
10907 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10908 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10909 (match_operand:QI 2 "const1_operand" "")))
10910 (clobber (reg:CC FLAGS_REG))]
10912 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10913 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10915 [(set_attr "type" "ishift")
10916 (set_attr "length_immediate" "0")
10917 (set_attr "mode" "DI")])
10919 (define_insn "*ashrdi3_1_rex64"
10920 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10921 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10922 (match_operand:QI 2 "nonmemory_operand" "J,c")))
10923 (clobber (reg:CC FLAGS_REG))]
10924 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10926 sar{q}\t{%2, %0|%0, %2}
10927 sar{q}\t{%b2, %0|%0, %b2}"
10928 [(set_attr "type" "ishift")
10929 (set_attr "mode" "DI")])
10931 ;; This pattern can't accept a variable shift count, since shifts by
10932 ;; zero don't affect the flags. We assume that shifts by constant
10933 ;; zero are optimized away.
10934 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10935 [(set (reg FLAGS_REG)
10937 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10938 (match_operand:QI 2 "const1_operand" ""))
10940 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10941 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10943 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10944 && ix86_match_ccmode (insn, CCGOCmode)
10945 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10947 [(set_attr "type" "ishift")
10948 (set_attr "length_immediate" "0")
10949 (set_attr "mode" "DI")])
10951 (define_insn "*ashrdi3_one_bit_cconly_rex64"
10952 [(set (reg FLAGS_REG)
10954 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10955 (match_operand:QI 2 "const1_operand" ""))
10957 (clobber (match_scratch:DI 0 "=r"))]
10959 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10960 && ix86_match_ccmode (insn, CCGOCmode)
10961 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10963 [(set_attr "type" "ishift")
10964 (set_attr "length_immediate" "0")
10965 (set_attr "mode" "DI")])
10967 ;; This pattern can't accept a variable shift count, since shifts by
10968 ;; zero don't affect the flags. We assume that shifts by constant
10969 ;; zero are optimized away.
10970 (define_insn "*ashrdi3_cmp_rex64"
10971 [(set (reg FLAGS_REG)
10973 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10974 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10976 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10977 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10979 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10980 && ix86_match_ccmode (insn, CCGOCmode)
10981 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10982 "sar{q}\t{%2, %0|%0, %2}"
10983 [(set_attr "type" "ishift")
10984 (set_attr "mode" "DI")])
10986 (define_insn "*ashrdi3_cconly_rex64"
10987 [(set (reg FLAGS_REG)
10989 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10990 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10992 (clobber (match_scratch:DI 0 "=r"))]
10994 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10995 && ix86_match_ccmode (insn, CCGOCmode)
10996 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10997 "sar{q}\t{%2, %0|%0, %2}"
10998 [(set_attr "type" "ishift")
10999 (set_attr "mode" "DI")])
11001 (define_insn "*ashrdi3_1"
11002 [(set (match_operand:DI 0 "register_operand" "=r")
11003 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11004 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11005 (clobber (reg:CC FLAGS_REG))]
11008 [(set_attr "type" "multi")])
11010 ;; By default we don't ask for a scratch register, because when DImode
11011 ;; values are manipulated, registers are already at a premium. But if
11012 ;; we have one handy, we won't turn it away.
11014 [(match_scratch:SI 3 "r")
11015 (parallel [(set (match_operand:DI 0 "register_operand" "")
11016 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11017 (match_operand:QI 2 "nonmemory_operand" "")))
11018 (clobber (reg:CC FLAGS_REG))])
11020 "!TARGET_64BIT && TARGET_CMOVE"
11022 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11025 [(set (match_operand:DI 0 "register_operand" "")
11026 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11027 (match_operand:QI 2 "nonmemory_operand" "")))
11028 (clobber (reg:CC FLAGS_REG))]
11029 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11030 ? epilogue_completed : reload_completed)"
11032 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11034 (define_insn "x86_shrd"
11035 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11036 (ior:SI (ashiftrt:SI (match_dup 0)
11037 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11038 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11039 (minus:QI (const_int 32) (match_dup 2)))))
11040 (clobber (reg:CC FLAGS_REG))]
11042 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11043 [(set_attr "type" "ishift")
11044 (set_attr "prefix_0f" "1")
11045 (set_attr "pent_pair" "np")
11046 (set_attr "mode" "SI")])
11048 (define_expand "x86_shift_adj_3"
11049 [(use (match_operand:SI 0 "register_operand" ""))
11050 (use (match_operand:SI 1 "register_operand" ""))
11051 (use (match_operand:QI 2 "register_operand" ""))]
11054 rtx label = gen_label_rtx ();
11057 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11059 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11060 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11061 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11062 gen_rtx_LABEL_REF (VOIDmode, label),
11064 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11065 JUMP_LABEL (tmp) = label;
11067 emit_move_insn (operands[0], operands[1]);
11068 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11070 emit_label (label);
11071 LABEL_NUSES (label) = 1;
11076 (define_expand "ashrsi3_31"
11077 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11078 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11079 (match_operand:SI 2 "const_int_operand" "i,i")))
11080 (clobber (reg:CC FLAGS_REG))])]
11083 (define_insn "*ashrsi3_31"
11084 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11085 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11086 (match_operand:SI 2 "const_int_operand" "i,i")))
11087 (clobber (reg:CC FLAGS_REG))]
11088 "INTVAL (operands[2]) == 31
11089 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11090 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11093 sar{l}\t{%2, %0|%0, %2}"
11094 [(set_attr "type" "imovx,ishift")
11095 (set_attr "prefix_0f" "0,*")
11096 (set_attr "length_immediate" "0,*")
11097 (set_attr "modrm" "0,1")
11098 (set_attr "mode" "SI")])
11100 (define_insn "*ashrsi3_31_zext"
11101 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11102 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11103 (match_operand:SI 2 "const_int_operand" "i,i"))))
11104 (clobber (reg:CC FLAGS_REG))]
11105 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11106 && INTVAL (operands[2]) == 31
11107 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11110 sar{l}\t{%2, %k0|%k0, %2}"
11111 [(set_attr "type" "imovx,ishift")
11112 (set_attr "prefix_0f" "0,*")
11113 (set_attr "length_immediate" "0,*")
11114 (set_attr "modrm" "0,1")
11115 (set_attr "mode" "SI")])
11117 (define_expand "ashrsi3"
11118 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11119 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11120 (match_operand:QI 2 "nonmemory_operand" "")))]
11122 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11124 (define_insn "*ashrsi3_1_one_bit"
11125 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11126 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11127 (match_operand:QI 2 "const1_operand" "")))
11128 (clobber (reg:CC FLAGS_REG))]
11129 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11130 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11132 [(set_attr "type" "ishift")
11133 (set_attr "length_immediate" "0")
11134 (set_attr "mode" "SI")])
11136 (define_insn "*ashrsi3_1_one_bit_zext"
11137 [(set (match_operand:DI 0 "register_operand" "=r")
11138 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11139 (match_operand:QI 2 "const1_operand" ""))))
11140 (clobber (reg:CC FLAGS_REG))]
11142 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11143 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11145 [(set_attr "type" "ishift")
11146 (set_attr "length_immediate" "0")
11147 (set_attr "mode" "SI")])
11149 (define_insn "*ashrsi3_1"
11150 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11151 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11152 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11153 (clobber (reg:CC FLAGS_REG))]
11154 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11156 sar{l}\t{%2, %0|%0, %2}
11157 sar{l}\t{%b2, %0|%0, %b2}"
11158 [(set_attr "type" "ishift")
11159 (set_attr "mode" "SI")])
11161 (define_insn "*ashrsi3_1_zext"
11162 [(set (match_operand:DI 0 "register_operand" "=r,r")
11163 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11164 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11165 (clobber (reg:CC FLAGS_REG))]
11166 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11168 sar{l}\t{%2, %k0|%k0, %2}
11169 sar{l}\t{%b2, %k0|%k0, %b2}"
11170 [(set_attr "type" "ishift")
11171 (set_attr "mode" "SI")])
11173 ;; This pattern can't accept a variable shift count, since shifts by
11174 ;; zero don't affect the flags. We assume that shifts by constant
11175 ;; zero are optimized away.
11176 (define_insn "*ashrsi3_one_bit_cmp"
11177 [(set (reg FLAGS_REG)
11179 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11180 (match_operand:QI 2 "const1_operand" ""))
11182 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11183 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11184 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11185 && ix86_match_ccmode (insn, CCGOCmode)
11186 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11188 [(set_attr "type" "ishift")
11189 (set_attr "length_immediate" "0")
11190 (set_attr "mode" "SI")])
11192 (define_insn "*ashrsi3_one_bit_cconly"
11193 [(set (reg FLAGS_REG)
11195 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11196 (match_operand:QI 2 "const1_operand" ""))
11198 (clobber (match_scratch:SI 0 "=r"))]
11199 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11200 && ix86_match_ccmode (insn, CCGOCmode)
11201 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11203 [(set_attr "type" "ishift")
11204 (set_attr "length_immediate" "0")
11205 (set_attr "mode" "SI")])
11207 (define_insn "*ashrsi3_one_bit_cmp_zext"
11208 [(set (reg FLAGS_REG)
11210 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11211 (match_operand:QI 2 "const1_operand" ""))
11213 (set (match_operand:DI 0 "register_operand" "=r")
11214 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11216 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11217 && ix86_match_ccmode (insn, CCmode)
11218 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11220 [(set_attr "type" "ishift")
11221 (set_attr "length_immediate" "0")
11222 (set_attr "mode" "SI")])
11224 ;; This pattern can't accept a variable shift count, since shifts by
11225 ;; zero don't affect the flags. We assume that shifts by constant
11226 ;; zero are optimized away.
11227 (define_insn "*ashrsi3_cmp"
11228 [(set (reg FLAGS_REG)
11230 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11231 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11233 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11234 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11235 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11236 && ix86_match_ccmode (insn, CCGOCmode)
11237 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11238 "sar{l}\t{%2, %0|%0, %2}"
11239 [(set_attr "type" "ishift")
11240 (set_attr "mode" "SI")])
11242 (define_insn "*ashrsi3_cconly"
11243 [(set (reg FLAGS_REG)
11245 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11246 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11248 (clobber (match_scratch:SI 0 "=r"))]
11249 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11250 && ix86_match_ccmode (insn, CCGOCmode)
11251 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11252 "sar{l}\t{%2, %0|%0, %2}"
11253 [(set_attr "type" "ishift")
11254 (set_attr "mode" "SI")])
11256 (define_insn "*ashrsi3_cmp_zext"
11257 [(set (reg FLAGS_REG)
11259 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11260 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11262 (set (match_operand:DI 0 "register_operand" "=r")
11263 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11265 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11266 && ix86_match_ccmode (insn, CCGOCmode)
11267 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11268 "sar{l}\t{%2, %k0|%k0, %2}"
11269 [(set_attr "type" "ishift")
11270 (set_attr "mode" "SI")])
11272 (define_expand "ashrhi3"
11273 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11274 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11275 (match_operand:QI 2 "nonmemory_operand" "")))]
11276 "TARGET_HIMODE_MATH"
11277 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11279 (define_insn "*ashrhi3_1_one_bit"
11280 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11281 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11282 (match_operand:QI 2 "const1_operand" "")))
11283 (clobber (reg:CC FLAGS_REG))]
11284 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11285 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11287 [(set_attr "type" "ishift")
11288 (set_attr "length_immediate" "0")
11289 (set_attr "mode" "HI")])
11291 (define_insn "*ashrhi3_1"
11292 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11293 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11294 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11295 (clobber (reg:CC FLAGS_REG))]
11296 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11298 sar{w}\t{%2, %0|%0, %2}
11299 sar{w}\t{%b2, %0|%0, %b2}"
11300 [(set_attr "type" "ishift")
11301 (set_attr "mode" "HI")])
11303 ;; This pattern can't accept a variable shift count, since shifts by
11304 ;; zero don't affect the flags. We assume that shifts by constant
11305 ;; zero are optimized away.
11306 (define_insn "*ashrhi3_one_bit_cmp"
11307 [(set (reg FLAGS_REG)
11309 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11310 (match_operand:QI 2 "const1_operand" ""))
11312 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11313 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11314 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11315 && ix86_match_ccmode (insn, CCGOCmode)
11316 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11318 [(set_attr "type" "ishift")
11319 (set_attr "length_immediate" "0")
11320 (set_attr "mode" "HI")])
11322 (define_insn "*ashrhi3_one_bit_cconly"
11323 [(set (reg FLAGS_REG)
11325 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11326 (match_operand:QI 2 "const1_operand" ""))
11328 (clobber (match_scratch:HI 0 "=r"))]
11329 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11330 && ix86_match_ccmode (insn, CCGOCmode)
11331 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11333 [(set_attr "type" "ishift")
11334 (set_attr "length_immediate" "0")
11335 (set_attr "mode" "HI")])
11337 ;; This pattern can't accept a variable shift count, since shifts by
11338 ;; zero don't affect the flags. We assume that shifts by constant
11339 ;; zero are optimized away.
11340 (define_insn "*ashrhi3_cmp"
11341 [(set (reg FLAGS_REG)
11343 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11344 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11346 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11347 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11348 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11349 && ix86_match_ccmode (insn, CCGOCmode)
11350 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11351 "sar{w}\t{%2, %0|%0, %2}"
11352 [(set_attr "type" "ishift")
11353 (set_attr "mode" "HI")])
11355 (define_insn "*ashrhi3_cconly"
11356 [(set (reg FLAGS_REG)
11358 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11359 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11361 (clobber (match_scratch:HI 0 "=r"))]
11362 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11363 && ix86_match_ccmode (insn, CCGOCmode)
11364 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11365 "sar{w}\t{%2, %0|%0, %2}"
11366 [(set_attr "type" "ishift")
11367 (set_attr "mode" "HI")])
11369 (define_expand "ashrqi3"
11370 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11371 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11372 (match_operand:QI 2 "nonmemory_operand" "")))]
11373 "TARGET_QIMODE_MATH"
11374 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11376 (define_insn "*ashrqi3_1_one_bit"
11377 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11378 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11379 (match_operand:QI 2 "const1_operand" "")))
11380 (clobber (reg:CC FLAGS_REG))]
11381 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11382 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11384 [(set_attr "type" "ishift")
11385 (set_attr "length_immediate" "0")
11386 (set_attr "mode" "QI")])
11388 (define_insn "*ashrqi3_1_one_bit_slp"
11389 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11390 (ashiftrt:QI (match_dup 0)
11391 (match_operand:QI 1 "const1_operand" "")))
11392 (clobber (reg:CC FLAGS_REG))]
11393 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11394 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11395 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11397 [(set_attr "type" "ishift1")
11398 (set_attr "length_immediate" "0")
11399 (set_attr "mode" "QI")])
11401 (define_insn "*ashrqi3_1"
11402 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11403 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11404 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11405 (clobber (reg:CC FLAGS_REG))]
11406 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11408 sar{b}\t{%2, %0|%0, %2}
11409 sar{b}\t{%b2, %0|%0, %b2}"
11410 [(set_attr "type" "ishift")
11411 (set_attr "mode" "QI")])
11413 (define_insn "*ashrqi3_1_slp"
11414 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11415 (ashiftrt:QI (match_dup 0)
11416 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11417 (clobber (reg:CC FLAGS_REG))]
11418 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11419 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11421 sar{b}\t{%1, %0|%0, %1}
11422 sar{b}\t{%b1, %0|%0, %b1}"
11423 [(set_attr "type" "ishift1")
11424 (set_attr "mode" "QI")])
11426 ;; This pattern can't accept a variable shift count, since shifts by
11427 ;; zero don't affect the flags. We assume that shifts by constant
11428 ;; zero are optimized away.
11429 (define_insn "*ashrqi3_one_bit_cmp"
11430 [(set (reg FLAGS_REG)
11432 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11433 (match_operand:QI 2 "const1_operand" "I"))
11435 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11436 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11437 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11438 && ix86_match_ccmode (insn, CCGOCmode)
11439 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11441 [(set_attr "type" "ishift")
11442 (set_attr "length_immediate" "0")
11443 (set_attr "mode" "QI")])
11445 (define_insn "*ashrqi3_one_bit_cconly"
11446 [(set (reg FLAGS_REG)
11448 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11449 (match_operand:QI 2 "const1_operand" ""))
11451 (clobber (match_scratch:QI 0 "=q"))]
11452 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11453 && ix86_match_ccmode (insn, CCGOCmode)
11454 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11456 [(set_attr "type" "ishift")
11457 (set_attr "length_immediate" "0")
11458 (set_attr "mode" "QI")])
11460 ;; This pattern can't accept a variable shift count, since shifts by
11461 ;; zero don't affect the flags. We assume that shifts by constant
11462 ;; zero are optimized away.
11463 (define_insn "*ashrqi3_cmp"
11464 [(set (reg FLAGS_REG)
11466 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11467 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11469 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11470 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11471 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11472 && ix86_match_ccmode (insn, CCGOCmode)
11473 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11474 "sar{b}\t{%2, %0|%0, %2}"
11475 [(set_attr "type" "ishift")
11476 (set_attr "mode" "QI")])
11478 (define_insn "*ashrqi3_cconly"
11479 [(set (reg FLAGS_REG)
11481 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11482 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11484 (clobber (match_scratch:QI 0 "=q"))]
11485 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11486 && ix86_match_ccmode (insn, CCGOCmode)
11487 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11488 "sar{b}\t{%2, %0|%0, %2}"
11489 [(set_attr "type" "ishift")
11490 (set_attr "mode" "QI")])
11493 ;; Logical shift instructions
11495 ;; See comment above `ashldi3' about how this works.
11497 (define_expand "lshrti3"
11498 [(set (match_operand:TI 0 "register_operand" "")
11499 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11500 (match_operand:QI 2 "nonmemory_operand" "")))]
11502 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
11504 (define_insn "*lshrti3_1"
11505 [(set (match_operand:TI 0 "register_operand" "=r")
11506 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11507 (match_operand:QI 2 "nonmemory_operand" "Oc")))
11508 (clobber (reg:CC FLAGS_REG))]
11511 [(set_attr "type" "multi")])
11514 [(match_scratch:DI 3 "r")
11515 (parallel [(set (match_operand:TI 0 "register_operand" "")
11516 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11517 (match_operand:QI 2 "nonmemory_operand" "")))
11518 (clobber (reg:CC FLAGS_REG))])
11522 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11525 [(set (match_operand:TI 0 "register_operand" "")
11526 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11527 (match_operand:QI 2 "nonmemory_operand" "")))
11528 (clobber (reg:CC FLAGS_REG))]
11529 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11530 ? epilogue_completed : reload_completed)"
11532 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11534 (define_expand "lshrdi3"
11535 [(set (match_operand:DI 0 "shiftdi_operand" "")
11536 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11537 (match_operand:QI 2 "nonmemory_operand" "")))]
11539 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11541 (define_insn "*lshrdi3_1_one_bit_rex64"
11542 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11543 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11544 (match_operand:QI 2 "const1_operand" "")))
11545 (clobber (reg:CC FLAGS_REG))]
11547 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11548 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11550 [(set_attr "type" "ishift")
11551 (set_attr "length_immediate" "0")
11552 (set_attr "mode" "DI")])
11554 (define_insn "*lshrdi3_1_rex64"
11555 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11556 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11557 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11558 (clobber (reg:CC FLAGS_REG))]
11559 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11561 shr{q}\t{%2, %0|%0, %2}
11562 shr{q}\t{%b2, %0|%0, %b2}"
11563 [(set_attr "type" "ishift")
11564 (set_attr "mode" "DI")])
11566 ;; This pattern can't accept a variable shift count, since shifts by
11567 ;; zero don't affect the flags. We assume that shifts by constant
11568 ;; zero are optimized away.
11569 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11570 [(set (reg FLAGS_REG)
11572 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11573 (match_operand:QI 2 "const1_operand" ""))
11575 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11576 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11578 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11579 && ix86_match_ccmode (insn, CCGOCmode)
11580 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11582 [(set_attr "type" "ishift")
11583 (set_attr "length_immediate" "0")
11584 (set_attr "mode" "DI")])
11586 (define_insn "*lshrdi3_cconly_one_bit_rex64"
11587 [(set (reg FLAGS_REG)
11589 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11590 (match_operand:QI 2 "const1_operand" ""))
11592 (clobber (match_scratch:DI 0 "=r"))]
11594 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11595 && ix86_match_ccmode (insn, CCGOCmode)
11596 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11598 [(set_attr "type" "ishift")
11599 (set_attr "length_immediate" "0")
11600 (set_attr "mode" "DI")])
11602 ;; This pattern can't accept a variable shift count, since shifts by
11603 ;; zero don't affect the flags. We assume that shifts by constant
11604 ;; zero are optimized away.
11605 (define_insn "*lshrdi3_cmp_rex64"
11606 [(set (reg FLAGS_REG)
11608 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11609 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11611 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11612 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11614 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11615 && ix86_match_ccmode (insn, CCGOCmode)
11616 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11617 "shr{q}\t{%2, %0|%0, %2}"
11618 [(set_attr "type" "ishift")
11619 (set_attr "mode" "DI")])
11621 (define_insn "*lshrdi3_cconly_rex64"
11622 [(set (reg FLAGS_REG)
11624 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11625 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11627 (clobber (match_scratch:DI 0 "=r"))]
11629 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11630 && ix86_match_ccmode (insn, CCGOCmode)
11631 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11632 "shr{q}\t{%2, %0|%0, %2}"
11633 [(set_attr "type" "ishift")
11634 (set_attr "mode" "DI")])
11636 (define_insn "*lshrdi3_1"
11637 [(set (match_operand:DI 0 "register_operand" "=r")
11638 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11639 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11640 (clobber (reg:CC FLAGS_REG))]
11643 [(set_attr "type" "multi")])
11645 ;; By default we don't ask for a scratch register, because when DImode
11646 ;; values are manipulated, registers are already at a premium. But if
11647 ;; we have one handy, we won't turn it away.
11649 [(match_scratch:SI 3 "r")
11650 (parallel [(set (match_operand:DI 0 "register_operand" "")
11651 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11652 (match_operand:QI 2 "nonmemory_operand" "")))
11653 (clobber (reg:CC FLAGS_REG))])
11655 "!TARGET_64BIT && TARGET_CMOVE"
11657 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11660 [(set (match_operand:DI 0 "register_operand" "")
11661 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11662 (match_operand:QI 2 "nonmemory_operand" "")))
11663 (clobber (reg:CC FLAGS_REG))]
11664 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11665 ? epilogue_completed : reload_completed)"
11667 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11669 (define_expand "lshrsi3"
11670 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11671 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11672 (match_operand:QI 2 "nonmemory_operand" "")))]
11674 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11676 (define_insn "*lshrsi3_1_one_bit"
11677 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11678 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11679 (match_operand:QI 2 "const1_operand" "")))
11680 (clobber (reg:CC FLAGS_REG))]
11681 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11682 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11684 [(set_attr "type" "ishift")
11685 (set_attr "length_immediate" "0")
11686 (set_attr "mode" "SI")])
11688 (define_insn "*lshrsi3_1_one_bit_zext"
11689 [(set (match_operand:DI 0 "register_operand" "=r")
11690 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11691 (match_operand:QI 2 "const1_operand" "")))
11692 (clobber (reg:CC FLAGS_REG))]
11694 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11695 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11697 [(set_attr "type" "ishift")
11698 (set_attr "length_immediate" "0")
11699 (set_attr "mode" "SI")])
11701 (define_insn "*lshrsi3_1"
11702 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11703 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11704 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11705 (clobber (reg:CC FLAGS_REG))]
11706 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11708 shr{l}\t{%2, %0|%0, %2}
11709 shr{l}\t{%b2, %0|%0, %b2}"
11710 [(set_attr "type" "ishift")
11711 (set_attr "mode" "SI")])
11713 (define_insn "*lshrsi3_1_zext"
11714 [(set (match_operand:DI 0 "register_operand" "=r,r")
11716 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11717 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11718 (clobber (reg:CC FLAGS_REG))]
11719 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11721 shr{l}\t{%2, %k0|%k0, %2}
11722 shr{l}\t{%b2, %k0|%k0, %b2}"
11723 [(set_attr "type" "ishift")
11724 (set_attr "mode" "SI")])
11726 ;; This pattern can't accept a variable shift count, since shifts by
11727 ;; zero don't affect the flags. We assume that shifts by constant
11728 ;; zero are optimized away.
11729 (define_insn "*lshrsi3_one_bit_cmp"
11730 [(set (reg FLAGS_REG)
11732 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11733 (match_operand:QI 2 "const1_operand" ""))
11735 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11736 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11737 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11738 && ix86_match_ccmode (insn, CCGOCmode)
11739 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11741 [(set_attr "type" "ishift")
11742 (set_attr "length_immediate" "0")
11743 (set_attr "mode" "SI")])
11745 (define_insn "*lshrsi3_one_bit_cconly"
11746 [(set (reg FLAGS_REG)
11748 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11749 (match_operand:QI 2 "const1_operand" ""))
11751 (clobber (match_scratch:SI 0 "=r"))]
11752 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11753 && ix86_match_ccmode (insn, CCGOCmode)
11754 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11756 [(set_attr "type" "ishift")
11757 (set_attr "length_immediate" "0")
11758 (set_attr "mode" "SI")])
11760 (define_insn "*lshrsi3_cmp_one_bit_zext"
11761 [(set (reg FLAGS_REG)
11763 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11764 (match_operand:QI 2 "const1_operand" ""))
11766 (set (match_operand:DI 0 "register_operand" "=r")
11767 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11769 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11770 && ix86_match_ccmode (insn, CCGOCmode)
11771 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11773 [(set_attr "type" "ishift")
11774 (set_attr "length_immediate" "0")
11775 (set_attr "mode" "SI")])
11777 ;; This pattern can't accept a variable shift count, since shifts by
11778 ;; zero don't affect the flags. We assume that shifts by constant
11779 ;; zero are optimized away.
11780 (define_insn "*lshrsi3_cmp"
11781 [(set (reg FLAGS_REG)
11783 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11784 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11786 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11787 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11788 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11789 && ix86_match_ccmode (insn, CCGOCmode)
11790 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11791 "shr{l}\t{%2, %0|%0, %2}"
11792 [(set_attr "type" "ishift")
11793 (set_attr "mode" "SI")])
11795 (define_insn "*lshrsi3_cconly"
11796 [(set (reg FLAGS_REG)
11798 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11799 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11801 (clobber (match_scratch:SI 0 "=r"))]
11802 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11803 && ix86_match_ccmode (insn, CCGOCmode)
11804 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11805 "shr{l}\t{%2, %0|%0, %2}"
11806 [(set_attr "type" "ishift")
11807 (set_attr "mode" "SI")])
11809 (define_insn "*lshrsi3_cmp_zext"
11810 [(set (reg FLAGS_REG)
11812 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11813 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11815 (set (match_operand:DI 0 "register_operand" "=r")
11816 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11818 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11819 && ix86_match_ccmode (insn, CCGOCmode)
11820 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11821 "shr{l}\t{%2, %k0|%k0, %2}"
11822 [(set_attr "type" "ishift")
11823 (set_attr "mode" "SI")])
11825 (define_expand "lshrhi3"
11826 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11827 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11828 (match_operand:QI 2 "nonmemory_operand" "")))]
11829 "TARGET_HIMODE_MATH"
11830 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11832 (define_insn "*lshrhi3_1_one_bit"
11833 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11834 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11835 (match_operand:QI 2 "const1_operand" "")))
11836 (clobber (reg:CC FLAGS_REG))]
11837 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11838 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11840 [(set_attr "type" "ishift")
11841 (set_attr "length_immediate" "0")
11842 (set_attr "mode" "HI")])
11844 (define_insn "*lshrhi3_1"
11845 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11846 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11847 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11848 (clobber (reg:CC FLAGS_REG))]
11849 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11851 shr{w}\t{%2, %0|%0, %2}
11852 shr{w}\t{%b2, %0|%0, %b2}"
11853 [(set_attr "type" "ishift")
11854 (set_attr "mode" "HI")])
11856 ;; This pattern can't accept a variable shift count, since shifts by
11857 ;; zero don't affect the flags. We assume that shifts by constant
11858 ;; zero are optimized away.
11859 (define_insn "*lshrhi3_one_bit_cmp"
11860 [(set (reg FLAGS_REG)
11862 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11863 (match_operand:QI 2 "const1_operand" ""))
11865 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11866 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11867 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11868 && ix86_match_ccmode (insn, CCGOCmode)
11869 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11871 [(set_attr "type" "ishift")
11872 (set_attr "length_immediate" "0")
11873 (set_attr "mode" "HI")])
11875 (define_insn "*lshrhi3_one_bit_cconly"
11876 [(set (reg FLAGS_REG)
11878 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11879 (match_operand:QI 2 "const1_operand" ""))
11881 (clobber (match_scratch:HI 0 "=r"))]
11882 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11883 && ix86_match_ccmode (insn, CCGOCmode)
11884 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11886 [(set_attr "type" "ishift")
11887 (set_attr "length_immediate" "0")
11888 (set_attr "mode" "HI")])
11890 ;; This pattern can't accept a variable shift count, since shifts by
11891 ;; zero don't affect the flags. We assume that shifts by constant
11892 ;; zero are optimized away.
11893 (define_insn "*lshrhi3_cmp"
11894 [(set (reg FLAGS_REG)
11896 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11897 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11899 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11900 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11901 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11902 && ix86_match_ccmode (insn, CCGOCmode)
11903 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11904 "shr{w}\t{%2, %0|%0, %2}"
11905 [(set_attr "type" "ishift")
11906 (set_attr "mode" "HI")])
11908 (define_insn "*lshrhi3_cconly"
11909 [(set (reg FLAGS_REG)
11911 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11912 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11914 (clobber (match_scratch:HI 0 "=r"))]
11915 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11916 && ix86_match_ccmode (insn, CCGOCmode)
11917 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11918 "shr{w}\t{%2, %0|%0, %2}"
11919 [(set_attr "type" "ishift")
11920 (set_attr "mode" "HI")])
11922 (define_expand "lshrqi3"
11923 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11924 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11925 (match_operand:QI 2 "nonmemory_operand" "")))]
11926 "TARGET_QIMODE_MATH"
11927 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11929 (define_insn "*lshrqi3_1_one_bit"
11930 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11931 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11932 (match_operand:QI 2 "const1_operand" "")))
11933 (clobber (reg:CC FLAGS_REG))]
11934 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11935 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11937 [(set_attr "type" "ishift")
11938 (set_attr "length_immediate" "0")
11939 (set_attr "mode" "QI")])
11941 (define_insn "*lshrqi3_1_one_bit_slp"
11942 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11943 (lshiftrt:QI (match_dup 0)
11944 (match_operand:QI 1 "const1_operand" "")))
11945 (clobber (reg:CC FLAGS_REG))]
11946 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11947 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
11949 [(set_attr "type" "ishift1")
11950 (set_attr "length_immediate" "0")
11951 (set_attr "mode" "QI")])
11953 (define_insn "*lshrqi3_1"
11954 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11955 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11956 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11957 (clobber (reg:CC FLAGS_REG))]
11958 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11960 shr{b}\t{%2, %0|%0, %2}
11961 shr{b}\t{%b2, %0|%0, %b2}"
11962 [(set_attr "type" "ishift")
11963 (set_attr "mode" "QI")])
11965 (define_insn "*lshrqi3_1_slp"
11966 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11967 (lshiftrt:QI (match_dup 0)
11968 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11969 (clobber (reg:CC FLAGS_REG))]
11970 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11971 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11973 shr{b}\t{%1, %0|%0, %1}
11974 shr{b}\t{%b1, %0|%0, %b1}"
11975 [(set_attr "type" "ishift1")
11976 (set_attr "mode" "QI")])
11978 ;; This pattern can't accept a variable shift count, since shifts by
11979 ;; zero don't affect the flags. We assume that shifts by constant
11980 ;; zero are optimized away.
11981 (define_insn "*lshrqi2_one_bit_cmp"
11982 [(set (reg FLAGS_REG)
11984 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11985 (match_operand:QI 2 "const1_operand" ""))
11987 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11988 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11989 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11990 && ix86_match_ccmode (insn, CCGOCmode)
11991 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11993 [(set_attr "type" "ishift")
11994 (set_attr "length_immediate" "0")
11995 (set_attr "mode" "QI")])
11997 (define_insn "*lshrqi2_one_bit_cconly"
11998 [(set (reg FLAGS_REG)
12000 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12001 (match_operand:QI 2 "const1_operand" ""))
12003 (clobber (match_scratch:QI 0 "=q"))]
12004 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12005 && ix86_match_ccmode (insn, CCGOCmode)
12006 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12008 [(set_attr "type" "ishift")
12009 (set_attr "length_immediate" "0")
12010 (set_attr "mode" "QI")])
12012 ;; This pattern can't accept a variable shift count, since shifts by
12013 ;; zero don't affect the flags. We assume that shifts by constant
12014 ;; zero are optimized away.
12015 (define_insn "*lshrqi2_cmp"
12016 [(set (reg FLAGS_REG)
12018 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12019 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12021 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12022 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12023 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12024 && ix86_match_ccmode (insn, CCGOCmode)
12025 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12026 "shr{b}\t{%2, %0|%0, %2}"
12027 [(set_attr "type" "ishift")
12028 (set_attr "mode" "QI")])
12030 (define_insn "*lshrqi2_cconly"
12031 [(set (reg FLAGS_REG)
12033 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12034 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12036 (clobber (match_scratch:QI 0 "=q"))]
12037 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12038 && ix86_match_ccmode (insn, CCGOCmode)
12039 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12040 "shr{b}\t{%2, %0|%0, %2}"
12041 [(set_attr "type" "ishift")
12042 (set_attr "mode" "QI")])
12044 ;; Rotate instructions
12046 (define_expand "rotldi3"
12047 [(set (match_operand:DI 0 "shiftdi_operand" "")
12048 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12049 (match_operand:QI 2 "nonmemory_operand" "")))]
12054 ix86_expand_binary_operator (ROTATE, DImode, operands);
12057 if (!const_1_to_31_operand (operands[2], VOIDmode))
12059 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12063 ;; Implement rotation using two double-precision shift instructions
12064 ;; and a scratch register.
12065 (define_insn_and_split "ix86_rotldi3"
12066 [(set (match_operand:DI 0 "register_operand" "=r")
12067 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12068 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12069 (clobber (reg:CC FLAGS_REG))
12070 (clobber (match_scratch:SI 3 "=&r"))]
12073 "&& reload_completed"
12074 [(set (match_dup 3) (match_dup 4))
12076 [(set (match_dup 4)
12077 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12078 (lshiftrt:SI (match_dup 5)
12079 (minus:QI (const_int 32) (match_dup 2)))))
12080 (clobber (reg:CC FLAGS_REG))])
12082 [(set (match_dup 5)
12083 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12084 (lshiftrt:SI (match_dup 3)
12085 (minus:QI (const_int 32) (match_dup 2)))))
12086 (clobber (reg:CC FLAGS_REG))])]
12087 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12089 (define_insn "*rotlsi3_1_one_bit_rex64"
12090 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12091 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12092 (match_operand:QI 2 "const1_operand" "")))
12093 (clobber (reg:CC FLAGS_REG))]
12095 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12096 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12098 [(set_attr "type" "rotate")
12099 (set_attr "length_immediate" "0")
12100 (set_attr "mode" "DI")])
12102 (define_insn "*rotldi3_1_rex64"
12103 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12104 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12105 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12106 (clobber (reg:CC FLAGS_REG))]
12107 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12109 rol{q}\t{%2, %0|%0, %2}
12110 rol{q}\t{%b2, %0|%0, %b2}"
12111 [(set_attr "type" "rotate")
12112 (set_attr "mode" "DI")])
12114 (define_expand "rotlsi3"
12115 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12116 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12117 (match_operand:QI 2 "nonmemory_operand" "")))]
12119 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12121 (define_insn "*rotlsi3_1_one_bit"
12122 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12123 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12124 (match_operand:QI 2 "const1_operand" "")))
12125 (clobber (reg:CC FLAGS_REG))]
12126 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12127 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12129 [(set_attr "type" "rotate")
12130 (set_attr "length_immediate" "0")
12131 (set_attr "mode" "SI")])
12133 (define_insn "*rotlsi3_1_one_bit_zext"
12134 [(set (match_operand:DI 0 "register_operand" "=r")
12136 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12137 (match_operand:QI 2 "const1_operand" ""))))
12138 (clobber (reg:CC FLAGS_REG))]
12140 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12141 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12143 [(set_attr "type" "rotate")
12144 (set_attr "length_immediate" "0")
12145 (set_attr "mode" "SI")])
12147 (define_insn "*rotlsi3_1"
12148 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12149 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12150 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12151 (clobber (reg:CC FLAGS_REG))]
12152 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12154 rol{l}\t{%2, %0|%0, %2}
12155 rol{l}\t{%b2, %0|%0, %b2}"
12156 [(set_attr "type" "rotate")
12157 (set_attr "mode" "SI")])
12159 (define_insn "*rotlsi3_1_zext"
12160 [(set (match_operand:DI 0 "register_operand" "=r,r")
12162 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12163 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12164 (clobber (reg:CC FLAGS_REG))]
12165 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12167 rol{l}\t{%2, %k0|%k0, %2}
12168 rol{l}\t{%b2, %k0|%k0, %b2}"
12169 [(set_attr "type" "rotate")
12170 (set_attr "mode" "SI")])
12172 (define_expand "rotlhi3"
12173 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12174 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12175 (match_operand:QI 2 "nonmemory_operand" "")))]
12176 "TARGET_HIMODE_MATH"
12177 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12179 (define_insn "*rotlhi3_1_one_bit"
12180 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12181 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12182 (match_operand:QI 2 "const1_operand" "")))
12183 (clobber (reg:CC FLAGS_REG))]
12184 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12185 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
12187 [(set_attr "type" "rotate")
12188 (set_attr "length_immediate" "0")
12189 (set_attr "mode" "HI")])
12191 (define_insn "*rotlhi3_1"
12192 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12193 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12194 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12195 (clobber (reg:CC FLAGS_REG))]
12196 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12198 rol{w}\t{%2, %0|%0, %2}
12199 rol{w}\t{%b2, %0|%0, %b2}"
12200 [(set_attr "type" "rotate")
12201 (set_attr "mode" "HI")])
12204 [(set (match_operand:HI 0 "register_operand" "")
12205 (rotate:HI (match_dup 0) (const_int 8)))
12206 (clobber (reg:CC FLAGS_REG))]
12208 [(parallel [(set (strict_low_part (match_dup 0))
12209 (bswap:HI (match_dup 0)))
12210 (clobber (reg:CC FLAGS_REG))])]
12213 (define_expand "rotlqi3"
12214 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12215 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12216 (match_operand:QI 2 "nonmemory_operand" "")))]
12217 "TARGET_QIMODE_MATH"
12218 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12220 (define_insn "*rotlqi3_1_one_bit_slp"
12221 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12222 (rotate:QI (match_dup 0)
12223 (match_operand:QI 1 "const1_operand" "")))
12224 (clobber (reg:CC FLAGS_REG))]
12225 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12226 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12228 [(set_attr "type" "rotate1")
12229 (set_attr "length_immediate" "0")
12230 (set_attr "mode" "QI")])
12232 (define_insn "*rotlqi3_1_one_bit"
12233 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12234 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12235 (match_operand:QI 2 "const1_operand" "")))
12236 (clobber (reg:CC FLAGS_REG))]
12237 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12238 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
12240 [(set_attr "type" "rotate")
12241 (set_attr "length_immediate" "0")
12242 (set_attr "mode" "QI")])
12244 (define_insn "*rotlqi3_1_slp"
12245 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12246 (rotate:QI (match_dup 0)
12247 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12248 (clobber (reg:CC FLAGS_REG))]
12249 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12250 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12252 rol{b}\t{%1, %0|%0, %1}
12253 rol{b}\t{%b1, %0|%0, %b1}"
12254 [(set_attr "type" "rotate1")
12255 (set_attr "mode" "QI")])
12257 (define_insn "*rotlqi3_1"
12258 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12259 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12260 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12261 (clobber (reg:CC FLAGS_REG))]
12262 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12264 rol{b}\t{%2, %0|%0, %2}
12265 rol{b}\t{%b2, %0|%0, %b2}"
12266 [(set_attr "type" "rotate")
12267 (set_attr "mode" "QI")])
12269 (define_expand "rotrdi3"
12270 [(set (match_operand:DI 0 "shiftdi_operand" "")
12271 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12272 (match_operand:QI 2 "nonmemory_operand" "")))]
12277 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12280 if (!const_1_to_31_operand (operands[2], VOIDmode))
12282 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12286 ;; Implement rotation using two double-precision shift instructions
12287 ;; and a scratch register.
12288 (define_insn_and_split "ix86_rotrdi3"
12289 [(set (match_operand:DI 0 "register_operand" "=r")
12290 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12291 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12292 (clobber (reg:CC FLAGS_REG))
12293 (clobber (match_scratch:SI 3 "=&r"))]
12296 "&& reload_completed"
12297 [(set (match_dup 3) (match_dup 4))
12299 [(set (match_dup 4)
12300 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12301 (ashift:SI (match_dup 5)
12302 (minus:QI (const_int 32) (match_dup 2)))))
12303 (clobber (reg:CC FLAGS_REG))])
12305 [(set (match_dup 5)
12306 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12307 (ashift:SI (match_dup 3)
12308 (minus:QI (const_int 32) (match_dup 2)))))
12309 (clobber (reg:CC FLAGS_REG))])]
12310 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12312 (define_insn "*rotrdi3_1_one_bit_rex64"
12313 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12314 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12315 (match_operand:QI 2 "const1_operand" "")))
12316 (clobber (reg:CC FLAGS_REG))]
12318 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12319 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12321 [(set_attr "type" "rotate")
12322 (set_attr "length_immediate" "0")
12323 (set_attr "mode" "DI")])
12325 (define_insn "*rotrdi3_1_rex64"
12326 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12327 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12328 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12329 (clobber (reg:CC FLAGS_REG))]
12330 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12332 ror{q}\t{%2, %0|%0, %2}
12333 ror{q}\t{%b2, %0|%0, %b2}"
12334 [(set_attr "type" "rotate")
12335 (set_attr "mode" "DI")])
12337 (define_expand "rotrsi3"
12338 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12339 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12340 (match_operand:QI 2 "nonmemory_operand" "")))]
12342 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12344 (define_insn "*rotrsi3_1_one_bit"
12345 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12346 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12347 (match_operand:QI 2 "const1_operand" "")))
12348 (clobber (reg:CC FLAGS_REG))]
12349 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12350 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12352 [(set_attr "type" "rotate")
12353 (set_attr "length_immediate" "0")
12354 (set_attr "mode" "SI")])
12356 (define_insn "*rotrsi3_1_one_bit_zext"
12357 [(set (match_operand:DI 0 "register_operand" "=r")
12359 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12360 (match_operand:QI 2 "const1_operand" ""))))
12361 (clobber (reg:CC FLAGS_REG))]
12363 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12364 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12366 [(set_attr "type" "rotate")
12367 (set_attr "length_immediate" "0")
12368 (set_attr "mode" "SI")])
12370 (define_insn "*rotrsi3_1"
12371 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12372 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12373 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12374 (clobber (reg:CC FLAGS_REG))]
12375 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12377 ror{l}\t{%2, %0|%0, %2}
12378 ror{l}\t{%b2, %0|%0, %b2}"
12379 [(set_attr "type" "rotate")
12380 (set_attr "mode" "SI")])
12382 (define_insn "*rotrsi3_1_zext"
12383 [(set (match_operand:DI 0 "register_operand" "=r,r")
12385 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12386 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12387 (clobber (reg:CC FLAGS_REG))]
12388 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12390 ror{l}\t{%2, %k0|%k0, %2}
12391 ror{l}\t{%b2, %k0|%k0, %b2}"
12392 [(set_attr "type" "rotate")
12393 (set_attr "mode" "SI")])
12395 (define_expand "rotrhi3"
12396 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12397 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12398 (match_operand:QI 2 "nonmemory_operand" "")))]
12399 "TARGET_HIMODE_MATH"
12400 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12402 (define_insn "*rotrhi3_one_bit"
12403 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12404 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12405 (match_operand:QI 2 "const1_operand" "")))
12406 (clobber (reg:CC FLAGS_REG))]
12407 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12408 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12410 [(set_attr "type" "rotate")
12411 (set_attr "length_immediate" "0")
12412 (set_attr "mode" "HI")])
12414 (define_insn "*rotrhi3_1"
12415 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12416 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12417 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12418 (clobber (reg:CC FLAGS_REG))]
12419 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12421 ror{w}\t{%2, %0|%0, %2}
12422 ror{w}\t{%b2, %0|%0, %b2}"
12423 [(set_attr "type" "rotate")
12424 (set_attr "mode" "HI")])
12427 [(set (match_operand:HI 0 "register_operand" "")
12428 (rotatert:HI (match_dup 0) (const_int 8)))
12429 (clobber (reg:CC FLAGS_REG))]
12431 [(parallel [(set (strict_low_part (match_dup 0))
12432 (bswap:HI (match_dup 0)))
12433 (clobber (reg:CC FLAGS_REG))])]
12436 (define_expand "rotrqi3"
12437 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12438 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12439 (match_operand:QI 2 "nonmemory_operand" "")))]
12440 "TARGET_QIMODE_MATH"
12441 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12443 (define_insn "*rotrqi3_1_one_bit"
12444 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12445 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12446 (match_operand:QI 2 "const1_operand" "")))
12447 (clobber (reg:CC FLAGS_REG))]
12448 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12449 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12451 [(set_attr "type" "rotate")
12452 (set_attr "length_immediate" "0")
12453 (set_attr "mode" "QI")])
12455 (define_insn "*rotrqi3_1_one_bit_slp"
12456 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12457 (rotatert:QI (match_dup 0)
12458 (match_operand:QI 1 "const1_operand" "")))
12459 (clobber (reg:CC FLAGS_REG))]
12460 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12461 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12463 [(set_attr "type" "rotate1")
12464 (set_attr "length_immediate" "0")
12465 (set_attr "mode" "QI")])
12467 (define_insn "*rotrqi3_1"
12468 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12469 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12470 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12471 (clobber (reg:CC FLAGS_REG))]
12472 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12474 ror{b}\t{%2, %0|%0, %2}
12475 ror{b}\t{%b2, %0|%0, %b2}"
12476 [(set_attr "type" "rotate")
12477 (set_attr "mode" "QI")])
12479 (define_insn "*rotrqi3_1_slp"
12480 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12481 (rotatert:QI (match_dup 0)
12482 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12483 (clobber (reg:CC FLAGS_REG))]
12484 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12485 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12487 ror{b}\t{%1, %0|%0, %1}
12488 ror{b}\t{%b1, %0|%0, %b1}"
12489 [(set_attr "type" "rotate1")
12490 (set_attr "mode" "QI")])
12492 ;; Bit set / bit test instructions
12494 (define_expand "extv"
12495 [(set (match_operand:SI 0 "register_operand" "")
12496 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12497 (match_operand:SI 2 "const8_operand" "")
12498 (match_operand:SI 3 "const8_operand" "")))]
12501 /* Handle extractions from %ah et al. */
12502 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12505 /* From mips.md: extract_bit_field doesn't verify that our source
12506 matches the predicate, so check it again here. */
12507 if (! ext_register_operand (operands[1], VOIDmode))
12511 (define_expand "extzv"
12512 [(set (match_operand:SI 0 "register_operand" "")
12513 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12514 (match_operand:SI 2 "const8_operand" "")
12515 (match_operand:SI 3 "const8_operand" "")))]
12518 /* Handle extractions from %ah et al. */
12519 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12522 /* From mips.md: extract_bit_field doesn't verify that our source
12523 matches the predicate, so check it again here. */
12524 if (! ext_register_operand (operands[1], VOIDmode))
12528 (define_expand "insv"
12529 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12530 (match_operand 1 "const8_operand" "")
12531 (match_operand 2 "const8_operand" ""))
12532 (match_operand 3 "register_operand" ""))]
12535 /* Handle insertions to %ah et al. */
12536 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12539 /* From mips.md: insert_bit_field doesn't verify that our source
12540 matches the predicate, so check it again here. */
12541 if (! ext_register_operand (operands[0], VOIDmode))
12545 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12547 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12552 ;; %%% bts, btr, btc, bt.
12553 ;; In general these instructions are *slow* when applied to memory,
12554 ;; since they enforce atomic operation. When applied to registers,
12555 ;; it depends on the cpu implementation. They're never faster than
12556 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12557 ;; no point. But in 64-bit, we can't hold the relevant immediates
12558 ;; within the instruction itself, so operating on bits in the high
12559 ;; 32-bits of a register becomes easier.
12561 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12562 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12563 ;; negdf respectively, so they can never be disabled entirely.
12565 (define_insn "*btsq"
12566 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12568 (match_operand:DI 1 "const_0_to_63_operand" ""))
12570 (clobber (reg:CC FLAGS_REG))]
12571 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12572 "bts{q}\t{%1, %0|%0, %1}"
12573 [(set_attr "type" "alu1")
12574 (set_attr "prefix_0f" "1")
12575 (set_attr "mode" "DI")])
12577 (define_insn "*btrq"
12578 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12580 (match_operand:DI 1 "const_0_to_63_operand" ""))
12582 (clobber (reg:CC FLAGS_REG))]
12583 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12584 "btr{q}\t{%1, %0|%0, %1}"
12585 [(set_attr "type" "alu1")
12586 (set_attr "prefix_0f" "1")
12587 (set_attr "mode" "DI")])
12589 (define_insn "*btcq"
12590 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12592 (match_operand:DI 1 "const_0_to_63_operand" ""))
12593 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12594 (clobber (reg:CC FLAGS_REG))]
12595 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12596 "btc{q}\t{%1, %0|%0, %1}"
12597 [(set_attr "type" "alu1")
12598 (set_attr "prefix_0f" "1")
12599 (set_attr "mode" "DI")])
12601 ;; Allow Nocona to avoid these instructions if a register is available.
12604 [(match_scratch:DI 2 "r")
12605 (parallel [(set (zero_extract:DI
12606 (match_operand:DI 0 "register_operand" "")
12608 (match_operand:DI 1 "const_0_to_63_operand" ""))
12610 (clobber (reg:CC FLAGS_REG))])]
12611 "TARGET_64BIT && !TARGET_USE_BT"
12614 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12617 if (HOST_BITS_PER_WIDE_INT >= 64)
12618 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12619 else if (i < HOST_BITS_PER_WIDE_INT)
12620 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12622 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12624 op1 = immed_double_const (lo, hi, DImode);
12627 emit_move_insn (operands[2], op1);
12631 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12636 [(match_scratch:DI 2 "r")
12637 (parallel [(set (zero_extract:DI
12638 (match_operand:DI 0 "register_operand" "")
12640 (match_operand:DI 1 "const_0_to_63_operand" ""))
12642 (clobber (reg:CC FLAGS_REG))])]
12643 "TARGET_64BIT && !TARGET_USE_BT"
12646 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12649 if (HOST_BITS_PER_WIDE_INT >= 64)
12650 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12651 else if (i < HOST_BITS_PER_WIDE_INT)
12652 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12654 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12656 op1 = immed_double_const (~lo, ~hi, DImode);
12659 emit_move_insn (operands[2], op1);
12663 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12668 [(match_scratch:DI 2 "r")
12669 (parallel [(set (zero_extract:DI
12670 (match_operand:DI 0 "register_operand" "")
12672 (match_operand:DI 1 "const_0_to_63_operand" ""))
12673 (not:DI (zero_extract:DI
12674 (match_dup 0) (const_int 1) (match_dup 1))))
12675 (clobber (reg:CC FLAGS_REG))])]
12676 "TARGET_64BIT && !TARGET_USE_BT"
12679 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12682 if (HOST_BITS_PER_WIDE_INT >= 64)
12683 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12684 else if (i < HOST_BITS_PER_WIDE_INT)
12685 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12687 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12689 op1 = immed_double_const (lo, hi, DImode);
12692 emit_move_insn (operands[2], op1);
12696 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12700 (define_insn "*btdi_rex64"
12701 [(set (reg:CCC FLAGS_REG)
12704 (match_operand:DI 0 "register_operand" "r")
12706 (match_operand:DI 1 "nonmemory_operand" "rN"))
12708 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
12709 "bt{q}\t{%1, %0|%0, %1}"
12710 [(set_attr "type" "alu1")
12711 (set_attr "prefix_0f" "1")
12712 (set_attr "mode" "DI")])
12714 (define_insn "*btsi"
12715 [(set (reg:CCC FLAGS_REG)
12718 (match_operand:SI 0 "register_operand" "r")
12720 (match_operand:SI 1 "nonmemory_operand" "rN"))
12722 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12723 "bt{l}\t{%1, %0|%0, %1}"
12724 [(set_attr "type" "alu1")
12725 (set_attr "prefix_0f" "1")
12726 (set_attr "mode" "SI")])
12728 ;; Store-flag instructions.
12730 ;; For all sCOND expanders, also expand the compare or test insn that
12731 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12733 (define_insn_and_split "*setcc_di_1"
12734 [(set (match_operand:DI 0 "register_operand" "=q")
12735 (match_operator:DI 1 "ix86_comparison_operator"
12736 [(reg FLAGS_REG) (const_int 0)]))]
12737 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12739 "&& reload_completed"
12740 [(set (match_dup 2) (match_dup 1))
12741 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12743 PUT_MODE (operands[1], QImode);
12744 operands[2] = gen_lowpart (QImode, operands[0]);
12747 (define_insn_and_split "*setcc_si_1_and"
12748 [(set (match_operand:SI 0 "register_operand" "=q")
12749 (match_operator:SI 1 "ix86_comparison_operator"
12750 [(reg FLAGS_REG) (const_int 0)]))
12751 (clobber (reg:CC FLAGS_REG))]
12752 "!TARGET_PARTIAL_REG_STALL
12753 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12755 "&& reload_completed"
12756 [(set (match_dup 2) (match_dup 1))
12757 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12758 (clobber (reg:CC FLAGS_REG))])]
12760 PUT_MODE (operands[1], QImode);
12761 operands[2] = gen_lowpart (QImode, operands[0]);
12764 (define_insn_and_split "*setcc_si_1_movzbl"
12765 [(set (match_operand:SI 0 "register_operand" "=q")
12766 (match_operator:SI 1 "ix86_comparison_operator"
12767 [(reg FLAGS_REG) (const_int 0)]))]
12768 "!TARGET_PARTIAL_REG_STALL
12769 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12771 "&& reload_completed"
12772 [(set (match_dup 2) (match_dup 1))
12773 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12775 PUT_MODE (operands[1], QImode);
12776 operands[2] = gen_lowpart (QImode, operands[0]);
12779 (define_insn "*setcc_qi"
12780 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12781 (match_operator:QI 1 "ix86_comparison_operator"
12782 [(reg FLAGS_REG) (const_int 0)]))]
12785 [(set_attr "type" "setcc")
12786 (set_attr "mode" "QI")])
12788 (define_insn "*setcc_qi_slp"
12789 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12790 (match_operator:QI 1 "ix86_comparison_operator"
12791 [(reg FLAGS_REG) (const_int 0)]))]
12794 [(set_attr "type" "setcc")
12795 (set_attr "mode" "QI")])
12797 ;; In general it is not safe to assume too much about CCmode registers,
12798 ;; so simplify-rtx stops when it sees a second one. Under certain
12799 ;; conditions this is safe on x86, so help combine not create
12806 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12807 (ne:QI (match_operator 1 "ix86_comparison_operator"
12808 [(reg FLAGS_REG) (const_int 0)])
12811 [(set (match_dup 0) (match_dup 1))]
12813 PUT_MODE (operands[1], QImode);
12817 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12818 (ne:QI (match_operator 1 "ix86_comparison_operator"
12819 [(reg FLAGS_REG) (const_int 0)])
12822 [(set (match_dup 0) (match_dup 1))]
12824 PUT_MODE (operands[1], QImode);
12828 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12829 (eq:QI (match_operator 1 "ix86_comparison_operator"
12830 [(reg FLAGS_REG) (const_int 0)])
12833 [(set (match_dup 0) (match_dup 1))]
12835 rtx new_op1 = copy_rtx (operands[1]);
12836 operands[1] = new_op1;
12837 PUT_MODE (new_op1, QImode);
12838 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12839 GET_MODE (XEXP (new_op1, 0))));
12841 /* Make sure that (a) the CCmode we have for the flags is strong
12842 enough for the reversed compare or (b) we have a valid FP compare. */
12843 if (! ix86_comparison_operator (new_op1, VOIDmode))
12848 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12849 (eq:QI (match_operator 1 "ix86_comparison_operator"
12850 [(reg FLAGS_REG) (const_int 0)])
12853 [(set (match_dup 0) (match_dup 1))]
12855 rtx new_op1 = copy_rtx (operands[1]);
12856 operands[1] = new_op1;
12857 PUT_MODE (new_op1, QImode);
12858 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12859 GET_MODE (XEXP (new_op1, 0))));
12861 /* Make sure that (a) the CCmode we have for the flags is strong
12862 enough for the reversed compare or (b) we have a valid FP compare. */
12863 if (! ix86_comparison_operator (new_op1, VOIDmode))
12867 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12868 ;; subsequent logical operations are used to imitate conditional moves.
12869 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12872 (define_insn "*avx_setcc<mode>"
12873 [(set (match_operand:MODEF 0 "register_operand" "=x")
12874 (match_operator:MODEF 1 "avx_comparison_float_operator"
12875 [(match_operand:MODEF 2 "register_operand" "x")
12876 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12878 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
12879 [(set_attr "type" "ssecmp")
12880 (set_attr "prefix" "vex")
12881 (set_attr "length_immediate" "1")
12882 (set_attr "mode" "<MODE>")])
12884 (define_insn "*sse_setcc<mode>"
12885 [(set (match_operand:MODEF 0 "register_operand" "=x")
12886 (match_operator:MODEF 1 "sse_comparison_operator"
12887 [(match_operand:MODEF 2 "register_operand" "0")
12888 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12889 "SSE_FLOAT_MODE_P (<MODE>mode)"
12890 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
12891 [(set_attr "type" "ssecmp")
12892 (set_attr "length_immediate" "1")
12893 (set_attr "mode" "<MODE>")])
12895 ;; Basic conditional jump instructions.
12896 ;; We ignore the overflow flag for signed branch instructions.
12898 (define_insn "*jcc_1"
12900 (if_then_else (match_operator 1 "ix86_comparison_operator"
12901 [(reg FLAGS_REG) (const_int 0)])
12902 (label_ref (match_operand 0 "" ""))
12906 [(set_attr "type" "ibr")
12907 (set_attr "modrm" "0")
12908 (set (attr "length")
12909 (if_then_else (and (ge (minus (match_dup 0) (pc))
12911 (lt (minus (match_dup 0) (pc))
12916 (define_insn "*jcc_2"
12918 (if_then_else (match_operator 1 "ix86_comparison_operator"
12919 [(reg FLAGS_REG) (const_int 0)])
12921 (label_ref (match_operand 0 "" ""))))]
12924 [(set_attr "type" "ibr")
12925 (set_attr "modrm" "0")
12926 (set (attr "length")
12927 (if_then_else (and (ge (minus (match_dup 0) (pc))
12929 (lt (minus (match_dup 0) (pc))
12934 ;; In general it is not safe to assume too much about CCmode registers,
12935 ;; so simplify-rtx stops when it sees a second one. Under certain
12936 ;; conditions this is safe on x86, so help combine not create
12944 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12945 [(reg FLAGS_REG) (const_int 0)])
12947 (label_ref (match_operand 1 "" ""))
12951 (if_then_else (match_dup 0)
12952 (label_ref (match_dup 1))
12955 PUT_MODE (operands[0], VOIDmode);
12960 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12961 [(reg FLAGS_REG) (const_int 0)])
12963 (label_ref (match_operand 1 "" ""))
12967 (if_then_else (match_dup 0)
12968 (label_ref (match_dup 1))
12971 rtx new_op0 = copy_rtx (operands[0]);
12972 operands[0] = new_op0;
12973 PUT_MODE (new_op0, VOIDmode);
12974 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12975 GET_MODE (XEXP (new_op0, 0))));
12977 /* Make sure that (a) the CCmode we have for the flags is strong
12978 enough for the reversed compare or (b) we have a valid FP compare. */
12979 if (! ix86_comparison_operator (new_op0, VOIDmode))
12983 ;; zero_extend in SImode is correct, since this is what combine pass
12984 ;; generates from shift insn with QImode operand. Actually, the mode of
12985 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
12986 ;; appropriate modulo of the bit offset value.
12988 (define_insn_and_split "*jcc_btdi_rex64"
12990 (if_then_else (match_operator 0 "bt_comparison_operator"
12992 (match_operand:DI 1 "register_operand" "r")
12995 (match_operand:QI 2 "register_operand" "r")))
12997 (label_ref (match_operand 3 "" ""))
12999 (clobber (reg:CC FLAGS_REG))]
13000 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13003 [(set (reg:CCC FLAGS_REG)
13011 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13012 (label_ref (match_dup 3))
13015 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
13017 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13020 ;; avoid useless masking of bit offset operand
13021 (define_insn_and_split "*jcc_btdi_mask_rex64"
13023 (if_then_else (match_operator 0 "bt_comparison_operator"
13025 (match_operand:DI 1 "register_operand" "r")
13028 (match_operand:SI 2 "register_operand" "r")
13029 (match_operand:SI 3 "const_int_operand" "n")))])
13030 (label_ref (match_operand 4 "" ""))
13032 (clobber (reg:CC FLAGS_REG))]
13033 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
13034 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
13037 [(set (reg:CCC FLAGS_REG)
13045 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13046 (label_ref (match_dup 4))
13049 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
13051 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13054 (define_insn_and_split "*jcc_btsi"
13056 (if_then_else (match_operator 0 "bt_comparison_operator"
13058 (match_operand:SI 1 "register_operand" "r")
13061 (match_operand:QI 2 "register_operand" "r")))
13063 (label_ref (match_operand 3 "" ""))
13065 (clobber (reg:CC FLAGS_REG))]
13066 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13069 [(set (reg:CCC FLAGS_REG)
13077 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13078 (label_ref (match_dup 3))
13081 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13083 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13086 ;; avoid useless masking of bit offset operand
13087 (define_insn_and_split "*jcc_btsi_mask"
13089 (if_then_else (match_operator 0 "bt_comparison_operator"
13091 (match_operand:SI 1 "register_operand" "r")
13094 (match_operand:SI 2 "register_operand" "r")
13095 (match_operand:SI 3 "const_int_operand" "n")))])
13096 (label_ref (match_operand 4 "" ""))
13098 (clobber (reg:CC FLAGS_REG))]
13099 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13100 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13103 [(set (reg:CCC FLAGS_REG)
13111 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13112 (label_ref (match_dup 4))
13114 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13116 (define_insn_and_split "*jcc_btsi_1"
13118 (if_then_else (match_operator 0 "bt_comparison_operator"
13121 (match_operand:SI 1 "register_operand" "r")
13122 (match_operand:QI 2 "register_operand" "r"))
13125 (label_ref (match_operand 3 "" ""))
13127 (clobber (reg:CC FLAGS_REG))]
13128 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13131 [(set (reg:CCC FLAGS_REG)
13139 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13140 (label_ref (match_dup 3))
13143 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13145 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13148 ;; avoid useless masking of bit offset operand
13149 (define_insn_and_split "*jcc_btsi_mask_1"
13152 (match_operator 0 "bt_comparison_operator"
13155 (match_operand:SI 1 "register_operand" "r")
13158 (match_operand:SI 2 "register_operand" "r")
13159 (match_operand:SI 3 "const_int_operand" "n")) 0))
13162 (label_ref (match_operand 4 "" ""))
13164 (clobber (reg:CC FLAGS_REG))]
13165 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13166 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13169 [(set (reg:CCC FLAGS_REG)
13177 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13178 (label_ref (match_dup 4))
13180 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13182 ;; Define combination compare-and-branch fp compare instructions to help
13185 (define_insn "*fp_jcc_3_387"
13187 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13188 [(match_operand 1 "register_operand" "f")
13189 (match_operand 2 "nonimmediate_operand" "fm")])
13190 (label_ref (match_operand 3 "" ""))
13192 (clobber (reg:CCFP FPSR_REG))
13193 (clobber (reg:CCFP FLAGS_REG))
13194 (clobber (match_scratch:HI 4 "=a"))]
13196 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13197 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13198 && SELECT_CC_MODE (GET_CODE (operands[0]),
13199 operands[1], operands[2]) == CCFPmode
13203 (define_insn "*fp_jcc_4_387"
13205 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13206 [(match_operand 1 "register_operand" "f")
13207 (match_operand 2 "nonimmediate_operand" "fm")])
13209 (label_ref (match_operand 3 "" ""))))
13210 (clobber (reg:CCFP FPSR_REG))
13211 (clobber (reg:CCFP FLAGS_REG))
13212 (clobber (match_scratch:HI 4 "=a"))]
13214 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13215 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13216 && SELECT_CC_MODE (GET_CODE (operands[0]),
13217 operands[1], operands[2]) == CCFPmode
13221 (define_insn "*fp_jcc_5_387"
13223 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13224 [(match_operand 1 "register_operand" "f")
13225 (match_operand 2 "register_operand" "f")])
13226 (label_ref (match_operand 3 "" ""))
13228 (clobber (reg:CCFP FPSR_REG))
13229 (clobber (reg:CCFP FLAGS_REG))
13230 (clobber (match_scratch:HI 4 "=a"))]
13231 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13232 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13236 (define_insn "*fp_jcc_6_387"
13238 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13239 [(match_operand 1 "register_operand" "f")
13240 (match_operand 2 "register_operand" "f")])
13242 (label_ref (match_operand 3 "" ""))))
13243 (clobber (reg:CCFP FPSR_REG))
13244 (clobber (reg:CCFP FLAGS_REG))
13245 (clobber (match_scratch:HI 4 "=a"))]
13246 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13247 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13251 (define_insn "*fp_jcc_7_387"
13253 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13254 [(match_operand 1 "register_operand" "f")
13255 (match_operand 2 "const0_operand" "")])
13256 (label_ref (match_operand 3 "" ""))
13258 (clobber (reg:CCFP FPSR_REG))
13259 (clobber (reg:CCFP FLAGS_REG))
13260 (clobber (match_scratch:HI 4 "=a"))]
13261 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13262 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13263 && SELECT_CC_MODE (GET_CODE (operands[0]),
13264 operands[1], operands[2]) == CCFPmode
13268 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13269 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13270 ;; with a precedence over other operators and is always put in the first
13271 ;; place. Swap condition and operands to match ficom instruction.
13273 (define_insn "*fp_jcc_8<mode>_387"
13275 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13276 [(match_operator 1 "float_operator"
13277 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13278 (match_operand 3 "register_operand" "f,f")])
13279 (label_ref (match_operand 4 "" ""))
13281 (clobber (reg:CCFP FPSR_REG))
13282 (clobber (reg:CCFP FLAGS_REG))
13283 (clobber (match_scratch:HI 5 "=a,a"))]
13284 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13285 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
13286 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13287 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13293 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13294 [(match_operand 1 "register_operand" "")
13295 (match_operand 2 "nonimmediate_operand" "")])
13296 (match_operand 3 "" "")
13297 (match_operand 4 "" "")))
13298 (clobber (reg:CCFP FPSR_REG))
13299 (clobber (reg:CCFP FLAGS_REG))]
13303 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13304 operands[3], operands[4], NULL_RTX, NULL_RTX);
13310 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13311 [(match_operand 1 "register_operand" "")
13312 (match_operand 2 "general_operand" "")])
13313 (match_operand 3 "" "")
13314 (match_operand 4 "" "")))
13315 (clobber (reg:CCFP FPSR_REG))
13316 (clobber (reg:CCFP FLAGS_REG))
13317 (clobber (match_scratch:HI 5 "=a"))]
13321 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13322 operands[3], operands[4], operands[5], NULL_RTX);
13328 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13329 [(match_operator 1 "float_operator"
13330 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13331 (match_operand 3 "register_operand" "")])
13332 (match_operand 4 "" "")
13333 (match_operand 5 "" "")))
13334 (clobber (reg:CCFP FPSR_REG))
13335 (clobber (reg:CCFP FLAGS_REG))
13336 (clobber (match_scratch:HI 6 "=a"))]
13340 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13341 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13342 operands[3], operands[7],
13343 operands[4], operands[5], operands[6], NULL_RTX);
13347 ;; %%% Kill this when reload knows how to do it.
13350 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13351 [(match_operator 1 "float_operator"
13352 [(match_operand:X87MODEI12 2 "register_operand" "")])
13353 (match_operand 3 "register_operand" "")])
13354 (match_operand 4 "" "")
13355 (match_operand 5 "" "")))
13356 (clobber (reg:CCFP FPSR_REG))
13357 (clobber (reg:CCFP FLAGS_REG))
13358 (clobber (match_scratch:HI 6 "=a"))]
13362 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13363 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13364 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13365 operands[3], operands[7],
13366 operands[4], operands[5], operands[6], operands[2]);
13370 ;; Unconditional and other jump instructions
13372 (define_insn "jump"
13374 (label_ref (match_operand 0 "" "")))]
13377 [(set_attr "type" "ibr")
13378 (set (attr "length")
13379 (if_then_else (and (ge (minus (match_dup 0) (pc))
13381 (lt (minus (match_dup 0) (pc))
13385 (set_attr "modrm" "0")])
13387 (define_expand "indirect_jump"
13388 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
13392 (define_insn "*indirect_jump"
13393 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
13396 [(set_attr "type" "ibr")
13397 (set_attr "length_immediate" "0")])
13399 (define_expand "tablejump"
13400 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
13401 (use (label_ref (match_operand 1 "" "")))])]
13404 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13405 relative. Convert the relative address to an absolute address. */
13409 enum rtx_code code;
13411 /* We can't use @GOTOFF for text labels on VxWorks;
13412 see gotoff_operand. */
13413 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
13417 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13419 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13423 op1 = pic_offset_table_rtx;
13428 op0 = pic_offset_table_rtx;
13432 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13437 (define_insn "*tablejump_1"
13438 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
13439 (use (label_ref (match_operand 1 "" "")))]
13442 [(set_attr "type" "ibr")
13443 (set_attr "length_immediate" "0")])
13445 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13448 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13449 (set (match_operand:QI 1 "register_operand" "")
13450 (match_operator:QI 2 "ix86_comparison_operator"
13451 [(reg FLAGS_REG) (const_int 0)]))
13452 (set (match_operand 3 "q_regs_operand" "")
13453 (zero_extend (match_dup 1)))]
13454 "(peep2_reg_dead_p (3, operands[1])
13455 || operands_match_p (operands[1], operands[3]))
13456 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13457 [(set (match_dup 4) (match_dup 0))
13458 (set (strict_low_part (match_dup 5))
13461 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13462 operands[5] = gen_lowpart (QImode, operands[3]);
13463 ix86_expand_clear (operands[3]);
13466 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13469 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13470 (set (match_operand:QI 1 "register_operand" "")
13471 (match_operator:QI 2 "ix86_comparison_operator"
13472 [(reg FLAGS_REG) (const_int 0)]))
13473 (parallel [(set (match_operand 3 "q_regs_operand" "")
13474 (zero_extend (match_dup 1)))
13475 (clobber (reg:CC FLAGS_REG))])]
13476 "(peep2_reg_dead_p (3, operands[1])
13477 || operands_match_p (operands[1], operands[3]))
13478 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13479 [(set (match_dup 4) (match_dup 0))
13480 (set (strict_low_part (match_dup 5))
13483 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13484 operands[5] = gen_lowpart (QImode, operands[3]);
13485 ix86_expand_clear (operands[3]);
13488 ;; Call instructions.
13490 ;; The predicates normally associated with named expanders are not properly
13491 ;; checked for calls. This is a bug in the generic code, but it isn't that
13492 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13494 ;; P6 processors will jump to the address after the decrement when %esp
13495 ;; is used as a call operand, so they will execute return address as a code.
13496 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
13498 ;; Call subroutine returning no value.
13500 (define_expand "call_pop"
13501 [(parallel [(call (match_operand:QI 0 "" "")
13502 (match_operand:SI 1 "" ""))
13503 (set (reg:SI SP_REG)
13504 (plus:SI (reg:SI SP_REG)
13505 (match_operand:SI 3 "" "")))])]
13508 ix86_expand_call (NULL, operands[0], operands[1],
13509 operands[2], operands[3], 0);
13513 (define_insn "*call_pop_0"
13514 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13515 (match_operand:SI 1 "" ""))
13516 (set (reg:SI SP_REG)
13517 (plus:SI (reg:SI SP_REG)
13518 (match_operand:SI 2 "immediate_operand" "")))]
13521 if (SIBLING_CALL_P (insn))
13524 return "call\t%P0";
13526 [(set_attr "type" "call")])
13528 (define_insn "*call_pop_1"
13529 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13530 (match_operand:SI 1 "" ""))
13531 (set (reg:SI SP_REG)
13532 (plus:SI (reg:SI SP_REG)
13533 (match_operand:SI 2 "immediate_operand" "i")))]
13534 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13536 if (constant_call_address_operand (operands[0], Pmode))
13537 return "call\t%P0";
13538 return "call\t%A0";
13540 [(set_attr "type" "call")])
13542 (define_insn "*sibcall_pop_1"
13543 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13544 (match_operand:SI 1 "" ""))
13545 (set (reg:SI SP_REG)
13546 (plus:SI (reg:SI SP_REG)
13547 (match_operand:SI 2 "immediate_operand" "i,i")))]
13548 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13552 [(set_attr "type" "call")])
13554 (define_expand "call"
13555 [(call (match_operand:QI 0 "" "")
13556 (match_operand 1 "" ""))
13557 (use (match_operand 2 "" ""))]
13560 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13564 (define_expand "sibcall"
13565 [(call (match_operand:QI 0 "" "")
13566 (match_operand 1 "" ""))
13567 (use (match_operand 2 "" ""))]
13570 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13574 (define_insn "*call_0"
13575 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13576 (match_operand 1 "" ""))]
13579 if (SIBLING_CALL_P (insn))
13582 return "call\t%P0";
13584 [(set_attr "type" "call")])
13586 (define_insn "*call_1"
13587 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13588 (match_operand 1 "" ""))]
13589 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13591 if (constant_call_address_operand (operands[0], Pmode))
13592 return "call\t%P0";
13593 return "call\t%A0";
13595 [(set_attr "type" "call")])
13597 (define_insn "*sibcall_1"
13598 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13599 (match_operand 1 "" ""))]
13600 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13604 [(set_attr "type" "call")])
13606 (define_insn "*call_1_rex64"
13607 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13608 (match_operand 1 "" ""))]
13609 "TARGET_64BIT && !SIBLING_CALL_P (insn)
13610 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
13612 if (constant_call_address_operand (operands[0], Pmode))
13613 return "call\t%P0";
13614 return "call\t%A0";
13616 [(set_attr "type" "call")])
13618 (define_insn "*call_1_rex64_ms_sysv"
13619 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13620 (match_operand 1 "" ""))
13621 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
13622 (clobber (reg:TI XMM6_REG))
13623 (clobber (reg:TI XMM7_REG))
13624 (clobber (reg:TI XMM8_REG))
13625 (clobber (reg:TI XMM9_REG))
13626 (clobber (reg:TI XMM10_REG))
13627 (clobber (reg:TI XMM11_REG))
13628 (clobber (reg:TI XMM12_REG))
13629 (clobber (reg:TI XMM13_REG))
13630 (clobber (reg:TI XMM14_REG))
13631 (clobber (reg:TI XMM15_REG))
13632 (clobber (reg:DI SI_REG))
13633 (clobber (reg:DI DI_REG))]
13634 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13636 if (constant_call_address_operand (operands[0], Pmode))
13637 return "call\t%P0";
13638 return "call\t%A0";
13640 [(set_attr "type" "call")])
13642 (define_insn "*call_1_rex64_large"
13643 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
13644 (match_operand 1 "" ""))]
13645 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13647 [(set_attr "type" "call")])
13649 (define_insn "*sibcall_1_rex64"
13650 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
13651 (match_operand 1 "" ""))]
13652 "TARGET_64BIT && SIBLING_CALL_P (insn)"
13656 [(set_attr "type" "call")])
13658 ;; Call subroutine, returning value in operand 0
13659 (define_expand "call_value_pop"
13660 [(parallel [(set (match_operand 0 "" "")
13661 (call (match_operand:QI 1 "" "")
13662 (match_operand:SI 2 "" "")))
13663 (set (reg:SI SP_REG)
13664 (plus:SI (reg:SI SP_REG)
13665 (match_operand:SI 4 "" "")))])]
13668 ix86_expand_call (operands[0], operands[1], operands[2],
13669 operands[3], operands[4], 0);
13673 (define_expand "call_value"
13674 [(set (match_operand 0 "" "")
13675 (call (match_operand:QI 1 "" "")
13676 (match_operand:SI 2 "" "")))
13677 (use (match_operand:SI 3 "" ""))]
13678 ;; Operand 3 is not used on the i386.
13681 ix86_expand_call (operands[0], operands[1], operands[2],
13682 operands[3], NULL, 0);
13686 (define_expand "sibcall_value"
13687 [(set (match_operand 0 "" "")
13688 (call (match_operand:QI 1 "" "")
13689 (match_operand:SI 2 "" "")))
13690 (use (match_operand:SI 3 "" ""))]
13691 ;; Operand 3 is not used on the i386.
13694 ix86_expand_call (operands[0], operands[1], operands[2],
13695 operands[3], NULL, 1);
13699 ;; Call subroutine returning any type.
13701 (define_expand "untyped_call"
13702 [(parallel [(call (match_operand 0 "" "")
13704 (match_operand 1 "" "")
13705 (match_operand 2 "" "")])]
13710 /* In order to give reg-stack an easier job in validating two
13711 coprocessor registers as containing a possible return value,
13712 simply pretend the untyped call returns a complex long double
13715 We can't use SSE_REGPARM_MAX here since callee is unprototyped
13716 and should have the default ABI. */
13718 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13719 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13720 operands[0], const0_rtx,
13721 GEN_INT ((TARGET_64BIT
13722 ? (ix86_abi == SYSV_ABI
13723 ? X86_64_SSE_REGPARM_MAX
13724 : X86_64_MS_SSE_REGPARM_MAX)
13725 : X86_32_SSE_REGPARM_MAX)
13729 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13731 rtx set = XVECEXP (operands[2], 0, i);
13732 emit_move_insn (SET_DEST (set), SET_SRC (set));
13735 /* The optimizer does not know that the call sets the function value
13736 registers we stored in the result block. We avoid problems by
13737 claiming that all hard registers are used and clobbered at this
13739 emit_insn (gen_blockage ());
13744 ;; Prologue and epilogue instructions
13746 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13747 ;; all of memory. This blocks insns from being moved across this point.
13749 (define_insn "blockage"
13750 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13753 [(set_attr "length" "0")])
13755 ;; Do not schedule instructions accessing memory across this point.
13757 (define_expand "memory_blockage"
13758 [(set (match_dup 0)
13759 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13762 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13763 MEM_VOLATILE_P (operands[0]) = 1;
13766 (define_insn "*memory_blockage"
13767 [(set (match_operand:BLK 0 "" "")
13768 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13771 [(set_attr "length" "0")])
13773 ;; As USE insns aren't meaningful after reload, this is used instead
13774 ;; to prevent deleting instructions setting registers for PIC code
13775 (define_insn "prologue_use"
13776 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
13779 [(set_attr "length" "0")])
13781 ;; Insn emitted into the body of a function to return from a function.
13782 ;; This is only done if the function's epilogue is known to be simple.
13783 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13785 (define_expand "return"
13787 "ix86_can_use_return_insn_p ()"
13789 if (crtl->args.pops_args)
13791 rtx popc = GEN_INT (crtl->args.pops_args);
13792 emit_jump_insn (gen_return_pop_internal (popc));
13797 (define_insn "return_internal"
13801 [(set_attr "length" "1")
13802 (set_attr "atom_unit" "jeu")
13803 (set_attr "length_immediate" "0")
13804 (set_attr "modrm" "0")])
13806 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13807 ;; instruction Athlon and K8 have.
13809 (define_insn "return_internal_long"
13811 (unspec [(const_int 0)] UNSPEC_REP)]
13814 [(set_attr "length" "2")
13815 (set_attr "atom_unit" "jeu")
13816 (set_attr "length_immediate" "0")
13817 (set_attr "prefix_rep" "1")
13818 (set_attr "modrm" "0")])
13820 (define_insn "return_pop_internal"
13822 (use (match_operand:SI 0 "const_int_operand" ""))]
13825 [(set_attr "length" "3")
13826 (set_attr "atom_unit" "jeu")
13827 (set_attr "length_immediate" "2")
13828 (set_attr "modrm" "0")])
13830 (define_insn "return_indirect_internal"
13832 (use (match_operand:SI 0 "register_operand" "r"))]
13835 [(set_attr "type" "ibr")
13836 (set_attr "length_immediate" "0")])
13842 [(set_attr "length" "1")
13843 (set_attr "length_immediate" "0")
13844 (set_attr "modrm" "0")])
13846 (define_insn "vswapmov"
13847 [(set (match_operand:SI 0 "register_operand" "=r")
13848 (match_operand:SI 1 "register_operand" "r"))
13849 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
13851 "movl.s\t{%1, %0|%0, %1}"
13852 [(set_attr "length" "2")
13853 (set_attr "length_immediate" "0")
13854 (set_attr "modrm" "0")])
13856 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13857 ;; branch prediction penalty for the third jump in a 16-byte
13861 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13864 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13865 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13867 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13868 The align insn is used to avoid 3 jump instructions in the row to improve
13869 branch prediction and the benefits hardly outweigh the cost of extra 8
13870 nops on the average inserted by full alignment pseudo operation. */
13874 [(set_attr "length" "16")])
13876 (define_expand "prologue"
13879 "ix86_expand_prologue (); DONE;")
13881 (define_insn "set_got"
13882 [(set (match_operand:SI 0 "register_operand" "=r")
13883 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13884 (clobber (reg:CC FLAGS_REG))]
13886 { return output_set_got (operands[0], NULL_RTX); }
13887 [(set_attr "type" "multi")
13888 (set_attr "length" "12")])
13890 (define_insn "set_got_labelled"
13891 [(set (match_operand:SI 0 "register_operand" "=r")
13892 (unspec:SI [(label_ref (match_operand 1 "" ""))]
13894 (clobber (reg:CC FLAGS_REG))]
13896 { return output_set_got (operands[0], operands[1]); }
13897 [(set_attr "type" "multi")
13898 (set_attr "length" "12")])
13900 (define_insn "set_got_rex64"
13901 [(set (match_operand:DI 0 "register_operand" "=r")
13902 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13904 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13905 [(set_attr "type" "lea")
13906 (set_attr "length_address" "4")
13907 (set_attr "mode" "DI")])
13909 (define_insn "set_rip_rex64"
13910 [(set (match_operand:DI 0 "register_operand" "=r")
13911 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
13913 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13914 [(set_attr "type" "lea")
13915 (set_attr "length_address" "4")
13916 (set_attr "mode" "DI")])
13918 (define_insn "set_got_offset_rex64"
13919 [(set (match_operand:DI 0 "register_operand" "=r")
13921 [(label_ref (match_operand 1 "" ""))]
13922 UNSPEC_SET_GOT_OFFSET))]
13924 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13925 [(set_attr "type" "imov")
13926 (set_attr "length_immediate" "0")
13927 (set_attr "length_address" "8")
13928 (set_attr "mode" "DI")])
13930 (define_expand "epilogue"
13933 "ix86_expand_epilogue (1); DONE;")
13935 (define_expand "sibcall_epilogue"
13938 "ix86_expand_epilogue (0); DONE;")
13940 (define_expand "eh_return"
13941 [(use (match_operand 0 "register_operand" ""))]
13944 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13946 /* Tricky bit: we write the address of the handler to which we will
13947 be returning into someone else's stack frame, one word below the
13948 stack address we wish to restore. */
13949 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13950 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13951 tmp = gen_rtx_MEM (Pmode, tmp);
13952 emit_move_insn (tmp, ra);
13954 emit_jump_insn (gen_eh_return_internal ());
13959 (define_insn_and_split "eh_return_internal"
13963 "epilogue_completed"
13965 "ix86_expand_epilogue (2); DONE;")
13967 (define_insn "leave"
13968 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13969 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13970 (clobber (mem:BLK (scratch)))]
13973 [(set_attr "type" "leave")])
13975 (define_insn "leave_rex64"
13976 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13977 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13978 (clobber (mem:BLK (scratch)))]
13981 [(set_attr "type" "leave")])
13983 (define_expand "ffssi2"
13985 [(set (match_operand:SI 0 "register_operand" "")
13986 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13987 (clobber (match_scratch:SI 2 ""))
13988 (clobber (reg:CC FLAGS_REG))])]
13993 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
13998 (define_expand "ffs_cmove"
13999 [(set (match_dup 2) (const_int -1))
14000 (parallel [(set (reg:CCZ FLAGS_REG)
14001 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
14003 (set (match_operand:SI 0 "register_operand" "")
14004 (ctz:SI (match_dup 1)))])
14005 (set (match_dup 0) (if_then_else:SI
14006 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14009 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14010 (clobber (reg:CC FLAGS_REG))])]
14012 "operands[2] = gen_reg_rtx (SImode);")
14014 (define_insn_and_split "*ffs_no_cmove"
14015 [(set (match_operand:SI 0 "register_operand" "=r")
14016 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14017 (clobber (match_scratch:SI 2 "=&q"))
14018 (clobber (reg:CC FLAGS_REG))]
14021 "&& reload_completed"
14022 [(parallel [(set (reg:CCZ FLAGS_REG)
14023 (compare:CCZ (match_dup 1) (const_int 0)))
14024 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14025 (set (strict_low_part (match_dup 3))
14026 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14027 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14028 (clobber (reg:CC FLAGS_REG))])
14029 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14030 (clobber (reg:CC FLAGS_REG))])
14031 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14032 (clobber (reg:CC FLAGS_REG))])]
14034 operands[3] = gen_lowpart (QImode, operands[2]);
14035 ix86_expand_clear (operands[2]);
14038 (define_insn "*ffssi_1"
14039 [(set (reg:CCZ FLAGS_REG)
14040 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14042 (set (match_operand:SI 0 "register_operand" "=r")
14043 (ctz:SI (match_dup 1)))]
14045 "bsf{l}\t{%1, %0|%0, %1}"
14046 [(set_attr "type" "alu1")
14047 (set_attr "prefix_0f" "1")
14048 (set_attr "mode" "SI")])
14050 (define_expand "ffsdi2"
14051 [(set (match_dup 2) (const_int -1))
14052 (parallel [(set (reg:CCZ FLAGS_REG)
14053 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
14055 (set (match_operand:DI 0 "register_operand" "")
14056 (ctz:DI (match_dup 1)))])
14057 (set (match_dup 0) (if_then_else:DI
14058 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14061 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14062 (clobber (reg:CC FLAGS_REG))])]
14064 "operands[2] = gen_reg_rtx (DImode);")
14066 (define_insn "*ffsdi_1"
14067 [(set (reg:CCZ FLAGS_REG)
14068 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14070 (set (match_operand:DI 0 "register_operand" "=r")
14071 (ctz:DI (match_dup 1)))]
14073 "bsf{q}\t{%1, %0|%0, %1}"
14074 [(set_attr "type" "alu1")
14075 (set_attr "prefix_0f" "1")
14076 (set_attr "mode" "DI")])
14078 (define_insn "ctzsi2"
14079 [(set (match_operand:SI 0 "register_operand" "=r")
14080 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14081 (clobber (reg:CC FLAGS_REG))]
14083 "bsf{l}\t{%1, %0|%0, %1}"
14084 [(set_attr "type" "alu1")
14085 (set_attr "prefix_0f" "1")
14086 (set_attr "mode" "SI")])
14088 (define_insn "ctzdi2"
14089 [(set (match_operand:DI 0 "register_operand" "=r")
14090 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14091 (clobber (reg:CC FLAGS_REG))]
14093 "bsf{q}\t{%1, %0|%0, %1}"
14094 [(set_attr "type" "alu1")
14095 (set_attr "prefix_0f" "1")
14096 (set_attr "mode" "DI")])
14098 (define_expand "clzsi2"
14100 [(set (match_operand:SI 0 "register_operand" "")
14101 (minus:SI (const_int 31)
14102 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14103 (clobber (reg:CC FLAGS_REG))])
14105 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14106 (clobber (reg:CC FLAGS_REG))])]
14111 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14116 (define_insn "clzsi2_abm"
14117 [(set (match_operand:SI 0 "register_operand" "=r")
14118 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14119 (clobber (reg:CC FLAGS_REG))]
14121 "lzcnt{l}\t{%1, %0|%0, %1}"
14122 [(set_attr "prefix_rep" "1")
14123 (set_attr "type" "bitmanip")
14124 (set_attr "mode" "SI")])
14127 [(set (match_operand:SI 0 "register_operand" "=r")
14128 (minus:SI (const_int 31)
14129 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14130 (clobber (reg:CC FLAGS_REG))]
14132 "bsr{l}\t{%1, %0|%0, %1}"
14133 [(set_attr "type" "alu1")
14134 (set_attr "prefix_0f" "1")
14135 (set_attr "mode" "SI")])
14137 (define_insn "popcount<mode>2"
14138 [(set (match_operand:SWI248 0 "register_operand" "=r")
14140 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
14141 (clobber (reg:CC FLAGS_REG))]
14145 return "popcnt\t{%1, %0|%0, %1}";
14147 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14150 [(set_attr "prefix_rep" "1")
14151 (set_attr "type" "bitmanip")
14152 (set_attr "mode" "<MODE>")])
14154 (define_insn "*popcount<mode>2_cmp"
14155 [(set (reg FLAGS_REG)
14158 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
14160 (set (match_operand:SWI248 0 "register_operand" "=r")
14161 (popcount:SWI248 (match_dup 1)))]
14162 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14165 return "popcnt\t{%1, %0|%0, %1}";
14167 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14170 [(set_attr "prefix_rep" "1")
14171 (set_attr "type" "bitmanip")
14172 (set_attr "mode" "<MODE>")])
14174 (define_insn "*popcountsi2_cmp_zext"
14175 [(set (reg FLAGS_REG)
14177 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14179 (set (match_operand:DI 0 "register_operand" "=r")
14180 (zero_extend:DI(popcount:SI (match_dup 1))))]
14181 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14184 return "popcnt\t{%1, %0|%0, %1}";
14186 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14189 [(set_attr "prefix_rep" "1")
14190 (set_attr "type" "bitmanip")
14191 (set_attr "mode" "SI")])
14193 (define_expand "bswapsi2"
14194 [(set (match_operand:SI 0 "register_operand" "")
14195 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14198 if (!(TARGET_BSWAP || TARGET_MOVBE))
14200 rtx x = operands[0];
14202 emit_move_insn (x, operands[1]);
14203 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14204 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14205 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14210 (define_insn "*bswapsi_movbe"
14211 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
14212 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
14213 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14216 movbe\t{%1, %0|%0, %1}
14217 movbe\t{%1, %0|%0, %1}"
14218 [(set_attr "type" "*,imov,imov")
14219 (set_attr "modrm" "*,1,1")
14220 (set_attr "prefix_0f" "1")
14221 (set_attr "prefix_extra" "*,1,1")
14222 (set_attr "length" "2,*,*")
14223 (set_attr "mode" "SI")])
14225 (define_insn "*bswapsi_1"
14226 [(set (match_operand:SI 0 "register_operand" "=r")
14227 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14230 [(set_attr "prefix_0f" "1")
14231 (set_attr "length" "2")])
14233 (define_insn "*bswaphi_lowpart_1"
14234 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14235 (bswap:HI (match_dup 0)))
14236 (clobber (reg:CC FLAGS_REG))]
14237 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
14239 xchg{b}\t{%h0, %b0|%b0, %h0}
14240 rol{w}\t{$8, %0|%0, 8}"
14241 [(set_attr "length" "2,4")
14242 (set_attr "mode" "QI,HI")])
14244 (define_insn "bswaphi_lowpart"
14245 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14246 (bswap:HI (match_dup 0)))
14247 (clobber (reg:CC FLAGS_REG))]
14249 "rol{w}\t{$8, %0|%0, 8}"
14250 [(set_attr "length" "4")
14251 (set_attr "mode" "HI")])
14253 (define_expand "bswapdi2"
14254 [(set (match_operand:DI 0 "register_operand" "")
14255 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
14259 (define_insn "*bswapdi_movbe"
14260 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
14261 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
14262 "TARGET_64BIT && TARGET_MOVBE
14263 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14266 movbe\t{%1, %0|%0, %1}
14267 movbe\t{%1, %0|%0, %1}"
14268 [(set_attr "type" "*,imov,imov")
14269 (set_attr "modrm" "*,1,1")
14270 (set_attr "prefix_0f" "1")
14271 (set_attr "prefix_extra" "*,1,1")
14272 (set_attr "length" "3,*,*")
14273 (set_attr "mode" "DI")])
14275 (define_insn "*bswapdi_1"
14276 [(set (match_operand:DI 0 "register_operand" "=r")
14277 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14280 [(set_attr "prefix_0f" "1")
14281 (set_attr "length" "3")])
14283 (define_expand "clzdi2"
14285 [(set (match_operand:DI 0 "register_operand" "")
14286 (minus:DI (const_int 63)
14287 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14288 (clobber (reg:CC FLAGS_REG))])
14290 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14291 (clobber (reg:CC FLAGS_REG))])]
14296 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14301 (define_insn "clzdi2_abm"
14302 [(set (match_operand:DI 0 "register_operand" "=r")
14303 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14304 (clobber (reg:CC FLAGS_REG))]
14305 "TARGET_64BIT && TARGET_ABM"
14306 "lzcnt{q}\t{%1, %0|%0, %1}"
14307 [(set_attr "prefix_rep" "1")
14308 (set_attr "type" "bitmanip")
14309 (set_attr "mode" "DI")])
14311 (define_insn "bsr_rex64"
14312 [(set (match_operand:DI 0 "register_operand" "=r")
14313 (minus:DI (const_int 63)
14314 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14315 (clobber (reg:CC FLAGS_REG))]
14317 "bsr{q}\t{%1, %0|%0, %1}"
14318 [(set_attr "type" "alu1")
14319 (set_attr "prefix_0f" "1")
14320 (set_attr "mode" "DI")])
14322 (define_expand "clzhi2"
14324 [(set (match_operand:HI 0 "register_operand" "")
14325 (minus:HI (const_int 15)
14326 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14327 (clobber (reg:CC FLAGS_REG))])
14329 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14330 (clobber (reg:CC FLAGS_REG))])]
14335 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14340 (define_insn "clzhi2_abm"
14341 [(set (match_operand:HI 0 "register_operand" "=r")
14342 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
14343 (clobber (reg:CC FLAGS_REG))]
14345 "lzcnt{w}\t{%1, %0|%0, %1}"
14346 [(set_attr "prefix_rep" "1")
14347 (set_attr "type" "bitmanip")
14348 (set_attr "mode" "HI")])
14350 (define_insn "*bsrhi"
14351 [(set (match_operand:HI 0 "register_operand" "=r")
14352 (minus:HI (const_int 15)
14353 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14354 (clobber (reg:CC FLAGS_REG))]
14356 "bsr{w}\t{%1, %0|%0, %1}"
14357 [(set_attr "type" "alu1")
14358 (set_attr "prefix_0f" "1")
14359 (set_attr "mode" "HI")])
14361 (define_expand "paritydi2"
14362 [(set (match_operand:DI 0 "register_operand" "")
14363 (parity:DI (match_operand:DI 1 "register_operand" "")))]
14366 rtx scratch = gen_reg_rtx (QImode);
14369 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14370 NULL_RTX, operands[1]));
14372 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14373 gen_rtx_REG (CCmode, FLAGS_REG),
14375 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14378 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14381 rtx tmp = gen_reg_rtx (SImode);
14383 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14384 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14389 (define_insn_and_split "paritydi2_cmp"
14390 [(set (reg:CC FLAGS_REG)
14391 (parity:CC (match_operand:DI 3 "register_operand" "0")))
14392 (clobber (match_scratch:DI 0 "=r"))
14393 (clobber (match_scratch:SI 1 "=&r"))
14394 (clobber (match_scratch:HI 2 "=Q"))]
14397 "&& reload_completed"
14399 [(set (match_dup 1)
14400 (xor:SI (match_dup 1) (match_dup 4)))
14401 (clobber (reg:CC FLAGS_REG))])
14403 [(set (reg:CC FLAGS_REG)
14404 (parity:CC (match_dup 1)))
14405 (clobber (match_dup 1))
14406 (clobber (match_dup 2))])]
14408 operands[4] = gen_lowpart (SImode, operands[3]);
14412 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14413 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14416 operands[1] = gen_highpart (SImode, operands[3]);
14419 (define_expand "paritysi2"
14420 [(set (match_operand:SI 0 "register_operand" "")
14421 (parity:SI (match_operand:SI 1 "register_operand" "")))]
14424 rtx scratch = gen_reg_rtx (QImode);
14427 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14429 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14430 gen_rtx_REG (CCmode, FLAGS_REG),
14432 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14434 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14438 (define_insn_and_split "paritysi2_cmp"
14439 [(set (reg:CC FLAGS_REG)
14440 (parity:CC (match_operand:SI 2 "register_operand" "0")))
14441 (clobber (match_scratch:SI 0 "=r"))
14442 (clobber (match_scratch:HI 1 "=&Q"))]
14445 "&& reload_completed"
14447 [(set (match_dup 1)
14448 (xor:HI (match_dup 1) (match_dup 3)))
14449 (clobber (reg:CC FLAGS_REG))])
14451 [(set (reg:CC FLAGS_REG)
14452 (parity:CC (match_dup 1)))
14453 (clobber (match_dup 1))])]
14455 operands[3] = gen_lowpart (HImode, operands[2]);
14457 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14458 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14461 (define_insn "*parityhi2_cmp"
14462 [(set (reg:CC FLAGS_REG)
14463 (parity:CC (match_operand:HI 1 "register_operand" "0")))
14464 (clobber (match_scratch:HI 0 "=Q"))]
14466 "xor{b}\t{%h0, %b0|%b0, %h0}"
14467 [(set_attr "length" "2")
14468 (set_attr "mode" "HI")])
14470 (define_insn "*parityqi2_cmp"
14471 [(set (reg:CC FLAGS_REG)
14472 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
14475 [(set_attr "length" "2")
14476 (set_attr "mode" "QI")])
14478 ;; Thread-local storage patterns for ELF.
14480 ;; Note that these code sequences must appear exactly as shown
14481 ;; in order to allow linker relaxation.
14483 (define_insn "*tls_global_dynamic_32_gnu"
14484 [(set (match_operand:SI 0 "register_operand" "=a")
14485 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14486 (match_operand:SI 2 "tls_symbolic_operand" "")
14487 (match_operand:SI 3 "call_insn_operand" "")]
14489 (clobber (match_scratch:SI 4 "=d"))
14490 (clobber (match_scratch:SI 5 "=c"))
14491 (clobber (reg:CC FLAGS_REG))]
14492 "!TARGET_64BIT && TARGET_GNU_TLS"
14493 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14494 [(set_attr "type" "multi")
14495 (set_attr "length" "12")])
14497 (define_insn "*tls_global_dynamic_32_sun"
14498 [(set (match_operand:SI 0 "register_operand" "=a")
14499 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14500 (match_operand:SI 2 "tls_symbolic_operand" "")
14501 (match_operand:SI 3 "call_insn_operand" "")]
14503 (clobber (match_scratch:SI 4 "=d"))
14504 (clobber (match_scratch:SI 5 "=c"))
14505 (clobber (reg:CC FLAGS_REG))]
14506 "!TARGET_64BIT && TARGET_SUN_TLS"
14507 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14508 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14509 [(set_attr "type" "multi")
14510 (set_attr "length" "14")])
14512 (define_expand "tls_global_dynamic_32"
14513 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14516 (match_operand:SI 1 "tls_symbolic_operand" "")
14519 (clobber (match_scratch:SI 4 ""))
14520 (clobber (match_scratch:SI 5 ""))
14521 (clobber (reg:CC FLAGS_REG))])]
14525 operands[2] = pic_offset_table_rtx;
14528 operands[2] = gen_reg_rtx (Pmode);
14529 emit_insn (gen_set_got (operands[2]));
14531 if (TARGET_GNU2_TLS)
14533 emit_insn (gen_tls_dynamic_gnu2_32
14534 (operands[0], operands[1], operands[2]));
14537 operands[3] = ix86_tls_get_addr ();
14540 (define_insn "*tls_global_dynamic_64"
14541 [(set (match_operand:DI 0 "register_operand" "=a")
14542 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14543 (match_operand:DI 3 "" "")))
14544 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14547 { 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"; }
14548 [(set_attr "type" "multi")
14549 (set_attr "length" "16")])
14551 (define_expand "tls_global_dynamic_64"
14552 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14553 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14554 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14558 if (TARGET_GNU2_TLS)
14560 emit_insn (gen_tls_dynamic_gnu2_64
14561 (operands[0], operands[1]));
14564 operands[2] = ix86_tls_get_addr ();
14567 (define_insn "*tls_local_dynamic_base_32_gnu"
14568 [(set (match_operand:SI 0 "register_operand" "=a")
14569 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14570 (match_operand:SI 2 "call_insn_operand" "")]
14571 UNSPEC_TLS_LD_BASE))
14572 (clobber (match_scratch:SI 3 "=d"))
14573 (clobber (match_scratch:SI 4 "=c"))
14574 (clobber (reg:CC FLAGS_REG))]
14575 "!TARGET_64BIT && TARGET_GNU_TLS"
14576 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14577 [(set_attr "type" "multi")
14578 (set_attr "length" "11")])
14580 (define_insn "*tls_local_dynamic_base_32_sun"
14581 [(set (match_operand:SI 0 "register_operand" "=a")
14582 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14583 (match_operand:SI 2 "call_insn_operand" "")]
14584 UNSPEC_TLS_LD_BASE))
14585 (clobber (match_scratch:SI 3 "=d"))
14586 (clobber (match_scratch:SI 4 "=c"))
14587 (clobber (reg:CC FLAGS_REG))]
14588 "!TARGET_64BIT && TARGET_SUN_TLS"
14589 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14590 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14591 [(set_attr "type" "multi")
14592 (set_attr "length" "13")])
14594 (define_expand "tls_local_dynamic_base_32"
14595 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14596 (unspec:SI [(match_dup 1) (match_dup 2)]
14597 UNSPEC_TLS_LD_BASE))
14598 (clobber (match_scratch:SI 3 ""))
14599 (clobber (match_scratch:SI 4 ""))
14600 (clobber (reg:CC FLAGS_REG))])]
14604 operands[1] = pic_offset_table_rtx;
14607 operands[1] = gen_reg_rtx (Pmode);
14608 emit_insn (gen_set_got (operands[1]));
14610 if (TARGET_GNU2_TLS)
14612 emit_insn (gen_tls_dynamic_gnu2_32
14613 (operands[0], ix86_tls_module_base (), operands[1]));
14616 operands[2] = ix86_tls_get_addr ();
14619 (define_insn "*tls_local_dynamic_base_64"
14620 [(set (match_operand:DI 0 "register_operand" "=a")
14621 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14622 (match_operand:DI 2 "" "")))
14623 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14625 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
14626 [(set_attr "type" "multi")
14627 (set_attr "length" "12")])
14629 (define_expand "tls_local_dynamic_base_64"
14630 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14631 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14632 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14635 if (TARGET_GNU2_TLS)
14637 emit_insn (gen_tls_dynamic_gnu2_64
14638 (operands[0], ix86_tls_module_base ()));
14641 operands[1] = ix86_tls_get_addr ();
14644 ;; Local dynamic of a single variable is a lose. Show combine how
14645 ;; to convert that back to global dynamic.
14647 (define_insn_and_split "*tls_local_dynamic_32_once"
14648 [(set (match_operand:SI 0 "register_operand" "=a")
14649 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14650 (match_operand:SI 2 "call_insn_operand" "")]
14651 UNSPEC_TLS_LD_BASE)
14652 (const:SI (unspec:SI
14653 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14655 (clobber (match_scratch:SI 4 "=d"))
14656 (clobber (match_scratch:SI 5 "=c"))
14657 (clobber (reg:CC FLAGS_REG))]
14661 [(parallel [(set (match_dup 0)
14662 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14664 (clobber (match_dup 4))
14665 (clobber (match_dup 5))
14666 (clobber (reg:CC FLAGS_REG))])]
14669 ;; Load and add the thread base pointer from %gs:0.
14671 (define_insn "*load_tp_si"
14672 [(set (match_operand:SI 0 "register_operand" "=r")
14673 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14675 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14676 [(set_attr "type" "imov")
14677 (set_attr "modrm" "0")
14678 (set_attr "length" "7")
14679 (set_attr "memory" "load")
14680 (set_attr "imm_disp" "false")])
14682 (define_insn "*add_tp_si"
14683 [(set (match_operand:SI 0 "register_operand" "=r")
14684 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14685 (match_operand:SI 1 "register_operand" "0")))
14686 (clobber (reg:CC FLAGS_REG))]
14688 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14689 [(set_attr "type" "alu")
14690 (set_attr "modrm" "0")
14691 (set_attr "length" "7")
14692 (set_attr "memory" "load")
14693 (set_attr "imm_disp" "false")])
14695 (define_insn "*load_tp_di"
14696 [(set (match_operand:DI 0 "register_operand" "=r")
14697 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14699 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14700 [(set_attr "type" "imov")
14701 (set_attr "modrm" "0")
14702 (set_attr "length" "7")
14703 (set_attr "memory" "load")
14704 (set_attr "imm_disp" "false")])
14706 (define_insn "*add_tp_di"
14707 [(set (match_operand:DI 0 "register_operand" "=r")
14708 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14709 (match_operand:DI 1 "register_operand" "0")))
14710 (clobber (reg:CC FLAGS_REG))]
14712 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14713 [(set_attr "type" "alu")
14714 (set_attr "modrm" "0")
14715 (set_attr "length" "7")
14716 (set_attr "memory" "load")
14717 (set_attr "imm_disp" "false")])
14719 ;; GNU2 TLS patterns can be split.
14721 (define_expand "tls_dynamic_gnu2_32"
14722 [(set (match_dup 3)
14723 (plus:SI (match_operand:SI 2 "register_operand" "")
14725 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14728 [(set (match_operand:SI 0 "register_operand" "")
14729 (unspec:SI [(match_dup 1) (match_dup 3)
14730 (match_dup 2) (reg:SI SP_REG)]
14732 (clobber (reg:CC FLAGS_REG))])]
14733 "!TARGET_64BIT && TARGET_GNU2_TLS"
14735 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14736 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14739 (define_insn "*tls_dynamic_lea_32"
14740 [(set (match_operand:SI 0 "register_operand" "=r")
14741 (plus:SI (match_operand:SI 1 "register_operand" "b")
14743 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14744 UNSPEC_TLSDESC))))]
14745 "!TARGET_64BIT && TARGET_GNU2_TLS"
14746 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14747 [(set_attr "type" "lea")
14748 (set_attr "mode" "SI")
14749 (set_attr "length" "6")
14750 (set_attr "length_address" "4")])
14752 (define_insn "*tls_dynamic_call_32"
14753 [(set (match_operand:SI 0 "register_operand" "=a")
14754 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14755 (match_operand:SI 2 "register_operand" "0")
14756 ;; we have to make sure %ebx still points to the GOT
14757 (match_operand:SI 3 "register_operand" "b")
14760 (clobber (reg:CC FLAGS_REG))]
14761 "!TARGET_64BIT && TARGET_GNU2_TLS"
14762 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14763 [(set_attr "type" "call")
14764 (set_attr "length" "2")
14765 (set_attr "length_address" "0")])
14767 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14768 [(set (match_operand:SI 0 "register_operand" "=&a")
14770 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14771 (match_operand:SI 4 "" "")
14772 (match_operand:SI 2 "register_operand" "b")
14775 (const:SI (unspec:SI
14776 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14778 (clobber (reg:CC FLAGS_REG))]
14779 "!TARGET_64BIT && TARGET_GNU2_TLS"
14782 [(set (match_dup 0) (match_dup 5))]
14784 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14785 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14788 (define_expand "tls_dynamic_gnu2_64"
14789 [(set (match_dup 2)
14790 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14793 [(set (match_operand:DI 0 "register_operand" "")
14794 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14796 (clobber (reg:CC FLAGS_REG))])]
14797 "TARGET_64BIT && TARGET_GNU2_TLS"
14799 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14800 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14803 (define_insn "*tls_dynamic_lea_64"
14804 [(set (match_operand:DI 0 "register_operand" "=r")
14805 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14807 "TARGET_64BIT && TARGET_GNU2_TLS"
14808 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
14809 [(set_attr "type" "lea")
14810 (set_attr "mode" "DI")
14811 (set_attr "length" "7")
14812 (set_attr "length_address" "4")])
14814 (define_insn "*tls_dynamic_call_64"
14815 [(set (match_operand:DI 0 "register_operand" "=a")
14816 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14817 (match_operand:DI 2 "register_operand" "0")
14820 (clobber (reg:CC FLAGS_REG))]
14821 "TARGET_64BIT && TARGET_GNU2_TLS"
14822 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14823 [(set_attr "type" "call")
14824 (set_attr "length" "2")
14825 (set_attr "length_address" "0")])
14827 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14828 [(set (match_operand:DI 0 "register_operand" "=&a")
14830 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14831 (match_operand:DI 3 "" "")
14834 (const:DI (unspec:DI
14835 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14837 (clobber (reg:CC FLAGS_REG))]
14838 "TARGET_64BIT && TARGET_GNU2_TLS"
14841 [(set (match_dup 0) (match_dup 4))]
14843 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14844 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14849 ;; These patterns match the binary 387 instructions for addM3, subM3,
14850 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14851 ;; SFmode. The first is the normal insn, the second the same insn but
14852 ;; with one operand a conversion, and the third the same insn but with
14853 ;; the other operand a conversion. The conversion may be SFmode or
14854 ;; SImode if the target mode DFmode, but only SImode if the target mode
14857 ;; Gcc is slightly more smart about handling normal two address instructions
14858 ;; so use special patterns for add and mull.
14860 (define_insn "*fop_<mode>_comm_mixed_avx"
14861 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14862 (match_operator:MODEF 3 "binary_fp_operator"
14863 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
14864 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14865 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14866 && COMMUTATIVE_ARITH_P (operands[3])
14867 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14868 "* return output_387_binary_op (insn, operands);"
14869 [(set (attr "type")
14870 (if_then_else (eq_attr "alternative" "1")
14871 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14872 (const_string "ssemul")
14873 (const_string "sseadd"))
14874 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14875 (const_string "fmul")
14876 (const_string "fop"))))
14877 (set_attr "prefix" "orig,maybe_vex")
14878 (set_attr "mode" "<MODE>")])
14880 (define_insn "*fop_<mode>_comm_mixed"
14881 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14882 (match_operator:MODEF 3 "binary_fp_operator"
14883 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
14884 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14885 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14886 && COMMUTATIVE_ARITH_P (operands[3])
14887 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14888 "* return output_387_binary_op (insn, operands);"
14889 [(set (attr "type")
14890 (if_then_else (eq_attr "alternative" "1")
14891 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14892 (const_string "ssemul")
14893 (const_string "sseadd"))
14894 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14895 (const_string "fmul")
14896 (const_string "fop"))))
14897 (set_attr "mode" "<MODE>")])
14899 (define_insn "*fop_<mode>_comm_avx"
14900 [(set (match_operand:MODEF 0 "register_operand" "=x")
14901 (match_operator:MODEF 3 "binary_fp_operator"
14902 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
14903 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14904 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14905 && COMMUTATIVE_ARITH_P (operands[3])
14906 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14907 "* return output_387_binary_op (insn, operands);"
14908 [(set (attr "type")
14909 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14910 (const_string "ssemul")
14911 (const_string "sseadd")))
14912 (set_attr "prefix" "vex")
14913 (set_attr "mode" "<MODE>")])
14915 (define_insn "*fop_<mode>_comm_sse"
14916 [(set (match_operand:MODEF 0 "register_operand" "=x")
14917 (match_operator:MODEF 3 "binary_fp_operator"
14918 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14919 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14920 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14921 && COMMUTATIVE_ARITH_P (operands[3])
14922 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14923 "* return output_387_binary_op (insn, operands);"
14924 [(set (attr "type")
14925 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14926 (const_string "ssemul")
14927 (const_string "sseadd")))
14928 (set_attr "mode" "<MODE>")])
14930 (define_insn "*fop_<mode>_comm_i387"
14931 [(set (match_operand:MODEF 0 "register_operand" "=f")
14932 (match_operator:MODEF 3 "binary_fp_operator"
14933 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14934 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
14935 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14936 && COMMUTATIVE_ARITH_P (operands[3])
14937 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14938 "* return output_387_binary_op (insn, operands);"
14939 [(set (attr "type")
14940 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14941 (const_string "fmul")
14942 (const_string "fop")))
14943 (set_attr "mode" "<MODE>")])
14945 (define_insn "*fop_<mode>_1_mixed_avx"
14946 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14947 (match_operator:MODEF 3 "binary_fp_operator"
14948 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
14949 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14950 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14951 && !COMMUTATIVE_ARITH_P (operands[3])
14952 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14953 "* return output_387_binary_op (insn, operands);"
14954 [(set (attr "type")
14955 (cond [(and (eq_attr "alternative" "2")
14956 (match_operand:MODEF 3 "mult_operator" ""))
14957 (const_string "ssemul")
14958 (and (eq_attr "alternative" "2")
14959 (match_operand:MODEF 3 "div_operator" ""))
14960 (const_string "ssediv")
14961 (eq_attr "alternative" "2")
14962 (const_string "sseadd")
14963 (match_operand:MODEF 3 "mult_operator" "")
14964 (const_string "fmul")
14965 (match_operand:MODEF 3 "div_operator" "")
14966 (const_string "fdiv")
14968 (const_string "fop")))
14969 (set_attr "prefix" "orig,orig,maybe_vex")
14970 (set_attr "mode" "<MODE>")])
14972 (define_insn "*fop_<mode>_1_mixed"
14973 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14974 (match_operator:MODEF 3 "binary_fp_operator"
14975 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
14976 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14977 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14978 && !COMMUTATIVE_ARITH_P (operands[3])
14979 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14980 "* return output_387_binary_op (insn, operands);"
14981 [(set (attr "type")
14982 (cond [(and (eq_attr "alternative" "2")
14983 (match_operand:MODEF 3 "mult_operator" ""))
14984 (const_string "ssemul")
14985 (and (eq_attr "alternative" "2")
14986 (match_operand:MODEF 3 "div_operator" ""))
14987 (const_string "ssediv")
14988 (eq_attr "alternative" "2")
14989 (const_string "sseadd")
14990 (match_operand:MODEF 3 "mult_operator" "")
14991 (const_string "fmul")
14992 (match_operand:MODEF 3 "div_operator" "")
14993 (const_string "fdiv")
14995 (const_string "fop")))
14996 (set_attr "mode" "<MODE>")])
14998 (define_insn "*rcpsf2_sse"
14999 [(set (match_operand:SF 0 "register_operand" "=x")
15000 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15003 "%vrcpss\t{%1, %d0|%d0, %1}"
15004 [(set_attr "type" "sse")
15005 (set_attr "atom_sse_attr" "rcp")
15006 (set_attr "prefix" "maybe_vex")
15007 (set_attr "mode" "SF")])
15009 (define_insn "*fop_<mode>_1_avx"
15010 [(set (match_operand:MODEF 0 "register_operand" "=x")
15011 (match_operator:MODEF 3 "binary_fp_operator"
15012 [(match_operand:MODEF 1 "register_operand" "x")
15013 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15014 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15015 && !COMMUTATIVE_ARITH_P (operands[3])"
15016 "* return output_387_binary_op (insn, operands);"
15017 [(set (attr "type")
15018 (cond [(match_operand:MODEF 3 "mult_operator" "")
15019 (const_string "ssemul")
15020 (match_operand:MODEF 3 "div_operator" "")
15021 (const_string "ssediv")
15023 (const_string "sseadd")))
15024 (set_attr "prefix" "vex")
15025 (set_attr "mode" "<MODE>")])
15027 (define_insn "*fop_<mode>_1_sse"
15028 [(set (match_operand:MODEF 0 "register_operand" "=x")
15029 (match_operator:MODEF 3 "binary_fp_operator"
15030 [(match_operand:MODEF 1 "register_operand" "0")
15031 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15032 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15033 && !COMMUTATIVE_ARITH_P (operands[3])"
15034 "* return output_387_binary_op (insn, operands);"
15035 [(set (attr "type")
15036 (cond [(match_operand:MODEF 3 "mult_operator" "")
15037 (const_string "ssemul")
15038 (match_operand:MODEF 3 "div_operator" "")
15039 (const_string "ssediv")
15041 (const_string "sseadd")))
15042 (set_attr "mode" "<MODE>")])
15044 ;; This pattern is not fully shadowed by the pattern above.
15045 (define_insn "*fop_<mode>_1_i387"
15046 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15047 (match_operator:MODEF 3 "binary_fp_operator"
15048 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
15049 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
15050 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15051 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15052 && !COMMUTATIVE_ARITH_P (operands[3])
15053 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15054 "* return output_387_binary_op (insn, operands);"
15055 [(set (attr "type")
15056 (cond [(match_operand:MODEF 3 "mult_operator" "")
15057 (const_string "fmul")
15058 (match_operand:MODEF 3 "div_operator" "")
15059 (const_string "fdiv")
15061 (const_string "fop")))
15062 (set_attr "mode" "<MODE>")])
15064 ;; ??? Add SSE splitters for these!
15065 (define_insn "*fop_<MODEF:mode>_2_i387"
15066 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15067 (match_operator:MODEF 3 "binary_fp_operator"
15069 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15070 (match_operand:MODEF 2 "register_operand" "0,0")]))]
15071 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15072 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15073 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15074 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15075 [(set (attr "type")
15076 (cond [(match_operand:MODEF 3 "mult_operator" "")
15077 (const_string "fmul")
15078 (match_operand:MODEF 3 "div_operator" "")
15079 (const_string "fdiv")
15081 (const_string "fop")))
15082 (set_attr "fp_int_src" "true")
15083 (set_attr "mode" "<X87MODEI12:MODE>")])
15085 (define_insn "*fop_<MODEF:mode>_3_i387"
15086 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15087 (match_operator:MODEF 3 "binary_fp_operator"
15088 [(match_operand:MODEF 1 "register_operand" "0,0")
15090 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15091 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15092 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15093 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15094 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15095 [(set (attr "type")
15096 (cond [(match_operand:MODEF 3 "mult_operator" "")
15097 (const_string "fmul")
15098 (match_operand:MODEF 3 "div_operator" "")
15099 (const_string "fdiv")
15101 (const_string "fop")))
15102 (set_attr "fp_int_src" "true")
15103 (set_attr "mode" "<MODE>")])
15105 (define_insn "*fop_df_4_i387"
15106 [(set (match_operand:DF 0 "register_operand" "=f,f")
15107 (match_operator:DF 3 "binary_fp_operator"
15109 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15110 (match_operand:DF 2 "register_operand" "0,f")]))]
15111 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15112 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15113 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15114 "* return output_387_binary_op (insn, operands);"
15115 [(set (attr "type")
15116 (cond [(match_operand:DF 3 "mult_operator" "")
15117 (const_string "fmul")
15118 (match_operand:DF 3 "div_operator" "")
15119 (const_string "fdiv")
15121 (const_string "fop")))
15122 (set_attr "mode" "SF")])
15124 (define_insn "*fop_df_5_i387"
15125 [(set (match_operand:DF 0 "register_operand" "=f,f")
15126 (match_operator:DF 3 "binary_fp_operator"
15127 [(match_operand:DF 1 "register_operand" "0,f")
15129 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15130 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15131 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15132 "* return output_387_binary_op (insn, operands);"
15133 [(set (attr "type")
15134 (cond [(match_operand:DF 3 "mult_operator" "")
15135 (const_string "fmul")
15136 (match_operand:DF 3 "div_operator" "")
15137 (const_string "fdiv")
15139 (const_string "fop")))
15140 (set_attr "mode" "SF")])
15142 (define_insn "*fop_df_6_i387"
15143 [(set (match_operand:DF 0 "register_operand" "=f,f")
15144 (match_operator:DF 3 "binary_fp_operator"
15146 (match_operand:SF 1 "register_operand" "0,f"))
15148 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15149 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15150 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15151 "* return output_387_binary_op (insn, operands);"
15152 [(set (attr "type")
15153 (cond [(match_operand:DF 3 "mult_operator" "")
15154 (const_string "fmul")
15155 (match_operand:DF 3 "div_operator" "")
15156 (const_string "fdiv")
15158 (const_string "fop")))
15159 (set_attr "mode" "SF")])
15161 (define_insn "*fop_xf_comm_i387"
15162 [(set (match_operand:XF 0 "register_operand" "=f")
15163 (match_operator:XF 3 "binary_fp_operator"
15164 [(match_operand:XF 1 "register_operand" "%0")
15165 (match_operand:XF 2 "register_operand" "f")]))]
15167 && COMMUTATIVE_ARITH_P (operands[3])"
15168 "* return output_387_binary_op (insn, operands);"
15169 [(set (attr "type")
15170 (if_then_else (match_operand:XF 3 "mult_operator" "")
15171 (const_string "fmul")
15172 (const_string "fop")))
15173 (set_attr "mode" "XF")])
15175 (define_insn "*fop_xf_1_i387"
15176 [(set (match_operand:XF 0 "register_operand" "=f,f")
15177 (match_operator:XF 3 "binary_fp_operator"
15178 [(match_operand:XF 1 "register_operand" "0,f")
15179 (match_operand:XF 2 "register_operand" "f,0")]))]
15181 && !COMMUTATIVE_ARITH_P (operands[3])"
15182 "* return output_387_binary_op (insn, operands);"
15183 [(set (attr "type")
15184 (cond [(match_operand:XF 3 "mult_operator" "")
15185 (const_string "fmul")
15186 (match_operand:XF 3 "div_operator" "")
15187 (const_string "fdiv")
15189 (const_string "fop")))
15190 (set_attr "mode" "XF")])
15192 (define_insn "*fop_xf_2_i387"
15193 [(set (match_operand:XF 0 "register_operand" "=f,f")
15194 (match_operator:XF 3 "binary_fp_operator"
15196 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15197 (match_operand:XF 2 "register_operand" "0,0")]))]
15198 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15199 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15200 [(set (attr "type")
15201 (cond [(match_operand:XF 3 "mult_operator" "")
15202 (const_string "fmul")
15203 (match_operand:XF 3 "div_operator" "")
15204 (const_string "fdiv")
15206 (const_string "fop")))
15207 (set_attr "fp_int_src" "true")
15208 (set_attr "mode" "<MODE>")])
15210 (define_insn "*fop_xf_3_i387"
15211 [(set (match_operand:XF 0 "register_operand" "=f,f")
15212 (match_operator:XF 3 "binary_fp_operator"
15213 [(match_operand:XF 1 "register_operand" "0,0")
15215 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15216 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15217 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15218 [(set (attr "type")
15219 (cond [(match_operand:XF 3 "mult_operator" "")
15220 (const_string "fmul")
15221 (match_operand:XF 3 "div_operator" "")
15222 (const_string "fdiv")
15224 (const_string "fop")))
15225 (set_attr "fp_int_src" "true")
15226 (set_attr "mode" "<MODE>")])
15228 (define_insn "*fop_xf_4_i387"
15229 [(set (match_operand:XF 0 "register_operand" "=f,f")
15230 (match_operator:XF 3 "binary_fp_operator"
15232 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15233 (match_operand:XF 2 "register_operand" "0,f")]))]
15235 "* return output_387_binary_op (insn, operands);"
15236 [(set (attr "type")
15237 (cond [(match_operand:XF 3 "mult_operator" "")
15238 (const_string "fmul")
15239 (match_operand:XF 3 "div_operator" "")
15240 (const_string "fdiv")
15242 (const_string "fop")))
15243 (set_attr "mode" "<MODE>")])
15245 (define_insn "*fop_xf_5_i387"
15246 [(set (match_operand:XF 0 "register_operand" "=f,f")
15247 (match_operator:XF 3 "binary_fp_operator"
15248 [(match_operand:XF 1 "register_operand" "0,f")
15250 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15252 "* return output_387_binary_op (insn, operands);"
15253 [(set (attr "type")
15254 (cond [(match_operand:XF 3 "mult_operator" "")
15255 (const_string "fmul")
15256 (match_operand:XF 3 "div_operator" "")
15257 (const_string "fdiv")
15259 (const_string "fop")))
15260 (set_attr "mode" "<MODE>")])
15262 (define_insn "*fop_xf_6_i387"
15263 [(set (match_operand:XF 0 "register_operand" "=f,f")
15264 (match_operator:XF 3 "binary_fp_operator"
15266 (match_operand:MODEF 1 "register_operand" "0,f"))
15268 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15270 "* return output_387_binary_op (insn, operands);"
15271 [(set (attr "type")
15272 (cond [(match_operand:XF 3 "mult_operator" "")
15273 (const_string "fmul")
15274 (match_operand:XF 3 "div_operator" "")
15275 (const_string "fdiv")
15277 (const_string "fop")))
15278 (set_attr "mode" "<MODE>")])
15281 [(set (match_operand 0 "register_operand" "")
15282 (match_operator 3 "binary_fp_operator"
15283 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15284 (match_operand 2 "register_operand" "")]))]
15286 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15287 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
15290 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15291 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15292 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15293 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15294 GET_MODE (operands[3]),
15297 ix86_free_from_memory (GET_MODE (operands[1]));
15302 [(set (match_operand 0 "register_operand" "")
15303 (match_operator 3 "binary_fp_operator"
15304 [(match_operand 1 "register_operand" "")
15305 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15307 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15308 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
15311 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15312 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15313 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15314 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15315 GET_MODE (operands[3]),
15318 ix86_free_from_memory (GET_MODE (operands[2]));
15322 ;; FPU special functions.
15324 ;; This pattern implements a no-op XFmode truncation for
15325 ;; all fancy i386 XFmode math functions.
15327 (define_insn "truncxf<mode>2_i387_noop_unspec"
15328 [(set (match_operand:MODEF 0 "register_operand" "=f")
15329 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15330 UNSPEC_TRUNC_NOOP))]
15331 "TARGET_USE_FANCY_MATH_387"
15332 "* return output_387_reg_move (insn, operands);"
15333 [(set_attr "type" "fmov")
15334 (set_attr "mode" "<MODE>")])
15336 (define_insn "sqrtxf2"
15337 [(set (match_operand:XF 0 "register_operand" "=f")
15338 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15339 "TARGET_USE_FANCY_MATH_387"
15341 [(set_attr "type" "fpspc")
15342 (set_attr "mode" "XF")
15343 (set_attr "athlon_decode" "direct")
15344 (set_attr "amdfam10_decode" "direct")])
15346 (define_insn "sqrt_extend<mode>xf2_i387"
15347 [(set (match_operand:XF 0 "register_operand" "=f")
15350 (match_operand:MODEF 1 "register_operand" "0"))))]
15351 "TARGET_USE_FANCY_MATH_387"
15353 [(set_attr "type" "fpspc")
15354 (set_attr "mode" "XF")
15355 (set_attr "athlon_decode" "direct")
15356 (set_attr "amdfam10_decode" "direct")])
15358 (define_insn "*rsqrtsf2_sse"
15359 [(set (match_operand:SF 0 "register_operand" "=x")
15360 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15363 "%vrsqrtss\t{%1, %d0|%d0, %1}"
15364 [(set_attr "type" "sse")
15365 (set_attr "atom_sse_attr" "rcp")
15366 (set_attr "prefix" "maybe_vex")
15367 (set_attr "mode" "SF")])
15369 (define_expand "rsqrtsf2"
15370 [(set (match_operand:SF 0 "register_operand" "")
15371 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
15375 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15379 (define_insn "*sqrt<mode>2_sse"
15380 [(set (match_operand:MODEF 0 "register_operand" "=x")
15382 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
15383 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15384 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
15385 [(set_attr "type" "sse")
15386 (set_attr "atom_sse_attr" "sqrt")
15387 (set_attr "prefix" "maybe_vex")
15388 (set_attr "mode" "<MODE>")
15389 (set_attr "athlon_decode" "*")
15390 (set_attr "amdfam10_decode" "*")])
15392 (define_expand "sqrt<mode>2"
15393 [(set (match_operand:MODEF 0 "register_operand" "")
15395 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
15396 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15397 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15399 if (<MODE>mode == SFmode
15400 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
15401 && flag_finite_math_only && !flag_trapping_math
15402 && flag_unsafe_math_optimizations)
15404 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15408 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15410 rtx op0 = gen_reg_rtx (XFmode);
15411 rtx op1 = force_reg (<MODE>mode, operands[1]);
15413 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15414 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15419 (define_insn "fpremxf4_i387"
15420 [(set (match_operand:XF 0 "register_operand" "=f")
15421 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15422 (match_operand:XF 3 "register_operand" "1")]
15424 (set (match_operand:XF 1 "register_operand" "=u")
15425 (unspec:XF [(match_dup 2) (match_dup 3)]
15427 (set (reg:CCFP FPSR_REG)
15428 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15430 "TARGET_USE_FANCY_MATH_387"
15432 [(set_attr "type" "fpspc")
15433 (set_attr "mode" "XF")])
15435 (define_expand "fmodxf3"
15436 [(use (match_operand:XF 0 "register_operand" ""))
15437 (use (match_operand:XF 1 "general_operand" ""))
15438 (use (match_operand:XF 2 "general_operand" ""))]
15439 "TARGET_USE_FANCY_MATH_387"
15441 rtx label = gen_label_rtx ();
15443 rtx op1 = gen_reg_rtx (XFmode);
15444 rtx op2 = gen_reg_rtx (XFmode);
15446 emit_move_insn (op2, operands[2]);
15447 emit_move_insn (op1, operands[1]);
15449 emit_label (label);
15450 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15451 ix86_emit_fp_unordered_jump (label);
15452 LABEL_NUSES (label) = 1;
15454 emit_move_insn (operands[0], op1);
15458 (define_expand "fmod<mode>3"
15459 [(use (match_operand:MODEF 0 "register_operand" ""))
15460 (use (match_operand:MODEF 1 "general_operand" ""))
15461 (use (match_operand:MODEF 2 "general_operand" ""))]
15462 "TARGET_USE_FANCY_MATH_387"
15464 rtx label = gen_label_rtx ();
15466 rtx op1 = gen_reg_rtx (XFmode);
15467 rtx op2 = gen_reg_rtx (XFmode);
15469 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15470 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15472 emit_label (label);
15473 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15474 ix86_emit_fp_unordered_jump (label);
15475 LABEL_NUSES (label) = 1;
15477 /* Truncate the result properly for strict SSE math. */
15478 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15479 && !TARGET_MIX_SSE_I387)
15480 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15482 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15487 (define_insn "fprem1xf4_i387"
15488 [(set (match_operand:XF 0 "register_operand" "=f")
15489 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15490 (match_operand:XF 3 "register_operand" "1")]
15492 (set (match_operand:XF 1 "register_operand" "=u")
15493 (unspec:XF [(match_dup 2) (match_dup 3)]
15495 (set (reg:CCFP FPSR_REG)
15496 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15498 "TARGET_USE_FANCY_MATH_387"
15500 [(set_attr "type" "fpspc")
15501 (set_attr "mode" "XF")])
15503 (define_expand "remainderxf3"
15504 [(use (match_operand:XF 0 "register_operand" ""))
15505 (use (match_operand:XF 1 "general_operand" ""))
15506 (use (match_operand:XF 2 "general_operand" ""))]
15507 "TARGET_USE_FANCY_MATH_387"
15509 rtx label = gen_label_rtx ();
15511 rtx op1 = gen_reg_rtx (XFmode);
15512 rtx op2 = gen_reg_rtx (XFmode);
15514 emit_move_insn (op2, operands[2]);
15515 emit_move_insn (op1, operands[1]);
15517 emit_label (label);
15518 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15519 ix86_emit_fp_unordered_jump (label);
15520 LABEL_NUSES (label) = 1;
15522 emit_move_insn (operands[0], op1);
15526 (define_expand "remainder<mode>3"
15527 [(use (match_operand:MODEF 0 "register_operand" ""))
15528 (use (match_operand:MODEF 1 "general_operand" ""))
15529 (use (match_operand:MODEF 2 "general_operand" ""))]
15530 "TARGET_USE_FANCY_MATH_387"
15532 rtx label = gen_label_rtx ();
15534 rtx op1 = gen_reg_rtx (XFmode);
15535 rtx op2 = gen_reg_rtx (XFmode);
15537 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15538 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15540 emit_label (label);
15542 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15543 ix86_emit_fp_unordered_jump (label);
15544 LABEL_NUSES (label) = 1;
15546 /* Truncate the result properly for strict SSE math. */
15547 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15548 && !TARGET_MIX_SSE_I387)
15549 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15551 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15556 (define_insn "*sinxf2_i387"
15557 [(set (match_operand:XF 0 "register_operand" "=f")
15558 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15559 "TARGET_USE_FANCY_MATH_387
15560 && flag_unsafe_math_optimizations"
15562 [(set_attr "type" "fpspc")
15563 (set_attr "mode" "XF")])
15565 (define_insn "*sin_extend<mode>xf2_i387"
15566 [(set (match_operand:XF 0 "register_operand" "=f")
15567 (unspec:XF [(float_extend:XF
15568 (match_operand:MODEF 1 "register_operand" "0"))]
15570 "TARGET_USE_FANCY_MATH_387
15571 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15572 || TARGET_MIX_SSE_I387)
15573 && flag_unsafe_math_optimizations"
15575 [(set_attr "type" "fpspc")
15576 (set_attr "mode" "XF")])
15578 (define_insn "*cosxf2_i387"
15579 [(set (match_operand:XF 0 "register_operand" "=f")
15580 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15581 "TARGET_USE_FANCY_MATH_387
15582 && flag_unsafe_math_optimizations"
15584 [(set_attr "type" "fpspc")
15585 (set_attr "mode" "XF")])
15587 (define_insn "*cos_extend<mode>xf2_i387"
15588 [(set (match_operand:XF 0 "register_operand" "=f")
15589 (unspec:XF [(float_extend:XF
15590 (match_operand:MODEF 1 "register_operand" "0"))]
15592 "TARGET_USE_FANCY_MATH_387
15593 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15594 || TARGET_MIX_SSE_I387)
15595 && flag_unsafe_math_optimizations"
15597 [(set_attr "type" "fpspc")
15598 (set_attr "mode" "XF")])
15600 ;; When sincos pattern is defined, sin and cos builtin functions will be
15601 ;; expanded to sincos pattern with one of its outputs left unused.
15602 ;; CSE pass will figure out if two sincos patterns can be combined,
15603 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15604 ;; depending on the unused output.
15606 (define_insn "sincosxf3"
15607 [(set (match_operand:XF 0 "register_operand" "=f")
15608 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15609 UNSPEC_SINCOS_COS))
15610 (set (match_operand:XF 1 "register_operand" "=u")
15611 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15612 "TARGET_USE_FANCY_MATH_387
15613 && flag_unsafe_math_optimizations"
15615 [(set_attr "type" "fpspc")
15616 (set_attr "mode" "XF")])
15619 [(set (match_operand:XF 0 "register_operand" "")
15620 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15621 UNSPEC_SINCOS_COS))
15622 (set (match_operand:XF 1 "register_operand" "")
15623 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15624 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15625 && !(reload_completed || reload_in_progress)"
15626 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15630 [(set (match_operand:XF 0 "register_operand" "")
15631 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15632 UNSPEC_SINCOS_COS))
15633 (set (match_operand:XF 1 "register_operand" "")
15634 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15635 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15636 && !(reload_completed || reload_in_progress)"
15637 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15640 (define_insn "sincos_extend<mode>xf3_i387"
15641 [(set (match_operand:XF 0 "register_operand" "=f")
15642 (unspec:XF [(float_extend:XF
15643 (match_operand:MODEF 2 "register_operand" "0"))]
15644 UNSPEC_SINCOS_COS))
15645 (set (match_operand:XF 1 "register_operand" "=u")
15646 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15647 "TARGET_USE_FANCY_MATH_387
15648 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15649 || TARGET_MIX_SSE_I387)
15650 && flag_unsafe_math_optimizations"
15652 [(set_attr "type" "fpspc")
15653 (set_attr "mode" "XF")])
15656 [(set (match_operand:XF 0 "register_operand" "")
15657 (unspec:XF [(float_extend:XF
15658 (match_operand:MODEF 2 "register_operand" ""))]
15659 UNSPEC_SINCOS_COS))
15660 (set (match_operand:XF 1 "register_operand" "")
15661 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15662 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15663 && !(reload_completed || reload_in_progress)"
15664 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15668 [(set (match_operand:XF 0 "register_operand" "")
15669 (unspec:XF [(float_extend:XF
15670 (match_operand:MODEF 2 "register_operand" ""))]
15671 UNSPEC_SINCOS_COS))
15672 (set (match_operand:XF 1 "register_operand" "")
15673 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15674 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15675 && !(reload_completed || reload_in_progress)"
15676 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15679 (define_expand "sincos<mode>3"
15680 [(use (match_operand:MODEF 0 "register_operand" ""))
15681 (use (match_operand:MODEF 1 "register_operand" ""))
15682 (use (match_operand:MODEF 2 "register_operand" ""))]
15683 "TARGET_USE_FANCY_MATH_387
15684 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15685 || TARGET_MIX_SSE_I387)
15686 && flag_unsafe_math_optimizations"
15688 rtx op0 = gen_reg_rtx (XFmode);
15689 rtx op1 = gen_reg_rtx (XFmode);
15691 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15692 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15693 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15697 (define_insn "fptanxf4_i387"
15698 [(set (match_operand:XF 0 "register_operand" "=f")
15699 (match_operand:XF 3 "const_double_operand" "F"))
15700 (set (match_operand:XF 1 "register_operand" "=u")
15701 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15703 "TARGET_USE_FANCY_MATH_387
15704 && flag_unsafe_math_optimizations
15705 && standard_80387_constant_p (operands[3]) == 2"
15707 [(set_attr "type" "fpspc")
15708 (set_attr "mode" "XF")])
15710 (define_insn "fptan_extend<mode>xf4_i387"
15711 [(set (match_operand:MODEF 0 "register_operand" "=f")
15712 (match_operand:MODEF 3 "const_double_operand" "F"))
15713 (set (match_operand:XF 1 "register_operand" "=u")
15714 (unspec:XF [(float_extend:XF
15715 (match_operand:MODEF 2 "register_operand" "0"))]
15717 "TARGET_USE_FANCY_MATH_387
15718 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15719 || TARGET_MIX_SSE_I387)
15720 && flag_unsafe_math_optimizations
15721 && standard_80387_constant_p (operands[3]) == 2"
15723 [(set_attr "type" "fpspc")
15724 (set_attr "mode" "XF")])
15726 (define_expand "tanxf2"
15727 [(use (match_operand:XF 0 "register_operand" ""))
15728 (use (match_operand:XF 1 "register_operand" ""))]
15729 "TARGET_USE_FANCY_MATH_387
15730 && flag_unsafe_math_optimizations"
15732 rtx one = gen_reg_rtx (XFmode);
15733 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15735 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15739 (define_expand "tan<mode>2"
15740 [(use (match_operand:MODEF 0 "register_operand" ""))
15741 (use (match_operand:MODEF 1 "register_operand" ""))]
15742 "TARGET_USE_FANCY_MATH_387
15743 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15744 || TARGET_MIX_SSE_I387)
15745 && flag_unsafe_math_optimizations"
15747 rtx op0 = gen_reg_rtx (XFmode);
15749 rtx one = gen_reg_rtx (<MODE>mode);
15750 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15752 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15753 operands[1], op2));
15754 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15758 (define_insn "*fpatanxf3_i387"
15759 [(set (match_operand:XF 0 "register_operand" "=f")
15760 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15761 (match_operand:XF 2 "register_operand" "u")]
15763 (clobber (match_scratch:XF 3 "=2"))]
15764 "TARGET_USE_FANCY_MATH_387
15765 && flag_unsafe_math_optimizations"
15767 [(set_attr "type" "fpspc")
15768 (set_attr "mode" "XF")])
15770 (define_insn "fpatan_extend<mode>xf3_i387"
15771 [(set (match_operand:XF 0 "register_operand" "=f")
15772 (unspec:XF [(float_extend:XF
15773 (match_operand:MODEF 1 "register_operand" "0"))
15775 (match_operand:MODEF 2 "register_operand" "u"))]
15777 (clobber (match_scratch:XF 3 "=2"))]
15778 "TARGET_USE_FANCY_MATH_387
15779 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15780 || TARGET_MIX_SSE_I387)
15781 && flag_unsafe_math_optimizations"
15783 [(set_attr "type" "fpspc")
15784 (set_attr "mode" "XF")])
15786 (define_expand "atan2xf3"
15787 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15788 (unspec:XF [(match_operand:XF 2 "register_operand" "")
15789 (match_operand:XF 1 "register_operand" "")]
15791 (clobber (match_scratch:XF 3 ""))])]
15792 "TARGET_USE_FANCY_MATH_387
15793 && flag_unsafe_math_optimizations"
15796 (define_expand "atan2<mode>3"
15797 [(use (match_operand:MODEF 0 "register_operand" ""))
15798 (use (match_operand:MODEF 1 "register_operand" ""))
15799 (use (match_operand:MODEF 2 "register_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"
15805 rtx op0 = gen_reg_rtx (XFmode);
15807 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15808 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15812 (define_expand "atanxf2"
15813 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15814 (unspec:XF [(match_dup 2)
15815 (match_operand:XF 1 "register_operand" "")]
15817 (clobber (match_scratch:XF 3 ""))])]
15818 "TARGET_USE_FANCY_MATH_387
15819 && flag_unsafe_math_optimizations"
15821 operands[2] = gen_reg_rtx (XFmode);
15822 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15825 (define_expand "atan<mode>2"
15826 [(use (match_operand:MODEF 0 "register_operand" ""))
15827 (use (match_operand:MODEF 1 "register_operand" ""))]
15828 "TARGET_USE_FANCY_MATH_387
15829 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15830 || TARGET_MIX_SSE_I387)
15831 && flag_unsafe_math_optimizations"
15833 rtx op0 = gen_reg_rtx (XFmode);
15835 rtx op2 = gen_reg_rtx (<MODE>mode);
15836 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
15838 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15839 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15843 (define_expand "asinxf2"
15844 [(set (match_dup 2)
15845 (mult:XF (match_operand:XF 1 "register_operand" "")
15847 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15848 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15849 (parallel [(set (match_operand:XF 0 "register_operand" "")
15850 (unspec:XF [(match_dup 5) (match_dup 1)]
15852 (clobber (match_scratch:XF 6 ""))])]
15853 "TARGET_USE_FANCY_MATH_387
15854 && flag_unsafe_math_optimizations"
15858 if (optimize_insn_for_size_p ())
15861 for (i = 2; i < 6; i++)
15862 operands[i] = gen_reg_rtx (XFmode);
15864 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15867 (define_expand "asin<mode>2"
15868 [(use (match_operand:MODEF 0 "register_operand" ""))
15869 (use (match_operand:MODEF 1 "general_operand" ""))]
15870 "TARGET_USE_FANCY_MATH_387
15871 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15872 || TARGET_MIX_SSE_I387)
15873 && flag_unsafe_math_optimizations"
15875 rtx op0 = gen_reg_rtx (XFmode);
15876 rtx op1 = gen_reg_rtx (XFmode);
15878 if (optimize_insn_for_size_p ())
15881 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15882 emit_insn (gen_asinxf2 (op0, op1));
15883 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15887 (define_expand "acosxf2"
15888 [(set (match_dup 2)
15889 (mult:XF (match_operand:XF 1 "register_operand" "")
15891 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15892 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15893 (parallel [(set (match_operand:XF 0 "register_operand" "")
15894 (unspec:XF [(match_dup 1) (match_dup 5)]
15896 (clobber (match_scratch:XF 6 ""))])]
15897 "TARGET_USE_FANCY_MATH_387
15898 && flag_unsafe_math_optimizations"
15902 if (optimize_insn_for_size_p ())
15905 for (i = 2; i < 6; i++)
15906 operands[i] = gen_reg_rtx (XFmode);
15908 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15911 (define_expand "acos<mode>2"
15912 [(use (match_operand:MODEF 0 "register_operand" ""))
15913 (use (match_operand:MODEF 1 "general_operand" ""))]
15914 "TARGET_USE_FANCY_MATH_387
15915 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15916 || TARGET_MIX_SSE_I387)
15917 && flag_unsafe_math_optimizations"
15919 rtx op0 = gen_reg_rtx (XFmode);
15920 rtx op1 = gen_reg_rtx (XFmode);
15922 if (optimize_insn_for_size_p ())
15925 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15926 emit_insn (gen_acosxf2 (op0, op1));
15927 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15931 (define_insn "fyl2xxf3_i387"
15932 [(set (match_operand:XF 0 "register_operand" "=f")
15933 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15934 (match_operand:XF 2 "register_operand" "u")]
15936 (clobber (match_scratch:XF 3 "=2"))]
15937 "TARGET_USE_FANCY_MATH_387
15938 && flag_unsafe_math_optimizations"
15940 [(set_attr "type" "fpspc")
15941 (set_attr "mode" "XF")])
15943 (define_insn "fyl2x_extend<mode>xf3_i387"
15944 [(set (match_operand:XF 0 "register_operand" "=f")
15945 (unspec:XF [(float_extend:XF
15946 (match_operand:MODEF 1 "register_operand" "0"))
15947 (match_operand:XF 2 "register_operand" "u")]
15949 (clobber (match_scratch:XF 3 "=2"))]
15950 "TARGET_USE_FANCY_MATH_387
15951 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15952 || TARGET_MIX_SSE_I387)
15953 && flag_unsafe_math_optimizations"
15955 [(set_attr "type" "fpspc")
15956 (set_attr "mode" "XF")])
15958 (define_expand "logxf2"
15959 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15960 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15961 (match_dup 2)] UNSPEC_FYL2X))
15962 (clobber (match_scratch:XF 3 ""))])]
15963 "TARGET_USE_FANCY_MATH_387
15964 && flag_unsafe_math_optimizations"
15966 operands[2] = gen_reg_rtx (XFmode);
15967 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15970 (define_expand "log<mode>2"
15971 [(use (match_operand:MODEF 0 "register_operand" ""))
15972 (use (match_operand:MODEF 1 "register_operand" ""))]
15973 "TARGET_USE_FANCY_MATH_387
15974 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15975 || TARGET_MIX_SSE_I387)
15976 && flag_unsafe_math_optimizations"
15978 rtx op0 = gen_reg_rtx (XFmode);
15980 rtx op2 = gen_reg_rtx (XFmode);
15981 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15983 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15984 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15988 (define_expand "log10xf2"
15989 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15990 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15991 (match_dup 2)] UNSPEC_FYL2X))
15992 (clobber (match_scratch:XF 3 ""))])]
15993 "TARGET_USE_FANCY_MATH_387
15994 && flag_unsafe_math_optimizations"
15996 operands[2] = gen_reg_rtx (XFmode);
15997 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16000 (define_expand "log10<mode>2"
16001 [(use (match_operand:MODEF 0 "register_operand" ""))
16002 (use (match_operand:MODEF 1 "register_operand" ""))]
16003 "TARGET_USE_FANCY_MATH_387
16004 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16005 || TARGET_MIX_SSE_I387)
16006 && flag_unsafe_math_optimizations"
16008 rtx op0 = gen_reg_rtx (XFmode);
16010 rtx op2 = gen_reg_rtx (XFmode);
16011 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16013 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16014 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16018 (define_expand "log2xf2"
16019 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16020 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16021 (match_dup 2)] UNSPEC_FYL2X))
16022 (clobber (match_scratch:XF 3 ""))])]
16023 "TARGET_USE_FANCY_MATH_387
16024 && flag_unsafe_math_optimizations"
16026 operands[2] = gen_reg_rtx (XFmode);
16027 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16030 (define_expand "log2<mode>2"
16031 [(use (match_operand:MODEF 0 "register_operand" ""))
16032 (use (match_operand:MODEF 1 "register_operand" ""))]
16033 "TARGET_USE_FANCY_MATH_387
16034 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16035 || TARGET_MIX_SSE_I387)
16036 && flag_unsafe_math_optimizations"
16038 rtx op0 = gen_reg_rtx (XFmode);
16040 rtx op2 = gen_reg_rtx (XFmode);
16041 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16043 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16044 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16048 (define_insn "fyl2xp1xf3_i387"
16049 [(set (match_operand:XF 0 "register_operand" "=f")
16050 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16051 (match_operand:XF 2 "register_operand" "u")]
16053 (clobber (match_scratch:XF 3 "=2"))]
16054 "TARGET_USE_FANCY_MATH_387
16055 && flag_unsafe_math_optimizations"
16057 [(set_attr "type" "fpspc")
16058 (set_attr "mode" "XF")])
16060 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16061 [(set (match_operand:XF 0 "register_operand" "=f")
16062 (unspec:XF [(float_extend:XF
16063 (match_operand:MODEF 1 "register_operand" "0"))
16064 (match_operand:XF 2 "register_operand" "u")]
16066 (clobber (match_scratch:XF 3 "=2"))]
16067 "TARGET_USE_FANCY_MATH_387
16068 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16069 || TARGET_MIX_SSE_I387)
16070 && flag_unsafe_math_optimizations"
16072 [(set_attr "type" "fpspc")
16073 (set_attr "mode" "XF")])
16075 (define_expand "log1pxf2"
16076 [(use (match_operand:XF 0 "register_operand" ""))
16077 (use (match_operand:XF 1 "register_operand" ""))]
16078 "TARGET_USE_FANCY_MATH_387
16079 && flag_unsafe_math_optimizations"
16081 if (optimize_insn_for_size_p ())
16084 ix86_emit_i387_log1p (operands[0], operands[1]);
16088 (define_expand "log1p<mode>2"
16089 [(use (match_operand:MODEF 0 "register_operand" ""))
16090 (use (match_operand:MODEF 1 "register_operand" ""))]
16091 "TARGET_USE_FANCY_MATH_387
16092 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16093 || TARGET_MIX_SSE_I387)
16094 && flag_unsafe_math_optimizations"
16098 if (optimize_insn_for_size_p ())
16101 op0 = gen_reg_rtx (XFmode);
16103 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16105 ix86_emit_i387_log1p (op0, operands[1]);
16106 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16110 (define_insn "fxtractxf3_i387"
16111 [(set (match_operand:XF 0 "register_operand" "=f")
16112 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16113 UNSPEC_XTRACT_FRACT))
16114 (set (match_operand:XF 1 "register_operand" "=u")
16115 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16116 "TARGET_USE_FANCY_MATH_387
16117 && flag_unsafe_math_optimizations"
16119 [(set_attr "type" "fpspc")
16120 (set_attr "mode" "XF")])
16122 (define_insn "fxtract_extend<mode>xf3_i387"
16123 [(set (match_operand:XF 0 "register_operand" "=f")
16124 (unspec:XF [(float_extend:XF
16125 (match_operand:MODEF 2 "register_operand" "0"))]
16126 UNSPEC_XTRACT_FRACT))
16127 (set (match_operand:XF 1 "register_operand" "=u")
16128 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16129 "TARGET_USE_FANCY_MATH_387
16130 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16131 || TARGET_MIX_SSE_I387)
16132 && flag_unsafe_math_optimizations"
16134 [(set_attr "type" "fpspc")
16135 (set_attr "mode" "XF")])
16137 (define_expand "logbxf2"
16138 [(parallel [(set (match_dup 2)
16139 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16140 UNSPEC_XTRACT_FRACT))
16141 (set (match_operand:XF 0 "register_operand" "")
16142 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16143 "TARGET_USE_FANCY_MATH_387
16144 && flag_unsafe_math_optimizations"
16146 operands[2] = gen_reg_rtx (XFmode);
16149 (define_expand "logb<mode>2"
16150 [(use (match_operand:MODEF 0 "register_operand" ""))
16151 (use (match_operand:MODEF 1 "register_operand" ""))]
16152 "TARGET_USE_FANCY_MATH_387
16153 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16154 || TARGET_MIX_SSE_I387)
16155 && flag_unsafe_math_optimizations"
16157 rtx op0 = gen_reg_rtx (XFmode);
16158 rtx op1 = gen_reg_rtx (XFmode);
16160 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16161 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16165 (define_expand "ilogbxf2"
16166 [(use (match_operand:SI 0 "register_operand" ""))
16167 (use (match_operand:XF 1 "register_operand" ""))]
16168 "TARGET_USE_FANCY_MATH_387
16169 && flag_unsafe_math_optimizations"
16173 if (optimize_insn_for_size_p ())
16176 op0 = gen_reg_rtx (XFmode);
16177 op1 = gen_reg_rtx (XFmode);
16179 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16180 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16184 (define_expand "ilogb<mode>2"
16185 [(use (match_operand:SI 0 "register_operand" ""))
16186 (use (match_operand:MODEF 1 "register_operand" ""))]
16187 "TARGET_USE_FANCY_MATH_387
16188 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16189 || TARGET_MIX_SSE_I387)
16190 && flag_unsafe_math_optimizations"
16194 if (optimize_insn_for_size_p ())
16197 op0 = gen_reg_rtx (XFmode);
16198 op1 = gen_reg_rtx (XFmode);
16200 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16201 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16205 (define_insn "*f2xm1xf2_i387"
16206 [(set (match_operand:XF 0 "register_operand" "=f")
16207 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16209 "TARGET_USE_FANCY_MATH_387
16210 && flag_unsafe_math_optimizations"
16212 [(set_attr "type" "fpspc")
16213 (set_attr "mode" "XF")])
16215 (define_insn "*fscalexf4_i387"
16216 [(set (match_operand:XF 0 "register_operand" "=f")
16217 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16218 (match_operand:XF 3 "register_operand" "1")]
16219 UNSPEC_FSCALE_FRACT))
16220 (set (match_operand:XF 1 "register_operand" "=u")
16221 (unspec:XF [(match_dup 2) (match_dup 3)]
16222 UNSPEC_FSCALE_EXP))]
16223 "TARGET_USE_FANCY_MATH_387
16224 && flag_unsafe_math_optimizations"
16226 [(set_attr "type" "fpspc")
16227 (set_attr "mode" "XF")])
16229 (define_expand "expNcorexf3"
16230 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16231 (match_operand:XF 2 "register_operand" "")))
16232 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16233 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16234 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16235 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16236 (parallel [(set (match_operand:XF 0 "register_operand" "")
16237 (unspec:XF [(match_dup 8) (match_dup 4)]
16238 UNSPEC_FSCALE_FRACT))
16240 (unspec:XF [(match_dup 8) (match_dup 4)]
16241 UNSPEC_FSCALE_EXP))])]
16242 "TARGET_USE_FANCY_MATH_387
16243 && flag_unsafe_math_optimizations"
16247 if (optimize_insn_for_size_p ())
16250 for (i = 3; i < 10; i++)
16251 operands[i] = gen_reg_rtx (XFmode);
16253 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16256 (define_expand "expxf2"
16257 [(use (match_operand:XF 0 "register_operand" ""))
16258 (use (match_operand:XF 1 "register_operand" ""))]
16259 "TARGET_USE_FANCY_MATH_387
16260 && flag_unsafe_math_optimizations"
16264 if (optimize_insn_for_size_p ())
16267 op2 = gen_reg_rtx (XFmode);
16268 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16270 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16274 (define_expand "exp<mode>2"
16275 [(use (match_operand:MODEF 0 "register_operand" ""))
16276 (use (match_operand:MODEF 1 "general_operand" ""))]
16277 "TARGET_USE_FANCY_MATH_387
16278 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16279 || TARGET_MIX_SSE_I387)
16280 && flag_unsafe_math_optimizations"
16284 if (optimize_insn_for_size_p ())
16287 op0 = gen_reg_rtx (XFmode);
16288 op1 = gen_reg_rtx (XFmode);
16290 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16291 emit_insn (gen_expxf2 (op0, op1));
16292 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16296 (define_expand "exp10xf2"
16297 [(use (match_operand:XF 0 "register_operand" ""))
16298 (use (match_operand:XF 1 "register_operand" ""))]
16299 "TARGET_USE_FANCY_MATH_387
16300 && flag_unsafe_math_optimizations"
16304 if (optimize_insn_for_size_p ())
16307 op2 = gen_reg_rtx (XFmode);
16308 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16310 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16314 (define_expand "exp10<mode>2"
16315 [(use (match_operand:MODEF 0 "register_operand" ""))
16316 (use (match_operand:MODEF 1 "general_operand" ""))]
16317 "TARGET_USE_FANCY_MATH_387
16318 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16319 || TARGET_MIX_SSE_I387)
16320 && flag_unsafe_math_optimizations"
16324 if (optimize_insn_for_size_p ())
16327 op0 = gen_reg_rtx (XFmode);
16328 op1 = gen_reg_rtx (XFmode);
16330 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16331 emit_insn (gen_exp10xf2 (op0, op1));
16332 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16336 (define_expand "exp2xf2"
16337 [(use (match_operand:XF 0 "register_operand" ""))
16338 (use (match_operand:XF 1 "register_operand" ""))]
16339 "TARGET_USE_FANCY_MATH_387
16340 && flag_unsafe_math_optimizations"
16344 if (optimize_insn_for_size_p ())
16347 op2 = gen_reg_rtx (XFmode);
16348 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16350 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16354 (define_expand "exp2<mode>2"
16355 [(use (match_operand:MODEF 0 "register_operand" ""))
16356 (use (match_operand:MODEF 1 "general_operand" ""))]
16357 "TARGET_USE_FANCY_MATH_387
16358 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16359 || TARGET_MIX_SSE_I387)
16360 && flag_unsafe_math_optimizations"
16364 if (optimize_insn_for_size_p ())
16367 op0 = gen_reg_rtx (XFmode);
16368 op1 = gen_reg_rtx (XFmode);
16370 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16371 emit_insn (gen_exp2xf2 (op0, op1));
16372 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16376 (define_expand "expm1xf2"
16377 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16379 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16380 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16381 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16382 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16383 (parallel [(set (match_dup 7)
16384 (unspec:XF [(match_dup 6) (match_dup 4)]
16385 UNSPEC_FSCALE_FRACT))
16387 (unspec:XF [(match_dup 6) (match_dup 4)]
16388 UNSPEC_FSCALE_EXP))])
16389 (parallel [(set (match_dup 10)
16390 (unspec:XF [(match_dup 9) (match_dup 8)]
16391 UNSPEC_FSCALE_FRACT))
16392 (set (match_dup 11)
16393 (unspec:XF [(match_dup 9) (match_dup 8)]
16394 UNSPEC_FSCALE_EXP))])
16395 (set (match_dup 12) (minus:XF (match_dup 10)
16396 (float_extend:XF (match_dup 13))))
16397 (set (match_operand:XF 0 "register_operand" "")
16398 (plus:XF (match_dup 12) (match_dup 7)))]
16399 "TARGET_USE_FANCY_MATH_387
16400 && flag_unsafe_math_optimizations"
16404 if (optimize_insn_for_size_p ())
16407 for (i = 2; i < 13; i++)
16408 operands[i] = gen_reg_rtx (XFmode);
16411 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16413 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16416 (define_expand "expm1<mode>2"
16417 [(use (match_operand:MODEF 0 "register_operand" ""))
16418 (use (match_operand:MODEF 1 "general_operand" ""))]
16419 "TARGET_USE_FANCY_MATH_387
16420 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16421 || TARGET_MIX_SSE_I387)
16422 && flag_unsafe_math_optimizations"
16426 if (optimize_insn_for_size_p ())
16429 op0 = gen_reg_rtx (XFmode);
16430 op1 = gen_reg_rtx (XFmode);
16432 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16433 emit_insn (gen_expm1xf2 (op0, op1));
16434 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16438 (define_expand "ldexpxf3"
16439 [(set (match_dup 3)
16440 (float:XF (match_operand:SI 2 "register_operand" "")))
16441 (parallel [(set (match_operand:XF 0 " register_operand" "")
16442 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16444 UNSPEC_FSCALE_FRACT))
16446 (unspec:XF [(match_dup 1) (match_dup 3)]
16447 UNSPEC_FSCALE_EXP))])]
16448 "TARGET_USE_FANCY_MATH_387
16449 && flag_unsafe_math_optimizations"
16451 if (optimize_insn_for_size_p ())
16454 operands[3] = gen_reg_rtx (XFmode);
16455 operands[4] = gen_reg_rtx (XFmode);
16458 (define_expand "ldexp<mode>3"
16459 [(use (match_operand:MODEF 0 "register_operand" ""))
16460 (use (match_operand:MODEF 1 "general_operand" ""))
16461 (use (match_operand:SI 2 "register_operand" ""))]
16462 "TARGET_USE_FANCY_MATH_387
16463 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16464 || TARGET_MIX_SSE_I387)
16465 && flag_unsafe_math_optimizations"
16469 if (optimize_insn_for_size_p ())
16472 op0 = gen_reg_rtx (XFmode);
16473 op1 = gen_reg_rtx (XFmode);
16475 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16476 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16477 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16481 (define_expand "scalbxf3"
16482 [(parallel [(set (match_operand:XF 0 " register_operand" "")
16483 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16484 (match_operand:XF 2 "register_operand" "")]
16485 UNSPEC_FSCALE_FRACT))
16487 (unspec:XF [(match_dup 1) (match_dup 2)]
16488 UNSPEC_FSCALE_EXP))])]
16489 "TARGET_USE_FANCY_MATH_387
16490 && flag_unsafe_math_optimizations"
16492 if (optimize_insn_for_size_p ())
16495 operands[3] = gen_reg_rtx (XFmode);
16498 (define_expand "scalb<mode>3"
16499 [(use (match_operand:MODEF 0 "register_operand" ""))
16500 (use (match_operand:MODEF 1 "general_operand" ""))
16501 (use (match_operand:MODEF 2 "general_operand" ""))]
16502 "TARGET_USE_FANCY_MATH_387
16503 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16504 || TARGET_MIX_SSE_I387)
16505 && flag_unsafe_math_optimizations"
16509 if (optimize_insn_for_size_p ())
16512 op0 = gen_reg_rtx (XFmode);
16513 op1 = gen_reg_rtx (XFmode);
16514 op2 = gen_reg_rtx (XFmode);
16516 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16517 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16518 emit_insn (gen_scalbxf3 (op0, op1, op2));
16519 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16523 (define_expand "significandxf2"
16524 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16525 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16526 UNSPEC_XTRACT_FRACT))
16528 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16529 "TARGET_USE_FANCY_MATH_387
16530 && flag_unsafe_math_optimizations"
16532 operands[2] = gen_reg_rtx (XFmode);
16535 (define_expand "significand<mode>2"
16536 [(use (match_operand:MODEF 0 "register_operand" ""))
16537 (use (match_operand:MODEF 1 "register_operand" ""))]
16538 "TARGET_USE_FANCY_MATH_387
16539 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16540 || TARGET_MIX_SSE_I387)
16541 && flag_unsafe_math_optimizations"
16543 rtx op0 = gen_reg_rtx (XFmode);
16544 rtx op1 = gen_reg_rtx (XFmode);
16546 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16547 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16552 (define_insn "sse4_1_round<mode>2"
16553 [(set (match_operand:MODEF 0 "register_operand" "=x")
16554 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
16555 (match_operand:SI 2 "const_0_to_15_operand" "n")]
16558 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16559 [(set_attr "type" "ssecvt")
16560 (set_attr "prefix_extra" "1")
16561 (set_attr "prefix" "maybe_vex")
16562 (set_attr "mode" "<MODE>")])
16564 (define_insn "rintxf2"
16565 [(set (match_operand:XF 0 "register_operand" "=f")
16566 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16568 "TARGET_USE_FANCY_MATH_387
16569 && flag_unsafe_math_optimizations"
16571 [(set_attr "type" "fpspc")
16572 (set_attr "mode" "XF")])
16574 (define_expand "rint<mode>2"
16575 [(use (match_operand:MODEF 0 "register_operand" ""))
16576 (use (match_operand:MODEF 1 "register_operand" ""))]
16577 "(TARGET_USE_FANCY_MATH_387
16578 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16579 || TARGET_MIX_SSE_I387)
16580 && flag_unsafe_math_optimizations)
16581 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16582 && !flag_trapping_math)"
16584 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16585 && !flag_trapping_math)
16587 if (!TARGET_ROUND && optimize_insn_for_size_p ())
16590 emit_insn (gen_sse4_1_round<mode>2
16591 (operands[0], operands[1], GEN_INT (0x04)));
16593 ix86_expand_rint (operand0, operand1);
16597 rtx op0 = gen_reg_rtx (XFmode);
16598 rtx op1 = gen_reg_rtx (XFmode);
16600 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16601 emit_insn (gen_rintxf2 (op0, op1));
16603 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16608 (define_expand "round<mode>2"
16609 [(match_operand:MODEF 0 "register_operand" "")
16610 (match_operand:MODEF 1 "nonimmediate_operand" "")]
16611 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16612 && !flag_trapping_math && !flag_rounding_math"
16614 if (optimize_insn_for_size_p ())
16616 if (TARGET_64BIT || (<MODE>mode != DFmode))
16617 ix86_expand_round (operand0, operand1);
16619 ix86_expand_rounddf_32 (operand0, operand1);
16623 (define_insn_and_split "*fistdi2_1"
16624 [(set (match_operand:DI 0 "nonimmediate_operand" "")
16625 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16627 "TARGET_USE_FANCY_MATH_387
16628 && can_create_pseudo_p ()"
16633 if (memory_operand (operands[0], VOIDmode))
16634 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16637 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16638 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16643 [(set_attr "type" "fpspc")
16644 (set_attr "mode" "DI")])
16646 (define_insn "fistdi2"
16647 [(set (match_operand:DI 0 "memory_operand" "=m")
16648 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16650 (clobber (match_scratch:XF 2 "=&1f"))]
16651 "TARGET_USE_FANCY_MATH_387"
16652 "* return output_fix_trunc (insn, operands, 0);"
16653 [(set_attr "type" "fpspc")
16654 (set_attr "mode" "DI")])
16656 (define_insn "fistdi2_with_temp"
16657 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16658 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16660 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16661 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16662 "TARGET_USE_FANCY_MATH_387"
16664 [(set_attr "type" "fpspc")
16665 (set_attr "mode" "DI")])
16668 [(set (match_operand:DI 0 "register_operand" "")
16669 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16671 (clobber (match_operand:DI 2 "memory_operand" ""))
16672 (clobber (match_scratch 3 ""))]
16674 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16675 (clobber (match_dup 3))])
16676 (set (match_dup 0) (match_dup 2))]
16680 [(set (match_operand:DI 0 "memory_operand" "")
16681 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16683 (clobber (match_operand:DI 2 "memory_operand" ""))
16684 (clobber (match_scratch 3 ""))]
16686 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16687 (clobber (match_dup 3))])]
16690 (define_insn_and_split "*fist<mode>2_1"
16691 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16692 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16694 "TARGET_USE_FANCY_MATH_387
16695 && can_create_pseudo_p ()"
16700 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16701 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16705 [(set_attr "type" "fpspc")
16706 (set_attr "mode" "<MODE>")])
16708 (define_insn "fist<mode>2"
16709 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16710 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16712 "TARGET_USE_FANCY_MATH_387"
16713 "* return output_fix_trunc (insn, operands, 0);"
16714 [(set_attr "type" "fpspc")
16715 (set_attr "mode" "<MODE>")])
16717 (define_insn "fist<mode>2_with_temp"
16718 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16719 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16721 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16722 "TARGET_USE_FANCY_MATH_387"
16724 [(set_attr "type" "fpspc")
16725 (set_attr "mode" "<MODE>")])
16728 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16729 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16731 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16733 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
16734 (set (match_dup 0) (match_dup 2))]
16738 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16739 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16741 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16743 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
16746 (define_expand "lrintxf<mode>2"
16747 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16748 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16750 "TARGET_USE_FANCY_MATH_387"
16753 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
16754 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16755 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
16756 UNSPEC_FIX_NOTRUNC))]
16757 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16758 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
16761 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
16762 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16763 (match_operand:MODEF 1 "register_operand" "")]
16764 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16765 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
16766 && !flag_trapping_math && !flag_rounding_math"
16768 if (optimize_insn_for_size_p ())
16770 ix86_expand_lround (operand0, operand1);
16774 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16775 (define_insn_and_split "frndintxf2_floor"
16776 [(set (match_operand:XF 0 "register_operand" "")
16777 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16778 UNSPEC_FRNDINT_FLOOR))
16779 (clobber (reg:CC FLAGS_REG))]
16780 "TARGET_USE_FANCY_MATH_387
16781 && flag_unsafe_math_optimizations
16782 && can_create_pseudo_p ()"
16787 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16789 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16790 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16792 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16793 operands[2], operands[3]));
16796 [(set_attr "type" "frndint")
16797 (set_attr "i387_cw" "floor")
16798 (set_attr "mode" "XF")])
16800 (define_insn "frndintxf2_floor_i387"
16801 [(set (match_operand:XF 0 "register_operand" "=f")
16802 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16803 UNSPEC_FRNDINT_FLOOR))
16804 (use (match_operand:HI 2 "memory_operand" "m"))
16805 (use (match_operand:HI 3 "memory_operand" "m"))]
16806 "TARGET_USE_FANCY_MATH_387
16807 && flag_unsafe_math_optimizations"
16808 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16809 [(set_attr "type" "frndint")
16810 (set_attr "i387_cw" "floor")
16811 (set_attr "mode" "XF")])
16813 (define_expand "floorxf2"
16814 [(use (match_operand:XF 0 "register_operand" ""))
16815 (use (match_operand:XF 1 "register_operand" ""))]
16816 "TARGET_USE_FANCY_MATH_387
16817 && flag_unsafe_math_optimizations"
16819 if (optimize_insn_for_size_p ())
16821 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16825 (define_expand "floor<mode>2"
16826 [(use (match_operand:MODEF 0 "register_operand" ""))
16827 (use (match_operand:MODEF 1 "register_operand" ""))]
16828 "(TARGET_USE_FANCY_MATH_387
16829 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16830 || TARGET_MIX_SSE_I387)
16831 && flag_unsafe_math_optimizations)
16832 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16833 && !flag_trapping_math)"
16835 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16836 && !flag_trapping_math
16837 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
16839 if (!TARGET_ROUND && optimize_insn_for_size_p ())
16842 emit_insn (gen_sse4_1_round<mode>2
16843 (operands[0], operands[1], GEN_INT (0x01)));
16844 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16845 ix86_expand_floorceil (operand0, operand1, true);
16847 ix86_expand_floorceildf_32 (operand0, operand1, true);
16853 if (optimize_insn_for_size_p ())
16856 op0 = gen_reg_rtx (XFmode);
16857 op1 = gen_reg_rtx (XFmode);
16858 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16859 emit_insn (gen_frndintxf2_floor (op0, op1));
16861 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16866 (define_insn_and_split "*fist<mode>2_floor_1"
16867 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16868 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16869 UNSPEC_FIST_FLOOR))
16870 (clobber (reg:CC FLAGS_REG))]
16871 "TARGET_USE_FANCY_MATH_387
16872 && flag_unsafe_math_optimizations
16873 && can_create_pseudo_p ()"
16878 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16880 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16881 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16882 if (memory_operand (operands[0], VOIDmode))
16883 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16884 operands[2], operands[3]));
16887 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16888 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16889 operands[2], operands[3],
16894 [(set_attr "type" "fistp")
16895 (set_attr "i387_cw" "floor")
16896 (set_attr "mode" "<MODE>")])
16898 (define_insn "fistdi2_floor"
16899 [(set (match_operand:DI 0 "memory_operand" "=m")
16900 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16901 UNSPEC_FIST_FLOOR))
16902 (use (match_operand:HI 2 "memory_operand" "m"))
16903 (use (match_operand:HI 3 "memory_operand" "m"))
16904 (clobber (match_scratch:XF 4 "=&1f"))]
16905 "TARGET_USE_FANCY_MATH_387
16906 && flag_unsafe_math_optimizations"
16907 "* return output_fix_trunc (insn, operands, 0);"
16908 [(set_attr "type" "fistp")
16909 (set_attr "i387_cw" "floor")
16910 (set_attr "mode" "DI")])
16912 (define_insn "fistdi2_floor_with_temp"
16913 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16914 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16915 UNSPEC_FIST_FLOOR))
16916 (use (match_operand:HI 2 "memory_operand" "m,m"))
16917 (use (match_operand:HI 3 "memory_operand" "m,m"))
16918 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16919 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16920 "TARGET_USE_FANCY_MATH_387
16921 && flag_unsafe_math_optimizations"
16923 [(set_attr "type" "fistp")
16924 (set_attr "i387_cw" "floor")
16925 (set_attr "mode" "DI")])
16928 [(set (match_operand:DI 0 "register_operand" "")
16929 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16930 UNSPEC_FIST_FLOOR))
16931 (use (match_operand:HI 2 "memory_operand" ""))
16932 (use (match_operand:HI 3 "memory_operand" ""))
16933 (clobber (match_operand:DI 4 "memory_operand" ""))
16934 (clobber (match_scratch 5 ""))]
16936 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16937 (use (match_dup 2))
16938 (use (match_dup 3))
16939 (clobber (match_dup 5))])
16940 (set (match_dup 0) (match_dup 4))]
16944 [(set (match_operand:DI 0 "memory_operand" "")
16945 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16946 UNSPEC_FIST_FLOOR))
16947 (use (match_operand:HI 2 "memory_operand" ""))
16948 (use (match_operand:HI 3 "memory_operand" ""))
16949 (clobber (match_operand:DI 4 "memory_operand" ""))
16950 (clobber (match_scratch 5 ""))]
16952 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16953 (use (match_dup 2))
16954 (use (match_dup 3))
16955 (clobber (match_dup 5))])]
16958 (define_insn "fist<mode>2_floor"
16959 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16960 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16961 UNSPEC_FIST_FLOOR))
16962 (use (match_operand:HI 2 "memory_operand" "m"))
16963 (use (match_operand:HI 3 "memory_operand" "m"))]
16964 "TARGET_USE_FANCY_MATH_387
16965 && flag_unsafe_math_optimizations"
16966 "* return output_fix_trunc (insn, operands, 0);"
16967 [(set_attr "type" "fistp")
16968 (set_attr "i387_cw" "floor")
16969 (set_attr "mode" "<MODE>")])
16971 (define_insn "fist<mode>2_floor_with_temp"
16972 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16973 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16974 UNSPEC_FIST_FLOOR))
16975 (use (match_operand:HI 2 "memory_operand" "m,m"))
16976 (use (match_operand:HI 3 "memory_operand" "m,m"))
16977 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
16978 "TARGET_USE_FANCY_MATH_387
16979 && flag_unsafe_math_optimizations"
16981 [(set_attr "type" "fistp")
16982 (set_attr "i387_cw" "floor")
16983 (set_attr "mode" "<MODE>")])
16986 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16987 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16988 UNSPEC_FIST_FLOOR))
16989 (use (match_operand:HI 2 "memory_operand" ""))
16990 (use (match_operand:HI 3 "memory_operand" ""))
16991 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16993 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16994 UNSPEC_FIST_FLOOR))
16995 (use (match_dup 2))
16996 (use (match_dup 3))])
16997 (set (match_dup 0) (match_dup 4))]
17001 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17002 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17003 UNSPEC_FIST_FLOOR))
17004 (use (match_operand:HI 2 "memory_operand" ""))
17005 (use (match_operand:HI 3 "memory_operand" ""))
17006 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17008 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17009 UNSPEC_FIST_FLOOR))
17010 (use (match_dup 2))
17011 (use (match_dup 3))])]
17014 (define_expand "lfloorxf<mode>2"
17015 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17016 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17017 UNSPEC_FIST_FLOOR))
17018 (clobber (reg:CC FLAGS_REG))])]
17019 "TARGET_USE_FANCY_MATH_387
17020 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17021 && flag_unsafe_math_optimizations"
17024 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
17025 [(match_operand:SWI48 0 "nonimmediate_operand" "")
17026 (match_operand:MODEF 1 "register_operand" "")]
17027 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17028 && !flag_trapping_math"
17030 if (TARGET_64BIT && optimize_insn_for_size_p ())
17032 ix86_expand_lfloorceil (operand0, operand1, true);
17036 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17037 (define_insn_and_split "frndintxf2_ceil"
17038 [(set (match_operand:XF 0 "register_operand" "")
17039 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17040 UNSPEC_FRNDINT_CEIL))
17041 (clobber (reg:CC FLAGS_REG))]
17042 "TARGET_USE_FANCY_MATH_387
17043 && flag_unsafe_math_optimizations
17044 && can_create_pseudo_p ()"
17049 ix86_optimize_mode_switching[I387_CEIL] = 1;
17051 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17052 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17054 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17055 operands[2], operands[3]));
17058 [(set_attr "type" "frndint")
17059 (set_attr "i387_cw" "ceil")
17060 (set_attr "mode" "XF")])
17062 (define_insn "frndintxf2_ceil_i387"
17063 [(set (match_operand:XF 0 "register_operand" "=f")
17064 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17065 UNSPEC_FRNDINT_CEIL))
17066 (use (match_operand:HI 2 "memory_operand" "m"))
17067 (use (match_operand:HI 3 "memory_operand" "m"))]
17068 "TARGET_USE_FANCY_MATH_387
17069 && flag_unsafe_math_optimizations"
17070 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17071 [(set_attr "type" "frndint")
17072 (set_attr "i387_cw" "ceil")
17073 (set_attr "mode" "XF")])
17075 (define_expand "ceilxf2"
17076 [(use (match_operand:XF 0 "register_operand" ""))
17077 (use (match_operand:XF 1 "register_operand" ""))]
17078 "TARGET_USE_FANCY_MATH_387
17079 && flag_unsafe_math_optimizations"
17081 if (optimize_insn_for_size_p ())
17083 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17087 (define_expand "ceil<mode>2"
17088 [(use (match_operand:MODEF 0 "register_operand" ""))
17089 (use (match_operand:MODEF 1 "register_operand" ""))]
17090 "(TARGET_USE_FANCY_MATH_387
17091 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17092 || TARGET_MIX_SSE_I387)
17093 && flag_unsafe_math_optimizations)
17094 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17095 && !flag_trapping_math)"
17097 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17098 && !flag_trapping_math
17099 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17102 emit_insn (gen_sse4_1_round<mode>2
17103 (operands[0], operands[1], GEN_INT (0x02)));
17104 else if (optimize_insn_for_size_p ())
17106 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17107 ix86_expand_floorceil (operand0, operand1, false);
17109 ix86_expand_floorceildf_32 (operand0, operand1, false);
17115 if (optimize_insn_for_size_p ())
17118 op0 = gen_reg_rtx (XFmode);
17119 op1 = gen_reg_rtx (XFmode);
17120 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17121 emit_insn (gen_frndintxf2_ceil (op0, op1));
17123 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17128 (define_insn_and_split "*fist<mode>2_ceil_1"
17129 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17130 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17132 (clobber (reg:CC FLAGS_REG))]
17133 "TARGET_USE_FANCY_MATH_387
17134 && flag_unsafe_math_optimizations
17135 && can_create_pseudo_p ()"
17140 ix86_optimize_mode_switching[I387_CEIL] = 1;
17142 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17143 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17144 if (memory_operand (operands[0], VOIDmode))
17145 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17146 operands[2], operands[3]));
17149 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17150 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17151 operands[2], operands[3],
17156 [(set_attr "type" "fistp")
17157 (set_attr "i387_cw" "ceil")
17158 (set_attr "mode" "<MODE>")])
17160 (define_insn "fistdi2_ceil"
17161 [(set (match_operand:DI 0 "memory_operand" "=m")
17162 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17164 (use (match_operand:HI 2 "memory_operand" "m"))
17165 (use (match_operand:HI 3 "memory_operand" "m"))
17166 (clobber (match_scratch:XF 4 "=&1f"))]
17167 "TARGET_USE_FANCY_MATH_387
17168 && flag_unsafe_math_optimizations"
17169 "* return output_fix_trunc (insn, operands, 0);"
17170 [(set_attr "type" "fistp")
17171 (set_attr "i387_cw" "ceil")
17172 (set_attr "mode" "DI")])
17174 (define_insn "fistdi2_ceil_with_temp"
17175 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17176 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17178 (use (match_operand:HI 2 "memory_operand" "m,m"))
17179 (use (match_operand:HI 3 "memory_operand" "m,m"))
17180 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17181 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17182 "TARGET_USE_FANCY_MATH_387
17183 && flag_unsafe_math_optimizations"
17185 [(set_attr "type" "fistp")
17186 (set_attr "i387_cw" "ceil")
17187 (set_attr "mode" "DI")])
17190 [(set (match_operand:DI 0 "register_operand" "")
17191 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17193 (use (match_operand:HI 2 "memory_operand" ""))
17194 (use (match_operand:HI 3 "memory_operand" ""))
17195 (clobber (match_operand:DI 4 "memory_operand" ""))
17196 (clobber (match_scratch 5 ""))]
17198 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17199 (use (match_dup 2))
17200 (use (match_dup 3))
17201 (clobber (match_dup 5))])
17202 (set (match_dup 0) (match_dup 4))]
17206 [(set (match_operand:DI 0 "memory_operand" "")
17207 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17209 (use (match_operand:HI 2 "memory_operand" ""))
17210 (use (match_operand:HI 3 "memory_operand" ""))
17211 (clobber (match_operand:DI 4 "memory_operand" ""))
17212 (clobber (match_scratch 5 ""))]
17214 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17215 (use (match_dup 2))
17216 (use (match_dup 3))
17217 (clobber (match_dup 5))])]
17220 (define_insn "fist<mode>2_ceil"
17221 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17222 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17224 (use (match_operand:HI 2 "memory_operand" "m"))
17225 (use (match_operand:HI 3 "memory_operand" "m"))]
17226 "TARGET_USE_FANCY_MATH_387
17227 && flag_unsafe_math_optimizations"
17228 "* return output_fix_trunc (insn, operands, 0);"
17229 [(set_attr "type" "fistp")
17230 (set_attr "i387_cw" "ceil")
17231 (set_attr "mode" "<MODE>")])
17233 (define_insn "fist<mode>2_ceil_with_temp"
17234 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17235 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17237 (use (match_operand:HI 2 "memory_operand" "m,m"))
17238 (use (match_operand:HI 3 "memory_operand" "m,m"))
17239 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17240 "TARGET_USE_FANCY_MATH_387
17241 && flag_unsafe_math_optimizations"
17243 [(set_attr "type" "fistp")
17244 (set_attr "i387_cw" "ceil")
17245 (set_attr "mode" "<MODE>")])
17248 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17249 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17251 (use (match_operand:HI 2 "memory_operand" ""))
17252 (use (match_operand:HI 3 "memory_operand" ""))
17253 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17255 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17257 (use (match_dup 2))
17258 (use (match_dup 3))])
17259 (set (match_dup 0) (match_dup 4))]
17263 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17264 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17266 (use (match_operand:HI 2 "memory_operand" ""))
17267 (use (match_operand:HI 3 "memory_operand" ""))
17268 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17270 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17272 (use (match_dup 2))
17273 (use (match_dup 3))])]
17276 (define_expand "lceilxf<mode>2"
17277 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17278 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17280 (clobber (reg:CC FLAGS_REG))])]
17281 "TARGET_USE_FANCY_MATH_387
17282 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17283 && flag_unsafe_math_optimizations"
17286 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
17287 [(match_operand:SWI48 0 "nonimmediate_operand" "")
17288 (match_operand:MODEF 1 "register_operand" "")]
17289 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17290 && !flag_trapping_math"
17292 ix86_expand_lfloorceil (operand0, operand1, false);
17296 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17297 (define_insn_and_split "frndintxf2_trunc"
17298 [(set (match_operand:XF 0 "register_operand" "")
17299 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17300 UNSPEC_FRNDINT_TRUNC))
17301 (clobber (reg:CC FLAGS_REG))]
17302 "TARGET_USE_FANCY_MATH_387
17303 && flag_unsafe_math_optimizations
17304 && can_create_pseudo_p ()"
17309 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17311 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17312 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17314 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17315 operands[2], operands[3]));
17318 [(set_attr "type" "frndint")
17319 (set_attr "i387_cw" "trunc")
17320 (set_attr "mode" "XF")])
17322 (define_insn "frndintxf2_trunc_i387"
17323 [(set (match_operand:XF 0 "register_operand" "=f")
17324 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17325 UNSPEC_FRNDINT_TRUNC))
17326 (use (match_operand:HI 2 "memory_operand" "m"))
17327 (use (match_operand:HI 3 "memory_operand" "m"))]
17328 "TARGET_USE_FANCY_MATH_387
17329 && flag_unsafe_math_optimizations"
17330 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17331 [(set_attr "type" "frndint")
17332 (set_attr "i387_cw" "trunc")
17333 (set_attr "mode" "XF")])
17335 (define_expand "btruncxf2"
17336 [(use (match_operand:XF 0 "register_operand" ""))
17337 (use (match_operand:XF 1 "register_operand" ""))]
17338 "TARGET_USE_FANCY_MATH_387
17339 && flag_unsafe_math_optimizations"
17341 if (optimize_insn_for_size_p ())
17343 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17347 (define_expand "btrunc<mode>2"
17348 [(use (match_operand:MODEF 0 "register_operand" ""))
17349 (use (match_operand:MODEF 1 "register_operand" ""))]
17350 "(TARGET_USE_FANCY_MATH_387
17351 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17352 || TARGET_MIX_SSE_I387)
17353 && flag_unsafe_math_optimizations)
17354 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17355 && !flag_trapping_math)"
17357 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17358 && !flag_trapping_math
17359 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17362 emit_insn (gen_sse4_1_round<mode>2
17363 (operands[0], operands[1], GEN_INT (0x03)));
17364 else if (optimize_insn_for_size_p ())
17366 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17367 ix86_expand_trunc (operand0, operand1);
17369 ix86_expand_truncdf_32 (operand0, operand1);
17375 if (optimize_insn_for_size_p ())
17378 op0 = gen_reg_rtx (XFmode);
17379 op1 = gen_reg_rtx (XFmode);
17380 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17381 emit_insn (gen_frndintxf2_trunc (op0, op1));
17383 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17388 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17389 (define_insn_and_split "frndintxf2_mask_pm"
17390 [(set (match_operand:XF 0 "register_operand" "")
17391 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17392 UNSPEC_FRNDINT_MASK_PM))
17393 (clobber (reg:CC FLAGS_REG))]
17394 "TARGET_USE_FANCY_MATH_387
17395 && flag_unsafe_math_optimizations
17396 && can_create_pseudo_p ()"
17401 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17403 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17404 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17406 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17407 operands[2], operands[3]));
17410 [(set_attr "type" "frndint")
17411 (set_attr "i387_cw" "mask_pm")
17412 (set_attr "mode" "XF")])
17414 (define_insn "frndintxf2_mask_pm_i387"
17415 [(set (match_operand:XF 0 "register_operand" "=f")
17416 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17417 UNSPEC_FRNDINT_MASK_PM))
17418 (use (match_operand:HI 2 "memory_operand" "m"))
17419 (use (match_operand:HI 3 "memory_operand" "m"))]
17420 "TARGET_USE_FANCY_MATH_387
17421 && flag_unsafe_math_optimizations"
17422 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17423 [(set_attr "type" "frndint")
17424 (set_attr "i387_cw" "mask_pm")
17425 (set_attr "mode" "XF")])
17427 (define_expand "nearbyintxf2"
17428 [(use (match_operand:XF 0 "register_operand" ""))
17429 (use (match_operand:XF 1 "register_operand" ""))]
17430 "TARGET_USE_FANCY_MATH_387
17431 && flag_unsafe_math_optimizations"
17433 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17438 (define_expand "nearbyint<mode>2"
17439 [(use (match_operand:MODEF 0 "register_operand" ""))
17440 (use (match_operand:MODEF 1 "register_operand" ""))]
17441 "TARGET_USE_FANCY_MATH_387
17442 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17443 || TARGET_MIX_SSE_I387)
17444 && flag_unsafe_math_optimizations"
17446 rtx op0 = gen_reg_rtx (XFmode);
17447 rtx op1 = gen_reg_rtx (XFmode);
17449 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17450 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17452 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17456 (define_insn "fxam<mode>2_i387"
17457 [(set (match_operand:HI 0 "register_operand" "=a")
17459 [(match_operand:X87MODEF 1 "register_operand" "f")]
17461 "TARGET_USE_FANCY_MATH_387"
17462 "fxam\n\tfnstsw\t%0"
17463 [(set_attr "type" "multi")
17464 (set_attr "length" "4")
17465 (set_attr "unit" "i387")
17466 (set_attr "mode" "<MODE>")])
17468 (define_insn_and_split "fxam<mode>2_i387_with_temp"
17469 [(set (match_operand:HI 0 "register_operand" "")
17471 [(match_operand:MODEF 1 "memory_operand" "")]
17473 "TARGET_USE_FANCY_MATH_387
17474 && can_create_pseudo_p ()"
17477 [(set (match_dup 2)(match_dup 1))
17479 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17481 operands[2] = gen_reg_rtx (<MODE>mode);
17483 MEM_VOLATILE_P (operands[1]) = 1;
17485 [(set_attr "type" "multi")
17486 (set_attr "unit" "i387")
17487 (set_attr "mode" "<MODE>")])
17489 (define_expand "isinfxf2"
17490 [(use (match_operand:SI 0 "register_operand" ""))
17491 (use (match_operand:XF 1 "register_operand" ""))]
17492 "TARGET_USE_FANCY_MATH_387
17493 && TARGET_C99_FUNCTIONS"
17495 rtx mask = GEN_INT (0x45);
17496 rtx val = GEN_INT (0x05);
17500 rtx scratch = gen_reg_rtx (HImode);
17501 rtx res = gen_reg_rtx (QImode);
17503 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17505 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17506 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17507 cond = gen_rtx_fmt_ee (EQ, QImode,
17508 gen_rtx_REG (CCmode, FLAGS_REG),
17510 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17511 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17515 (define_expand "isinf<mode>2"
17516 [(use (match_operand:SI 0 "register_operand" ""))
17517 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
17518 "TARGET_USE_FANCY_MATH_387
17519 && TARGET_C99_FUNCTIONS
17520 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17522 rtx mask = GEN_INT (0x45);
17523 rtx val = GEN_INT (0x05);
17527 rtx scratch = gen_reg_rtx (HImode);
17528 rtx res = gen_reg_rtx (QImode);
17530 /* Remove excess precision by forcing value through memory. */
17531 if (memory_operand (operands[1], VOIDmode))
17532 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17535 enum ix86_stack_slot slot = (virtuals_instantiated
17538 rtx temp = assign_386_stack_local (<MODE>mode, slot);
17540 emit_move_insn (temp, operands[1]);
17541 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17544 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17545 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17546 cond = gen_rtx_fmt_ee (EQ, QImode,
17547 gen_rtx_REG (CCmode, FLAGS_REG),
17549 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17550 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17554 (define_expand "signbit<mode>2"
17555 [(use (match_operand:SI 0 "register_operand" ""))
17556 (use (match_operand:X87MODEF 1 "register_operand" ""))]
17557 "TARGET_USE_FANCY_MATH_387
17558 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17560 rtx mask = GEN_INT (0x0200);
17562 rtx scratch = gen_reg_rtx (HImode);
17564 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17565 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
17569 ;; Block operation instructions
17572 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17575 [(set_attr "length" "1")
17576 (set_attr "length_immediate" "0")
17577 (set_attr "modrm" "0")])
17579 (define_expand "movmemsi"
17580 [(use (match_operand:BLK 0 "memory_operand" ""))
17581 (use (match_operand:BLK 1 "memory_operand" ""))
17582 (use (match_operand:SI 2 "nonmemory_operand" ""))
17583 (use (match_operand:SI 3 "const_int_operand" ""))
17584 (use (match_operand:SI 4 "const_int_operand" ""))
17585 (use (match_operand:SI 5 "const_int_operand" ""))]
17588 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17589 operands[4], operands[5]))
17595 (define_expand "movmemdi"
17596 [(use (match_operand:BLK 0 "memory_operand" ""))
17597 (use (match_operand:BLK 1 "memory_operand" ""))
17598 (use (match_operand:DI 2 "nonmemory_operand" ""))
17599 (use (match_operand:DI 3 "const_int_operand" ""))
17600 (use (match_operand:SI 4 "const_int_operand" ""))
17601 (use (match_operand:SI 5 "const_int_operand" ""))]
17604 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17605 operands[4], operands[5]))
17611 ;; Most CPUs don't like single string operations
17612 ;; Handle this case here to simplify previous expander.
17614 (define_expand "strmov"
17615 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17616 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17617 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17618 (clobber (reg:CC FLAGS_REG))])
17619 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17620 (clobber (reg:CC FLAGS_REG))])]
17623 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17625 /* If .md ever supports :P for Pmode, these can be directly
17626 in the pattern above. */
17627 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17628 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17630 /* Can't use this if the user has appropriated esi or edi. */
17631 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17632 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17634 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17635 operands[2], operands[3],
17636 operands[5], operands[6]));
17640 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17643 (define_expand "strmov_singleop"
17644 [(parallel [(set (match_operand 1 "memory_operand" "")
17645 (match_operand 3 "memory_operand" ""))
17646 (set (match_operand 0 "register_operand" "")
17647 (match_operand 4 "" ""))
17648 (set (match_operand 2 "register_operand" "")
17649 (match_operand 5 "" ""))])]
17651 "ix86_current_function_needs_cld = 1;")
17653 (define_insn "*strmovdi_rex_1"
17654 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17655 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17656 (set (match_operand:DI 0 "register_operand" "=D")
17657 (plus:DI (match_dup 2)
17659 (set (match_operand:DI 1 "register_operand" "=S")
17660 (plus:DI (match_dup 3)
17664 [(set_attr "type" "str")
17665 (set_attr "mode" "DI")
17666 (set_attr "memory" "both")])
17668 (define_insn "*strmovsi_1"
17669 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17670 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17671 (set (match_operand:SI 0 "register_operand" "=D")
17672 (plus:SI (match_dup 2)
17674 (set (match_operand:SI 1 "register_operand" "=S")
17675 (plus:SI (match_dup 3)
17679 [(set_attr "type" "str")
17680 (set_attr "mode" "SI")
17681 (set_attr "memory" "both")])
17683 (define_insn "*strmovsi_rex_1"
17684 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17685 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17686 (set (match_operand:DI 0 "register_operand" "=D")
17687 (plus:DI (match_dup 2)
17689 (set (match_operand:DI 1 "register_operand" "=S")
17690 (plus:DI (match_dup 3)
17694 [(set_attr "type" "str")
17695 (set_attr "mode" "SI")
17696 (set_attr "memory" "both")])
17698 (define_insn "*strmovhi_1"
17699 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17700 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17701 (set (match_operand:SI 0 "register_operand" "=D")
17702 (plus:SI (match_dup 2)
17704 (set (match_operand:SI 1 "register_operand" "=S")
17705 (plus:SI (match_dup 3)
17709 [(set_attr "type" "str")
17710 (set_attr "memory" "both")
17711 (set_attr "mode" "HI")])
17713 (define_insn "*strmovhi_rex_1"
17714 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17715 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17716 (set (match_operand:DI 0 "register_operand" "=D")
17717 (plus:DI (match_dup 2)
17719 (set (match_operand:DI 1 "register_operand" "=S")
17720 (plus:DI (match_dup 3)
17724 [(set_attr "type" "str")
17725 (set_attr "memory" "both")
17726 (set_attr "mode" "HI")])
17728 (define_insn "*strmovqi_1"
17729 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17730 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17731 (set (match_operand:SI 0 "register_operand" "=D")
17732 (plus:SI (match_dup 2)
17734 (set (match_operand:SI 1 "register_operand" "=S")
17735 (plus:SI (match_dup 3)
17739 [(set_attr "type" "str")
17740 (set_attr "memory" "both")
17741 (set_attr "mode" "QI")])
17743 (define_insn "*strmovqi_rex_1"
17744 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17745 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17746 (set (match_operand:DI 0 "register_operand" "=D")
17747 (plus:DI (match_dup 2)
17749 (set (match_operand:DI 1 "register_operand" "=S")
17750 (plus:DI (match_dup 3)
17754 [(set_attr "type" "str")
17755 (set_attr "memory" "both")
17756 (set_attr "prefix_rex" "0")
17757 (set_attr "mode" "QI")])
17759 (define_expand "rep_mov"
17760 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17761 (set (match_operand 0 "register_operand" "")
17762 (match_operand 5 "" ""))
17763 (set (match_operand 2 "register_operand" "")
17764 (match_operand 6 "" ""))
17765 (set (match_operand 1 "memory_operand" "")
17766 (match_operand 3 "memory_operand" ""))
17767 (use (match_dup 4))])]
17769 "ix86_current_function_needs_cld = 1;")
17771 (define_insn "*rep_movdi_rex64"
17772 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17773 (set (match_operand:DI 0 "register_operand" "=D")
17774 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17776 (match_operand:DI 3 "register_operand" "0")))
17777 (set (match_operand:DI 1 "register_operand" "=S")
17778 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17779 (match_operand:DI 4 "register_operand" "1")))
17780 (set (mem:BLK (match_dup 3))
17781 (mem:BLK (match_dup 4)))
17782 (use (match_dup 5))]
17785 [(set_attr "type" "str")
17786 (set_attr "prefix_rep" "1")
17787 (set_attr "memory" "both")
17788 (set_attr "mode" "DI")])
17790 (define_insn "*rep_movsi"
17791 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17792 (set (match_operand:SI 0 "register_operand" "=D")
17793 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17795 (match_operand:SI 3 "register_operand" "0")))
17796 (set (match_operand:SI 1 "register_operand" "=S")
17797 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17798 (match_operand:SI 4 "register_operand" "1")))
17799 (set (mem:BLK (match_dup 3))
17800 (mem:BLK (match_dup 4)))
17801 (use (match_dup 5))]
17804 [(set_attr "type" "str")
17805 (set_attr "prefix_rep" "1")
17806 (set_attr "memory" "both")
17807 (set_attr "mode" "SI")])
17809 (define_insn "*rep_movsi_rex64"
17810 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17811 (set (match_operand:DI 0 "register_operand" "=D")
17812 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17814 (match_operand:DI 3 "register_operand" "0")))
17815 (set (match_operand:DI 1 "register_operand" "=S")
17816 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17817 (match_operand:DI 4 "register_operand" "1")))
17818 (set (mem:BLK (match_dup 3))
17819 (mem:BLK (match_dup 4)))
17820 (use (match_dup 5))]
17823 [(set_attr "type" "str")
17824 (set_attr "prefix_rep" "1")
17825 (set_attr "memory" "both")
17826 (set_attr "mode" "SI")])
17828 (define_insn "*rep_movqi"
17829 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17830 (set (match_operand:SI 0 "register_operand" "=D")
17831 (plus:SI (match_operand:SI 3 "register_operand" "0")
17832 (match_operand:SI 5 "register_operand" "2")))
17833 (set (match_operand:SI 1 "register_operand" "=S")
17834 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17835 (set (mem:BLK (match_dup 3))
17836 (mem:BLK (match_dup 4)))
17837 (use (match_dup 5))]
17840 [(set_attr "type" "str")
17841 (set_attr "prefix_rep" "1")
17842 (set_attr "memory" "both")
17843 (set_attr "mode" "SI")])
17845 (define_insn "*rep_movqi_rex64"
17846 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17847 (set (match_operand:DI 0 "register_operand" "=D")
17848 (plus:DI (match_operand:DI 3 "register_operand" "0")
17849 (match_operand:DI 5 "register_operand" "2")))
17850 (set (match_operand:DI 1 "register_operand" "=S")
17851 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17852 (set (mem:BLK (match_dup 3))
17853 (mem:BLK (match_dup 4)))
17854 (use (match_dup 5))]
17857 [(set_attr "type" "str")
17858 (set_attr "prefix_rep" "1")
17859 (set_attr "memory" "both")
17860 (set_attr "mode" "SI")])
17862 (define_expand "setmemsi"
17863 [(use (match_operand:BLK 0 "memory_operand" ""))
17864 (use (match_operand:SI 1 "nonmemory_operand" ""))
17865 (use (match_operand 2 "const_int_operand" ""))
17866 (use (match_operand 3 "const_int_operand" ""))
17867 (use (match_operand:SI 4 "const_int_operand" ""))
17868 (use (match_operand:SI 5 "const_int_operand" ""))]
17871 if (ix86_expand_setmem (operands[0], operands[1],
17872 operands[2], operands[3],
17873 operands[4], operands[5]))
17879 (define_expand "setmemdi"
17880 [(use (match_operand:BLK 0 "memory_operand" ""))
17881 (use (match_operand:DI 1 "nonmemory_operand" ""))
17882 (use (match_operand 2 "const_int_operand" ""))
17883 (use (match_operand 3 "const_int_operand" ""))
17884 (use (match_operand 4 "const_int_operand" ""))
17885 (use (match_operand 5 "const_int_operand" ""))]
17888 if (ix86_expand_setmem (operands[0], operands[1],
17889 operands[2], operands[3],
17890 operands[4], operands[5]))
17896 ;; Most CPUs don't like single string operations
17897 ;; Handle this case here to simplify previous expander.
17899 (define_expand "strset"
17900 [(set (match_operand 1 "memory_operand" "")
17901 (match_operand 2 "register_operand" ""))
17902 (parallel [(set (match_operand 0 "register_operand" "")
17904 (clobber (reg:CC FLAGS_REG))])]
17907 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17908 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17910 /* If .md ever supports :P for Pmode, this can be directly
17911 in the pattern above. */
17912 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17913 GEN_INT (GET_MODE_SIZE (GET_MODE
17915 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17917 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17923 (define_expand "strset_singleop"
17924 [(parallel [(set (match_operand 1 "memory_operand" "")
17925 (match_operand 2 "register_operand" ""))
17926 (set (match_operand 0 "register_operand" "")
17927 (match_operand 3 "" ""))])]
17929 "ix86_current_function_needs_cld = 1;")
17931 (define_insn "*strsetdi_rex_1"
17932 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17933 (match_operand:DI 2 "register_operand" "a"))
17934 (set (match_operand:DI 0 "register_operand" "=D")
17935 (plus:DI (match_dup 1)
17939 [(set_attr "type" "str")
17940 (set_attr "memory" "store")
17941 (set_attr "mode" "DI")])
17943 (define_insn "*strsetsi_1"
17944 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17945 (match_operand:SI 2 "register_operand" "a"))
17946 (set (match_operand:SI 0 "register_operand" "=D")
17947 (plus:SI (match_dup 1)
17951 [(set_attr "type" "str")
17952 (set_attr "memory" "store")
17953 (set_attr "mode" "SI")])
17955 (define_insn "*strsetsi_rex_1"
17956 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17957 (match_operand:SI 2 "register_operand" "a"))
17958 (set (match_operand:DI 0 "register_operand" "=D")
17959 (plus:DI (match_dup 1)
17963 [(set_attr "type" "str")
17964 (set_attr "memory" "store")
17965 (set_attr "mode" "SI")])
17967 (define_insn "*strsethi_1"
17968 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17969 (match_operand:HI 2 "register_operand" "a"))
17970 (set (match_operand:SI 0 "register_operand" "=D")
17971 (plus:SI (match_dup 1)
17975 [(set_attr "type" "str")
17976 (set_attr "memory" "store")
17977 (set_attr "mode" "HI")])
17979 (define_insn "*strsethi_rex_1"
17980 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17981 (match_operand:HI 2 "register_operand" "a"))
17982 (set (match_operand:DI 0 "register_operand" "=D")
17983 (plus:DI (match_dup 1)
17987 [(set_attr "type" "str")
17988 (set_attr "memory" "store")
17989 (set_attr "mode" "HI")])
17991 (define_insn "*strsetqi_1"
17992 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17993 (match_operand:QI 2 "register_operand" "a"))
17994 (set (match_operand:SI 0 "register_operand" "=D")
17995 (plus:SI (match_dup 1)
17999 [(set_attr "type" "str")
18000 (set_attr "memory" "store")
18001 (set_attr "mode" "QI")])
18003 (define_insn "*strsetqi_rex_1"
18004 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18005 (match_operand:QI 2 "register_operand" "a"))
18006 (set (match_operand:DI 0 "register_operand" "=D")
18007 (plus:DI (match_dup 1)
18011 [(set_attr "type" "str")
18012 (set_attr "memory" "store")
18013 (set_attr "prefix_rex" "0")
18014 (set_attr "mode" "QI")])
18016 (define_expand "rep_stos"
18017 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18018 (set (match_operand 0 "register_operand" "")
18019 (match_operand 4 "" ""))
18020 (set (match_operand 2 "memory_operand" "") (const_int 0))
18021 (use (match_operand 3 "register_operand" ""))
18022 (use (match_dup 1))])]
18024 "ix86_current_function_needs_cld = 1;")
18026 (define_insn "*rep_stosdi_rex64"
18027 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18028 (set (match_operand:DI 0 "register_operand" "=D")
18029 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18031 (match_operand:DI 3 "register_operand" "0")))
18032 (set (mem:BLK (match_dup 3))
18034 (use (match_operand:DI 2 "register_operand" "a"))
18035 (use (match_dup 4))]
18038 [(set_attr "type" "str")
18039 (set_attr "prefix_rep" "1")
18040 (set_attr "memory" "store")
18041 (set_attr "mode" "DI")])
18043 (define_insn "*rep_stossi"
18044 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18045 (set (match_operand:SI 0 "register_operand" "=D")
18046 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18048 (match_operand:SI 3 "register_operand" "0")))
18049 (set (mem:BLK (match_dup 3))
18051 (use (match_operand:SI 2 "register_operand" "a"))
18052 (use (match_dup 4))]
18055 [(set_attr "type" "str")
18056 (set_attr "prefix_rep" "1")
18057 (set_attr "memory" "store")
18058 (set_attr "mode" "SI")])
18060 (define_insn "*rep_stossi_rex64"
18061 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18062 (set (match_operand:DI 0 "register_operand" "=D")
18063 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18065 (match_operand:DI 3 "register_operand" "0")))
18066 (set (mem:BLK (match_dup 3))
18068 (use (match_operand:SI 2 "register_operand" "a"))
18069 (use (match_dup 4))]
18072 [(set_attr "type" "str")
18073 (set_attr "prefix_rep" "1")
18074 (set_attr "memory" "store")
18075 (set_attr "mode" "SI")])
18077 (define_insn "*rep_stosqi"
18078 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18079 (set (match_operand:SI 0 "register_operand" "=D")
18080 (plus:SI (match_operand:SI 3 "register_operand" "0")
18081 (match_operand:SI 4 "register_operand" "1")))
18082 (set (mem:BLK (match_dup 3))
18084 (use (match_operand:QI 2 "register_operand" "a"))
18085 (use (match_dup 4))]
18088 [(set_attr "type" "str")
18089 (set_attr "prefix_rep" "1")
18090 (set_attr "memory" "store")
18091 (set_attr "mode" "QI")])
18093 (define_insn "*rep_stosqi_rex64"
18094 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18095 (set (match_operand:DI 0 "register_operand" "=D")
18096 (plus:DI (match_operand:DI 3 "register_operand" "0")
18097 (match_operand:DI 4 "register_operand" "1")))
18098 (set (mem:BLK (match_dup 3))
18100 (use (match_operand:QI 2 "register_operand" "a"))
18101 (use (match_dup 4))]
18104 [(set_attr "type" "str")
18105 (set_attr "prefix_rep" "1")
18106 (set_attr "memory" "store")
18107 (set_attr "prefix_rex" "0")
18108 (set_attr "mode" "QI")])
18110 (define_expand "cmpstrnsi"
18111 [(set (match_operand:SI 0 "register_operand" "")
18112 (compare:SI (match_operand:BLK 1 "general_operand" "")
18113 (match_operand:BLK 2 "general_operand" "")))
18114 (use (match_operand 3 "general_operand" ""))
18115 (use (match_operand 4 "immediate_operand" ""))]
18118 rtx addr1, addr2, out, outlow, count, countreg, align;
18120 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
18123 /* Can't use this if the user has appropriated esi or edi. */
18124 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18129 out = gen_reg_rtx (SImode);
18131 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18132 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18133 if (addr1 != XEXP (operands[1], 0))
18134 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18135 if (addr2 != XEXP (operands[2], 0))
18136 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18138 count = operands[3];
18139 countreg = ix86_zero_extend_to_Pmode (count);
18141 /* %%% Iff we are testing strict equality, we can use known alignment
18142 to good advantage. This may be possible with combine, particularly
18143 once cc0 is dead. */
18144 align = operands[4];
18146 if (CONST_INT_P (count))
18148 if (INTVAL (count) == 0)
18150 emit_move_insn (operands[0], const0_rtx);
18153 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18154 operands[1], operands[2]));
18158 rtx (*cmp_insn)(rtx, rtx);
18161 cmp_insn = gen_cmpdi_1;
18163 cmp_insn = gen_cmpsi_1;
18164 emit_insn (cmp_insn (countreg, countreg));
18165 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18166 operands[1], operands[2]));
18169 outlow = gen_lowpart (QImode, out);
18170 emit_insn (gen_cmpintqi (outlow));
18171 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18173 if (operands[0] != out)
18174 emit_move_insn (operands[0], out);
18179 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18181 (define_expand "cmpintqi"
18182 [(set (match_dup 1)
18183 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18185 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18186 (parallel [(set (match_operand:QI 0 "register_operand" "")
18187 (minus:QI (match_dup 1)
18189 (clobber (reg:CC FLAGS_REG))])]
18191 "operands[1] = gen_reg_rtx (QImode);
18192 operands[2] = gen_reg_rtx (QImode);")
18194 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18195 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18197 (define_expand "cmpstrnqi_nz_1"
18198 [(parallel [(set (reg:CC FLAGS_REG)
18199 (compare:CC (match_operand 4 "memory_operand" "")
18200 (match_operand 5 "memory_operand" "")))
18201 (use (match_operand 2 "register_operand" ""))
18202 (use (match_operand:SI 3 "immediate_operand" ""))
18203 (clobber (match_operand 0 "register_operand" ""))
18204 (clobber (match_operand 1 "register_operand" ""))
18205 (clobber (match_dup 2))])]
18207 "ix86_current_function_needs_cld = 1;")
18209 (define_insn "*cmpstrnqi_nz_1"
18210 [(set (reg:CC FLAGS_REG)
18211 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18212 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18213 (use (match_operand:SI 6 "register_operand" "2"))
18214 (use (match_operand:SI 3 "immediate_operand" "i"))
18215 (clobber (match_operand:SI 0 "register_operand" "=S"))
18216 (clobber (match_operand:SI 1 "register_operand" "=D"))
18217 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18220 [(set_attr "type" "str")
18221 (set_attr "mode" "QI")
18222 (set_attr "prefix_rep" "1")])
18224 (define_insn "*cmpstrnqi_nz_rex_1"
18225 [(set (reg:CC FLAGS_REG)
18226 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18227 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18228 (use (match_operand:DI 6 "register_operand" "2"))
18229 (use (match_operand:SI 3 "immediate_operand" "i"))
18230 (clobber (match_operand:DI 0 "register_operand" "=S"))
18231 (clobber (match_operand:DI 1 "register_operand" "=D"))
18232 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18235 [(set_attr "type" "str")
18236 (set_attr "mode" "QI")
18237 (set_attr "prefix_rex" "0")
18238 (set_attr "prefix_rep" "1")])
18240 ;; The same, but the count is not known to not be zero.
18242 (define_expand "cmpstrnqi_1"
18243 [(parallel [(set (reg:CC FLAGS_REG)
18244 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18246 (compare:CC (match_operand 4 "memory_operand" "")
18247 (match_operand 5 "memory_operand" ""))
18249 (use (match_operand:SI 3 "immediate_operand" ""))
18250 (use (reg:CC FLAGS_REG))
18251 (clobber (match_operand 0 "register_operand" ""))
18252 (clobber (match_operand 1 "register_operand" ""))
18253 (clobber (match_dup 2))])]
18255 "ix86_current_function_needs_cld = 1;")
18257 (define_insn "*cmpstrnqi_1"
18258 [(set (reg:CC FLAGS_REG)
18259 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18261 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18262 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18264 (use (match_operand:SI 3 "immediate_operand" "i"))
18265 (use (reg:CC FLAGS_REG))
18266 (clobber (match_operand:SI 0 "register_operand" "=S"))
18267 (clobber (match_operand:SI 1 "register_operand" "=D"))
18268 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18271 [(set_attr "type" "str")
18272 (set_attr "mode" "QI")
18273 (set_attr "prefix_rep" "1")])
18275 (define_insn "*cmpstrnqi_rex_1"
18276 [(set (reg:CC FLAGS_REG)
18277 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18279 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18280 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18282 (use (match_operand:SI 3 "immediate_operand" "i"))
18283 (use (reg:CC FLAGS_REG))
18284 (clobber (match_operand:DI 0 "register_operand" "=S"))
18285 (clobber (match_operand:DI 1 "register_operand" "=D"))
18286 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18289 [(set_attr "type" "str")
18290 (set_attr "mode" "QI")
18291 (set_attr "prefix_rex" "0")
18292 (set_attr "prefix_rep" "1")])
18294 (define_expand "strlensi"
18295 [(set (match_operand:SI 0 "register_operand" "")
18296 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18297 (match_operand:QI 2 "immediate_operand" "")
18298 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18301 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18307 (define_expand "strlendi"
18308 [(set (match_operand:DI 0 "register_operand" "")
18309 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18310 (match_operand:QI 2 "immediate_operand" "")
18311 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18314 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18320 (define_expand "strlenqi_1"
18321 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18322 (clobber (match_operand 1 "register_operand" ""))
18323 (clobber (reg:CC FLAGS_REG))])]
18325 "ix86_current_function_needs_cld = 1;")
18327 (define_insn "*strlenqi_1"
18328 [(set (match_operand:SI 0 "register_operand" "=&c")
18329 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18330 (match_operand:QI 2 "register_operand" "a")
18331 (match_operand:SI 3 "immediate_operand" "i")
18332 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18333 (clobber (match_operand:SI 1 "register_operand" "=D"))
18334 (clobber (reg:CC FLAGS_REG))]
18337 [(set_attr "type" "str")
18338 (set_attr "mode" "QI")
18339 (set_attr "prefix_rep" "1")])
18341 (define_insn "*strlenqi_rex_1"
18342 [(set (match_operand:DI 0 "register_operand" "=&c")
18343 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18344 (match_operand:QI 2 "register_operand" "a")
18345 (match_operand:DI 3 "immediate_operand" "i")
18346 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18347 (clobber (match_operand:DI 1 "register_operand" "=D"))
18348 (clobber (reg:CC FLAGS_REG))]
18351 [(set_attr "type" "str")
18352 (set_attr "mode" "QI")
18353 (set_attr "prefix_rex" "0")
18354 (set_attr "prefix_rep" "1")])
18356 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18357 ;; handled in combine, but it is not currently up to the task.
18358 ;; When used for their truth value, the cmpstrn* expanders generate
18367 ;; The intermediate three instructions are unnecessary.
18369 ;; This one handles cmpstrn*_nz_1...
18372 (set (reg:CC FLAGS_REG)
18373 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18374 (mem:BLK (match_operand 5 "register_operand" ""))))
18375 (use (match_operand 6 "register_operand" ""))
18376 (use (match_operand:SI 3 "immediate_operand" ""))
18377 (clobber (match_operand 0 "register_operand" ""))
18378 (clobber (match_operand 1 "register_operand" ""))
18379 (clobber (match_operand 2 "register_operand" ""))])
18380 (set (match_operand:QI 7 "register_operand" "")
18381 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18382 (set (match_operand:QI 8 "register_operand" "")
18383 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18384 (set (reg FLAGS_REG)
18385 (compare (match_dup 7) (match_dup 8)))
18387 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18389 (set (reg:CC FLAGS_REG)
18390 (compare:CC (mem:BLK (match_dup 4))
18391 (mem:BLK (match_dup 5))))
18392 (use (match_dup 6))
18393 (use (match_dup 3))
18394 (clobber (match_dup 0))
18395 (clobber (match_dup 1))
18396 (clobber (match_dup 2))])]
18399 ;; ...and this one handles cmpstrn*_1.
18402 (set (reg:CC FLAGS_REG)
18403 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18405 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18406 (mem:BLK (match_operand 5 "register_operand" "")))
18408 (use (match_operand:SI 3 "immediate_operand" ""))
18409 (use (reg:CC FLAGS_REG))
18410 (clobber (match_operand 0 "register_operand" ""))
18411 (clobber (match_operand 1 "register_operand" ""))
18412 (clobber (match_operand 2 "register_operand" ""))])
18413 (set (match_operand:QI 7 "register_operand" "")
18414 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18415 (set (match_operand:QI 8 "register_operand" "")
18416 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18417 (set (reg FLAGS_REG)
18418 (compare (match_dup 7) (match_dup 8)))
18420 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18422 (set (reg:CC FLAGS_REG)
18423 (if_then_else:CC (ne (match_dup 6)
18425 (compare:CC (mem:BLK (match_dup 4))
18426 (mem:BLK (match_dup 5)))
18428 (use (match_dup 3))
18429 (use (reg:CC FLAGS_REG))
18430 (clobber (match_dup 0))
18431 (clobber (match_dup 1))
18432 (clobber (match_dup 2))])]
18437 ;; Conditional move instructions.
18439 (define_expand "mov<mode>cc"
18440 [(set (match_operand:SWIM 0 "register_operand" "")
18441 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
18442 (match_operand:SWIM 2 "general_operand" "")
18443 (match_operand:SWIM 3 "general_operand" "")))]
18445 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18447 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18448 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18449 ;; So just document what we're doing explicitly.
18451 (define_expand "x86_mov<mode>cc_0_m1"
18453 [(set (match_operand:SWI48 0 "register_operand" "")
18454 (if_then_else:SWI48
18455 (match_operator:SWI48 2 "ix86_carry_flag_operator"
18456 [(match_operand 1 "flags_reg_operand" "")
18460 (clobber (reg:CC FLAGS_REG))])]
18464 (define_insn "*x86_mov<mode>cc_0_m1"
18465 [(set (match_operand:SWI48 0 "register_operand" "=r")
18466 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18467 [(reg FLAGS_REG) (const_int 0)])
18470 (clobber (reg:CC FLAGS_REG))]
18472 "sbb{<imodesuffix>}\t%0, %0"
18473 ; Since we don't have the proper number of operands for an alu insn,
18474 ; fill in all the blanks.
18475 [(set_attr "type" "alu")
18476 (set_attr "use_carry" "1")
18477 (set_attr "pent_pair" "pu")
18478 (set_attr "memory" "none")
18479 (set_attr "imm_disp" "false")
18480 (set_attr "mode" "<MODE>")
18481 (set_attr "length_immediate" "0")])
18483 (define_insn "*x86_mov<mode>cc_0_m1_se"
18484 [(set (match_operand:SWI48 0 "register_operand" "=r")
18485 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18486 [(reg FLAGS_REG) (const_int 0)])
18489 (clobber (reg:CC FLAGS_REG))]
18491 "sbb{<imodesuffix>}\t%0, %0"
18492 [(set_attr "type" "alu")
18493 (set_attr "use_carry" "1")
18494 (set_attr "pent_pair" "pu")
18495 (set_attr "memory" "none")
18496 (set_attr "imm_disp" "false")
18497 (set_attr "mode" "<MODE>")
18498 (set_attr "length_immediate" "0")])
18500 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18501 [(set (match_operand:SWI48 0 "register_operand" "=r")
18502 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18503 [(reg FLAGS_REG) (const_int 0)])))]
18505 "sbb{<imodesuffix>}\t%0, %0"
18506 [(set_attr "type" "alu")
18507 (set_attr "use_carry" "1")
18508 (set_attr "pent_pair" "pu")
18509 (set_attr "memory" "none")
18510 (set_attr "imm_disp" "false")
18511 (set_attr "mode" "<MODE>")
18512 (set_attr "length_immediate" "0")])
18514 (define_insn "*mov<mode>cc_noc"
18515 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18516 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18517 [(reg FLAGS_REG) (const_int 0)])
18518 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18519 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18520 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18522 cmov%O2%C1\t{%2, %0|%0, %2}
18523 cmov%O2%c1\t{%3, %0|%0, %3}"
18524 [(set_attr "type" "icmov")
18525 (set_attr "mode" "<MODE>")])
18527 (define_insn_and_split "*movqicc_noc"
18528 [(set (match_operand:QI 0 "register_operand" "=r,r")
18529 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18530 [(match_operand 4 "flags_reg_operand" "")
18532 (match_operand:QI 2 "register_operand" "r,0")
18533 (match_operand:QI 3 "register_operand" "0,r")))]
18534 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18536 "&& reload_completed"
18537 [(set (match_dup 0)
18538 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18541 "operands[0] = gen_lowpart (SImode, operands[0]);
18542 operands[2] = gen_lowpart (SImode, operands[2]);
18543 operands[3] = gen_lowpart (SImode, operands[3]);"
18544 [(set_attr "type" "icmov")
18545 (set_attr "mode" "SI")])
18547 (define_expand "mov<mode>cc"
18548 [(set (match_operand:X87MODEF 0 "register_operand" "")
18549 (if_then_else:X87MODEF
18550 (match_operand 1 "ix86_fp_comparison_operator" "")
18551 (match_operand:X87MODEF 2 "register_operand" "")
18552 (match_operand:X87MODEF 3 "register_operand" "")))]
18553 "(TARGET_80387 && TARGET_CMOVE)
18554 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18555 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18557 (define_insn "*movsfcc_1_387"
18558 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18559 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18560 [(reg FLAGS_REG) (const_int 0)])
18561 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18562 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18563 "TARGET_80387 && TARGET_CMOVE
18564 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18566 fcmov%F1\t{%2, %0|%0, %2}
18567 fcmov%f1\t{%3, %0|%0, %3}
18568 cmov%O2%C1\t{%2, %0|%0, %2}
18569 cmov%O2%c1\t{%3, %0|%0, %3}"
18570 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18571 (set_attr "mode" "SF,SF,SI,SI")])
18573 (define_insn "*movdfcc_1"
18574 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18575 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18576 [(reg FLAGS_REG) (const_int 0)])
18577 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18578 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18579 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18580 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18582 fcmov%F1\t{%2, %0|%0, %2}
18583 fcmov%f1\t{%3, %0|%0, %3}
18586 [(set_attr "type" "fcmov,fcmov,multi,multi")
18587 (set_attr "mode" "DF")])
18589 (define_insn "*movdfcc_1_rex64"
18590 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18591 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18592 [(reg FLAGS_REG) (const_int 0)])
18593 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18594 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18595 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18596 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18598 fcmov%F1\t{%2, %0|%0, %2}
18599 fcmov%f1\t{%3, %0|%0, %3}
18600 cmov%O2%C1\t{%2, %0|%0, %2}
18601 cmov%O2%c1\t{%3, %0|%0, %3}"
18602 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18603 (set_attr "mode" "DF")])
18606 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18607 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18608 [(match_operand 4 "flags_reg_operand" "")
18610 (match_operand:DF 2 "nonimmediate_operand" "")
18611 (match_operand:DF 3 "nonimmediate_operand" "")))]
18612 "!TARGET_64BIT && reload_completed"
18613 [(set (match_dup 2)
18614 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18618 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18621 "split_di (&operands[2], 2, &operands[5], &operands[7]);
18622 split_di (&operands[0], 1, &operands[2], &operands[3]);")
18624 (define_insn "*movxfcc_1"
18625 [(set (match_operand:XF 0 "register_operand" "=f,f")
18626 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18627 [(reg FLAGS_REG) (const_int 0)])
18628 (match_operand:XF 2 "register_operand" "f,0")
18629 (match_operand:XF 3 "register_operand" "0,f")))]
18630 "TARGET_80387 && TARGET_CMOVE"
18632 fcmov%F1\t{%2, %0|%0, %2}
18633 fcmov%f1\t{%3, %0|%0, %3}"
18634 [(set_attr "type" "fcmov")
18635 (set_attr "mode" "XF")])
18637 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18638 ;; the scalar versions to have only XMM registers as operands.
18640 ;; XOP conditional move
18641 (define_insn "*xop_pcmov_<mode>"
18642 [(set (match_operand:MODEF 0 "register_operand" "=x")
18643 (if_then_else:MODEF
18644 (match_operand:MODEF 1 "register_operand" "x")
18645 (match_operand:MODEF 2 "register_operand" "x")
18646 (match_operand:MODEF 3 "register_operand" "x")))]
18648 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18649 [(set_attr "type" "sse4arg")])
18651 ;; These versions of the min/max patterns are intentionally ignorant of
18652 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18653 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18654 ;; are undefined in this condition, we're certain this is correct.
18656 (define_insn "*avx_<code><mode>3"
18657 [(set (match_operand:MODEF 0 "register_operand" "=x")
18659 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
18660 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18661 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18662 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18663 [(set_attr "type" "sseadd")
18664 (set_attr "prefix" "vex")
18665 (set_attr "mode" "<MODE>")])
18667 (define_insn "<code><mode>3"
18668 [(set (match_operand:MODEF 0 "register_operand" "=x")
18670 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
18671 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18672 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18673 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
18674 [(set_attr "type" "sseadd")
18675 (set_attr "mode" "<MODE>")])
18677 ;; These versions of the min/max patterns implement exactly the operations
18678 ;; min = (op1 < op2 ? op1 : op2)
18679 ;; max = (!(op1 < op2) ? op1 : op2)
18680 ;; Their operands are not commutative, and thus they may be used in the
18681 ;; presence of -0.0 and NaN.
18683 (define_insn "*avx_ieee_smin<mode>3"
18684 [(set (match_operand:MODEF 0 "register_operand" "=x")
18686 [(match_operand:MODEF 1 "register_operand" "x")
18687 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18689 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18690 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18691 [(set_attr "type" "sseadd")
18692 (set_attr "prefix" "vex")
18693 (set_attr "mode" "<MODE>")])
18695 (define_insn "*ieee_smin<mode>3"
18696 [(set (match_operand:MODEF 0 "register_operand" "=x")
18698 [(match_operand:MODEF 1 "register_operand" "0")
18699 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18701 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18702 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
18703 [(set_attr "type" "sseadd")
18704 (set_attr "mode" "<MODE>")])
18706 (define_insn "*avx_ieee_smax<mode>3"
18707 [(set (match_operand:MODEF 0 "register_operand" "=x")
18709 [(match_operand:MODEF 1 "register_operand" "0")
18710 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18712 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18713 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18714 [(set_attr "type" "sseadd")
18715 (set_attr "prefix" "vex")
18716 (set_attr "mode" "<MODE>")])
18718 (define_insn "*ieee_smax<mode>3"
18719 [(set (match_operand:MODEF 0 "register_operand" "=x")
18721 [(match_operand:MODEF 1 "register_operand" "0")
18722 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18724 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18725 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
18726 [(set_attr "type" "sseadd")
18727 (set_attr "mode" "<MODE>")])
18729 ;; Make two stack loads independent:
18731 ;; fld %st(0) -> fld bb
18732 ;; fmul bb fmul %st(1), %st
18734 ;; Actually we only match the last two instructions for simplicity.
18736 [(set (match_operand 0 "fp_register_operand" "")
18737 (match_operand 1 "fp_register_operand" ""))
18739 (match_operator 2 "binary_fp_operator"
18741 (match_operand 3 "memory_operand" "")]))]
18742 "REGNO (operands[0]) != REGNO (operands[1])"
18743 [(set (match_dup 0) (match_dup 3))
18744 (set (match_dup 0) (match_dup 4))]
18746 ;; The % modifier is not operational anymore in peephole2's, so we have to
18747 ;; swap the operands manually in the case of addition and multiplication.
18748 "if (COMMUTATIVE_ARITH_P (operands[2]))
18749 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18750 operands[0], operands[1]);
18752 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18753 operands[1], operands[0]);")
18755 ;; Conditional addition patterns
18756 (define_expand "add<mode>cc"
18757 [(match_operand:SWI 0 "register_operand" "")
18758 (match_operand 1 "comparison_operator" "")
18759 (match_operand:SWI 2 "register_operand" "")
18760 (match_operand:SWI 3 "const_int_operand" "")]
18762 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18765 ;; Misc patterns (?)
18767 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18768 ;; Otherwise there will be nothing to keep
18770 ;; [(set (reg ebp) (reg esp))]
18771 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18772 ;; (clobber (eflags)]
18773 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18775 ;; in proper program order.
18776 (define_insn "pro_epilogue_adjust_stack_1"
18777 [(set (match_operand:SI 0 "register_operand" "=r,r")
18778 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18779 (match_operand:SI 2 "immediate_operand" "i,i")))
18780 (clobber (reg:CC FLAGS_REG))
18781 (clobber (mem:BLK (scratch)))]
18784 switch (get_attr_type (insn))
18787 return "mov{l}\t{%1, %0|%0, %1}";
18790 if (CONST_INT_P (operands[2])
18791 && (INTVAL (operands[2]) == 128
18792 || (INTVAL (operands[2]) < 0
18793 && INTVAL (operands[2]) != -128)))
18795 operands[2] = GEN_INT (-INTVAL (operands[2]));
18796 return "sub{l}\t{%2, %0|%0, %2}";
18798 return "add{l}\t{%2, %0|%0, %2}";
18801 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18802 return "lea{l}\t{%a2, %0|%0, %a2}";
18805 gcc_unreachable ();
18808 [(set (attr "type")
18809 (cond [(and (eq_attr "alternative" "0")
18810 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18811 (const_string "alu")
18812 (match_operand:SI 2 "const0_operand" "")
18813 (const_string "imov")
18815 (const_string "lea")))
18816 (set (attr "length_immediate")
18817 (cond [(eq_attr "type" "imov")
18819 (and (eq_attr "type" "alu")
18820 (match_operand 2 "const128_operand" ""))
18823 (const_string "*")))
18824 (set_attr "mode" "SI")])
18826 (define_insn "pro_epilogue_adjust_stack_rex64"
18827 [(set (match_operand:DI 0 "register_operand" "=r,r")
18828 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18829 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18830 (clobber (reg:CC FLAGS_REG))
18831 (clobber (mem:BLK (scratch)))]
18834 switch (get_attr_type (insn))
18837 return "mov{q}\t{%1, %0|%0, %1}";
18840 if (CONST_INT_P (operands[2])
18841 /* Avoid overflows. */
18842 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18843 && (INTVAL (operands[2]) == 128
18844 || (INTVAL (operands[2]) < 0
18845 && INTVAL (operands[2]) != -128)))
18847 operands[2] = GEN_INT (-INTVAL (operands[2]));
18848 return "sub{q}\t{%2, %0|%0, %2}";
18850 return "add{q}\t{%2, %0|%0, %2}";
18853 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18854 return "lea{q}\t{%a2, %0|%0, %a2}";
18857 gcc_unreachable ();
18860 [(set (attr "type")
18861 (cond [(and (eq_attr "alternative" "0")
18862 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18863 (const_string "alu")
18864 (match_operand:DI 2 "const0_operand" "")
18865 (const_string "imov")
18867 (const_string "lea")))
18868 (set (attr "length_immediate")
18869 (cond [(eq_attr "type" "imov")
18871 (and (eq_attr "type" "alu")
18872 (match_operand 2 "const128_operand" ""))
18875 (const_string "*")))
18876 (set_attr "mode" "DI")])
18878 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18879 [(set (match_operand:DI 0 "register_operand" "=r,r")
18880 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18881 (match_operand:DI 3 "immediate_operand" "i,i")))
18882 (use (match_operand:DI 2 "register_operand" "r,r"))
18883 (clobber (reg:CC FLAGS_REG))
18884 (clobber (mem:BLK (scratch)))]
18887 switch (get_attr_type (insn))
18890 return "add{q}\t{%2, %0|%0, %2}";
18893 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18894 return "lea{q}\t{%a2, %0|%0, %a2}";
18897 gcc_unreachable ();
18900 [(set_attr "type" "alu,lea")
18901 (set_attr "mode" "DI")])
18903 (define_insn "allocate_stack_worker_32"
18904 [(set (match_operand:SI 0 "register_operand" "=a")
18905 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
18906 UNSPECV_STACK_PROBE))
18907 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
18908 (clobber (reg:CC FLAGS_REG))]
18909 "!TARGET_64BIT && TARGET_STACK_PROBE"
18911 [(set_attr "type" "multi")
18912 (set_attr "length" "5")])
18914 (define_insn "allocate_stack_worker_64"
18915 [(set (match_operand:DI 0 "register_operand" "=a")
18916 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
18917 UNSPECV_STACK_PROBE))
18918 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
18919 (clobber (reg:DI R10_REG))
18920 (clobber (reg:DI R11_REG))
18921 (clobber (reg:CC FLAGS_REG))]
18922 "TARGET_64BIT && TARGET_STACK_PROBE"
18924 [(set_attr "type" "multi")
18925 (set_attr "length" "5")])
18927 (define_expand "allocate_stack"
18928 [(match_operand 0 "register_operand" "")
18929 (match_operand 1 "general_operand" "")]
18930 "TARGET_STACK_PROBE"
18934 #ifndef CHECK_STACK_LIMIT
18935 #define CHECK_STACK_LIMIT 0
18938 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18939 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18941 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
18942 stack_pointer_rtx, 0, OPTAB_DIRECT);
18943 if (x != stack_pointer_rtx)
18944 emit_move_insn (stack_pointer_rtx, x);
18948 x = copy_to_mode_reg (Pmode, operands[1]);
18950 x = gen_allocate_stack_worker_64 (x, x);
18952 x = gen_allocate_stack_worker_32 (x, x);
18956 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18960 ;; Use IOR for stack probes, this is shorter.
18961 (define_expand "probe_stack"
18962 [(match_operand 0 "memory_operand" "")]
18965 if (GET_MODE (operands[0]) == DImode)
18966 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
18968 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
18972 (define_expand "builtin_setjmp_receiver"
18973 [(label_ref (match_operand 0 "" ""))]
18974 "!TARGET_64BIT && flag_pic"
18980 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
18981 rtx label_rtx = gen_label_rtx ();
18982 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18983 xops[0] = xops[1] = picreg;
18984 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18985 ix86_expand_binary_operator (MINUS, SImode, xops);
18989 emit_insn (gen_set_got (pic_offset_table_rtx));
18993 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18996 [(set (match_operand 0 "register_operand" "")
18997 (match_operator 3 "promotable_binary_operator"
18998 [(match_operand 1 "register_operand" "")
18999 (match_operand 2 "aligned_operand" "")]))
19000 (clobber (reg:CC FLAGS_REG))]
19001 "! TARGET_PARTIAL_REG_STALL && reload_completed
19002 && ((GET_MODE (operands[0]) == HImode
19003 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
19004 /* ??? next two lines just !satisfies_constraint_K (...) */
19005 || !CONST_INT_P (operands[2])
19006 || satisfies_constraint_K (operands[2])))
19007 || (GET_MODE (operands[0]) == QImode
19008 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
19009 [(parallel [(set (match_dup 0)
19010 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19011 (clobber (reg:CC FLAGS_REG))])]
19012 "operands[0] = gen_lowpart (SImode, operands[0]);
19013 operands[1] = gen_lowpart (SImode, operands[1]);
19014 if (GET_CODE (operands[3]) != ASHIFT)
19015 operands[2] = gen_lowpart (SImode, operands[2]);
19016 PUT_MODE (operands[3], SImode);")
19018 ; Promote the QImode tests, as i386 has encoding of the AND
19019 ; instruction with 32-bit sign-extended immediate and thus the
19020 ; instruction size is unchanged, except in the %eax case for
19021 ; which it is increased by one byte, hence the ! optimize_size.
19023 [(set (match_operand 0 "flags_reg_operand" "")
19024 (match_operator 2 "compare_operator"
19025 [(and (match_operand 3 "aligned_operand" "")
19026 (match_operand 4 "const_int_operand" ""))
19028 (set (match_operand 1 "register_operand" "")
19029 (and (match_dup 3) (match_dup 4)))]
19030 "! TARGET_PARTIAL_REG_STALL && reload_completed
19031 && optimize_insn_for_speed_p ()
19032 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19033 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19034 /* Ensure that the operand will remain sign-extended immediate. */
19035 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19036 [(parallel [(set (match_dup 0)
19037 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19040 (and:SI (match_dup 3) (match_dup 4)))])]
19043 = gen_int_mode (INTVAL (operands[4])
19044 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19045 operands[1] = gen_lowpart (SImode, operands[1]);
19046 operands[3] = gen_lowpart (SImode, operands[3]);
19049 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19050 ; the TEST instruction with 32-bit sign-extended immediate and thus
19051 ; the instruction size would at least double, which is not what we
19052 ; want even with ! optimize_size.
19054 [(set (match_operand 0 "flags_reg_operand" "")
19055 (match_operator 1 "compare_operator"
19056 [(and (match_operand:HI 2 "aligned_operand" "")
19057 (match_operand:HI 3 "const_int_operand" ""))
19059 "! TARGET_PARTIAL_REG_STALL && reload_completed
19060 && ! TARGET_FAST_PREFIX
19061 && optimize_insn_for_speed_p ()
19062 /* Ensure that the operand will remain sign-extended immediate. */
19063 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19064 [(set (match_dup 0)
19065 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19069 = gen_int_mode (INTVAL (operands[3])
19070 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19071 operands[2] = gen_lowpart (SImode, operands[2]);
19075 [(set (match_operand 0 "register_operand" "")
19076 (neg (match_operand 1 "register_operand" "")))
19077 (clobber (reg:CC FLAGS_REG))]
19078 "! TARGET_PARTIAL_REG_STALL && reload_completed
19079 && (GET_MODE (operands[0]) == HImode
19080 || (GET_MODE (operands[0]) == QImode
19081 && (TARGET_PROMOTE_QImode
19082 || optimize_insn_for_size_p ())))"
19083 [(parallel [(set (match_dup 0)
19084 (neg:SI (match_dup 1)))
19085 (clobber (reg:CC FLAGS_REG))])]
19086 "operands[0] = gen_lowpart (SImode, operands[0]);
19087 operands[1] = gen_lowpart (SImode, operands[1]);")
19090 [(set (match_operand 0 "register_operand" "")
19091 (not (match_operand 1 "register_operand" "")))]
19092 "! TARGET_PARTIAL_REG_STALL && reload_completed
19093 && (GET_MODE (operands[0]) == HImode
19094 || (GET_MODE (operands[0]) == QImode
19095 && (TARGET_PROMOTE_QImode
19096 || optimize_insn_for_size_p ())))"
19097 [(set (match_dup 0)
19098 (not:SI (match_dup 1)))]
19099 "operands[0] = gen_lowpart (SImode, operands[0]);
19100 operands[1] = gen_lowpart (SImode, operands[1]);")
19103 [(set (match_operand 0 "register_operand" "")
19104 (if_then_else (match_operator 1 "comparison_operator"
19105 [(reg FLAGS_REG) (const_int 0)])
19106 (match_operand 2 "register_operand" "")
19107 (match_operand 3 "register_operand" "")))]
19108 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19109 && (GET_MODE (operands[0]) == HImode
19110 || (GET_MODE (operands[0]) == QImode
19111 && (TARGET_PROMOTE_QImode
19112 || optimize_insn_for_size_p ())))"
19113 [(set (match_dup 0)
19114 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19115 "operands[0] = gen_lowpart (SImode, operands[0]);
19116 operands[2] = gen_lowpart (SImode, operands[2]);
19117 operands[3] = gen_lowpart (SImode, operands[3]);")
19120 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19121 ;; transform a complex memory operation into two memory to register operations.
19123 ;; Don't push memory operands
19125 [(set (match_operand:SI 0 "push_operand" "")
19126 (match_operand:SI 1 "memory_operand" ""))
19127 (match_scratch:SI 2 "r")]
19128 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19129 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19130 [(set (match_dup 2) (match_dup 1))
19131 (set (match_dup 0) (match_dup 2))]
19135 [(set (match_operand:DI 0 "push_operand" "")
19136 (match_operand:DI 1 "memory_operand" ""))
19137 (match_scratch:DI 2 "r")]
19138 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19139 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19140 [(set (match_dup 2) (match_dup 1))
19141 (set (match_dup 0) (match_dup 2))]
19144 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19147 [(set (match_operand:SF 0 "push_operand" "")
19148 (match_operand:SF 1 "memory_operand" ""))
19149 (match_scratch:SF 2 "r")]
19150 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19151 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19152 [(set (match_dup 2) (match_dup 1))
19153 (set (match_dup 0) (match_dup 2))]
19157 [(set (match_operand:HI 0 "push_operand" "")
19158 (match_operand:HI 1 "memory_operand" ""))
19159 (match_scratch:HI 2 "r")]
19160 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19161 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19162 [(set (match_dup 2) (match_dup 1))
19163 (set (match_dup 0) (match_dup 2))]
19167 [(set (match_operand:QI 0 "push_operand" "")
19168 (match_operand:QI 1 "memory_operand" ""))
19169 (match_scratch:QI 2 "q")]
19170 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19171 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19172 [(set (match_dup 2) (match_dup 1))
19173 (set (match_dup 0) (match_dup 2))]
19176 ;; Don't move an immediate directly to memory when the instruction
19179 [(match_scratch:SI 1 "r")
19180 (set (match_operand:SI 0 "memory_operand" "")
19182 "optimize_insn_for_speed_p ()
19183 && ! TARGET_USE_MOV0
19184 && TARGET_SPLIT_LONG_MOVES
19185 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19186 && peep2_regno_dead_p (0, FLAGS_REG)"
19187 [(parallel [(set (match_dup 1) (const_int 0))
19188 (clobber (reg:CC FLAGS_REG))])
19189 (set (match_dup 0) (match_dup 1))]
19193 [(match_scratch:HI 1 "r")
19194 (set (match_operand:HI 0 "memory_operand" "")
19196 "optimize_insn_for_speed_p ()
19197 && ! TARGET_USE_MOV0
19198 && TARGET_SPLIT_LONG_MOVES
19199 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19200 && peep2_regno_dead_p (0, FLAGS_REG)"
19201 [(parallel [(set (match_dup 2) (const_int 0))
19202 (clobber (reg:CC FLAGS_REG))])
19203 (set (match_dup 0) (match_dup 1))]
19204 "operands[2] = gen_lowpart (SImode, operands[1]);")
19207 [(match_scratch:QI 1 "q")
19208 (set (match_operand:QI 0 "memory_operand" "")
19210 "optimize_insn_for_speed_p ()
19211 && ! TARGET_USE_MOV0
19212 && TARGET_SPLIT_LONG_MOVES
19213 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19214 && peep2_regno_dead_p (0, FLAGS_REG)"
19215 [(parallel [(set (match_dup 2) (const_int 0))
19216 (clobber (reg:CC FLAGS_REG))])
19217 (set (match_dup 0) (match_dup 1))]
19218 "operands[2] = gen_lowpart (SImode, operands[1]);")
19221 [(match_scratch:SI 2 "r")
19222 (set (match_operand:SI 0 "memory_operand" "")
19223 (match_operand:SI 1 "immediate_operand" ""))]
19224 "optimize_insn_for_speed_p ()
19225 && TARGET_SPLIT_LONG_MOVES
19226 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19227 [(set (match_dup 2) (match_dup 1))
19228 (set (match_dup 0) (match_dup 2))]
19232 [(match_scratch:HI 2 "r")
19233 (set (match_operand:HI 0 "memory_operand" "")
19234 (match_operand:HI 1 "immediate_operand" ""))]
19235 "optimize_insn_for_speed_p ()
19236 && TARGET_SPLIT_LONG_MOVES
19237 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19238 [(set (match_dup 2) (match_dup 1))
19239 (set (match_dup 0) (match_dup 2))]
19243 [(match_scratch:QI 2 "q")
19244 (set (match_operand:QI 0 "memory_operand" "")
19245 (match_operand:QI 1 "immediate_operand" ""))]
19246 "optimize_insn_for_speed_p ()
19247 && TARGET_SPLIT_LONG_MOVES
19248 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19249 [(set (match_dup 2) (match_dup 1))
19250 (set (match_dup 0) (match_dup 2))]
19253 ;; Don't compare memory with zero, load and use a test instead.
19255 [(set (match_operand 0 "flags_reg_operand" "")
19256 (match_operator 1 "compare_operator"
19257 [(match_operand:SI 2 "memory_operand" "")
19259 (match_scratch:SI 3 "r")]
19260 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19261 [(set (match_dup 3) (match_dup 2))
19262 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19265 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19266 ;; Don't split NOTs with a displacement operand, because resulting XOR
19267 ;; will not be pairable anyway.
19269 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19270 ;; represented using a modRM byte. The XOR replacement is long decoded,
19271 ;; so this split helps here as well.
19273 ;; Note: Can't do this as a regular split because we can't get proper
19274 ;; lifetime information then.
19277 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19278 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19279 "optimize_insn_for_speed_p ()
19280 && ((TARGET_NOT_UNPAIRABLE
19281 && (!MEM_P (operands[0])
19282 || !memory_displacement_operand (operands[0], SImode)))
19283 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19284 && peep2_regno_dead_p (0, FLAGS_REG)"
19285 [(parallel [(set (match_dup 0)
19286 (xor:SI (match_dup 1) (const_int -1)))
19287 (clobber (reg:CC FLAGS_REG))])]
19291 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19292 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19293 "optimize_insn_for_speed_p ()
19294 && ((TARGET_NOT_UNPAIRABLE
19295 && (!MEM_P (operands[0])
19296 || !memory_displacement_operand (operands[0], HImode)))
19297 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
19298 && peep2_regno_dead_p (0, FLAGS_REG)"
19299 [(parallel [(set (match_dup 0)
19300 (xor:HI (match_dup 1) (const_int -1)))
19301 (clobber (reg:CC FLAGS_REG))])]
19305 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19306 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19307 "optimize_insn_for_speed_p ()
19308 && ((TARGET_NOT_UNPAIRABLE
19309 && (!MEM_P (operands[0])
19310 || !memory_displacement_operand (operands[0], QImode)))
19311 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
19312 && peep2_regno_dead_p (0, FLAGS_REG)"
19313 [(parallel [(set (match_dup 0)
19314 (xor:QI (match_dup 1) (const_int -1)))
19315 (clobber (reg:CC FLAGS_REG))])]
19318 ;; Non pairable "test imm, reg" instructions can be translated to
19319 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19320 ;; byte opcode instead of two, have a short form for byte operands),
19321 ;; so do it for other CPUs as well. Given that the value was dead,
19322 ;; this should not create any new dependencies. Pass on the sub-word
19323 ;; versions if we're concerned about partial register stalls.
19326 [(set (match_operand 0 "flags_reg_operand" "")
19327 (match_operator 1 "compare_operator"
19328 [(and:SI (match_operand:SI 2 "register_operand" "")
19329 (match_operand:SI 3 "immediate_operand" ""))
19331 "ix86_match_ccmode (insn, CCNOmode)
19332 && (true_regnum (operands[2]) != AX_REG
19333 || satisfies_constraint_K (operands[3]))
19334 && peep2_reg_dead_p (1, operands[2])"
19336 [(set (match_dup 0)
19337 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19340 (and:SI (match_dup 2) (match_dup 3)))])]
19343 ;; We don't need to handle HImode case, because it will be promoted to SImode
19344 ;; on ! TARGET_PARTIAL_REG_STALL
19347 [(set (match_operand 0 "flags_reg_operand" "")
19348 (match_operator 1 "compare_operator"
19349 [(and:QI (match_operand:QI 2 "register_operand" "")
19350 (match_operand:QI 3 "immediate_operand" ""))
19352 "! TARGET_PARTIAL_REG_STALL
19353 && ix86_match_ccmode (insn, CCNOmode)
19354 && true_regnum (operands[2]) != AX_REG
19355 && peep2_reg_dead_p (1, operands[2])"
19357 [(set (match_dup 0)
19358 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19361 (and:QI (match_dup 2) (match_dup 3)))])]
19365 [(set (match_operand 0 "flags_reg_operand" "")
19366 (match_operator 1 "compare_operator"
19369 (match_operand 2 "ext_register_operand" "")
19372 (match_operand 3 "const_int_operand" ""))
19374 "! TARGET_PARTIAL_REG_STALL
19375 && ix86_match_ccmode (insn, CCNOmode)
19376 && true_regnum (operands[2]) != AX_REG
19377 && peep2_reg_dead_p (1, operands[2])"
19378 [(parallel [(set (match_dup 0)
19387 (set (zero_extract:SI (match_dup 2)
19398 ;; Don't do logical operations with memory inputs.
19400 [(match_scratch:SI 2 "r")
19401 (parallel [(set (match_operand:SI 0 "register_operand" "")
19402 (match_operator:SI 3 "arith_or_logical_operator"
19404 (match_operand:SI 1 "memory_operand" "")]))
19405 (clobber (reg:CC FLAGS_REG))])]
19406 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19407 [(set (match_dup 2) (match_dup 1))
19408 (parallel [(set (match_dup 0)
19409 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19410 (clobber (reg:CC FLAGS_REG))])]
19414 [(match_scratch:SI 2 "r")
19415 (parallel [(set (match_operand:SI 0 "register_operand" "")
19416 (match_operator:SI 3 "arith_or_logical_operator"
19417 [(match_operand:SI 1 "memory_operand" "")
19419 (clobber (reg:CC FLAGS_REG))])]
19420 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19421 [(set (match_dup 2) (match_dup 1))
19422 (parallel [(set (match_dup 0)
19423 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19424 (clobber (reg:CC FLAGS_REG))])]
19427 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
19428 ;; refers to the destination of the load!
19431 [(set (match_operand:SI 0 "register_operand" "")
19432 (match_operand:SI 1 "register_operand" ""))
19433 (parallel [(set (match_dup 0)
19434 (match_operator:SI 3 "commutative_operator"
19436 (match_operand:SI 2 "memory_operand" "")]))
19437 (clobber (reg:CC FLAGS_REG))])]
19438 "REGNO (operands[0]) != REGNO (operands[1])
19439 && GENERAL_REGNO_P (REGNO (operands[0]))
19440 && GENERAL_REGNO_P (REGNO (operands[1]))"
19441 [(set (match_dup 0) (match_dup 4))
19442 (parallel [(set (match_dup 0)
19443 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19444 (clobber (reg:CC FLAGS_REG))])]
19445 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
19448 [(set (match_operand 0 "register_operand" "")
19449 (match_operand 1 "register_operand" ""))
19451 (match_operator 3 "commutative_operator"
19453 (match_operand 2 "memory_operand" "")]))]
19454 "REGNO (operands[0]) != REGNO (operands[1])
19455 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
19456 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
19457 [(set (match_dup 0) (match_dup 2))
19459 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
19462 ; Don't do logical operations with memory outputs
19464 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19465 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19466 ; the same decoder scheduling characteristics as the original.
19469 [(match_scratch:SI 2 "r")
19470 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19471 (match_operator:SI 3 "arith_or_logical_operator"
19473 (match_operand:SI 1 "nonmemory_operand" "")]))
19474 (clobber (reg:CC FLAGS_REG))])]
19475 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19476 /* Do not split stack checking probes. */
19477 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19478 [(set (match_dup 2) (match_dup 0))
19479 (parallel [(set (match_dup 2)
19480 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19481 (clobber (reg:CC FLAGS_REG))])
19482 (set (match_dup 0) (match_dup 2))]
19486 [(match_scratch:SI 2 "r")
19487 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19488 (match_operator:SI 3 "arith_or_logical_operator"
19489 [(match_operand:SI 1 "nonmemory_operand" "")
19491 (clobber (reg:CC FLAGS_REG))])]
19492 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19493 /* Do not split stack checking probes. */
19494 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19495 [(set (match_dup 2) (match_dup 0))
19496 (parallel [(set (match_dup 2)
19497 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19498 (clobber (reg:CC FLAGS_REG))])
19499 (set (match_dup 0) (match_dup 2))]
19502 ;; Attempt to always use XOR for zeroing registers.
19504 [(set (match_operand 0 "register_operand" "")
19505 (match_operand 1 "const0_operand" ""))]
19506 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19507 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19508 && GENERAL_REG_P (operands[0])
19509 && peep2_regno_dead_p (0, FLAGS_REG)"
19510 [(parallel [(set (match_dup 0) (const_int 0))
19511 (clobber (reg:CC FLAGS_REG))])]
19513 operands[0] = gen_lowpart (word_mode, operands[0]);
19517 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19519 "(GET_MODE (operands[0]) == QImode
19520 || GET_MODE (operands[0]) == HImode)
19521 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19522 && peep2_regno_dead_p (0, FLAGS_REG)"
19523 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19524 (clobber (reg:CC FLAGS_REG))])])
19526 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19528 [(set (match_operand 0 "register_operand" "")
19530 "(GET_MODE (operands[0]) == HImode
19531 || GET_MODE (operands[0]) == SImode
19532 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19533 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
19534 && peep2_regno_dead_p (0, FLAGS_REG)"
19535 [(parallel [(set (match_dup 0) (const_int -1))
19536 (clobber (reg:CC FLAGS_REG))])]
19537 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19540 ;; Attempt to convert simple leas to adds. These can be created by
19543 [(set (match_operand:SI 0 "register_operand" "")
19544 (plus:SI (match_dup 0)
19545 (match_operand:SI 1 "nonmemory_operand" "")))]
19546 "peep2_regno_dead_p (0, FLAGS_REG)"
19547 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19548 (clobber (reg:CC FLAGS_REG))])]
19552 [(set (match_operand:SI 0 "register_operand" "")
19553 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19554 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19555 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19556 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19557 (clobber (reg:CC FLAGS_REG))])]
19558 "operands[2] = gen_lowpart (SImode, operands[2]);")
19561 [(set (match_operand:DI 0 "register_operand" "")
19562 (plus:DI (match_dup 0)
19563 (match_operand:DI 1 "x86_64_general_operand" "")))]
19564 "peep2_regno_dead_p (0, FLAGS_REG)"
19565 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19566 (clobber (reg:CC FLAGS_REG))])]
19570 [(set (match_operand:SI 0 "register_operand" "")
19571 (mult:SI (match_dup 0)
19572 (match_operand:SI 1 "const_int_operand" "")))]
19573 "exact_log2 (INTVAL (operands[1])) >= 0
19574 && peep2_regno_dead_p (0, FLAGS_REG)"
19575 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19576 (clobber (reg:CC FLAGS_REG))])]
19577 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19580 [(set (match_operand:DI 0 "register_operand" "")
19581 (mult:DI (match_dup 0)
19582 (match_operand:DI 1 "const_int_operand" "")))]
19583 "exact_log2 (INTVAL (operands[1])) >= 0
19584 && peep2_regno_dead_p (0, FLAGS_REG)"
19585 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19586 (clobber (reg:CC FLAGS_REG))])]
19587 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19590 [(set (match_operand:SI 0 "register_operand" "")
19591 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19592 (match_operand:DI 2 "const_int_operand" "")) 0))]
19593 "exact_log2 (INTVAL (operands[2])) >= 0
19594 && REGNO (operands[0]) == REGNO (operands[1])
19595 && peep2_regno_dead_p (0, FLAGS_REG)"
19596 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19597 (clobber (reg:CC FLAGS_REG))])]
19598 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19600 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19601 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19602 ;; many CPUs it is also faster, since special hardware to avoid esp
19603 ;; dependencies is present.
19605 ;; While some of these conversions may be done using splitters, we use peepholes
19606 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19608 ;; Convert prologue esp subtractions to push.
19609 ;; We need register to push. In order to keep verify_flow_info happy we have
19611 ;; - use scratch and clobber it in order to avoid dependencies
19612 ;; - use already live register
19613 ;; We can't use the second way right now, since there is no reliable way how to
19614 ;; verify that given register is live. First choice will also most likely in
19615 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19616 ;; call clobbered registers are dead. We may want to use base pointer as an
19617 ;; alternative when no register is available later.
19620 [(match_scratch:SI 0 "r")
19621 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19622 (clobber (reg:CC FLAGS_REG))
19623 (clobber (mem:BLK (scratch)))])]
19624 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19625 [(clobber (match_dup 0))
19626 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19627 (clobber (mem:BLK (scratch)))])])
19630 [(match_scratch:SI 0 "r")
19631 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19632 (clobber (reg:CC FLAGS_REG))
19633 (clobber (mem:BLK (scratch)))])]
19634 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19635 [(clobber (match_dup 0))
19636 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19637 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19638 (clobber (mem:BLK (scratch)))])])
19640 ;; Convert esp subtractions to push.
19642 [(match_scratch:SI 0 "r")
19643 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19644 (clobber (reg:CC FLAGS_REG))])]
19645 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19646 [(clobber (match_dup 0))
19647 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19650 [(match_scratch:SI 0 "r")
19651 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19652 (clobber (reg:CC FLAGS_REG))])]
19653 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19654 [(clobber (match_dup 0))
19655 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19656 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19658 ;; Convert epilogue deallocator to pop.
19660 [(match_scratch:SI 0 "r")
19661 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19662 (clobber (reg:CC FLAGS_REG))
19663 (clobber (mem:BLK (scratch)))])]
19664 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19665 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19666 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19667 (clobber (mem:BLK (scratch)))])]
19670 ;; Two pops case is tricky, since pop causes dependency on destination register.
19671 ;; We use two registers if available.
19673 [(match_scratch:SI 0 "r")
19674 (match_scratch:SI 1 "r")
19675 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19676 (clobber (reg:CC FLAGS_REG))
19677 (clobber (mem:BLK (scratch)))])]
19678 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19679 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19680 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19681 (clobber (mem:BLK (scratch)))])
19682 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19683 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19687 [(match_scratch:SI 0 "r")
19688 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19689 (clobber (reg:CC FLAGS_REG))
19690 (clobber (mem:BLK (scratch)))])]
19691 "optimize_insn_for_size_p ()"
19692 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19693 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19694 (clobber (mem:BLK (scratch)))])
19695 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19696 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19699 ;; Convert esp additions to pop.
19701 [(match_scratch:SI 0 "r")
19702 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19703 (clobber (reg:CC FLAGS_REG))])]
19705 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19706 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19709 ;; Two pops case is tricky, since pop causes dependency on destination register.
19710 ;; We use two registers if available.
19712 [(match_scratch:SI 0 "r")
19713 (match_scratch:SI 1 "r")
19714 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19715 (clobber (reg:CC FLAGS_REG))])]
19717 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19718 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19719 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19720 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19724 [(match_scratch:SI 0 "r")
19725 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19726 (clobber (reg:CC FLAGS_REG))])]
19727 "optimize_insn_for_size_p ()"
19728 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19729 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19730 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19731 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19734 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19735 ;; required and register dies. Similarly for 128 to -128.
19737 [(set (match_operand 0 "flags_reg_operand" "")
19738 (match_operator 1 "compare_operator"
19739 [(match_operand 2 "register_operand" "")
19740 (match_operand 3 "const_int_operand" "")]))]
19741 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19742 && incdec_operand (operands[3], GET_MODE (operands[3])))
19743 || (!TARGET_FUSE_CMP_AND_BRANCH
19744 && INTVAL (operands[3]) == 128))
19745 && ix86_match_ccmode (insn, CCGCmode)
19746 && peep2_reg_dead_p (1, operands[2])"
19747 [(parallel [(set (match_dup 0)
19748 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19749 (clobber (match_dup 2))])]
19753 [(match_scratch:DI 0 "r")
19754 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19755 (clobber (reg:CC FLAGS_REG))
19756 (clobber (mem:BLK (scratch)))])]
19757 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19758 [(clobber (match_dup 0))
19759 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19760 (clobber (mem:BLK (scratch)))])])
19763 [(match_scratch:DI 0 "r")
19764 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19765 (clobber (reg:CC FLAGS_REG))
19766 (clobber (mem:BLK (scratch)))])]
19767 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19768 [(clobber (match_dup 0))
19769 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19770 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19771 (clobber (mem:BLK (scratch)))])])
19773 ;; Convert esp subtractions to push.
19775 [(match_scratch:DI 0 "r")
19776 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19777 (clobber (reg:CC FLAGS_REG))])]
19778 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19779 [(clobber (match_dup 0))
19780 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19783 [(match_scratch:DI 0 "r")
19784 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19785 (clobber (reg:CC FLAGS_REG))])]
19786 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19787 [(clobber (match_dup 0))
19788 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19789 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19791 ;; Convert epilogue deallocator to pop.
19793 [(match_scratch:DI 0 "r")
19794 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19795 (clobber (reg:CC FLAGS_REG))
19796 (clobber (mem:BLK (scratch)))])]
19797 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19798 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19799 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19800 (clobber (mem:BLK (scratch)))])]
19803 ;; Two pops case is tricky, since pop causes dependency on destination register.
19804 ;; We use two registers if available.
19806 [(match_scratch:DI 0 "r")
19807 (match_scratch:DI 1 "r")
19808 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19809 (clobber (reg:CC FLAGS_REG))
19810 (clobber (mem:BLK (scratch)))])]
19811 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19812 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19813 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19814 (clobber (mem:BLK (scratch)))])
19815 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19816 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19820 [(match_scratch:DI 0 "r")
19821 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19822 (clobber (reg:CC FLAGS_REG))
19823 (clobber (mem:BLK (scratch)))])]
19824 "optimize_insn_for_size_p ()"
19825 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19826 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19827 (clobber (mem:BLK (scratch)))])
19828 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19829 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19832 ;; Convert esp additions to pop.
19834 [(match_scratch:DI 0 "r")
19835 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19836 (clobber (reg:CC FLAGS_REG))])]
19838 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19839 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19842 ;; Two pops case is tricky, since pop causes dependency on destination register.
19843 ;; We use two registers if available.
19845 [(match_scratch:DI 0 "r")
19846 (match_scratch:DI 1 "r")
19847 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19848 (clobber (reg:CC FLAGS_REG))])]
19850 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19851 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19852 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19853 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19857 [(match_scratch:DI 0 "r")
19858 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19859 (clobber (reg:CC FLAGS_REG))])]
19860 "optimize_insn_for_size_p ()"
19861 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19862 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19863 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19864 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19867 ;; Convert imul by three, five and nine into lea
19870 [(set (match_operand:SI 0 "register_operand" "")
19871 (mult:SI (match_operand:SI 1 "register_operand" "")
19872 (match_operand:SI 2 "const_int_operand" "")))
19873 (clobber (reg:CC FLAGS_REG))])]
19874 "INTVAL (operands[2]) == 3
19875 || INTVAL (operands[2]) == 5
19876 || INTVAL (operands[2]) == 9"
19877 [(set (match_dup 0)
19878 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19880 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19884 [(set (match_operand:SI 0 "register_operand" "")
19885 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19886 (match_operand:SI 2 "const_int_operand" "")))
19887 (clobber (reg:CC FLAGS_REG))])]
19888 "optimize_insn_for_speed_p ()
19889 && (INTVAL (operands[2]) == 3
19890 || INTVAL (operands[2]) == 5
19891 || INTVAL (operands[2]) == 9)"
19892 [(set (match_dup 0) (match_dup 1))
19894 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19896 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19900 [(set (match_operand:DI 0 "register_operand" "")
19901 (mult:DI (match_operand:DI 1 "register_operand" "")
19902 (match_operand:DI 2 "const_int_operand" "")))
19903 (clobber (reg:CC FLAGS_REG))])]
19905 && (INTVAL (operands[2]) == 3
19906 || INTVAL (operands[2]) == 5
19907 || INTVAL (operands[2]) == 9)"
19908 [(set (match_dup 0)
19909 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19911 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19915 [(set (match_operand:DI 0 "register_operand" "")
19916 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19917 (match_operand:DI 2 "const_int_operand" "")))
19918 (clobber (reg:CC FLAGS_REG))])]
19920 && optimize_insn_for_speed_p ()
19921 && (INTVAL (operands[2]) == 3
19922 || INTVAL (operands[2]) == 5
19923 || INTVAL (operands[2]) == 9)"
19924 [(set (match_dup 0) (match_dup 1))
19926 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19928 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19930 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19931 ;; imul $32bit_imm, reg, reg is direct decoded.
19933 [(match_scratch:DI 3 "r")
19934 (parallel [(set (match_operand:DI 0 "register_operand" "")
19935 (mult:DI (match_operand:DI 1 "memory_operand" "")
19936 (match_operand:DI 2 "immediate_operand" "")))
19937 (clobber (reg:CC FLAGS_REG))])]
19938 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19939 && !satisfies_constraint_K (operands[2])"
19940 [(set (match_dup 3) (match_dup 1))
19941 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19942 (clobber (reg:CC FLAGS_REG))])]
19946 [(match_scratch:SI 3 "r")
19947 (parallel [(set (match_operand:SI 0 "register_operand" "")
19948 (mult:SI (match_operand:SI 1 "memory_operand" "")
19949 (match_operand:SI 2 "immediate_operand" "")))
19950 (clobber (reg:CC FLAGS_REG))])]
19951 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19952 && !satisfies_constraint_K (operands[2])"
19953 [(set (match_dup 3) (match_dup 1))
19954 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19955 (clobber (reg:CC FLAGS_REG))])]
19959 [(match_scratch:SI 3 "r")
19960 (parallel [(set (match_operand:DI 0 "register_operand" "")
19962 (mult:SI (match_operand:SI 1 "memory_operand" "")
19963 (match_operand:SI 2 "immediate_operand" ""))))
19964 (clobber (reg:CC FLAGS_REG))])]
19965 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19966 && !satisfies_constraint_K (operands[2])"
19967 [(set (match_dup 3) (match_dup 1))
19968 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19969 (clobber (reg:CC FLAGS_REG))])]
19972 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19973 ;; Convert it into imul reg, reg
19974 ;; It would be better to force assembler to encode instruction using long
19975 ;; immediate, but there is apparently no way to do so.
19977 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19978 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19979 (match_operand:DI 2 "const_int_operand" "")))
19980 (clobber (reg:CC FLAGS_REG))])
19981 (match_scratch:DI 3 "r")]
19982 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19983 && satisfies_constraint_K (operands[2])"
19984 [(set (match_dup 3) (match_dup 2))
19985 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19986 (clobber (reg:CC FLAGS_REG))])]
19988 if (!rtx_equal_p (operands[0], operands[1]))
19989 emit_move_insn (operands[0], operands[1]);
19993 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19994 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19995 (match_operand:SI 2 "const_int_operand" "")))
19996 (clobber (reg:CC FLAGS_REG))])
19997 (match_scratch:SI 3 "r")]
19998 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19999 && satisfies_constraint_K (operands[2])"
20000 [(set (match_dup 3) (match_dup 2))
20001 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20002 (clobber (reg:CC FLAGS_REG))])]
20004 if (!rtx_equal_p (operands[0], operands[1]))
20005 emit_move_insn (operands[0], operands[1]);
20009 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20010 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20011 (match_operand:HI 2 "immediate_operand" "")))
20012 (clobber (reg:CC FLAGS_REG))])
20013 (match_scratch:HI 3 "r")]
20014 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
20015 [(set (match_dup 3) (match_dup 2))
20016 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20017 (clobber (reg:CC FLAGS_REG))])]
20019 if (!rtx_equal_p (operands[0], operands[1]))
20020 emit_move_insn (operands[0], operands[1]);
20023 ;; After splitting up read-modify operations, array accesses with memory
20024 ;; operands might end up in form:
20026 ;; movl 4(%esp), %edx
20028 ;; instead of pre-splitting:
20030 ;; addl 4(%esp), %eax
20032 ;; movl 4(%esp), %edx
20033 ;; leal (%edx,%eax,4), %eax
20036 [(parallel [(set (match_operand 0 "register_operand" "")
20037 (ashift (match_operand 1 "register_operand" "")
20038 (match_operand 2 "const_int_operand" "")))
20039 (clobber (reg:CC FLAGS_REG))])
20040 (set (match_operand 3 "register_operand")
20041 (match_operand 4 "x86_64_general_operand" ""))
20042 (parallel [(set (match_operand 5 "register_operand" "")
20043 (plus (match_operand 6 "register_operand" "")
20044 (match_operand 7 "register_operand" "")))
20045 (clobber (reg:CC FLAGS_REG))])]
20046 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20047 /* Validate MODE for lea. */
20048 && ((!TARGET_PARTIAL_REG_STALL
20049 && (GET_MODE (operands[0]) == QImode
20050 || GET_MODE (operands[0]) == HImode))
20051 || GET_MODE (operands[0]) == SImode
20052 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20053 /* We reorder load and the shift. */
20054 && !rtx_equal_p (operands[1], operands[3])
20055 && !reg_overlap_mentioned_p (operands[0], operands[4])
20056 /* Last PLUS must consist of operand 0 and 3. */
20057 && !rtx_equal_p (operands[0], operands[3])
20058 && (rtx_equal_p (operands[3], operands[6])
20059 || rtx_equal_p (operands[3], operands[7]))
20060 && (rtx_equal_p (operands[0], operands[6])
20061 || rtx_equal_p (operands[0], operands[7]))
20062 /* The intermediate operand 0 must die or be same as output. */
20063 && (rtx_equal_p (operands[0], operands[5])
20064 || peep2_reg_dead_p (3, operands[0]))"
20065 [(set (match_dup 3) (match_dup 4))
20066 (set (match_dup 0) (match_dup 1))]
20068 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20069 int scale = 1 << INTVAL (operands[2]);
20070 rtx index = gen_lowpart (Pmode, operands[1]);
20071 rtx base = gen_lowpart (Pmode, operands[3]);
20072 rtx dest = gen_lowpart (mode, operands[5]);
20074 operands[1] = gen_rtx_PLUS (Pmode, base,
20075 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20077 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20078 operands[0] = dest;
20081 ;; Call-value patterns last so that the wildcard operand does not
20082 ;; disrupt insn-recog's switch tables.
20084 (define_insn "*call_value_pop_0"
20085 [(set (match_operand 0 "" "")
20086 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20087 (match_operand:SI 2 "" "")))
20088 (set (reg:SI SP_REG)
20089 (plus:SI (reg:SI SP_REG)
20090 (match_operand:SI 3 "immediate_operand" "")))]
20093 if (SIBLING_CALL_P (insn))
20096 return "call\t%P1";
20098 [(set_attr "type" "callv")])
20100 (define_insn "*call_value_pop_1"
20101 [(set (match_operand 0 "" "")
20102 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20103 (match_operand:SI 2 "" "")))
20104 (set (reg:SI SP_REG)
20105 (plus:SI (reg:SI SP_REG)
20106 (match_operand:SI 3 "immediate_operand" "i")))]
20107 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20109 if (constant_call_address_operand (operands[1], Pmode))
20110 return "call\t%P1";
20111 return "call\t%A1";
20113 [(set_attr "type" "callv")])
20115 (define_insn "*sibcall_value_pop_1"
20116 [(set (match_operand 0 "" "")
20117 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20118 (match_operand:SI 2 "" "")))
20119 (set (reg:SI SP_REG)
20120 (plus:SI (reg:SI SP_REG)
20121 (match_operand:SI 3 "immediate_operand" "i,i")))]
20122 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20126 [(set_attr "type" "callv")])
20128 (define_insn "*call_value_0"
20129 [(set (match_operand 0 "" "")
20130 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20131 (match_operand:SI 2 "" "")))]
20134 if (SIBLING_CALL_P (insn))
20137 return "call\t%P1";
20139 [(set_attr "type" "callv")])
20141 (define_insn "*call_value_0_rex64"
20142 [(set (match_operand 0 "" "")
20143 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20144 (match_operand:DI 2 "const_int_operand" "")))]
20147 if (SIBLING_CALL_P (insn))
20150 return "call\t%P1";
20152 [(set_attr "type" "callv")])
20154 (define_insn "*call_value_0_rex64_ms_sysv"
20155 [(set (match_operand 0 "" "")
20156 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20157 (match_operand:DI 2 "const_int_operand" "")))
20158 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20159 (clobber (reg:TI XMM6_REG))
20160 (clobber (reg:TI XMM7_REG))
20161 (clobber (reg:TI XMM8_REG))
20162 (clobber (reg:TI XMM9_REG))
20163 (clobber (reg:TI XMM10_REG))
20164 (clobber (reg:TI XMM11_REG))
20165 (clobber (reg:TI XMM12_REG))
20166 (clobber (reg:TI XMM13_REG))
20167 (clobber (reg:TI XMM14_REG))
20168 (clobber (reg:TI XMM15_REG))
20169 (clobber (reg:DI SI_REG))
20170 (clobber (reg:DI DI_REG))]
20171 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20173 if (SIBLING_CALL_P (insn))
20176 return "call\t%P1";
20178 [(set_attr "type" "callv")])
20180 (define_insn "*call_value_1"
20181 [(set (match_operand 0 "" "")
20182 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20183 (match_operand:SI 2 "" "")))]
20184 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20186 if (constant_call_address_operand (operands[1], Pmode))
20187 return "call\t%P1";
20188 return "call\t%A1";
20190 [(set_attr "type" "callv")])
20192 (define_insn "*sibcall_value_1"
20193 [(set (match_operand 0 "" "")
20194 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20195 (match_operand:SI 2 "" "")))]
20196 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20200 [(set_attr "type" "callv")])
20202 (define_insn "*call_value_1_rex64"
20203 [(set (match_operand 0 "" "")
20204 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20205 (match_operand:DI 2 "" "")))]
20206 "TARGET_64BIT && !SIBLING_CALL_P (insn)
20207 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20209 if (constant_call_address_operand (operands[1], Pmode))
20210 return "call\t%P1";
20211 return "call\t%A1";
20213 [(set_attr "type" "callv")])
20215 (define_insn "*call_value_1_rex64_ms_sysv"
20216 [(set (match_operand 0 "" "")
20217 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20218 (match_operand:DI 2 "" "")))
20219 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20220 (clobber (reg:TI XMM6_REG))
20221 (clobber (reg:TI XMM7_REG))
20222 (clobber (reg:TI XMM8_REG))
20223 (clobber (reg:TI XMM9_REG))
20224 (clobber (reg:TI XMM10_REG))
20225 (clobber (reg:TI XMM11_REG))
20226 (clobber (reg:TI XMM12_REG))
20227 (clobber (reg:TI XMM13_REG))
20228 (clobber (reg:TI XMM14_REG))
20229 (clobber (reg:TI XMM15_REG))
20230 (clobber (reg:DI SI_REG))
20231 (clobber (reg:DI DI_REG))]
20232 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20234 if (constant_call_address_operand (operands[1], Pmode))
20235 return "call\t%P1";
20236 return "call\t%A1";
20238 [(set_attr "type" "callv")])
20240 (define_insn "*call_value_1_rex64_large"
20241 [(set (match_operand 0 "" "")
20242 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20243 (match_operand:DI 2 "" "")))]
20244 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20246 [(set_attr "type" "callv")])
20248 (define_insn "*sibcall_value_1_rex64"
20249 [(set (match_operand 0 "" "")
20250 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
20251 (match_operand:DI 2 "" "")))]
20252 "TARGET_64BIT && SIBLING_CALL_P (insn)"
20256 [(set_attr "type" "callv")])
20258 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20259 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20260 ;; caught for use by garbage collectors and the like. Using an insn that
20261 ;; maps to SIGILL makes it more likely the program will rightfully die.
20262 ;; Keeping with tradition, "6" is in honor of #UD.
20263 (define_insn "trap"
20264 [(trap_if (const_int 1) (const_int 6))]
20266 { return ASM_SHORT "0x0b0f"; }
20267 [(set_attr "length" "2")])
20269 (define_expand "sse_prologue_save"
20270 [(parallel [(set (match_operand:BLK 0 "" "")
20271 (unspec:BLK [(reg:DI XMM0_REG)
20278 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20279 (use (match_operand:DI 1 "register_operand" ""))
20280 (use (match_operand:DI 2 "immediate_operand" ""))
20281 (use (label_ref:DI (match_operand 3 "" "")))])]
20285 (define_insn "*sse_prologue_save_insn"
20286 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20287 (match_operand:DI 4 "const_int_operand" "n")))
20288 (unspec:BLK [(reg:DI XMM0_REG)
20295 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20296 (use (match_operand:DI 1 "register_operand" "r"))
20297 (use (match_operand:DI 2 "const_int_operand" "i"))
20298 (use (label_ref:DI (match_operand 3 "" "X")))]
20300 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20301 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20304 operands[0] = gen_rtx_MEM (Pmode,
20305 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20306 /* VEX instruction with a REX prefix will #UD. */
20307 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
20308 gcc_unreachable ();
20310 output_asm_insn ("jmp\t%A1", operands);
20311 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20313 operands[4] = adjust_address (operands[0], DImode, i*16);
20314 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20315 PUT_MODE (operands[4], TImode);
20316 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20317 output_asm_insn ("rex", operands);
20318 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
20320 (*targetm.asm_out.internal_label) (asm_out_file, "L",
20321 CODE_LABEL_NUMBER (operands[3]));
20324 [(set_attr "type" "other")
20325 (set_attr "length_immediate" "0")
20326 (set_attr "length_address" "0")
20327 (set (attr "length")
20329 (eq (symbol_ref "TARGET_AVX") (const_int 0))
20330 (const_string "34")
20331 (const_string "42")))
20332 (set_attr "memory" "store")
20333 (set_attr "modrm" "0")
20334 (set_attr "prefix" "maybe_vex")
20335 (set_attr "mode" "DI")])
20337 (define_expand "prefetch"
20338 [(prefetch (match_operand 0 "address_operand" "")
20339 (match_operand:SI 1 "const_int_operand" "")
20340 (match_operand:SI 2 "const_int_operand" ""))]
20341 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20343 int rw = INTVAL (operands[1]);
20344 int locality = INTVAL (operands[2]);
20346 gcc_assert (rw == 0 || rw == 1);
20347 gcc_assert (locality >= 0 && locality <= 3);
20348 gcc_assert (GET_MODE (operands[0]) == Pmode
20349 || GET_MODE (operands[0]) == VOIDmode);
20351 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20352 supported by SSE counterpart or the SSE prefetch is not available
20353 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20355 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20356 operands[2] = GEN_INT (3);
20358 operands[1] = const0_rtx;
20361 (define_insn "*prefetch_sse"
20362 [(prefetch (match_operand:SI 0 "address_operand" "p")
20364 (match_operand:SI 1 "const_int_operand" ""))]
20365 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20367 static const char * const patterns[4] = {
20368 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20371 int locality = INTVAL (operands[1]);
20372 gcc_assert (locality >= 0 && locality <= 3);
20374 return patterns[locality];
20376 [(set_attr "type" "sse")
20377 (set_attr "atom_sse_attr" "prefetch")
20378 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20379 (set_attr "memory" "none")])
20381 (define_insn "*prefetch_sse_rex"
20382 [(prefetch (match_operand:DI 0 "address_operand" "p")
20384 (match_operand:SI 1 "const_int_operand" ""))]
20385 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20387 static const char * const patterns[4] = {
20388 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20391 int locality = INTVAL (operands[1]);
20392 gcc_assert (locality >= 0 && locality <= 3);
20394 return patterns[locality];
20396 [(set_attr "type" "sse")
20397 (set_attr "atom_sse_attr" "prefetch")
20398 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20399 (set_attr "memory" "none")])
20401 (define_insn "*prefetch_3dnow"
20402 [(prefetch (match_operand:SI 0 "address_operand" "p")
20403 (match_operand:SI 1 "const_int_operand" "n")
20405 "TARGET_3DNOW && !TARGET_64BIT"
20407 if (INTVAL (operands[1]) == 0)
20408 return "prefetch\t%a0";
20410 return "prefetchw\t%a0";
20412 [(set_attr "type" "mmx")
20413 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20414 (set_attr "memory" "none")])
20416 (define_insn "*prefetch_3dnow_rex"
20417 [(prefetch (match_operand:DI 0 "address_operand" "p")
20418 (match_operand:SI 1 "const_int_operand" "n")
20420 "TARGET_3DNOW && TARGET_64BIT"
20422 if (INTVAL (operands[1]) == 0)
20423 return "prefetch\t%a0";
20425 return "prefetchw\t%a0";
20427 [(set_attr "type" "mmx")
20428 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20429 (set_attr "memory" "none")])
20431 (define_expand "stack_protect_set"
20432 [(match_operand 0 "memory_operand" "")
20433 (match_operand 1 "memory_operand" "")]
20436 #ifdef TARGET_THREAD_SSP_OFFSET
20438 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20439 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20441 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20442 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20445 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20447 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20452 (define_insn "stack_protect_set_si"
20453 [(set (match_operand:SI 0 "memory_operand" "=m")
20454 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20455 (set (match_scratch:SI 2 "=&r") (const_int 0))
20456 (clobber (reg:CC FLAGS_REG))]
20458 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20459 [(set_attr "type" "multi")])
20461 (define_insn "stack_protect_set_di"
20462 [(set (match_operand:DI 0 "memory_operand" "=m")
20463 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20464 (set (match_scratch:DI 2 "=&r") (const_int 0))
20465 (clobber (reg:CC FLAGS_REG))]
20467 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20468 [(set_attr "type" "multi")])
20470 (define_insn "stack_tls_protect_set_si"
20471 [(set (match_operand:SI 0 "memory_operand" "=m")
20472 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20473 (set (match_scratch:SI 2 "=&r") (const_int 0))
20474 (clobber (reg:CC FLAGS_REG))]
20476 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20477 [(set_attr "type" "multi")])
20479 (define_insn "stack_tls_protect_set_di"
20480 [(set (match_operand:DI 0 "memory_operand" "=m")
20481 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20482 (set (match_scratch:DI 2 "=&r") (const_int 0))
20483 (clobber (reg:CC FLAGS_REG))]
20486 /* The kernel uses a different segment register for performance reasons; a
20487 system call would not have to trash the userspace segment register,
20488 which would be expensive */
20489 if (ix86_cmodel != CM_KERNEL)
20490 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20492 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20494 [(set_attr "type" "multi")])
20496 (define_expand "stack_protect_test"
20497 [(match_operand 0 "memory_operand" "")
20498 (match_operand 1 "memory_operand" "")
20499 (match_operand 2 "" "")]
20502 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20504 #ifdef TARGET_THREAD_SSP_OFFSET
20506 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20507 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20509 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20510 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20513 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20515 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20518 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20519 flags, const0_rtx, operands[2]));
20523 (define_insn "stack_protect_test_si"
20524 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20525 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20526 (match_operand:SI 2 "memory_operand" "m")]
20528 (clobber (match_scratch:SI 3 "=&r"))]
20530 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20531 [(set_attr "type" "multi")])
20533 (define_insn "stack_protect_test_di"
20534 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20535 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20536 (match_operand:DI 2 "memory_operand" "m")]
20538 (clobber (match_scratch:DI 3 "=&r"))]
20540 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20541 [(set_attr "type" "multi")])
20543 (define_insn "stack_tls_protect_test_si"
20544 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20545 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20546 (match_operand:SI 2 "const_int_operand" "i")]
20547 UNSPEC_SP_TLS_TEST))
20548 (clobber (match_scratch:SI 3 "=r"))]
20550 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
20551 [(set_attr "type" "multi")])
20553 (define_insn "stack_tls_protect_test_di"
20554 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20555 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20556 (match_operand:DI 2 "const_int_operand" "i")]
20557 UNSPEC_SP_TLS_TEST))
20558 (clobber (match_scratch:DI 3 "=r"))]
20561 /* The kernel uses a different segment register for performance reasons; a
20562 system call would not have to trash the userspace segment register,
20563 which would be expensive */
20564 if (ix86_cmodel != CM_KERNEL)
20565 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
20567 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
20569 [(set_attr "type" "multi")])
20571 (define_insn "sse4_2_crc32<mode>"
20572 [(set (match_operand:SI 0 "register_operand" "=r")
20574 [(match_operand:SI 1 "register_operand" "0")
20575 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20577 "TARGET_SSE4_2 || TARGET_CRC32"
20578 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20579 [(set_attr "type" "sselog1")
20580 (set_attr "prefix_rep" "1")
20581 (set_attr "prefix_extra" "1")
20582 (set (attr "prefix_data16")
20583 (if_then_else (match_operand:HI 2 "" "")
20585 (const_string "*")))
20586 (set (attr "prefix_rex")
20587 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
20589 (const_string "*")))
20590 (set_attr "mode" "SI")])
20592 (define_insn "sse4_2_crc32di"
20593 [(set (match_operand:DI 0 "register_operand" "=r")
20595 [(match_operand:DI 1 "register_operand" "0")
20596 (match_operand:DI 2 "nonimmediate_operand" "rm")]
20598 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20599 "crc32{q}\t{%2, %0|%0, %2}"
20600 [(set_attr "type" "sselog1")
20601 (set_attr "prefix_rep" "1")
20602 (set_attr "prefix_extra" "1")
20603 (set_attr "mode" "DI")])
20605 (define_expand "rdpmc"
20606 [(match_operand:DI 0 "register_operand" "")
20607 (match_operand:SI 1 "register_operand" "")]
20610 rtx reg = gen_reg_rtx (DImode);
20613 /* Force operand 1 into ECX. */
20614 rtx ecx = gen_rtx_REG (SImode, CX_REG);
20615 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
20616 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
20621 rtvec vec = rtvec_alloc (2);
20622 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20623 rtx upper = gen_reg_rtx (DImode);
20624 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20625 gen_rtvec (1, const0_rtx),
20627 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
20628 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20630 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20631 NULL, 1, OPTAB_DIRECT);
20632 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20636 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
20637 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20641 (define_insn "*rdpmc"
20642 [(set (match_operand:DI 0 "register_operand" "=A")
20643 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20647 [(set_attr "type" "other")
20648 (set_attr "length" "2")])
20650 (define_insn "*rdpmc_rex64"
20651 [(set (match_operand:DI 0 "register_operand" "=a")
20652 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20654 (set (match_operand:DI 1 "register_operand" "=d")
20655 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
20658 [(set_attr "type" "other")
20659 (set_attr "length" "2")])
20661 (define_expand "rdtsc"
20662 [(set (match_operand:DI 0 "register_operand" "")
20663 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20668 rtvec vec = rtvec_alloc (2);
20669 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20670 rtx upper = gen_reg_rtx (DImode);
20671 rtx lower = gen_reg_rtx (DImode);
20672 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
20673 gen_rtvec (1, const0_rtx),
20675 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
20676 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
20678 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20679 NULL, 1, OPTAB_DIRECT);
20680 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
20682 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
20687 (define_insn "*rdtsc"
20688 [(set (match_operand:DI 0 "register_operand" "=A")
20689 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20692 [(set_attr "type" "other")
20693 (set_attr "length" "2")])
20695 (define_insn "*rdtsc_rex64"
20696 [(set (match_operand:DI 0 "register_operand" "=a")
20697 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20698 (set (match_operand:DI 1 "register_operand" "=d")
20699 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20702 [(set_attr "type" "other")
20703 (set_attr "length" "2")])
20705 (define_expand "rdtscp"
20706 [(match_operand:DI 0 "register_operand" "")
20707 (match_operand:SI 1 "memory_operand" "")]
20710 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20711 gen_rtvec (1, const0_rtx),
20713 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
20714 gen_rtvec (1, const0_rtx),
20716 rtx reg = gen_reg_rtx (DImode);
20717 rtx tmp = gen_reg_rtx (SImode);
20721 rtvec vec = rtvec_alloc (3);
20722 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20723 rtx upper = gen_reg_rtx (DImode);
20724 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20725 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20726 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
20728 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20729 NULL, 1, OPTAB_DIRECT);
20730 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20735 rtvec vec = rtvec_alloc (2);
20736 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20737 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20738 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
20741 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20742 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
20746 (define_insn "*rdtscp"
20747 [(set (match_operand:DI 0 "register_operand" "=A")
20748 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20749 (set (match_operand:SI 1 "register_operand" "=c")
20750 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20753 [(set_attr "type" "other")
20754 (set_attr "length" "3")])
20756 (define_insn "*rdtscp_rex64"
20757 [(set (match_operand:DI 0 "register_operand" "=a")
20758 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20759 (set (match_operand:DI 1 "register_operand" "=d")
20760 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20761 (set (match_operand:SI 2 "register_operand" "=c")
20762 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20765 [(set_attr "type" "other")
20766 (set_attr "length" "3")])
20768 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20770 ;; LWP instructions
20772 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20774 (define_expand "lwp_llwpcb"
20775 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
20776 UNSPECV_LLWP_INTRINSIC)]
20780 (define_insn "*lwp_llwpcb<mode>1"
20781 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20782 UNSPECV_LLWP_INTRINSIC)]
20785 [(set_attr "type" "lwp")
20786 (set_attr "mode" "<MODE>")
20787 (set_attr "length" "5")])
20789 (define_expand "lwp_slwpcb"
20790 [(set (match_operand 0 "register_operand" "=r")
20791 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20795 emit_insn (gen_lwp_slwpcbdi (operands[0]));
20797 emit_insn (gen_lwp_slwpcbsi (operands[0]));
20801 (define_insn "lwp_slwpcb<mode>"
20802 [(set (match_operand:P 0 "register_operand" "=r")
20803 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20806 [(set_attr "type" "lwp")
20807 (set_attr "mode" "<MODE>")
20808 (set_attr "length" "5")])
20810 (define_expand "lwp_lwpval<mode>3"
20811 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
20812 (match_operand:SI 2 "nonimmediate_operand" "rm")
20813 (match_operand:SI 3 "const_int_operand" "i")]
20814 UNSPECV_LWPVAL_INTRINSIC)]
20816 "/* Avoid unused variable warning. */
20819 (define_insn "*lwp_lwpval<mode>3_1"
20820 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20821 (match_operand:SI 1 "nonimmediate_operand" "rm")
20822 (match_operand:SI 2 "const_int_operand" "i")]
20823 UNSPECV_LWPVAL_INTRINSIC)]
20825 "lwpval\t{%2, %1, %0|%0, %1, %2}"
20826 [(set_attr "type" "lwp")
20827 (set_attr "mode" "<MODE>")
20828 (set (attr "length")
20829 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20831 (define_expand "lwp_lwpins<mode>3"
20832 [(set (reg:CCC FLAGS_REG)
20833 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
20834 (match_operand:SI 2 "nonimmediate_operand" "rm")
20835 (match_operand:SI 3 "const_int_operand" "i")]
20836 UNSPECV_LWPINS_INTRINSIC))
20837 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
20838 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20842 (define_insn "*lwp_lwpins<mode>3_1"
20843 [(set (reg:CCC FLAGS_REG)
20844 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20845 (match_operand:SI 1 "nonimmediate_operand" "rm")
20846 (match_operand:SI 2 "const_int_operand" "i")]
20847 UNSPECV_LWPINS_INTRINSIC))]
20849 "lwpins\t{%2, %1, %0|%0, %1, %2}"
20850 [(set_attr "type" "lwp")
20851 (set_attr "mode" "<MODE>")
20852 (set (attr "length")
20853 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20857 (include "sync.md")