1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
66 [; Relocation specifiers
77 (UNSPEC_MACHOPIC_OFFSET 10)
80 (UNSPEC_STACK_ALLOC 11)
82 (UNSPEC_SSE_PROLOGUE_SAVE 13)
86 (UNSPEC_SET_GOT_OFFSET 17)
87 (UNSPEC_MEMORY_BLOCKAGE 18)
92 (UNSPEC_TLS_LD_BASE 22)
95 ; Other random patterns
100 (UNSPEC_ADD_CARRY 34)
103 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
104 (UNSPEC_TRUNC_NOOP 39)
106 ; For SSE/MMX support:
107 (UNSPEC_FIX_NOTRUNC 40)
124 (UNSPEC_MS_TO_SYSV_CALL 48)
126 ; Generic math support
128 (UNSPEC_IEEE_MIN 51) ; not commutative
129 (UNSPEC_IEEE_MAX 52) ; not commutative
144 (UNSPEC_FRNDINT_FLOOR 70)
145 (UNSPEC_FRNDINT_CEIL 71)
146 (UNSPEC_FRNDINT_TRUNC 72)
147 (UNSPEC_FRNDINT_MASK_PM 73)
148 (UNSPEC_FIST_FLOOR 74)
149 (UNSPEC_FIST_CEIL 75)
151 ; x87 Double output FP
152 (UNSPEC_SINCOS_COS 80)
153 (UNSPEC_SINCOS_SIN 81)
154 (UNSPEC_XTRACT_FRACT 84)
155 (UNSPEC_XTRACT_EXP 85)
156 (UNSPEC_FSCALE_FRACT 86)
157 (UNSPEC_FSCALE_EXP 87)
169 (UNSPEC_SP_TLS_SET 102)
170 (UNSPEC_SP_TLS_TEST 103)
180 (UNSPEC_INSERTQI 132)
185 (UNSPEC_INSERTPS 135)
187 (UNSPEC_MOVNTDQA 137)
189 (UNSPEC_PHMINPOSUW 139)
195 (UNSPEC_PCMPESTR 144)
196 (UNSPEC_PCMPISTR 145)
199 (UNSPEC_FMA4_INTRINSIC 150)
200 (UNSPEC_FMA4_FMADDSUB 151)
201 (UNSPEC_FMA4_FMSUBADD 152)
202 (UNSPEC_XOP_UNSIGNED_CMP 151)
203 (UNSPEC_XOP_TRUEFALSE 152)
204 (UNSPEC_XOP_PERMUTE 153)
209 (UNSPEC_AESENCLAST 160)
211 (UNSPEC_AESDECLAST 162)
213 (UNSPEC_AESKEYGENASSIST 164)
221 (UNSPEC_VPERMIL2 168)
222 (UNSPEC_VPERMIL2F128 169)
223 (UNSPEC_MASKLOAD 170)
224 (UNSPEC_MASKSTORE 171)
230 [(UNSPECV_BLOCKAGE 0)
231 (UNSPECV_STACK_PROBE 1)
243 (UNSPECV_PROLOGUE_USE 14)
245 (UNSPECV_VZEROALL 16)
246 (UNSPECV_VZEROUPPER 17)
250 (UNSPECV_VSWAPMOV 21)
251 (UNSPECV_LLWP_INTRINSIC 22)
252 (UNSPECV_SLWP_INTRINSIC 23)
253 (UNSPECV_LWPVAL_INTRINSIC 24)
254 (UNSPECV_LWPINS_INTRINSIC 25)
257 ;; Constants to represent pcomtrue/pcomfalse variants
267 ;; Constants used in the XOP pperm instruction
269 [(PPERM_SRC 0x00) /* copy source */
270 (PPERM_INVERT 0x20) /* invert source */
271 (PPERM_REVERSE 0x40) /* bit reverse source */
272 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
273 (PPERM_ZERO 0x80) /* all 0's */
274 (PPERM_ONES 0xa0) /* all 1's */
275 (PPERM_SIGN 0xc0) /* propagate sign bit */
276 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
277 (PPERM_SRC1 0x00) /* use first source byte */
278 (PPERM_SRC2 0x10) /* use second source byte */
281 ;; Registers by name.
334 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
337 ;; In C guard expressions, put expressions which may be compile-time
338 ;; constants first. This allows for better optimization. For
339 ;; example, write "TARGET_64BIT && reload_completed", not
340 ;; "reload_completed && TARGET_64BIT".
344 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
346 (const (symbol_ref "ix86_schedule")))
348 ;; A basic instruction type. Refinements due to arguments to be
349 ;; provided in other attributes.
352 alu,alu1,negnot,imov,imovx,lea,
353 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
354 icmp,test,ibr,setcc,icmov,
355 push,pop,call,callv,leave,
357 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
358 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
359 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
360 ssemuladd,sse4arg,lwp,
361 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
362 (const_string "other"))
364 ;; Main data type used by the insn
366 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
367 (const_string "unknown"))
369 ;; The CPU unit operations uses.
370 (define_attr "unit" "integer,i387,sse,mmx,unknown"
371 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
372 (const_string "i387")
373 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
374 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
375 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
377 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
379 (eq_attr "type" "other")
380 (const_string "unknown")]
381 (const_string "integer")))
383 ;; The (bounding maximum) length of an instruction immediate.
384 (define_attr "length_immediate" ""
385 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
388 (eq_attr "unit" "i387,sse,mmx")
390 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
392 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
393 (eq_attr "type" "imov,test")
394 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
395 (eq_attr "type" "call")
396 (if_then_else (match_operand 0 "constant_call_address_operand" "")
399 (eq_attr "type" "callv")
400 (if_then_else (match_operand 1 "constant_call_address_operand" "")
403 ;; We don't know the size before shorten_branches. Expect
404 ;; the instruction to fit for better scheduling.
405 (eq_attr "type" "ibr")
408 (symbol_ref "/* Update immediate_length and other attributes! */
409 gcc_unreachable (),1")))
411 ;; The (bounding maximum) length of an instruction address.
412 (define_attr "length_address" ""
413 (cond [(eq_attr "type" "str,other,multi,fxch")
415 (and (eq_attr "type" "call")
416 (match_operand 0 "constant_call_address_operand" ""))
418 (and (eq_attr "type" "callv")
419 (match_operand 1 "constant_call_address_operand" ""))
422 (symbol_ref "ix86_attr_length_address_default (insn)")))
424 ;; Set when length prefix is used.
425 (define_attr "prefix_data16" ""
426 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
428 (eq_attr "mode" "HI")
430 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
435 ;; Set when string REP prefix is used.
436 (define_attr "prefix_rep" ""
437 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
439 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
444 ;; Set when 0f opcode prefix is used.
445 (define_attr "prefix_0f" ""
447 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
448 (eq_attr "unit" "sse,mmx"))
452 ;; Set when REX opcode prefix is used.
453 (define_attr "prefix_rex" ""
454 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
456 (and (eq_attr "mode" "DI")
457 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
458 (eq_attr "unit" "!mmx")))
460 (and (eq_attr "mode" "QI")
461 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
464 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
467 (and (eq_attr "type" "imovx")
468 (match_operand:QI 1 "ext_QIreg_operand" ""))
473 ;; There are also additional prefixes in 3DNOW, SSSE3.
474 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
475 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
476 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
477 (define_attr "prefix_extra" ""
478 (cond [(eq_attr "type" "ssemuladd,sse4arg")
480 (eq_attr "type" "sseiadd1,ssecvt1")
485 ;; Prefix used: original, VEX or maybe VEX.
486 (define_attr "prefix" "orig,vex,maybe_vex"
487 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
489 (const_string "orig")))
491 ;; VEX W bit is used.
492 (define_attr "prefix_vex_w" "" (const_int 0))
494 ;; The length of VEX prefix
495 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
496 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
497 ;; still prefix_0f 1, with prefix_extra 1.
498 (define_attr "length_vex" ""
499 (if_then_else (and (eq_attr "prefix_0f" "1")
500 (eq_attr "prefix_extra" "0"))
501 (if_then_else (eq_attr "prefix_vex_w" "1")
502 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
503 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
504 (if_then_else (eq_attr "prefix_vex_w" "1")
505 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
506 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
508 ;; Set when modrm byte is used.
509 (define_attr "modrm" ""
510 (cond [(eq_attr "type" "str,leave")
512 (eq_attr "unit" "i387")
514 (and (eq_attr "type" "incdec")
515 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
516 (ior (match_operand:SI 1 "register_operand" "")
517 (match_operand:HI 1 "register_operand" ""))))
519 (and (eq_attr "type" "push")
520 (not (match_operand 1 "memory_operand" "")))
522 (and (eq_attr "type" "pop")
523 (not (match_operand 0 "memory_operand" "")))
525 (and (eq_attr "type" "imov")
526 (and (not (eq_attr "mode" "DI"))
527 (ior (and (match_operand 0 "register_operand" "")
528 (match_operand 1 "immediate_operand" ""))
529 (ior (and (match_operand 0 "ax_reg_operand" "")
530 (match_operand 1 "memory_displacement_only_operand" ""))
531 (and (match_operand 0 "memory_displacement_only_operand" "")
532 (match_operand 1 "ax_reg_operand" ""))))))
534 (and (eq_attr "type" "call")
535 (match_operand 0 "constant_call_address_operand" ""))
537 (and (eq_attr "type" "callv")
538 (match_operand 1 "constant_call_address_operand" ""))
540 (and (eq_attr "type" "alu,alu1,icmp,test")
541 (match_operand 0 "ax_reg_operand" ""))
542 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
546 ;; The (bounding maximum) length of an instruction in bytes.
547 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
548 ;; Later we may want to split them and compute proper length as for
550 (define_attr "length" ""
551 (cond [(eq_attr "type" "other,multi,fistp,frndint")
553 (eq_attr "type" "fcmp")
555 (eq_attr "unit" "i387")
557 (plus (attr "prefix_data16")
558 (attr "length_address")))
559 (ior (eq_attr "prefix" "vex")
560 (and (eq_attr "prefix" "maybe_vex")
561 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
562 (plus (attr "length_vex")
563 (plus (attr "length_immediate")
565 (attr "length_address"))))]
566 (plus (plus (attr "modrm")
567 (plus (attr "prefix_0f")
568 (plus (attr "prefix_rex")
569 (plus (attr "prefix_extra")
571 (plus (attr "prefix_rep")
572 (plus (attr "prefix_data16")
573 (plus (attr "length_immediate")
574 (attr "length_address")))))))
576 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
577 ;; `store' if there is a simple memory reference therein, or `unknown'
578 ;; if the instruction is complex.
580 (define_attr "memory" "none,load,store,both,unknown"
581 (cond [(eq_attr "type" "other,multi,str,lwp")
582 (const_string "unknown")
583 (eq_attr "type" "lea,fcmov,fpspc")
584 (const_string "none")
585 (eq_attr "type" "fistp,leave")
586 (const_string "both")
587 (eq_attr "type" "frndint")
588 (const_string "load")
589 (eq_attr "type" "push")
590 (if_then_else (match_operand 1 "memory_operand" "")
591 (const_string "both")
592 (const_string "store"))
593 (eq_attr "type" "pop")
594 (if_then_else (match_operand 0 "memory_operand" "")
595 (const_string "both")
596 (const_string "load"))
597 (eq_attr "type" "setcc")
598 (if_then_else (match_operand 0 "memory_operand" "")
599 (const_string "store")
600 (const_string "none"))
601 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
602 (if_then_else (ior (match_operand 0 "memory_operand" "")
603 (match_operand 1 "memory_operand" ""))
604 (const_string "load")
605 (const_string "none"))
606 (eq_attr "type" "ibr")
607 (if_then_else (match_operand 0 "memory_operand" "")
608 (const_string "load")
609 (const_string "none"))
610 (eq_attr "type" "call")
611 (if_then_else (match_operand 0 "constant_call_address_operand" "")
612 (const_string "none")
613 (const_string "load"))
614 (eq_attr "type" "callv")
615 (if_then_else (match_operand 1 "constant_call_address_operand" "")
616 (const_string "none")
617 (const_string "load"))
618 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
619 (match_operand 1 "memory_operand" ""))
620 (const_string "both")
621 (and (match_operand 0 "memory_operand" "")
622 (match_operand 1 "memory_operand" ""))
623 (const_string "both")
624 (match_operand 0 "memory_operand" "")
625 (const_string "store")
626 (match_operand 1 "memory_operand" "")
627 (const_string "load")
629 "!alu1,negnot,ishift1,
630 imov,imovx,icmp,test,bitmanip,
632 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
633 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
634 (match_operand 2 "memory_operand" ""))
635 (const_string "load")
636 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
637 (match_operand 3 "memory_operand" ""))
638 (const_string "load")
640 (const_string "none")))
642 ;; Indicates if an instruction has both an immediate and a displacement.
644 (define_attr "imm_disp" "false,true,unknown"
645 (cond [(eq_attr "type" "other,multi")
646 (const_string "unknown")
647 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
648 (and (match_operand 0 "memory_displacement_operand" "")
649 (match_operand 1 "immediate_operand" "")))
650 (const_string "true")
651 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
652 (and (match_operand 0 "memory_displacement_operand" "")
653 (match_operand 2 "immediate_operand" "")))
654 (const_string "true")
656 (const_string "false")))
658 ;; Indicates if an FP operation has an integer source.
660 (define_attr "fp_int_src" "false,true"
661 (const_string "false"))
663 ;; Defines rounding mode of an FP operation.
665 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
666 (const_string "any"))
668 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
669 (define_attr "use_carry" "0,1" (const_string "0"))
671 ;; Define attribute to indicate unaligned ssemov insns
672 (define_attr "movu" "0,1" (const_string "0"))
674 ;; Describe a user's asm statement.
675 (define_asm_attributes
676 [(set_attr "length" "128")
677 (set_attr "type" "multi")])
679 ;; All integer comparison codes.
680 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
682 ;; All floating-point comparison codes.
683 (define_code_iterator fp_cond [unordered ordered
684 uneq unge ungt unle unlt ltgt])
686 (define_code_iterator plusminus [plus minus])
688 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
690 ;; Base name for define_insn
691 (define_code_attr plusminus_insn
692 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
693 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
695 ;; Base name for insn mnemonic.
696 (define_code_attr plusminus_mnemonic
697 [(plus "add") (ss_plus "adds") (us_plus "addus")
698 (minus "sub") (ss_minus "subs") (us_minus "subus")])
699 (define_code_attr plusminus_carry_mnemonic
700 [(plus "adc") (minus "sbb")])
702 ;; Mark commutative operators as such in constraints.
703 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
704 (minus "") (ss_minus "") (us_minus "")])
706 ;; Mapping of signed max and min
707 (define_code_iterator smaxmin [smax smin])
709 ;; Mapping of unsigned max and min
710 (define_code_iterator umaxmin [umax umin])
712 ;; Mapping of signed/unsigned max and min
713 (define_code_iterator maxmin [smax smin umax umin])
715 ;; Base name for integer and FP insn mnemonic
716 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
717 (umax "maxu") (umin "minu")])
718 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
720 ;; Mapping of logic operators
721 (define_code_iterator any_logic [and ior xor])
722 (define_code_iterator any_or [ior xor])
724 ;; Base name for insn mnemonic.
725 (define_code_attr logicprefix [(and "and") (ior "or") (xor "xor")])
727 ;; Mapping of shift-right operators
728 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
730 ;; Base name for define_insn
731 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
733 ;; Base name for insn mnemonic.
734 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
736 ;; Mapping of rotate operators
737 (define_code_iterator any_rotate [rotate rotatert])
739 ;; Base name for define_insn
740 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
742 ;; Base name for insn mnemonic.
743 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
745 ;; Mapping of abs neg operators
746 (define_code_iterator absneg [abs neg])
748 ;; Base name for x87 insn mnemonic.
749 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
751 ;; Used in signed and unsigned widening multiplications.
752 (define_code_iterator any_extend [sign_extend zero_extend])
754 ;; Various insn prefixes for signed and unsigned operations.
755 (define_code_attr u [(sign_extend "") (zero_extend "u")
756 (div "") (udiv "u")])
757 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
759 ;; Used in signed and unsigned divisions.
760 (define_code_iterator any_div [div udiv])
762 ;; Instruction prefix for signed and unsigned operations.
763 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
764 (div "i") (udiv "")])
766 ;; All single word integer modes.
767 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
769 ;; Single word integer modes without DImode.
770 (define_mode_iterator SWI124 [QI HI SI])
772 ;; Single word integer modes without QImode.
773 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
775 ;; Single word integer modes without QImode and HImode.
776 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
778 ;; All math-dependant single and double word integer modes.
779 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
780 (HI "TARGET_HIMODE_MATH")
781 SI DI (TI "TARGET_64BIT")])
783 ;; Math-dependant single word integer modes.
784 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
785 (HI "TARGET_HIMODE_MATH")
786 SI (DI "TARGET_64BIT")])
788 ;; Math-dependant single word integer modes without DImode.
789 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
790 (HI "TARGET_HIMODE_MATH")
793 ;; Math-dependant single word integer modes without QImode.
794 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
795 SI (DI "TARGET_64BIT")])
797 ;; Double word integer modes.
798 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
799 (TI "TARGET_64BIT")])
801 ;; Double word integer modes as mode attribute.
802 (define_mode_attr DWI [(SI "DI") (DI "TI")])
803 (define_mode_attr dwi [(SI "di") (DI "ti")])
805 ;; Half mode for double word integer modes.
806 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
807 (DI "TARGET_64BIT")])
809 ;; Instruction suffix for integer modes.
810 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
812 ;; Register class for integer modes.
813 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
815 ;; Immediate operand constraint for integer modes.
816 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
818 ;; General operand constraint for word modes.
819 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
821 ;; Immediate operand constraint for double integer modes.
822 (define_mode_attr di [(SI "iF") (DI "e")])
824 ;; Immediate operand constraint for shifts.
825 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
827 ;; General operand predicate for integer modes.
828 (define_mode_attr general_operand
829 [(QI "general_operand")
830 (HI "general_operand")
831 (SI "general_operand")
832 (DI "x86_64_general_operand")
833 (TI "x86_64_general_operand")])
835 ;; General sign/zero extend operand predicate for integer modes.
836 (define_mode_attr general_szext_operand
837 [(QI "general_operand")
838 (HI "general_operand")
839 (SI "general_operand")
840 (DI "x86_64_szext_general_operand")])
842 ;; Operand predicate for shifts.
843 (define_mode_attr shift_operand
844 [(QI "nonimmediate_operand")
845 (HI "nonimmediate_operand")
846 (SI "nonimmediate_operand")
847 (DI "shiftdi_operand")
848 (TI "register_operand")])
850 ;; Operand predicate for shift argument.
851 (define_mode_attr shift_immediate_operand
852 [(QI "const_1_to_31_operand")
853 (HI "const_1_to_31_operand")
854 (SI "const_1_to_31_operand")
855 (DI "const_1_to_63_operand")])
857 ;; Input operand predicate for arithmetic left shifts.
858 (define_mode_attr ashl_input_operand
859 [(QI "nonimmediate_operand")
860 (HI "nonimmediate_operand")
861 (SI "nonimmediate_operand")
862 (DI "ashldi_input_operand")
863 (TI "reg_or_pm1_operand")])
865 ;; SSE and x87 SFmode and DFmode floating point modes
866 (define_mode_iterator MODEF [SF DF])
868 ;; All x87 floating point modes
869 (define_mode_iterator X87MODEF [SF DF XF])
871 ;; All integer modes handled by x87 fisttp operator.
872 (define_mode_iterator X87MODEI [HI SI DI])
874 ;; All integer modes handled by integer x87 operators.
875 (define_mode_iterator X87MODEI12 [HI SI])
877 ;; All integer modes handled by SSE cvtts?2si* operators.
878 (define_mode_iterator SSEMODEI24 [SI DI])
880 ;; SSE asm suffix for floating point modes
881 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
883 ;; SSE vector mode corresponding to a scalar mode
884 (define_mode_attr ssevecmode
885 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
887 ;; Instruction suffix for REX 64bit operators.
888 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
890 ;; This mode iterator allows :P to be used for patterns that operate on
891 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
892 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
894 ;; Scheduling descriptions
896 (include "pentium.md")
899 (include "athlon.md")
904 ;; Operand and operator predicates and constraints
906 (include "predicates.md")
907 (include "constraints.md")
910 ;; Compare and branch/compare and store instructions.
912 (define_expand "cbranch<mode>4"
913 [(set (reg:CC FLAGS_REG)
914 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
915 (match_operand:SDWIM 2 "<general_operand>" "")))
916 (set (pc) (if_then_else
917 (match_operator 0 "comparison_operator"
918 [(reg:CC FLAGS_REG) (const_int 0)])
919 (label_ref (match_operand 3 "" ""))
923 if (MEM_P (operands[1]) && MEM_P (operands[2]))
924 operands[1] = force_reg (<MODE>mode, operands[1]);
925 ix86_compare_op0 = operands[1];
926 ix86_compare_op1 = operands[2];
927 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
931 (define_expand "cstore<mode>4"
932 [(set (reg:CC FLAGS_REG)
933 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
934 (match_operand:SWIM 3 "<general_operand>" "")))
935 (set (match_operand:QI 0 "register_operand" "")
936 (match_operator 1 "comparison_operator"
937 [(reg:CC FLAGS_REG) (const_int 0)]))]
940 if (MEM_P (operands[2]) && MEM_P (operands[3]))
941 operands[2] = force_reg (<MODE>mode, operands[2]);
942 ix86_compare_op0 = operands[2];
943 ix86_compare_op1 = operands[3];
944 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
948 (define_expand "cmp<mode>_1"
949 [(set (reg:CC FLAGS_REG)
950 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
951 (match_operand:SWI48 1 "<general_operand>" "")))]
955 (define_insn "*cmp<mode>_ccno_1"
956 [(set (reg FLAGS_REG)
957 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
958 (match_operand:SWI 1 "const0_operand" "")))]
959 "ix86_match_ccmode (insn, CCNOmode)"
961 test{<imodesuffix>}\t%0, %0
962 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
963 [(set_attr "type" "test,icmp")
964 (set_attr "length_immediate" "0,1")
965 (set_attr "mode" "<MODE>")])
967 (define_insn "*cmp<mode>_1"
968 [(set (reg FLAGS_REG)
969 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
970 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
971 "ix86_match_ccmode (insn, CCmode)"
972 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
973 [(set_attr "type" "icmp")
974 (set_attr "mode" "<MODE>")])
976 (define_insn "*cmp<mode>_minus_1"
977 [(set (reg FLAGS_REG)
979 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
980 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
982 "ix86_match_ccmode (insn, CCGOCmode)"
983 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
984 [(set_attr "type" "icmp")
985 (set_attr "mode" "<MODE>")])
987 (define_insn "*cmpqi_ext_1"
988 [(set (reg FLAGS_REG)
990 (match_operand:QI 0 "general_operand" "Qm")
993 (match_operand 1 "ext_register_operand" "Q")
996 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
997 "cmp{b}\t{%h1, %0|%0, %h1}"
998 [(set_attr "type" "icmp")
999 (set_attr "mode" "QI")])
1001 (define_insn "*cmpqi_ext_1_rex64"
1002 [(set (reg FLAGS_REG)
1004 (match_operand:QI 0 "register_operand" "Q")
1007 (match_operand 1 "ext_register_operand" "Q")
1009 (const_int 8)) 0)))]
1010 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1011 "cmp{b}\t{%h1, %0|%0, %h1}"
1012 [(set_attr "type" "icmp")
1013 (set_attr "mode" "QI")])
1015 (define_insn "*cmpqi_ext_2"
1016 [(set (reg FLAGS_REG)
1020 (match_operand 0 "ext_register_operand" "Q")
1023 (match_operand:QI 1 "const0_operand" "")))]
1024 "ix86_match_ccmode (insn, CCNOmode)"
1026 [(set_attr "type" "test")
1027 (set_attr "length_immediate" "0")
1028 (set_attr "mode" "QI")])
1030 (define_expand "cmpqi_ext_3"
1031 [(set (reg:CC FLAGS_REG)
1035 (match_operand 0 "ext_register_operand" "")
1038 (match_operand:QI 1 "immediate_operand" "")))]
1042 (define_insn "*cmpqi_ext_3_insn"
1043 [(set (reg FLAGS_REG)
1047 (match_operand 0 "ext_register_operand" "Q")
1050 (match_operand:QI 1 "general_operand" "Qmn")))]
1051 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1052 "cmp{b}\t{%1, %h0|%h0, %1}"
1053 [(set_attr "type" "icmp")
1054 (set_attr "modrm" "1")
1055 (set_attr "mode" "QI")])
1057 (define_insn "*cmpqi_ext_3_insn_rex64"
1058 [(set (reg FLAGS_REG)
1062 (match_operand 0 "ext_register_operand" "Q")
1065 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1066 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1067 "cmp{b}\t{%1, %h0|%h0, %1}"
1068 [(set_attr "type" "icmp")
1069 (set_attr "modrm" "1")
1070 (set_attr "mode" "QI")])
1072 (define_insn "*cmpqi_ext_4"
1073 [(set (reg FLAGS_REG)
1077 (match_operand 0 "ext_register_operand" "Q")
1082 (match_operand 1 "ext_register_operand" "Q")
1084 (const_int 8)) 0)))]
1085 "ix86_match_ccmode (insn, CCmode)"
1086 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1087 [(set_attr "type" "icmp")
1088 (set_attr "mode" "QI")])
1090 ;; These implement float point compares.
1091 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1092 ;; which would allow mix and match FP modes on the compares. Which is what
1093 ;; the old patterns did, but with many more of them.
1095 (define_expand "cbranchxf4"
1096 [(set (reg:CC FLAGS_REG)
1097 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1098 (match_operand:XF 2 "nonmemory_operand" "")))
1099 (set (pc) (if_then_else
1100 (match_operator 0 "ix86_fp_comparison_operator"
1103 (label_ref (match_operand 3 "" ""))
1107 ix86_compare_op0 = operands[1];
1108 ix86_compare_op1 = operands[2];
1109 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1113 (define_expand "cstorexf4"
1114 [(set (reg:CC FLAGS_REG)
1115 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1116 (match_operand:XF 3 "nonmemory_operand" "")))
1117 (set (match_operand:QI 0 "register_operand" "")
1118 (match_operator 1 "ix86_fp_comparison_operator"
1123 ix86_compare_op0 = operands[2];
1124 ix86_compare_op1 = operands[3];
1125 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1129 (define_expand "cbranch<mode>4"
1130 [(set (reg:CC FLAGS_REG)
1131 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1132 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1133 (set (pc) (if_then_else
1134 (match_operator 0 "ix86_fp_comparison_operator"
1137 (label_ref (match_operand 3 "" ""))
1139 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1141 ix86_compare_op0 = operands[1];
1142 ix86_compare_op1 = operands[2];
1143 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1147 (define_expand "cstore<mode>4"
1148 [(set (reg:CC FLAGS_REG)
1149 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1150 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1151 (set (match_operand:QI 0 "register_operand" "")
1152 (match_operator 1 "ix86_fp_comparison_operator"
1155 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1157 ix86_compare_op0 = operands[2];
1158 ix86_compare_op1 = operands[3];
1159 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1163 (define_expand "cbranchcc4"
1164 [(set (pc) (if_then_else
1165 (match_operator 0 "comparison_operator"
1166 [(match_operand 1 "flags_reg_operand" "")
1167 (match_operand 2 "const0_operand" "")])
1168 (label_ref (match_operand 3 "" ""))
1172 ix86_compare_op0 = operands[1];
1173 ix86_compare_op1 = operands[2];
1174 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1178 (define_expand "cstorecc4"
1179 [(set (match_operand:QI 0 "register_operand" "")
1180 (match_operator 1 "comparison_operator"
1181 [(match_operand 2 "flags_reg_operand" "")
1182 (match_operand 3 "const0_operand" "")]))]
1185 ix86_compare_op0 = operands[2];
1186 ix86_compare_op1 = operands[3];
1187 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1192 ;; FP compares, step 1:
1193 ;; Set the FP condition codes.
1195 ;; CCFPmode compare with exceptions
1196 ;; CCFPUmode compare with no exceptions
1198 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1199 ;; used to manage the reg stack popping would not be preserved.
1201 (define_insn "*cmpfp_0"
1202 [(set (match_operand:HI 0 "register_operand" "=a")
1205 (match_operand 1 "register_operand" "f")
1206 (match_operand 2 "const0_operand" ""))]
1208 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1209 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1210 "* return output_fp_compare (insn, operands, 0, 0);"
1211 [(set_attr "type" "multi")
1212 (set_attr "unit" "i387")
1214 (cond [(match_operand:SF 1 "" "")
1216 (match_operand:DF 1 "" "")
1219 (const_string "XF")))])
1221 (define_insn_and_split "*cmpfp_0_cc"
1222 [(set (reg:CCFP FLAGS_REG)
1224 (match_operand 1 "register_operand" "f")
1225 (match_operand 2 "const0_operand" "")))
1226 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1227 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1228 && TARGET_SAHF && !TARGET_CMOVE
1229 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1231 "&& reload_completed"
1234 [(compare:CCFP (match_dup 1)(match_dup 2))]
1236 (set (reg:CC FLAGS_REG)
1237 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1239 [(set_attr "type" "multi")
1240 (set_attr "unit" "i387")
1242 (cond [(match_operand:SF 1 "" "")
1244 (match_operand:DF 1 "" "")
1247 (const_string "XF")))])
1249 (define_insn "*cmpfp_xf"
1250 [(set (match_operand:HI 0 "register_operand" "=a")
1253 (match_operand:XF 1 "register_operand" "f")
1254 (match_operand:XF 2 "register_operand" "f"))]
1257 "* return output_fp_compare (insn, operands, 0, 0);"
1258 [(set_attr "type" "multi")
1259 (set_attr "unit" "i387")
1260 (set_attr "mode" "XF")])
1262 (define_insn_and_split "*cmpfp_xf_cc"
1263 [(set (reg:CCFP FLAGS_REG)
1265 (match_operand:XF 1 "register_operand" "f")
1266 (match_operand:XF 2 "register_operand" "f")))
1267 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1269 && TARGET_SAHF && !TARGET_CMOVE"
1271 "&& reload_completed"
1274 [(compare:CCFP (match_dup 1)(match_dup 2))]
1276 (set (reg:CC FLAGS_REG)
1277 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1279 [(set_attr "type" "multi")
1280 (set_attr "unit" "i387")
1281 (set_attr "mode" "XF")])
1283 (define_insn "*cmpfp_<mode>"
1284 [(set (match_operand:HI 0 "register_operand" "=a")
1287 (match_operand:MODEF 1 "register_operand" "f")
1288 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1291 "* return output_fp_compare (insn, operands, 0, 0);"
1292 [(set_attr "type" "multi")
1293 (set_attr "unit" "i387")
1294 (set_attr "mode" "<MODE>")])
1296 (define_insn_and_split "*cmpfp_<mode>_cc"
1297 [(set (reg:CCFP FLAGS_REG)
1299 (match_operand:MODEF 1 "register_operand" "f")
1300 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1301 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1303 && TARGET_SAHF && !TARGET_CMOVE"
1305 "&& reload_completed"
1308 [(compare:CCFP (match_dup 1)(match_dup 2))]
1310 (set (reg:CC FLAGS_REG)
1311 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1313 [(set_attr "type" "multi")
1314 (set_attr "unit" "i387")
1315 (set_attr "mode" "<MODE>")])
1317 (define_insn "*cmpfp_u"
1318 [(set (match_operand:HI 0 "register_operand" "=a")
1321 (match_operand 1 "register_operand" "f")
1322 (match_operand 2 "register_operand" "f"))]
1324 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1325 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1326 "* return output_fp_compare (insn, operands, 0, 1);"
1327 [(set_attr "type" "multi")
1328 (set_attr "unit" "i387")
1330 (cond [(match_operand:SF 1 "" "")
1332 (match_operand:DF 1 "" "")
1335 (const_string "XF")))])
1337 (define_insn_and_split "*cmpfp_u_cc"
1338 [(set (reg:CCFPU FLAGS_REG)
1340 (match_operand 1 "register_operand" "f")
1341 (match_operand 2 "register_operand" "f")))
1342 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1343 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1344 && TARGET_SAHF && !TARGET_CMOVE
1345 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1347 "&& reload_completed"
1350 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1352 (set (reg:CC FLAGS_REG)
1353 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1355 [(set_attr "type" "multi")
1356 (set_attr "unit" "i387")
1358 (cond [(match_operand:SF 1 "" "")
1360 (match_operand:DF 1 "" "")
1363 (const_string "XF")))])
1365 (define_insn "*cmpfp_<mode>"
1366 [(set (match_operand:HI 0 "register_operand" "=a")
1369 (match_operand 1 "register_operand" "f")
1370 (match_operator 3 "float_operator"
1371 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1373 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1374 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1375 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1376 "* return output_fp_compare (insn, operands, 0, 0);"
1377 [(set_attr "type" "multi")
1378 (set_attr "unit" "i387")
1379 (set_attr "fp_int_src" "true")
1380 (set_attr "mode" "<MODE>")])
1382 (define_insn_and_split "*cmpfp_<mode>_cc"
1383 [(set (reg:CCFP FLAGS_REG)
1385 (match_operand 1 "register_operand" "f")
1386 (match_operator 3 "float_operator"
1387 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1388 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1389 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1390 && TARGET_SAHF && !TARGET_CMOVE
1391 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1392 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1394 "&& reload_completed"
1399 (match_op_dup 3 [(match_dup 2)]))]
1401 (set (reg:CC FLAGS_REG)
1402 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1404 [(set_attr "type" "multi")
1405 (set_attr "unit" "i387")
1406 (set_attr "fp_int_src" "true")
1407 (set_attr "mode" "<MODE>")])
1409 ;; FP compares, step 2
1410 ;; Move the fpsw to ax.
1412 (define_insn "x86_fnstsw_1"
1413 [(set (match_operand:HI 0 "register_operand" "=a")
1414 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1417 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1418 (set_attr "mode" "SI")
1419 (set_attr "unit" "i387")])
1421 ;; FP compares, step 3
1422 ;; Get ax into flags, general case.
1424 (define_insn "x86_sahf_1"
1425 [(set (reg:CC FLAGS_REG)
1426 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1430 #ifdef HAVE_AS_IX86_SAHF
1433 return ASM_BYTE "0x9e";
1436 [(set_attr "length" "1")
1437 (set_attr "athlon_decode" "vector")
1438 (set_attr "amdfam10_decode" "direct")
1439 (set_attr "mode" "SI")])
1441 ;; Pentium Pro can do steps 1 through 3 in one go.
1442 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1443 (define_insn "*cmpfp_i_mixed"
1444 [(set (reg:CCFP FLAGS_REG)
1445 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1446 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1447 "TARGET_MIX_SSE_I387
1448 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1449 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1450 "* return output_fp_compare (insn, operands, 1, 0);"
1451 [(set_attr "type" "fcmp,ssecomi")
1452 (set_attr "prefix" "orig,maybe_vex")
1454 (if_then_else (match_operand:SF 1 "" "")
1456 (const_string "DF")))
1457 (set (attr "prefix_rep")
1458 (if_then_else (eq_attr "type" "ssecomi")
1460 (const_string "*")))
1461 (set (attr "prefix_data16")
1462 (cond [(eq_attr "type" "fcmp")
1464 (eq_attr "mode" "DF")
1467 (const_string "0")))
1468 (set_attr "athlon_decode" "vector")
1469 (set_attr "amdfam10_decode" "direct")])
1471 (define_insn "*cmpfp_i_sse"
1472 [(set (reg:CCFP FLAGS_REG)
1473 (compare:CCFP (match_operand 0 "register_operand" "x")
1474 (match_operand 1 "nonimmediate_operand" "xm")))]
1476 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1477 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1478 "* return output_fp_compare (insn, operands, 1, 0);"
1479 [(set_attr "type" "ssecomi")
1480 (set_attr "prefix" "maybe_vex")
1482 (if_then_else (match_operand:SF 1 "" "")
1484 (const_string "DF")))
1485 (set_attr "prefix_rep" "0")
1486 (set (attr "prefix_data16")
1487 (if_then_else (eq_attr "mode" "DF")
1489 (const_string "0")))
1490 (set_attr "athlon_decode" "vector")
1491 (set_attr "amdfam10_decode" "direct")])
1493 (define_insn "*cmpfp_i_i387"
1494 [(set (reg:CCFP FLAGS_REG)
1495 (compare:CCFP (match_operand 0 "register_operand" "f")
1496 (match_operand 1 "register_operand" "f")))]
1497 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1499 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1500 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1501 "* return output_fp_compare (insn, operands, 1, 0);"
1502 [(set_attr "type" "fcmp")
1504 (cond [(match_operand:SF 1 "" "")
1506 (match_operand:DF 1 "" "")
1509 (const_string "XF")))
1510 (set_attr "athlon_decode" "vector")
1511 (set_attr "amdfam10_decode" "direct")])
1513 (define_insn "*cmpfp_iu_mixed"
1514 [(set (reg:CCFPU FLAGS_REG)
1515 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1516 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1517 "TARGET_MIX_SSE_I387
1518 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1519 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1520 "* return output_fp_compare (insn, operands, 1, 1);"
1521 [(set_attr "type" "fcmp,ssecomi")
1522 (set_attr "prefix" "orig,maybe_vex")
1524 (if_then_else (match_operand:SF 1 "" "")
1526 (const_string "DF")))
1527 (set (attr "prefix_rep")
1528 (if_then_else (eq_attr "type" "ssecomi")
1530 (const_string "*")))
1531 (set (attr "prefix_data16")
1532 (cond [(eq_attr "type" "fcmp")
1534 (eq_attr "mode" "DF")
1537 (const_string "0")))
1538 (set_attr "athlon_decode" "vector")
1539 (set_attr "amdfam10_decode" "direct")])
1541 (define_insn "*cmpfp_iu_sse"
1542 [(set (reg:CCFPU FLAGS_REG)
1543 (compare:CCFPU (match_operand 0 "register_operand" "x")
1544 (match_operand 1 "nonimmediate_operand" "xm")))]
1546 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1547 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1548 "* return output_fp_compare (insn, operands, 1, 1);"
1549 [(set_attr "type" "ssecomi")
1550 (set_attr "prefix" "maybe_vex")
1552 (if_then_else (match_operand:SF 1 "" "")
1554 (const_string "DF")))
1555 (set_attr "prefix_rep" "0")
1556 (set (attr "prefix_data16")
1557 (if_then_else (eq_attr "mode" "DF")
1559 (const_string "0")))
1560 (set_attr "athlon_decode" "vector")
1561 (set_attr "amdfam10_decode" "direct")])
1563 (define_insn "*cmpfp_iu_387"
1564 [(set (reg:CCFPU FLAGS_REG)
1565 (compare:CCFPU (match_operand 0 "register_operand" "f")
1566 (match_operand 1 "register_operand" "f")))]
1567 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1569 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1570 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1571 "* return output_fp_compare (insn, operands, 1, 1);"
1572 [(set_attr "type" "fcmp")
1574 (cond [(match_operand:SF 1 "" "")
1576 (match_operand:DF 1 "" "")
1579 (const_string "XF")))
1580 (set_attr "athlon_decode" "vector")
1581 (set_attr "amdfam10_decode" "direct")])
1583 ;; Move instructions.
1585 ;; General case of fullword move.
1587 (define_expand "movsi"
1588 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1589 (match_operand:SI 1 "general_operand" ""))]
1591 "ix86_expand_move (SImode, operands); DONE;")
1593 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1596 ;; %%% We don't use a post-inc memory reference because x86 is not a
1597 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1598 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1599 ;; targets without our curiosities, and it is just as easy to represent
1600 ;; this differently.
1602 (define_insn "*pushsi2"
1603 [(set (match_operand:SI 0 "push_operand" "=<")
1604 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1607 [(set_attr "type" "push")
1608 (set_attr "mode" "SI")])
1610 ;; For 64BIT abi we always round up to 8 bytes.
1611 (define_insn "*pushsi2_rex64"
1612 [(set (match_operand:SI 0 "push_operand" "=X")
1613 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1616 [(set_attr "type" "push")
1617 (set_attr "mode" "SI")])
1619 (define_insn "*pushsi2_prologue"
1620 [(set (match_operand:SI 0 "push_operand" "=<")
1621 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1622 (clobber (mem:BLK (scratch)))]
1625 [(set_attr "type" "push")
1626 (set_attr "mode" "SI")])
1628 (define_insn "*popsi1_epilogue"
1629 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1630 (mem:SI (reg:SI SP_REG)))
1631 (set (reg:SI SP_REG)
1632 (plus:SI (reg:SI SP_REG) (const_int 4)))
1633 (clobber (mem:BLK (scratch)))]
1636 [(set_attr "type" "pop")
1637 (set_attr "mode" "SI")])
1639 (define_insn "popsi1"
1640 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1641 (mem:SI (reg:SI SP_REG)))
1642 (set (reg:SI SP_REG)
1643 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1646 [(set_attr "type" "pop")
1647 (set_attr "mode" "SI")])
1649 (define_insn "*movsi_xor"
1650 [(set (match_operand:SI 0 "register_operand" "=r")
1651 (match_operand:SI 1 "const0_operand" ""))
1652 (clobber (reg:CC FLAGS_REG))]
1655 [(set_attr "type" "alu1")
1656 (set_attr "mode" "SI")
1657 (set_attr "length_immediate" "0")])
1659 (define_insn "*movsi_or"
1660 [(set (match_operand:SI 0 "register_operand" "=r")
1661 (match_operand:SI 1 "immediate_operand" "i"))
1662 (clobber (reg:CC FLAGS_REG))]
1664 && operands[1] == constm1_rtx"
1666 operands[1] = constm1_rtx;
1667 return "or{l}\t{%1, %0|%0, %1}";
1669 [(set_attr "type" "alu1")
1670 (set_attr "mode" "SI")
1671 (set_attr "length_immediate" "1")])
1673 (define_insn "*movsi_1"
1674 [(set (match_operand:SI 0 "nonimmediate_operand"
1675 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1676 (match_operand:SI 1 "general_operand"
1677 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1678 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1680 switch (get_attr_type (insn))
1683 if (get_attr_mode (insn) == MODE_TI)
1684 return "%vpxor\t%0, %d0";
1685 return "%vxorps\t%0, %d0";
1688 switch (get_attr_mode (insn))
1691 return "%vmovdqa\t{%1, %0|%0, %1}";
1693 return "%vmovaps\t{%1, %0|%0, %1}";
1695 return "%vmovd\t{%1, %0|%0, %1}";
1697 return "%vmovss\t{%1, %0|%0, %1}";
1703 return "pxor\t%0, %0";
1706 if (get_attr_mode (insn) == MODE_DI)
1707 return "movq\t{%1, %0|%0, %1}";
1708 return "movd\t{%1, %0|%0, %1}";
1711 return "lea{l}\t{%1, %0|%0, %1}";
1714 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1715 return "mov{l}\t{%1, %0|%0, %1}";
1719 (cond [(eq_attr "alternative" "2")
1720 (const_string "mmx")
1721 (eq_attr "alternative" "3,4,5")
1722 (const_string "mmxmov")
1723 (eq_attr "alternative" "6")
1724 (const_string "sselog1")
1725 (eq_attr "alternative" "7,8,9,10,11")
1726 (const_string "ssemov")
1727 (match_operand:DI 1 "pic_32bit_operand" "")
1728 (const_string "lea")
1730 (const_string "imov")))
1731 (set (attr "prefix")
1732 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1733 (const_string "orig")
1734 (const_string "maybe_vex")))
1735 (set (attr "prefix_data16")
1736 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1738 (const_string "*")))
1740 (cond [(eq_attr "alternative" "2,3")
1742 (eq_attr "alternative" "6,7")
1744 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1745 (const_string "V4SF")
1746 (const_string "TI"))
1747 (and (eq_attr "alternative" "8,9,10,11")
1748 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1751 (const_string "SI")))])
1753 ;; Stores and loads of ax to arbitrary constant address.
1754 ;; We fake an second form of instruction to force reload to load address
1755 ;; into register when rax is not available
1756 (define_insn "*movabssi_1_rex64"
1757 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1758 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1759 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1761 movabs{l}\t{%1, %P0|%P0, %1}
1762 mov{l}\t{%1, %a0|%a0, %1}"
1763 [(set_attr "type" "imov")
1764 (set_attr "modrm" "0,*")
1765 (set_attr "length_address" "8,0")
1766 (set_attr "length_immediate" "0,*")
1767 (set_attr "memory" "store")
1768 (set_attr "mode" "SI")])
1770 (define_insn "*movabssi_2_rex64"
1771 [(set (match_operand:SI 0 "register_operand" "=a,r")
1772 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1773 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1775 movabs{l}\t{%P1, %0|%0, %P1}
1776 mov{l}\t{%a1, %0|%0, %a1}"
1777 [(set_attr "type" "imov")
1778 (set_attr "modrm" "0,*")
1779 (set_attr "length_address" "8,0")
1780 (set_attr "length_immediate" "0")
1781 (set_attr "memory" "load")
1782 (set_attr "mode" "SI")])
1784 (define_insn "*swapsi"
1785 [(set (match_operand:SI 0 "register_operand" "+r")
1786 (match_operand:SI 1 "register_operand" "+r"))
1791 [(set_attr "type" "imov")
1792 (set_attr "mode" "SI")
1793 (set_attr "pent_pair" "np")
1794 (set_attr "athlon_decode" "vector")
1795 (set_attr "amdfam10_decode" "double")])
1797 (define_expand "movhi"
1798 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1799 (match_operand:HI 1 "general_operand" ""))]
1801 "ix86_expand_move (HImode, operands); DONE;")
1803 (define_insn "*pushhi2"
1804 [(set (match_operand:HI 0 "push_operand" "=X")
1805 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1808 [(set_attr "type" "push")
1809 (set_attr "mode" "SI")])
1811 ;; For 64BIT abi we always round up to 8 bytes.
1812 (define_insn "*pushhi2_rex64"
1813 [(set (match_operand:HI 0 "push_operand" "=X")
1814 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1817 [(set_attr "type" "push")
1818 (set_attr "mode" "DI")])
1820 (define_insn "*movhi_1"
1821 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1822 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1823 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1825 switch (get_attr_type (insn))
1828 /* movzwl is faster than movw on p2 due to partial word stalls,
1829 though not as fast as an aligned movl. */
1830 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1832 if (get_attr_mode (insn) == MODE_SI)
1833 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1835 return "mov{w}\t{%1, %0|%0, %1}";
1839 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1840 (const_string "imov")
1841 (and (eq_attr "alternative" "0")
1842 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1844 (eq (symbol_ref "TARGET_HIMODE_MATH")
1846 (const_string "imov")
1847 (and (eq_attr "alternative" "1,2")
1848 (match_operand:HI 1 "aligned_operand" ""))
1849 (const_string "imov")
1850 (and (ne (symbol_ref "TARGET_MOVX")
1852 (eq_attr "alternative" "0,2"))
1853 (const_string "imovx")
1855 (const_string "imov")))
1857 (cond [(eq_attr "type" "imovx")
1859 (and (eq_attr "alternative" "1,2")
1860 (match_operand:HI 1 "aligned_operand" ""))
1862 (and (eq_attr "alternative" "0")
1863 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1865 (eq (symbol_ref "TARGET_HIMODE_MATH")
1869 (const_string "HI")))])
1871 ;; Stores and loads of ax to arbitrary constant address.
1872 ;; We fake an second form of instruction to force reload to load address
1873 ;; into register when rax is not available
1874 (define_insn "*movabshi_1_rex64"
1875 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1876 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1877 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1879 movabs{w}\t{%1, %P0|%P0, %1}
1880 mov{w}\t{%1, %a0|%a0, %1}"
1881 [(set_attr "type" "imov")
1882 (set_attr "modrm" "0,*")
1883 (set_attr "length_address" "8,0")
1884 (set_attr "length_immediate" "0,*")
1885 (set_attr "memory" "store")
1886 (set_attr "mode" "HI")])
1888 (define_insn "*movabshi_2_rex64"
1889 [(set (match_operand:HI 0 "register_operand" "=a,r")
1890 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1891 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1893 movabs{w}\t{%P1, %0|%0, %P1}
1894 mov{w}\t{%a1, %0|%0, %a1}"
1895 [(set_attr "type" "imov")
1896 (set_attr "modrm" "0,*")
1897 (set_attr "length_address" "8,0")
1898 (set_attr "length_immediate" "0")
1899 (set_attr "memory" "load")
1900 (set_attr "mode" "HI")])
1902 (define_insn "*swaphi_1"
1903 [(set (match_operand:HI 0 "register_operand" "+r")
1904 (match_operand:HI 1 "register_operand" "+r"))
1907 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1909 [(set_attr "type" "imov")
1910 (set_attr "mode" "SI")
1911 (set_attr "pent_pair" "np")
1912 (set_attr "athlon_decode" "vector")
1913 (set_attr "amdfam10_decode" "double")])
1915 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1916 (define_insn "*swaphi_2"
1917 [(set (match_operand:HI 0 "register_operand" "+r")
1918 (match_operand:HI 1 "register_operand" "+r"))
1921 "TARGET_PARTIAL_REG_STALL"
1923 [(set_attr "type" "imov")
1924 (set_attr "mode" "HI")
1925 (set_attr "pent_pair" "np")
1926 (set_attr "athlon_decode" "vector")])
1928 (define_expand "movstricthi"
1929 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1930 (match_operand:HI 1 "general_operand" ""))]
1933 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1935 /* Don't generate memory->memory moves, go through a register */
1936 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1937 operands[1] = force_reg (HImode, operands[1]);
1940 (define_insn "*movstricthi_1"
1941 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1942 (match_operand:HI 1 "general_operand" "rn,m"))]
1943 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1944 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1945 "mov{w}\t{%1, %0|%0, %1}"
1946 [(set_attr "type" "imov")
1947 (set_attr "mode" "HI")])
1949 (define_insn "*movstricthi_xor"
1950 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1951 (match_operand:HI 1 "const0_operand" ""))
1952 (clobber (reg:CC FLAGS_REG))]
1955 [(set_attr "type" "alu1")
1956 (set_attr "mode" "HI")
1957 (set_attr "length_immediate" "0")])
1959 (define_expand "movqi"
1960 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1961 (match_operand:QI 1 "general_operand" ""))]
1963 "ix86_expand_move (QImode, operands); DONE;")
1965 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1966 ;; "push a byte". But actually we use pushl, which has the effect
1967 ;; of rounding the amount pushed up to a word.
1969 (define_insn "*pushqi2"
1970 [(set (match_operand:QI 0 "push_operand" "=X")
1971 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1974 [(set_attr "type" "push")
1975 (set_attr "mode" "SI")])
1977 ;; For 64BIT abi we always round up to 8 bytes.
1978 (define_insn "*pushqi2_rex64"
1979 [(set (match_operand:QI 0 "push_operand" "=X")
1980 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1983 [(set_attr "type" "push")
1984 (set_attr "mode" "DI")])
1986 ;; Situation is quite tricky about when to choose full sized (SImode) move
1987 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1988 ;; partial register dependency machines (such as AMD Athlon), where QImode
1989 ;; moves issue extra dependency and for partial register stalls machines
1990 ;; that don't use QImode patterns (and QImode move cause stall on the next
1993 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1994 ;; register stall machines with, where we use QImode instructions, since
1995 ;; partial register stall can be caused there. Then we use movzx.
1996 (define_insn "*movqi_1"
1997 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1998 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1999 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2001 switch (get_attr_type (insn))
2004 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2005 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2007 if (get_attr_mode (insn) == MODE_SI)
2008 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2010 return "mov{b}\t{%1, %0|%0, %1}";
2014 (cond [(and (eq_attr "alternative" "5")
2015 (not (match_operand:QI 1 "aligned_operand" "")))
2016 (const_string "imovx")
2017 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2018 (const_string "imov")
2019 (and (eq_attr "alternative" "3")
2020 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2022 (eq (symbol_ref "TARGET_QIMODE_MATH")
2024 (const_string "imov")
2025 (eq_attr "alternative" "3,5")
2026 (const_string "imovx")
2027 (and (ne (symbol_ref "TARGET_MOVX")
2029 (eq_attr "alternative" "2"))
2030 (const_string "imovx")
2032 (const_string "imov")))
2034 (cond [(eq_attr "alternative" "3,4,5")
2036 (eq_attr "alternative" "6")
2038 (eq_attr "type" "imovx")
2040 (and (eq_attr "type" "imov")
2041 (and (eq_attr "alternative" "0,1")
2042 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2044 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2046 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2049 ;; Avoid partial register stalls when not using QImode arithmetic
2050 (and (eq_attr "type" "imov")
2051 (and (eq_attr "alternative" "0,1")
2052 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2054 (eq (symbol_ref "TARGET_QIMODE_MATH")
2058 (const_string "QI")))])
2060 (define_insn "*swapqi_1"
2061 [(set (match_operand:QI 0 "register_operand" "+r")
2062 (match_operand:QI 1 "register_operand" "+r"))
2065 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2067 [(set_attr "type" "imov")
2068 (set_attr "mode" "SI")
2069 (set_attr "pent_pair" "np")
2070 (set_attr "athlon_decode" "vector")
2071 (set_attr "amdfam10_decode" "vector")])
2073 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2074 (define_insn "*swapqi_2"
2075 [(set (match_operand:QI 0 "register_operand" "+q")
2076 (match_operand:QI 1 "register_operand" "+q"))
2079 "TARGET_PARTIAL_REG_STALL"
2081 [(set_attr "type" "imov")
2082 (set_attr "mode" "QI")
2083 (set_attr "pent_pair" "np")
2084 (set_attr "athlon_decode" "vector")])
2086 (define_expand "movstrictqi"
2087 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2088 (match_operand:QI 1 "general_operand" ""))]
2091 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2093 /* Don't generate memory->memory moves, go through a register. */
2094 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2095 operands[1] = force_reg (QImode, operands[1]);
2098 (define_insn "*movstrictqi_1"
2099 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2100 (match_operand:QI 1 "general_operand" "*qn,m"))]
2101 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2102 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2103 "mov{b}\t{%1, %0|%0, %1}"
2104 [(set_attr "type" "imov")
2105 (set_attr "mode" "QI")])
2107 (define_insn "*movstrictqi_xor"
2108 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2109 (match_operand:QI 1 "const0_operand" ""))
2110 (clobber (reg:CC FLAGS_REG))]
2113 [(set_attr "type" "alu1")
2114 (set_attr "mode" "QI")
2115 (set_attr "length_immediate" "0")])
2117 (define_insn "*movsi_extv_1"
2118 [(set (match_operand:SI 0 "register_operand" "=R")
2119 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2123 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2124 [(set_attr "type" "imovx")
2125 (set_attr "mode" "SI")])
2127 (define_insn "*movhi_extv_1"
2128 [(set (match_operand:HI 0 "register_operand" "=R")
2129 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2133 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2134 [(set_attr "type" "imovx")
2135 (set_attr "mode" "SI")])
2137 (define_insn "*movqi_extv_1"
2138 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2139 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2144 switch (get_attr_type (insn))
2147 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2149 return "mov{b}\t{%h1, %0|%0, %h1}";
2153 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2154 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2155 (ne (symbol_ref "TARGET_MOVX")
2157 (const_string "imovx")
2158 (const_string "imov")))
2160 (if_then_else (eq_attr "type" "imovx")
2162 (const_string "QI")))])
2164 (define_insn "*movqi_extv_1_rex64"
2165 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2166 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2171 switch (get_attr_type (insn))
2174 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2176 return "mov{b}\t{%h1, %0|%0, %h1}";
2180 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2181 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2182 (ne (symbol_ref "TARGET_MOVX")
2184 (const_string "imovx")
2185 (const_string "imov")))
2187 (if_then_else (eq_attr "type" "imovx")
2189 (const_string "QI")))])
2191 ;; Stores and loads of ax to arbitrary constant address.
2192 ;; We fake an second form of instruction to force reload to load address
2193 ;; into register when rax is not available
2194 (define_insn "*movabsqi_1_rex64"
2195 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2196 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2197 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2199 movabs{b}\t{%1, %P0|%P0, %1}
2200 mov{b}\t{%1, %a0|%a0, %1}"
2201 [(set_attr "type" "imov")
2202 (set_attr "modrm" "0,*")
2203 (set_attr "length_address" "8,0")
2204 (set_attr "length_immediate" "0,*")
2205 (set_attr "memory" "store")
2206 (set_attr "mode" "QI")])
2208 (define_insn "*movabsqi_2_rex64"
2209 [(set (match_operand:QI 0 "register_operand" "=a,r")
2210 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2211 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2213 movabs{b}\t{%P1, %0|%0, %P1}
2214 mov{b}\t{%a1, %0|%0, %a1}"
2215 [(set_attr "type" "imov")
2216 (set_attr "modrm" "0,*")
2217 (set_attr "length_address" "8,0")
2218 (set_attr "length_immediate" "0")
2219 (set_attr "memory" "load")
2220 (set_attr "mode" "QI")])
2222 (define_insn "*movdi_extzv_1"
2223 [(set (match_operand:DI 0 "register_operand" "=R")
2224 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2228 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2229 [(set_attr "type" "imovx")
2230 (set_attr "mode" "SI")])
2232 (define_insn "*movsi_extzv_1"
2233 [(set (match_operand:SI 0 "register_operand" "=R")
2234 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2238 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2239 [(set_attr "type" "imovx")
2240 (set_attr "mode" "SI")])
2242 (define_insn "*movqi_extzv_2"
2243 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2244 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2249 switch (get_attr_type (insn))
2252 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2254 return "mov{b}\t{%h1, %0|%0, %h1}";
2258 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2259 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2260 (ne (symbol_ref "TARGET_MOVX")
2262 (const_string "imovx")
2263 (const_string "imov")))
2265 (if_then_else (eq_attr "type" "imovx")
2267 (const_string "QI")))])
2269 (define_insn "*movqi_extzv_2_rex64"
2270 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2271 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2276 switch (get_attr_type (insn))
2279 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2281 return "mov{b}\t{%h1, %0|%0, %h1}";
2285 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2286 (ne (symbol_ref "TARGET_MOVX")
2288 (const_string "imovx")
2289 (const_string "imov")))
2291 (if_then_else (eq_attr "type" "imovx")
2293 (const_string "QI")))])
2295 (define_insn "movsi_insv_1"
2296 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2299 (match_operand:SI 1 "general_operand" "Qmn"))]
2301 "mov{b}\t{%b1, %h0|%h0, %b1}"
2302 [(set_attr "type" "imov")
2303 (set_attr "mode" "QI")])
2305 (define_insn "*movsi_insv_1_rex64"
2306 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2309 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2311 "mov{b}\t{%b1, %h0|%h0, %b1}"
2312 [(set_attr "type" "imov")
2313 (set_attr "mode" "QI")])
2315 (define_insn "movdi_insv_1_rex64"
2316 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2319 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2321 "mov{b}\t{%b1, %h0|%h0, %b1}"
2322 [(set_attr "type" "imov")
2323 (set_attr "mode" "QI")])
2325 (define_insn "*movqi_insv_2"
2326 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2329 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2332 "mov{b}\t{%h1, %h0|%h0, %h1}"
2333 [(set_attr "type" "imov")
2334 (set_attr "mode" "QI")])
2336 (define_expand "movdi"
2337 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2338 (match_operand:DI 1 "general_operand" ""))]
2340 "ix86_expand_move (DImode, operands); DONE;")
2342 (define_insn "*pushdi"
2343 [(set (match_operand:DI 0 "push_operand" "=<")
2344 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2348 (define_insn "*pushdi2_rex64"
2349 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2350 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2355 [(set_attr "type" "push,multi")
2356 (set_attr "mode" "DI")])
2358 ;; Convert impossible pushes of immediate to existing instructions.
2359 ;; First try to get scratch register and go through it. In case this
2360 ;; fails, push sign extended lower part first and then overwrite
2361 ;; upper part by 32bit move.
2363 [(match_scratch:DI 2 "r")
2364 (set (match_operand:DI 0 "push_operand" "")
2365 (match_operand:DI 1 "immediate_operand" ""))]
2366 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2367 && !x86_64_immediate_operand (operands[1], DImode)"
2368 [(set (match_dup 2) (match_dup 1))
2369 (set (match_dup 0) (match_dup 2))]
2372 ;; We need to define this as both peepholer and splitter for case
2373 ;; peephole2 pass is not run.
2374 ;; "&& 1" is needed to keep it from matching the previous pattern.
2376 [(set (match_operand:DI 0 "push_operand" "")
2377 (match_operand:DI 1 "immediate_operand" ""))]
2378 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2379 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2380 [(set (match_dup 0) (match_dup 1))
2381 (set (match_dup 2) (match_dup 3))]
2382 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2383 operands[1] = gen_lowpart (DImode, operands[2]);
2384 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2389 [(set (match_operand:DI 0 "push_operand" "")
2390 (match_operand:DI 1 "immediate_operand" ""))]
2391 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2392 ? epilogue_completed : reload_completed)
2393 && !symbolic_operand (operands[1], DImode)
2394 && !x86_64_immediate_operand (operands[1], DImode)"
2395 [(set (match_dup 0) (match_dup 1))
2396 (set (match_dup 2) (match_dup 3))]
2397 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2398 operands[1] = gen_lowpart (DImode, operands[2]);
2399 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2403 (define_insn "*pushdi2_prologue_rex64"
2404 [(set (match_operand:DI 0 "push_operand" "=<")
2405 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2406 (clobber (mem:BLK (scratch)))]
2409 [(set_attr "type" "push")
2410 (set_attr "mode" "DI")])
2412 (define_insn "*popdi1_epilogue_rex64"
2413 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2414 (mem:DI (reg:DI SP_REG)))
2415 (set (reg:DI SP_REG)
2416 (plus:DI (reg:DI SP_REG) (const_int 8)))
2417 (clobber (mem:BLK (scratch)))]
2420 [(set_attr "type" "pop")
2421 (set_attr "mode" "DI")])
2423 (define_insn "popdi1"
2424 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2425 (mem:DI (reg:DI SP_REG)))
2426 (set (reg:DI SP_REG)
2427 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2430 [(set_attr "type" "pop")
2431 (set_attr "mode" "DI")])
2433 (define_insn "*movdi_xor_rex64"
2434 [(set (match_operand:DI 0 "register_operand" "=r")
2435 (match_operand:DI 1 "const0_operand" ""))
2436 (clobber (reg:CC FLAGS_REG))]
2438 && reload_completed"
2440 [(set_attr "type" "alu1")
2441 (set_attr "mode" "SI")
2442 (set_attr "length_immediate" "0")])
2444 (define_insn "*movdi_or_rex64"
2445 [(set (match_operand:DI 0 "register_operand" "=r")
2446 (match_operand:DI 1 "const_int_operand" "i"))
2447 (clobber (reg:CC FLAGS_REG))]
2450 && operands[1] == constm1_rtx"
2452 operands[1] = constm1_rtx;
2453 return "or{q}\t{%1, %0|%0, %1}";
2455 [(set_attr "type" "alu1")
2456 (set_attr "mode" "DI")
2457 (set_attr "length_immediate" "1")])
2459 (define_insn "*movdi_2"
2460 [(set (match_operand:DI 0 "nonimmediate_operand"
2461 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2462 (match_operand:DI 1 "general_operand"
2463 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2464 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2469 movq\t{%1, %0|%0, %1}
2470 movq\t{%1, %0|%0, %1}
2472 %vmovq\t{%1, %0|%0, %1}
2473 %vmovdqa\t{%1, %0|%0, %1}
2474 %vmovq\t{%1, %0|%0, %1}
2476 movlps\t{%1, %0|%0, %1}
2477 movaps\t{%1, %0|%0, %1}
2478 movlps\t{%1, %0|%0, %1}"
2479 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2480 (set (attr "prefix")
2481 (if_then_else (eq_attr "alternative" "5,6,7,8")
2482 (const_string "vex")
2483 (const_string "orig")))
2484 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2487 [(set (match_operand:DI 0 "push_operand" "")
2488 (match_operand:DI 1 "general_operand" ""))]
2489 "!TARGET_64BIT && reload_completed
2490 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2492 "ix86_split_long_move (operands); DONE;")
2494 ;; %%% This multiword shite has got to go.
2496 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2497 (match_operand:DI 1 "general_operand" ""))]
2498 "!TARGET_64BIT && reload_completed
2499 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2500 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2502 "ix86_split_long_move (operands); DONE;")
2504 (define_insn "*movdi_1_rex64"
2505 [(set (match_operand:DI 0 "nonimmediate_operand"
2506 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2507 (match_operand:DI 1 "general_operand"
2508 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2509 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2511 switch (get_attr_type (insn))
2514 if (SSE_REG_P (operands[0]))
2515 return "movq2dq\t{%1, %0|%0, %1}";
2517 return "movdq2q\t{%1, %0|%0, %1}";
2522 if (get_attr_mode (insn) == MODE_TI)
2523 return "vmovdqa\t{%1, %0|%0, %1}";
2525 return "vmovq\t{%1, %0|%0, %1}";
2528 if (get_attr_mode (insn) == MODE_TI)
2529 return "movdqa\t{%1, %0|%0, %1}";
2533 /* Moves from and into integer register is done using movd
2534 opcode with REX prefix. */
2535 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2536 return "movd\t{%1, %0|%0, %1}";
2537 return "movq\t{%1, %0|%0, %1}";
2540 return "%vpxor\t%0, %d0";
2543 return "pxor\t%0, %0";
2549 return "lea{q}\t{%a1, %0|%0, %a1}";
2552 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2553 if (get_attr_mode (insn) == MODE_SI)
2554 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2555 else if (which_alternative == 2)
2556 return "movabs{q}\t{%1, %0|%0, %1}";
2558 return "mov{q}\t{%1, %0|%0, %1}";
2562 (cond [(eq_attr "alternative" "5")
2563 (const_string "mmx")
2564 (eq_attr "alternative" "6,7,8,9,10")
2565 (const_string "mmxmov")
2566 (eq_attr "alternative" "11")
2567 (const_string "sselog1")
2568 (eq_attr "alternative" "12,13,14,15,16")
2569 (const_string "ssemov")
2570 (eq_attr "alternative" "17,18")
2571 (const_string "ssecvt")
2572 (eq_attr "alternative" "4")
2573 (const_string "multi")
2574 (match_operand:DI 1 "pic_32bit_operand" "")
2575 (const_string "lea")
2577 (const_string "imov")))
2580 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2582 (const_string "*")))
2583 (set (attr "length_immediate")
2585 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2587 (const_string "*")))
2588 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2589 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2590 (set (attr "prefix")
2591 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2592 (const_string "maybe_vex")
2593 (const_string "orig")))
2594 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2596 ;; Stores and loads of ax to arbitrary constant address.
2597 ;; We fake an second form of instruction to force reload to load address
2598 ;; into register when rax is not available
2599 (define_insn "*movabsdi_1_rex64"
2600 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2601 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2602 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2604 movabs{q}\t{%1, %P0|%P0, %1}
2605 mov{q}\t{%1, %a0|%a0, %1}"
2606 [(set_attr "type" "imov")
2607 (set_attr "modrm" "0,*")
2608 (set_attr "length_address" "8,0")
2609 (set_attr "length_immediate" "0,*")
2610 (set_attr "memory" "store")
2611 (set_attr "mode" "DI")])
2613 (define_insn "*movabsdi_2_rex64"
2614 [(set (match_operand:DI 0 "register_operand" "=a,r")
2615 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2616 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2618 movabs{q}\t{%P1, %0|%0, %P1}
2619 mov{q}\t{%a1, %0|%0, %a1}"
2620 [(set_attr "type" "imov")
2621 (set_attr "modrm" "0,*")
2622 (set_attr "length_address" "8,0")
2623 (set_attr "length_immediate" "0")
2624 (set_attr "memory" "load")
2625 (set_attr "mode" "DI")])
2627 ;; Convert impossible stores of immediate to existing instructions.
2628 ;; First try to get scratch register and go through it. In case this
2629 ;; fails, move by 32bit parts.
2631 [(match_scratch:DI 2 "r")
2632 (set (match_operand:DI 0 "memory_operand" "")
2633 (match_operand:DI 1 "immediate_operand" ""))]
2634 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2635 && !x86_64_immediate_operand (operands[1], DImode)"
2636 [(set (match_dup 2) (match_dup 1))
2637 (set (match_dup 0) (match_dup 2))]
2640 ;; We need to define this as both peepholer and splitter for case
2641 ;; peephole2 pass is not run.
2642 ;; "&& 1" is needed to keep it from matching the previous pattern.
2644 [(set (match_operand:DI 0 "memory_operand" "")
2645 (match_operand:DI 1 "immediate_operand" ""))]
2646 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2647 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2648 [(set (match_dup 2) (match_dup 3))
2649 (set (match_dup 4) (match_dup 5))]
2650 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2653 [(set (match_operand:DI 0 "memory_operand" "")
2654 (match_operand:DI 1 "immediate_operand" ""))]
2655 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2656 ? epilogue_completed : reload_completed)
2657 && !symbolic_operand (operands[1], DImode)
2658 && !x86_64_immediate_operand (operands[1], DImode)"
2659 [(set (match_dup 2) (match_dup 3))
2660 (set (match_dup 4) (match_dup 5))]
2661 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2663 (define_insn "*swapdi_rex64"
2664 [(set (match_operand:DI 0 "register_operand" "+r")
2665 (match_operand:DI 1 "register_operand" "+r"))
2670 [(set_attr "type" "imov")
2671 (set_attr "mode" "DI")
2672 (set_attr "pent_pair" "np")
2673 (set_attr "athlon_decode" "vector")
2674 (set_attr "amdfam10_decode" "double")])
2676 (define_expand "movoi"
2677 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2678 (match_operand:OI 1 "general_operand" ""))]
2680 "ix86_expand_move (OImode, operands); DONE;")
2682 (define_insn "*movoi_internal"
2683 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2684 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2686 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2688 switch (which_alternative)
2691 return "vxorps\t%0, %0, %0";
2694 if (misaligned_operand (operands[0], OImode)
2695 || misaligned_operand (operands[1], OImode))
2696 return "vmovdqu\t{%1, %0|%0, %1}";
2698 return "vmovdqa\t{%1, %0|%0, %1}";
2703 [(set_attr "type" "sselog1,ssemov,ssemov")
2704 (set_attr "prefix" "vex")
2705 (set_attr "mode" "OI")])
2707 (define_expand "movti"
2708 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2709 (match_operand:TI 1 "nonimmediate_operand" ""))]
2710 "TARGET_SSE || TARGET_64BIT"
2713 ix86_expand_move (TImode, operands);
2714 else if (push_operand (operands[0], TImode))
2715 ix86_expand_push (TImode, operands[1]);
2717 ix86_expand_vector_move (TImode, operands);
2721 (define_insn "*movti_internal"
2722 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2723 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2724 "TARGET_SSE && !TARGET_64BIT
2725 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2727 switch (which_alternative)
2730 if (get_attr_mode (insn) == MODE_V4SF)
2731 return "%vxorps\t%0, %d0";
2733 return "%vpxor\t%0, %d0";
2736 /* TDmode values are passed as TImode on the stack. Moving them
2737 to stack may result in unaligned memory access. */
2738 if (misaligned_operand (operands[0], TImode)
2739 || misaligned_operand (operands[1], TImode))
2741 if (get_attr_mode (insn) == MODE_V4SF)
2742 return "%vmovups\t{%1, %0|%0, %1}";
2744 return "%vmovdqu\t{%1, %0|%0, %1}";
2748 if (get_attr_mode (insn) == MODE_V4SF)
2749 return "%vmovaps\t{%1, %0|%0, %1}";
2751 return "%vmovdqa\t{%1, %0|%0, %1}";
2757 [(set_attr "type" "sselog1,ssemov,ssemov")
2758 (set_attr "prefix" "maybe_vex")
2760 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2761 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2762 (const_string "V4SF")
2763 (and (eq_attr "alternative" "2")
2764 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2766 (const_string "V4SF")]
2767 (const_string "TI")))])
2769 (define_insn "*movti_rex64"
2770 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2771 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2773 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2775 switch (which_alternative)
2781 if (get_attr_mode (insn) == MODE_V4SF)
2782 return "%vxorps\t%0, %d0";
2784 return "%vpxor\t%0, %d0";
2787 /* TDmode values are passed as TImode on the stack. Moving them
2788 to stack may result in unaligned memory access. */
2789 if (misaligned_operand (operands[0], TImode)
2790 || misaligned_operand (operands[1], TImode))
2792 if (get_attr_mode (insn) == MODE_V4SF)
2793 return "%vmovups\t{%1, %0|%0, %1}";
2795 return "%vmovdqu\t{%1, %0|%0, %1}";
2799 if (get_attr_mode (insn) == MODE_V4SF)
2800 return "%vmovaps\t{%1, %0|%0, %1}";
2802 return "%vmovdqa\t{%1, %0|%0, %1}";
2808 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2809 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2811 (cond [(eq_attr "alternative" "2,3")
2813 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2815 (const_string "V4SF")
2816 (const_string "TI"))
2817 (eq_attr "alternative" "4")
2819 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2821 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2823 (const_string "V4SF")
2824 (const_string "TI"))]
2825 (const_string "DI")))])
2828 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2829 (match_operand:TI 1 "general_operand" ""))]
2830 "reload_completed && !SSE_REG_P (operands[0])
2831 && !SSE_REG_P (operands[1])"
2833 "ix86_split_long_move (operands); DONE;")
2835 ;; This expands to what emit_move_complex would generate if we didn't
2836 ;; have a movti pattern. Having this avoids problems with reload on
2837 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2838 ;; to have around all the time.
2839 (define_expand "movcdi"
2840 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2841 (match_operand:CDI 1 "general_operand" ""))]
2844 if (push_operand (operands[0], CDImode))
2845 emit_move_complex_push (CDImode, operands[0], operands[1]);
2847 emit_move_complex_parts (operands[0], operands[1]);
2851 (define_expand "movsf"
2852 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2853 (match_operand:SF 1 "general_operand" ""))]
2855 "ix86_expand_move (SFmode, operands); DONE;")
2857 (define_insn "*pushsf"
2858 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2859 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2862 /* Anything else should be already split before reg-stack. */
2863 gcc_assert (which_alternative == 1);
2864 return "push{l}\t%1";
2866 [(set_attr "type" "multi,push,multi")
2867 (set_attr "unit" "i387,*,*")
2868 (set_attr "mode" "SF,SI,SF")])
2870 (define_insn "*pushsf_rex64"
2871 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2872 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2875 /* Anything else should be already split before reg-stack. */
2876 gcc_assert (which_alternative == 1);
2877 return "push{q}\t%q1";
2879 [(set_attr "type" "multi,push,multi")
2880 (set_attr "unit" "i387,*,*")
2881 (set_attr "mode" "SF,DI,SF")])
2884 [(set (match_operand:SF 0 "push_operand" "")
2885 (match_operand:SF 1 "memory_operand" ""))]
2887 && MEM_P (operands[1])
2888 && (operands[2] = find_constant_src (insn))"
2892 ;; %%% Kill this when call knows how to work this out.
2894 [(set (match_operand:SF 0 "push_operand" "")
2895 (match_operand:SF 1 "any_fp_register_operand" ""))]
2897 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2898 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2901 [(set (match_operand:SF 0 "push_operand" "")
2902 (match_operand:SF 1 "any_fp_register_operand" ""))]
2904 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2905 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2907 (define_insn "*movsf_1"
2908 [(set (match_operand:SF 0 "nonimmediate_operand"
2909 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2910 (match_operand:SF 1 "general_operand"
2911 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2912 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2913 && (reload_in_progress || reload_completed
2914 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2915 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2916 && standard_80387_constant_p (operands[1]))
2917 || GET_CODE (operands[1]) != CONST_DOUBLE
2918 || memory_operand (operands[0], SFmode))"
2920 switch (which_alternative)
2924 return output_387_reg_move (insn, operands);
2927 return standard_80387_constant_opcode (operands[1]);
2931 return "mov{l}\t{%1, %0|%0, %1}";
2933 if (get_attr_mode (insn) == MODE_TI)
2934 return "%vpxor\t%0, %d0";
2936 return "%vxorps\t%0, %d0";
2938 if (get_attr_mode (insn) == MODE_V4SF)
2939 return "%vmovaps\t{%1, %0|%0, %1}";
2941 return "%vmovss\t{%1, %d0|%d0, %1}";
2944 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2945 : "vmovss\t{%1, %0|%0, %1}";
2947 return "movss\t{%1, %0|%0, %1}";
2949 return "%vmovss\t{%1, %0|%0, %1}";
2951 case 9: case 10: case 14: case 15:
2952 return "movd\t{%1, %0|%0, %1}";
2954 return "%vmovd\t{%1, %0|%0, %1}";
2957 return "movq\t{%1, %0|%0, %1}";
2963 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2964 (set (attr "prefix")
2965 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2966 (const_string "maybe_vex")
2967 (const_string "orig")))
2969 (cond [(eq_attr "alternative" "3,4,9,10")
2971 (eq_attr "alternative" "5")
2973 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2975 (ne (symbol_ref "TARGET_SSE2")
2977 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2980 (const_string "V4SF"))
2981 /* For architectures resolving dependencies on
2982 whole SSE registers use APS move to break dependency
2983 chains, otherwise use short move to avoid extra work.
2985 Do the same for architectures resolving dependencies on
2986 the parts. While in DF mode it is better to always handle
2987 just register parts, the SF mode is different due to lack
2988 of instructions to load just part of the register. It is
2989 better to maintain the whole registers in single format
2990 to avoid problems on using packed logical operations. */
2991 (eq_attr "alternative" "6")
2993 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2995 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2997 (const_string "V4SF")
2998 (const_string "SF"))
2999 (eq_attr "alternative" "11")
3000 (const_string "DI")]
3001 (const_string "SF")))])
3003 (define_insn "*swapsf"
3004 [(set (match_operand:SF 0 "fp_register_operand" "+f")
3005 (match_operand:SF 1 "fp_register_operand" "+f"))
3008 "reload_completed || TARGET_80387"
3010 if (STACK_TOP_P (operands[0]))
3015 [(set_attr "type" "fxch")
3016 (set_attr "mode" "SF")])
3018 (define_expand "movdf"
3019 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3020 (match_operand:DF 1 "general_operand" ""))]
3022 "ix86_expand_move (DFmode, operands); DONE;")
3024 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3025 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3026 ;; On the average, pushdf using integers can be still shorter. Allow this
3027 ;; pattern for optimize_size too.
3029 (define_insn "*pushdf_nointeger"
3030 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3031 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3032 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3034 /* This insn should be already split before reg-stack. */
3037 [(set_attr "type" "multi")
3038 (set_attr "unit" "i387,*,*,*")
3039 (set_attr "mode" "DF,SI,SI,DF")])
3041 (define_insn "*pushdf_integer"
3042 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3043 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3044 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3046 /* This insn should be already split before reg-stack. */
3049 [(set_attr "type" "multi")
3050 (set_attr "unit" "i387,*,*")
3051 (set_attr "mode" "DF,SI,DF")])
3053 ;; %%% Kill this when call knows how to work this out.
3055 [(set (match_operand:DF 0 "push_operand" "")
3056 (match_operand:DF 1 "any_fp_register_operand" ""))]
3058 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3059 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3063 [(set (match_operand:DF 0 "push_operand" "")
3064 (match_operand:DF 1 "general_operand" ""))]
3067 "ix86_split_long_move (operands); DONE;")
3069 ;; Moving is usually shorter when only FP registers are used. This separate
3070 ;; movdf pattern avoids the use of integer registers for FP operations
3071 ;; when optimizing for size.
3073 (define_insn "*movdf_nointeger"
3074 [(set (match_operand:DF 0 "nonimmediate_operand"
3075 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3076 (match_operand:DF 1 "general_operand"
3077 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3078 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3079 && ((optimize_function_for_size_p (cfun)
3080 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3081 && (reload_in_progress || reload_completed
3082 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3083 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3084 && optimize_function_for_size_p (cfun)
3085 && !memory_operand (operands[0], DFmode)
3086 && standard_80387_constant_p (operands[1]))
3087 || GET_CODE (operands[1]) != CONST_DOUBLE
3088 || ((optimize_function_for_size_p (cfun)
3089 || !TARGET_MEMORY_MISMATCH_STALL
3090 || reload_in_progress || reload_completed)
3091 && memory_operand (operands[0], DFmode)))"
3093 switch (which_alternative)
3097 return output_387_reg_move (insn, operands);
3100 return standard_80387_constant_opcode (operands[1]);
3106 switch (get_attr_mode (insn))
3109 return "%vxorps\t%0, %d0";
3111 return "%vxorpd\t%0, %d0";
3113 return "%vpxor\t%0, %d0";
3120 switch (get_attr_mode (insn))
3123 return "%vmovaps\t{%1, %0|%0, %1}";
3125 return "%vmovapd\t{%1, %0|%0, %1}";
3127 return "%vmovdqa\t{%1, %0|%0, %1}";
3129 return "%vmovq\t{%1, %0|%0, %1}";
3133 if (REG_P (operands[0]) && REG_P (operands[1]))
3134 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3136 return "vmovsd\t{%1, %0|%0, %1}";
3139 return "movsd\t{%1, %0|%0, %1}";
3143 if (REG_P (operands[0]))
3144 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3146 return "vmovlpd\t{%1, %0|%0, %1}";
3149 return "movlpd\t{%1, %0|%0, %1}";
3153 if (REG_P (operands[0]))
3154 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3156 return "vmovlps\t{%1, %0|%0, %1}";
3159 return "movlps\t{%1, %0|%0, %1}";
3168 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3169 (set (attr "prefix")
3170 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3171 (const_string "orig")
3172 (const_string "maybe_vex")))
3173 (set (attr "prefix_data16")
3174 (if_then_else (eq_attr "mode" "V1DF")
3176 (const_string "*")))
3178 (cond [(eq_attr "alternative" "0,1,2")
3180 (eq_attr "alternative" "3,4")
3183 /* For SSE1, we have many fewer alternatives. */
3184 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3185 (cond [(eq_attr "alternative" "5,6")
3186 (const_string "V4SF")
3188 (const_string "V2SF"))
3190 /* xorps is one byte shorter. */
3191 (eq_attr "alternative" "5")
3192 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3194 (const_string "V4SF")
3195 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3199 (const_string "V2DF"))
3201 /* For architectures resolving dependencies on
3202 whole SSE registers use APD move to break dependency
3203 chains, otherwise use short move to avoid extra work.
3205 movaps encodes one byte shorter. */
3206 (eq_attr "alternative" "6")
3208 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3210 (const_string "V4SF")
3211 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3213 (const_string "V2DF")
3215 (const_string "DF"))
3216 /* For architectures resolving dependencies on register
3217 parts we may avoid extra work to zero out upper part
3219 (eq_attr "alternative" "7")
3221 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3223 (const_string "V1DF")
3224 (const_string "DF"))
3226 (const_string "DF")))])
3228 (define_insn "*movdf_integer_rex64"
3229 [(set (match_operand:DF 0 "nonimmediate_operand"
3230 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3231 (match_operand:DF 1 "general_operand"
3232 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3233 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3234 && (reload_in_progress || reload_completed
3235 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3236 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3237 && optimize_function_for_size_p (cfun)
3238 && standard_80387_constant_p (operands[1]))
3239 || GET_CODE (operands[1]) != CONST_DOUBLE
3240 || memory_operand (operands[0], DFmode))"
3242 switch (which_alternative)
3246 return output_387_reg_move (insn, operands);
3249 return standard_80387_constant_opcode (operands[1]);
3256 switch (get_attr_mode (insn))
3259 return "%vxorps\t%0, %d0";
3261 return "%vxorpd\t%0, %d0";
3263 return "%vpxor\t%0, %d0";
3270 switch (get_attr_mode (insn))
3273 return "%vmovaps\t{%1, %0|%0, %1}";
3275 return "%vmovapd\t{%1, %0|%0, %1}";
3277 return "%vmovdqa\t{%1, %0|%0, %1}";
3279 return "%vmovq\t{%1, %0|%0, %1}";
3283 if (REG_P (operands[0]) && REG_P (operands[1]))
3284 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3286 return "vmovsd\t{%1, %0|%0, %1}";
3289 return "movsd\t{%1, %0|%0, %1}";
3291 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3293 return "%vmovlps\t{%1, %d0|%d0, %1}";
3300 return "%vmovd\t{%1, %0|%0, %1}";
3306 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3307 (set (attr "prefix")
3308 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3309 (const_string "orig")
3310 (const_string "maybe_vex")))
3311 (set (attr "prefix_data16")
3312 (if_then_else (eq_attr "mode" "V1DF")
3314 (const_string "*")))
3316 (cond [(eq_attr "alternative" "0,1,2")
3318 (eq_attr "alternative" "3,4,9,10")
3321 /* For SSE1, we have many fewer alternatives. */
3322 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3323 (cond [(eq_attr "alternative" "5,6")
3324 (const_string "V4SF")
3326 (const_string "V2SF"))
3328 /* xorps is one byte shorter. */
3329 (eq_attr "alternative" "5")
3330 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3332 (const_string "V4SF")
3333 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3337 (const_string "V2DF"))
3339 /* For architectures resolving dependencies on
3340 whole SSE registers use APD move to break dependency
3341 chains, otherwise use short move to avoid extra work.
3343 movaps encodes one byte shorter. */
3344 (eq_attr "alternative" "6")
3346 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3348 (const_string "V4SF")
3349 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3351 (const_string "V2DF")
3353 (const_string "DF"))
3354 /* For architectures resolving dependencies on register
3355 parts we may avoid extra work to zero out upper part
3357 (eq_attr "alternative" "7")
3359 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3361 (const_string "V1DF")
3362 (const_string "DF"))
3364 (const_string "DF")))])
3366 (define_insn "*movdf_integer"
3367 [(set (match_operand:DF 0 "nonimmediate_operand"
3368 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3369 (match_operand:DF 1 "general_operand"
3370 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3371 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3372 && optimize_function_for_speed_p (cfun)
3373 && TARGET_INTEGER_DFMODE_MOVES
3374 && (reload_in_progress || reload_completed
3375 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3376 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3377 && optimize_function_for_size_p (cfun)
3378 && standard_80387_constant_p (operands[1]))
3379 || GET_CODE (operands[1]) != CONST_DOUBLE
3380 || memory_operand (operands[0], DFmode))"
3382 switch (which_alternative)
3386 return output_387_reg_move (insn, operands);
3389 return standard_80387_constant_opcode (operands[1]);
3396 switch (get_attr_mode (insn))
3399 return "xorps\t%0, %0";
3401 return "xorpd\t%0, %0";
3403 return "pxor\t%0, %0";
3410 switch (get_attr_mode (insn))
3413 return "movaps\t{%1, %0|%0, %1}";
3415 return "movapd\t{%1, %0|%0, %1}";
3417 return "movdqa\t{%1, %0|%0, %1}";
3419 return "movq\t{%1, %0|%0, %1}";
3421 return "movsd\t{%1, %0|%0, %1}";
3423 return "movlpd\t{%1, %0|%0, %1}";
3425 return "movlps\t{%1, %0|%0, %1}";
3434 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3435 (set (attr "prefix_data16")
3436 (if_then_else (eq_attr "mode" "V1DF")
3438 (const_string "*")))
3440 (cond [(eq_attr "alternative" "0,1,2")
3442 (eq_attr "alternative" "3,4")
3445 /* For SSE1, we have many fewer alternatives. */
3446 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3447 (cond [(eq_attr "alternative" "5,6")
3448 (const_string "V4SF")
3450 (const_string "V2SF"))
3452 /* xorps is one byte shorter. */
3453 (eq_attr "alternative" "5")
3454 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3456 (const_string "V4SF")
3457 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3461 (const_string "V2DF"))
3463 /* For architectures resolving dependencies on
3464 whole SSE registers use APD move to break dependency
3465 chains, otherwise use short move to avoid extra work.
3467 movaps encodes one byte shorter. */
3468 (eq_attr "alternative" "6")
3470 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3472 (const_string "V4SF")
3473 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3475 (const_string "V2DF")
3477 (const_string "DF"))
3478 /* For architectures resolving dependencies on register
3479 parts we may avoid extra work to zero out upper part
3481 (eq_attr "alternative" "7")
3483 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3485 (const_string "V1DF")
3486 (const_string "DF"))
3488 (const_string "DF")))])
3491 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3492 (match_operand:DF 1 "general_operand" ""))]
3494 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3495 && ! (ANY_FP_REG_P (operands[0]) ||
3496 (GET_CODE (operands[0]) == SUBREG
3497 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3498 && ! (ANY_FP_REG_P (operands[1]) ||
3499 (GET_CODE (operands[1]) == SUBREG
3500 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3502 "ix86_split_long_move (operands); DONE;")
3504 (define_insn "*swapdf"
3505 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3506 (match_operand:DF 1 "fp_register_operand" "+f"))
3509 "reload_completed || TARGET_80387"
3511 if (STACK_TOP_P (operands[0]))
3516 [(set_attr "type" "fxch")
3517 (set_attr "mode" "DF")])
3519 (define_expand "movxf"
3520 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3521 (match_operand:XF 1 "general_operand" ""))]
3523 "ix86_expand_move (XFmode, operands); DONE;")
3525 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3526 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3527 ;; Pushing using integer instructions is longer except for constants
3528 ;; and direct memory references.
3529 ;; (assuming that any given constant is pushed only once, but this ought to be
3530 ;; handled elsewhere).
3532 (define_insn "*pushxf_nointeger"
3533 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3534 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3535 "optimize_function_for_size_p (cfun)"
3537 /* This insn should be already split before reg-stack. */
3540 [(set_attr "type" "multi")
3541 (set_attr "unit" "i387,*,*")
3542 (set_attr "mode" "XF,SI,SI")])
3544 (define_insn "*pushxf_integer"
3545 [(set (match_operand:XF 0 "push_operand" "=<,<")
3546 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3547 "optimize_function_for_speed_p (cfun)"
3549 /* This insn should be already split before reg-stack. */
3552 [(set_attr "type" "multi")
3553 (set_attr "unit" "i387,*")
3554 (set_attr "mode" "XF,SI")])
3557 [(set (match_operand 0 "push_operand" "")
3558 (match_operand 1 "general_operand" ""))]
3560 && (GET_MODE (operands[0]) == XFmode
3561 || GET_MODE (operands[0]) == DFmode)
3562 && !ANY_FP_REG_P (operands[1])"
3564 "ix86_split_long_move (operands); DONE;")
3567 [(set (match_operand:XF 0 "push_operand" "")
3568 (match_operand:XF 1 "any_fp_register_operand" ""))]
3570 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3571 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3572 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3574 ;; Do not use integer registers when optimizing for size
3575 (define_insn "*movxf_nointeger"
3576 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3577 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3578 "optimize_function_for_size_p (cfun)
3579 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3580 && (reload_in_progress || reload_completed
3581 || standard_80387_constant_p (operands[1])
3582 || GET_CODE (operands[1]) != CONST_DOUBLE
3583 || memory_operand (operands[0], XFmode))"
3585 switch (which_alternative)
3589 return output_387_reg_move (insn, operands);
3592 return standard_80387_constant_opcode (operands[1]);
3600 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3601 (set_attr "mode" "XF,XF,XF,SI,SI")])
3603 (define_insn "*movxf_integer"
3604 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3605 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3606 "optimize_function_for_speed_p (cfun)
3607 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3608 && (reload_in_progress || reload_completed
3609 || GET_CODE (operands[1]) != CONST_DOUBLE
3610 || memory_operand (operands[0], XFmode))"
3612 switch (which_alternative)
3616 return output_387_reg_move (insn, operands);
3619 return standard_80387_constant_opcode (operands[1]);
3628 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3629 (set_attr "mode" "XF,XF,XF,SI,SI")])
3631 (define_expand "movtf"
3632 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3633 (match_operand:TF 1 "nonimmediate_operand" ""))]
3636 ix86_expand_move (TFmode, operands);
3640 (define_insn "*movtf_internal"
3641 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3642 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3644 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3646 switch (which_alternative)
3650 if (get_attr_mode (insn) == MODE_V4SF)
3651 return "%vmovaps\t{%1, %0|%0, %1}";
3653 return "%vmovdqa\t{%1, %0|%0, %1}";
3655 if (get_attr_mode (insn) == MODE_V4SF)
3656 return "%vxorps\t%0, %d0";
3658 return "%vpxor\t%0, %d0";
3666 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3667 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3669 (cond [(eq_attr "alternative" "0,2")
3671 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3673 (const_string "V4SF")
3674 (const_string "TI"))
3675 (eq_attr "alternative" "1")
3677 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3679 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3681 (const_string "V4SF")
3682 (const_string "TI"))]
3683 (const_string "DI")))])
3685 (define_insn "*pushtf_sse"
3686 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3687 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3690 /* This insn should be already split before reg-stack. */
3693 [(set_attr "type" "multi")
3694 (set_attr "unit" "sse,*,*")
3695 (set_attr "mode" "TF,SI,SI")])
3698 [(set (match_operand:TF 0 "push_operand" "")
3699 (match_operand:TF 1 "general_operand" ""))]
3700 "TARGET_SSE2 && reload_completed
3701 && !SSE_REG_P (operands[1])"
3703 "ix86_split_long_move (operands); DONE;")
3706 [(set (match_operand:TF 0 "push_operand" "")
3707 (match_operand:TF 1 "any_fp_register_operand" ""))]
3709 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3710 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3714 [(set (match_operand 0 "nonimmediate_operand" "")
3715 (match_operand 1 "general_operand" ""))]
3717 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3718 && GET_MODE (operands[0]) == XFmode
3719 && ! (ANY_FP_REG_P (operands[0]) ||
3720 (GET_CODE (operands[0]) == SUBREG
3721 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3722 && ! (ANY_FP_REG_P (operands[1]) ||
3723 (GET_CODE (operands[1]) == SUBREG
3724 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3726 "ix86_split_long_move (operands); DONE;")
3729 [(set (match_operand 0 "register_operand" "")
3730 (match_operand 1 "memory_operand" ""))]
3732 && MEM_P (operands[1])
3733 && (GET_MODE (operands[0]) == TFmode
3734 || GET_MODE (operands[0]) == XFmode
3735 || GET_MODE (operands[0]) == SFmode
3736 || GET_MODE (operands[0]) == DFmode)
3737 && (operands[2] = find_constant_src (insn))"
3738 [(set (match_dup 0) (match_dup 2))]
3740 rtx c = operands[2];
3741 rtx r = operands[0];
3743 if (GET_CODE (r) == SUBREG)
3748 if (!standard_sse_constant_p (c))
3751 else if (FP_REG_P (r))
3753 if (!standard_80387_constant_p (c))
3756 else if (MMX_REG_P (r))
3761 [(set (match_operand 0 "register_operand" "")
3762 (float_extend (match_operand 1 "memory_operand" "")))]
3764 && MEM_P (operands[1])
3765 && (GET_MODE (operands[0]) == TFmode
3766 || GET_MODE (operands[0]) == XFmode
3767 || GET_MODE (operands[0]) == SFmode
3768 || GET_MODE (operands[0]) == DFmode)
3769 && (operands[2] = find_constant_src (insn))"
3770 [(set (match_dup 0) (match_dup 2))]
3772 rtx c = operands[2];
3773 rtx r = operands[0];
3775 if (GET_CODE (r) == SUBREG)
3780 if (!standard_sse_constant_p (c))
3783 else if (FP_REG_P (r))
3785 if (!standard_80387_constant_p (c))
3788 else if (MMX_REG_P (r))
3792 (define_insn "swapxf"
3793 [(set (match_operand:XF 0 "register_operand" "+f")
3794 (match_operand:XF 1 "register_operand" "+f"))
3799 if (STACK_TOP_P (operands[0]))
3804 [(set_attr "type" "fxch")
3805 (set_attr "mode" "XF")])
3807 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3809 [(set (match_operand:X87MODEF 0 "register_operand" "")
3810 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3811 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3812 && (standard_80387_constant_p (operands[1]) == 8
3813 || standard_80387_constant_p (operands[1]) == 9)"
3814 [(set (match_dup 0)(match_dup 1))
3816 (neg:X87MODEF (match_dup 0)))]
3820 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3821 if (real_isnegzero (&r))
3822 operands[1] = CONST0_RTX (<MODE>mode);
3824 operands[1] = CONST1_RTX (<MODE>mode);
3828 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3829 (match_operand:TF 1 "general_operand" ""))]
3831 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3833 "ix86_split_long_move (operands); DONE;")
3835 ;; Zero extension instructions
3837 (define_expand "zero_extendhisi2"
3838 [(set (match_operand:SI 0 "register_operand" "")
3839 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3842 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3844 operands[1] = force_reg (HImode, operands[1]);
3845 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3850 (define_insn "zero_extendhisi2_and"
3851 [(set (match_operand:SI 0 "register_operand" "=r")
3852 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3853 (clobber (reg:CC FLAGS_REG))]
3854 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3856 [(set_attr "type" "alu1")
3857 (set_attr "mode" "SI")])
3860 [(set (match_operand:SI 0 "register_operand" "")
3861 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3862 (clobber (reg:CC FLAGS_REG))]
3863 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3864 && optimize_function_for_speed_p (cfun)"
3865 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3866 (clobber (reg:CC FLAGS_REG))])]
3869 (define_insn "*zero_extendhisi2_movzwl"
3870 [(set (match_operand:SI 0 "register_operand" "=r")
3871 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3872 "!TARGET_ZERO_EXTEND_WITH_AND
3873 || optimize_function_for_size_p (cfun)"
3874 "movz{wl|x}\t{%1, %0|%0, %1}"
3875 [(set_attr "type" "imovx")
3876 (set_attr "mode" "SI")])
3878 (define_expand "zero_extendqihi2"
3880 [(set (match_operand:HI 0 "register_operand" "")
3881 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3882 (clobber (reg:CC FLAGS_REG))])]
3886 (define_insn "*zero_extendqihi2_and"
3887 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3888 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3889 (clobber (reg:CC FLAGS_REG))]
3890 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3892 [(set_attr "type" "alu1")
3893 (set_attr "mode" "HI")])
3895 (define_insn "*zero_extendqihi2_movzbw_and"
3896 [(set (match_operand:HI 0 "register_operand" "=r,r")
3897 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3898 (clobber (reg:CC FLAGS_REG))]
3899 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3901 [(set_attr "type" "imovx,alu1")
3902 (set_attr "mode" "HI")])
3904 ; zero extend to SImode here to avoid partial register stalls
3905 (define_insn "*zero_extendqihi2_movzbl"
3906 [(set (match_operand:HI 0 "register_operand" "=r")
3907 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3908 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3909 && reload_completed"
3910 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3911 [(set_attr "type" "imovx")
3912 (set_attr "mode" "SI")])
3914 ;; For the movzbw case strip only the clobber
3916 [(set (match_operand:HI 0 "register_operand" "")
3917 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3918 (clobber (reg:CC FLAGS_REG))]
3920 && (!TARGET_ZERO_EXTEND_WITH_AND
3921 || optimize_function_for_size_p (cfun))
3922 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3923 [(set (match_operand:HI 0 "register_operand" "")
3924 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3926 ;; When source and destination does not overlap, clear destination
3927 ;; first and then do the movb
3929 [(set (match_operand:HI 0 "register_operand" "")
3930 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3931 (clobber (reg:CC FLAGS_REG))]
3933 && ANY_QI_REG_P (operands[0])
3934 && (TARGET_ZERO_EXTEND_WITH_AND
3935 && optimize_function_for_speed_p (cfun))
3936 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3937 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3939 operands[2] = gen_lowpart (QImode, operands[0]);
3940 ix86_expand_clear (operands[0]);
3943 ;; Rest is handled by single and.
3945 [(set (match_operand:HI 0 "register_operand" "")
3946 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3947 (clobber (reg:CC FLAGS_REG))]
3949 && true_regnum (operands[0]) == true_regnum (operands[1])"
3950 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3951 (clobber (reg:CC FLAGS_REG))])]
3954 (define_expand "zero_extendqisi2"
3956 [(set (match_operand:SI 0 "register_operand" "")
3957 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3958 (clobber (reg:CC FLAGS_REG))])]
3962 (define_insn "*zero_extendqisi2_and"
3963 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3964 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3965 (clobber (reg:CC FLAGS_REG))]
3966 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3968 [(set_attr "type" "alu1")
3969 (set_attr "mode" "SI")])
3971 (define_insn "*zero_extendqisi2_movzbl_and"
3972 [(set (match_operand:SI 0 "register_operand" "=r,r")
3973 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3974 (clobber (reg:CC FLAGS_REG))]
3975 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3977 [(set_attr "type" "imovx,alu1")
3978 (set_attr "mode" "SI")])
3980 (define_insn "*zero_extendqisi2_movzbl"
3981 [(set (match_operand:SI 0 "register_operand" "=r")
3982 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3983 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3984 && reload_completed"
3985 "movz{bl|x}\t{%1, %0|%0, %1}"
3986 [(set_attr "type" "imovx")
3987 (set_attr "mode" "SI")])
3989 ;; For the movzbl case strip only the clobber
3991 [(set (match_operand:SI 0 "register_operand" "")
3992 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3993 (clobber (reg:CC FLAGS_REG))]
3995 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3996 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3998 (zero_extend:SI (match_dup 1)))])
4000 ;; When source and destination does not overlap, clear destination
4001 ;; first and then do the movb
4003 [(set (match_operand:SI 0 "register_operand" "")
4004 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4005 (clobber (reg:CC FLAGS_REG))]
4007 && ANY_QI_REG_P (operands[0])
4008 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4009 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4010 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4011 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
4013 operands[2] = gen_lowpart (QImode, operands[0]);
4014 ix86_expand_clear (operands[0]);
4017 ;; Rest is handled by single and.
4019 [(set (match_operand:SI 0 "register_operand" "")
4020 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4021 (clobber (reg:CC FLAGS_REG))]
4023 && true_regnum (operands[0]) == true_regnum (operands[1])"
4024 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4025 (clobber (reg:CC FLAGS_REG))])]
4028 ;; %%% Kill me once multi-word ops are sane.
4029 (define_expand "zero_extendsidi2"
4030 [(set (match_operand:DI 0 "register_operand" "")
4031 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4036 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4041 (define_insn "zero_extendsidi2_32"
4042 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4044 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
4045 (clobber (reg:CC FLAGS_REG))]
4051 movd\t{%1, %0|%0, %1}
4052 movd\t{%1, %0|%0, %1}
4053 %vmovd\t{%1, %0|%0, %1}
4054 %vmovd\t{%1, %0|%0, %1}"
4055 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4056 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4057 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4059 (define_insn "zero_extendsidi2_rex64"
4060 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4062 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4065 mov\t{%k1, %k0|%k0, %k1}
4067 movd\t{%1, %0|%0, %1}
4068 movd\t{%1, %0|%0, %1}
4069 %vmovd\t{%1, %0|%0, %1}
4070 %vmovd\t{%1, %0|%0, %1}"
4071 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4072 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4073 (set_attr "prefix_0f" "0,*,*,*,*,*")
4074 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4077 [(set (match_operand:DI 0 "memory_operand" "")
4078 (zero_extend:DI (match_dup 0)))]
4080 [(set (match_dup 4) (const_int 0))]
4081 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4084 [(set (match_operand:DI 0 "register_operand" "")
4085 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4086 (clobber (reg:CC FLAGS_REG))]
4087 "!TARGET_64BIT && reload_completed
4088 && true_regnum (operands[0]) == true_regnum (operands[1])"
4089 [(set (match_dup 4) (const_int 0))]
4090 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4093 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4094 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4095 (clobber (reg:CC FLAGS_REG))]
4096 "!TARGET_64BIT && reload_completed
4097 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4098 [(set (match_dup 3) (match_dup 1))
4099 (set (match_dup 4) (const_int 0))]
4100 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4102 (define_insn "zero_extendhidi2"
4103 [(set (match_operand:DI 0 "register_operand" "=r")
4104 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4106 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4107 [(set_attr "type" "imovx")
4108 (set_attr "mode" "SI")])
4110 (define_insn "zero_extendqidi2"
4111 [(set (match_operand:DI 0 "register_operand" "=r")
4112 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4114 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4115 [(set_attr "type" "imovx")
4116 (set_attr "mode" "SI")])
4118 ;; Sign extension instructions
4120 (define_expand "extendsidi2"
4121 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4122 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4123 (clobber (reg:CC FLAGS_REG))
4124 (clobber (match_scratch:SI 2 ""))])]
4129 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4134 (define_insn "*extendsidi2_1"
4135 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4136 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4137 (clobber (reg:CC FLAGS_REG))
4138 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4142 (define_insn "extendsidi2_rex64"
4143 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4144 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4148 movs{lq|x}\t{%1, %0|%0, %1}"
4149 [(set_attr "type" "imovx")
4150 (set_attr "mode" "DI")
4151 (set_attr "prefix_0f" "0")
4152 (set_attr "modrm" "0,1")])
4154 (define_insn "extendhidi2"
4155 [(set (match_operand:DI 0 "register_operand" "=r")
4156 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4158 "movs{wq|x}\t{%1, %0|%0, %1}"
4159 [(set_attr "type" "imovx")
4160 (set_attr "mode" "DI")])
4162 (define_insn "extendqidi2"
4163 [(set (match_operand:DI 0 "register_operand" "=r")
4164 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4166 "movs{bq|x}\t{%1, %0|%0, %1}"
4167 [(set_attr "type" "imovx")
4168 (set_attr "mode" "DI")])
4170 ;; Extend to memory case when source register does die.
4172 [(set (match_operand:DI 0 "memory_operand" "")
4173 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4174 (clobber (reg:CC FLAGS_REG))
4175 (clobber (match_operand:SI 2 "register_operand" ""))]
4177 && dead_or_set_p (insn, operands[1])
4178 && !reg_mentioned_p (operands[1], operands[0]))"
4179 [(set (match_dup 3) (match_dup 1))
4180 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4181 (clobber (reg:CC FLAGS_REG))])
4182 (set (match_dup 4) (match_dup 1))]
4183 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4185 ;; Extend to memory case when source register does not die.
4187 [(set (match_operand:DI 0 "memory_operand" "")
4188 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4189 (clobber (reg:CC FLAGS_REG))
4190 (clobber (match_operand:SI 2 "register_operand" ""))]
4194 split_di (&operands[0], 1, &operands[3], &operands[4]);
4196 emit_move_insn (operands[3], operands[1]);
4198 /* Generate a cltd if possible and doing so it profitable. */
4199 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4200 && true_regnum (operands[1]) == AX_REG
4201 && true_regnum (operands[2]) == DX_REG)
4203 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4207 emit_move_insn (operands[2], operands[1]);
4208 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4210 emit_move_insn (operands[4], operands[2]);
4214 ;; Extend to register case. Optimize case where source and destination
4215 ;; registers match and cases where we can use cltd.
4217 [(set (match_operand:DI 0 "register_operand" "")
4218 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4219 (clobber (reg:CC FLAGS_REG))
4220 (clobber (match_scratch:SI 2 ""))]
4224 split_di (&operands[0], 1, &operands[3], &operands[4]);
4226 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4227 emit_move_insn (operands[3], operands[1]);
4229 /* Generate a cltd if possible and doing so it profitable. */
4230 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4231 && true_regnum (operands[3]) == AX_REG
4232 && true_regnum (operands[4]) == DX_REG)
4234 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4238 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4239 emit_move_insn (operands[4], operands[1]);
4241 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4245 (define_insn "extendhisi2"
4246 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4247 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4250 switch (get_attr_prefix_0f (insn))
4253 return "{cwtl|cwde}";
4255 return "movs{wl|x}\t{%1, %0|%0, %1}";
4258 [(set_attr "type" "imovx")
4259 (set_attr "mode" "SI")
4260 (set (attr "prefix_0f")
4261 ;; movsx is short decodable while cwtl is vector decoded.
4262 (if_then_else (and (eq_attr "cpu" "!k6")
4263 (eq_attr "alternative" "0"))
4265 (const_string "1")))
4267 (if_then_else (eq_attr "prefix_0f" "0")
4269 (const_string "1")))])
4271 (define_insn "*extendhisi2_zext"
4272 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4274 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4277 switch (get_attr_prefix_0f (insn))
4280 return "{cwtl|cwde}";
4282 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4285 [(set_attr "type" "imovx")
4286 (set_attr "mode" "SI")
4287 (set (attr "prefix_0f")
4288 ;; movsx is short decodable while cwtl is vector decoded.
4289 (if_then_else (and (eq_attr "cpu" "!k6")
4290 (eq_attr "alternative" "0"))
4292 (const_string "1")))
4294 (if_then_else (eq_attr "prefix_0f" "0")
4296 (const_string "1")))])
4298 (define_insn "extendqihi2"
4299 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4300 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4303 switch (get_attr_prefix_0f (insn))
4306 return "{cbtw|cbw}";
4308 return "movs{bw|x}\t{%1, %0|%0, %1}";
4311 [(set_attr "type" "imovx")
4312 (set_attr "mode" "HI")
4313 (set (attr "prefix_0f")
4314 ;; movsx is short decodable while cwtl is vector decoded.
4315 (if_then_else (and (eq_attr "cpu" "!k6")
4316 (eq_attr "alternative" "0"))
4318 (const_string "1")))
4320 (if_then_else (eq_attr "prefix_0f" "0")
4322 (const_string "1")))])
4324 (define_insn "extendqisi2"
4325 [(set (match_operand:SI 0 "register_operand" "=r")
4326 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4328 "movs{bl|x}\t{%1, %0|%0, %1}"
4329 [(set_attr "type" "imovx")
4330 (set_attr "mode" "SI")])
4332 (define_insn "*extendqisi2_zext"
4333 [(set (match_operand:DI 0 "register_operand" "=r")
4335 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4337 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4338 [(set_attr "type" "imovx")
4339 (set_attr "mode" "SI")])
4341 ;; Conversions between float and double.
4343 ;; These are all no-ops in the model used for the 80387. So just
4346 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4347 (define_insn "*dummy_extendsfdf2"
4348 [(set (match_operand:DF 0 "push_operand" "=<")
4349 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4354 [(set (match_operand:DF 0 "push_operand" "")
4355 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4357 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4358 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4360 (define_insn "*dummy_extendsfxf2"
4361 [(set (match_operand:XF 0 "push_operand" "=<")
4362 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4367 [(set (match_operand:XF 0 "push_operand" "")
4368 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4370 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4371 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4372 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4375 [(set (match_operand:XF 0 "push_operand" "")
4376 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4378 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4379 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4380 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4382 (define_expand "extendsfdf2"
4383 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4384 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4385 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4387 /* ??? Needed for compress_float_constant since all fp constants
4388 are LEGITIMATE_CONSTANT_P. */
4389 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4391 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4392 && standard_80387_constant_p (operands[1]) > 0)
4394 operands[1] = simplify_const_unary_operation
4395 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4396 emit_move_insn_1 (operands[0], operands[1]);
4399 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4403 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4405 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4407 We do the conversion post reload to avoid producing of 128bit spills
4408 that might lead to ICE on 32bit target. The sequence unlikely combine
4411 [(set (match_operand:DF 0 "register_operand" "")
4413 (match_operand:SF 1 "nonimmediate_operand" "")))]
4414 "TARGET_USE_VECTOR_FP_CONVERTS
4415 && optimize_insn_for_speed_p ()
4416 && reload_completed && SSE_REG_P (operands[0])"
4421 (parallel [(const_int 0) (const_int 1)]))))]
4423 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4424 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4425 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4426 Try to avoid move when unpacking can be done in source. */
4427 if (REG_P (operands[1]))
4429 /* If it is unsafe to overwrite upper half of source, we need
4430 to move to destination and unpack there. */
4431 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4432 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4433 && true_regnum (operands[0]) != true_regnum (operands[1]))
4435 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4436 emit_move_insn (tmp, operands[1]);
4439 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4440 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4444 emit_insn (gen_vec_setv4sf_0 (operands[3],
4445 CONST0_RTX (V4SFmode), operands[1]));
4448 (define_insn "*extendsfdf2_mixed"
4449 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4451 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4452 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4454 switch (which_alternative)
4458 return output_387_reg_move (insn, operands);
4461 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4467 [(set_attr "type" "fmov,fmov,ssecvt")
4468 (set_attr "prefix" "orig,orig,maybe_vex")
4469 (set_attr "mode" "SF,XF,DF")])
4471 (define_insn "*extendsfdf2_sse"
4472 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4473 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4474 "TARGET_SSE2 && TARGET_SSE_MATH"
4475 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4476 [(set_attr "type" "ssecvt")
4477 (set_attr "prefix" "maybe_vex")
4478 (set_attr "mode" "DF")])
4480 (define_insn "*extendsfdf2_i387"
4481 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4482 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4484 "* return output_387_reg_move (insn, operands);"
4485 [(set_attr "type" "fmov")
4486 (set_attr "mode" "SF,XF")])
4488 (define_expand "extend<mode>xf2"
4489 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4490 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4493 /* ??? Needed for compress_float_constant since all fp constants
4494 are LEGITIMATE_CONSTANT_P. */
4495 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4497 if (standard_80387_constant_p (operands[1]) > 0)
4499 operands[1] = simplify_const_unary_operation
4500 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4501 emit_move_insn_1 (operands[0], operands[1]);
4504 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4508 (define_insn "*extend<mode>xf2_i387"
4509 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4511 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4513 "* return output_387_reg_move (insn, operands);"
4514 [(set_attr "type" "fmov")
4515 (set_attr "mode" "<MODE>,XF")])
4517 ;; %%% This seems bad bad news.
4518 ;; This cannot output into an f-reg because there is no way to be sure
4519 ;; of truncating in that case. Otherwise this is just like a simple move
4520 ;; insn. So we pretend we can output to a reg in order to get better
4521 ;; register preferencing, but we really use a stack slot.
4523 ;; Conversion from DFmode to SFmode.
4525 (define_expand "truncdfsf2"
4526 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4528 (match_operand:DF 1 "nonimmediate_operand" "")))]
4529 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4531 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4533 else if (flag_unsafe_math_optimizations)
4537 enum ix86_stack_slot slot = (virtuals_instantiated
4540 rtx temp = assign_386_stack_local (SFmode, slot);
4541 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4546 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4548 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4550 We do the conversion post reload to avoid producing of 128bit spills
4551 that might lead to ICE on 32bit target. The sequence unlikely combine
4554 [(set (match_operand:SF 0 "register_operand" "")
4556 (match_operand:DF 1 "nonimmediate_operand" "")))]
4557 "TARGET_USE_VECTOR_FP_CONVERTS
4558 && optimize_insn_for_speed_p ()
4559 && reload_completed && SSE_REG_P (operands[0])"
4562 (float_truncate:V2SF
4566 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4567 operands[3] = CONST0_RTX (V2SFmode);
4568 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4569 /* Use movsd for loading from memory, unpcklpd for registers.
4570 Try to avoid move when unpacking can be done in source, or SSE3
4571 movddup is available. */
4572 if (REG_P (operands[1]))
4575 && true_regnum (operands[0]) != true_regnum (operands[1])
4576 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4577 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4579 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4580 emit_move_insn (tmp, operands[1]);
4583 else if (!TARGET_SSE3)
4584 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4585 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4588 emit_insn (gen_sse2_loadlpd (operands[4],
4589 CONST0_RTX (V2DFmode), operands[1]));
4592 (define_expand "truncdfsf2_with_temp"
4593 [(parallel [(set (match_operand:SF 0 "" "")
4594 (float_truncate:SF (match_operand:DF 1 "" "")))
4595 (clobber (match_operand:SF 2 "" ""))])]
4598 (define_insn "*truncdfsf_fast_mixed"
4599 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4601 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4602 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4604 switch (which_alternative)
4607 return output_387_reg_move (insn, operands);
4609 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4614 [(set_attr "type" "fmov,ssecvt")
4615 (set_attr "prefix" "orig,maybe_vex")
4616 (set_attr "mode" "SF")])
4618 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4619 ;; because nothing we do here is unsafe.
4620 (define_insn "*truncdfsf_fast_sse"
4621 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4623 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4624 "TARGET_SSE2 && TARGET_SSE_MATH"
4625 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4626 [(set_attr "type" "ssecvt")
4627 (set_attr "prefix" "maybe_vex")
4628 (set_attr "mode" "SF")])
4630 (define_insn "*truncdfsf_fast_i387"
4631 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4633 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4634 "TARGET_80387 && flag_unsafe_math_optimizations"
4635 "* return output_387_reg_move (insn, operands);"
4636 [(set_attr "type" "fmov")
4637 (set_attr "mode" "SF")])
4639 (define_insn "*truncdfsf_mixed"
4640 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4642 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4643 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4644 "TARGET_MIX_SSE_I387"
4646 switch (which_alternative)
4649 return output_387_reg_move (insn, operands);
4651 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4657 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4658 (set_attr "unit" "*,*,i387,i387,i387")
4659 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4660 (set_attr "mode" "SF")])
4662 (define_insn "*truncdfsf_i387"
4663 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4665 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4666 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4669 switch (which_alternative)
4672 return output_387_reg_move (insn, operands);
4678 [(set_attr "type" "fmov,multi,multi,multi")
4679 (set_attr "unit" "*,i387,i387,i387")
4680 (set_attr "mode" "SF")])
4682 (define_insn "*truncdfsf2_i387_1"
4683 [(set (match_operand:SF 0 "memory_operand" "=m")
4685 (match_operand:DF 1 "register_operand" "f")))]
4687 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4688 && !TARGET_MIX_SSE_I387"
4689 "* return output_387_reg_move (insn, operands);"
4690 [(set_attr "type" "fmov")
4691 (set_attr "mode" "SF")])
4694 [(set (match_operand:SF 0 "register_operand" "")
4696 (match_operand:DF 1 "fp_register_operand" "")))
4697 (clobber (match_operand 2 "" ""))]
4699 [(set (match_dup 2) (match_dup 1))
4700 (set (match_dup 0) (match_dup 2))]
4702 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4705 ;; Conversion from XFmode to {SF,DF}mode
4707 (define_expand "truncxf<mode>2"
4708 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4709 (float_truncate:MODEF
4710 (match_operand:XF 1 "register_operand" "")))
4711 (clobber (match_dup 2))])]
4714 if (flag_unsafe_math_optimizations)
4716 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4717 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4718 if (reg != operands[0])
4719 emit_move_insn (operands[0], reg);
4724 enum ix86_stack_slot slot = (virtuals_instantiated
4727 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4731 (define_insn "*truncxfsf2_mixed"
4732 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4734 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4735 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4738 gcc_assert (!which_alternative);
4739 return output_387_reg_move (insn, operands);
4741 [(set_attr "type" "fmov,multi,multi,multi")
4742 (set_attr "unit" "*,i387,i387,i387")
4743 (set_attr "mode" "SF")])
4745 (define_insn "*truncxfdf2_mixed"
4746 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4748 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4749 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4752 gcc_assert (!which_alternative);
4753 return output_387_reg_move (insn, operands);
4755 [(set_attr "type" "fmov,multi,multi,multi")
4756 (set_attr "unit" "*,i387,i387,i387")
4757 (set_attr "mode" "DF")])
4759 (define_insn "truncxf<mode>2_i387_noop"
4760 [(set (match_operand:MODEF 0 "register_operand" "=f")
4761 (float_truncate:MODEF
4762 (match_operand:XF 1 "register_operand" "f")))]
4763 "TARGET_80387 && flag_unsafe_math_optimizations"
4764 "* return output_387_reg_move (insn, operands);"
4765 [(set_attr "type" "fmov")
4766 (set_attr "mode" "<MODE>")])
4768 (define_insn "*truncxf<mode>2_i387"
4769 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4770 (float_truncate:MODEF
4771 (match_operand:XF 1 "register_operand" "f")))]
4773 "* return output_387_reg_move (insn, operands);"
4774 [(set_attr "type" "fmov")
4775 (set_attr "mode" "<MODE>")])
4778 [(set (match_operand:MODEF 0 "register_operand" "")
4779 (float_truncate:MODEF
4780 (match_operand:XF 1 "register_operand" "")))
4781 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4782 "TARGET_80387 && reload_completed"
4783 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4784 (set (match_dup 0) (match_dup 2))]
4788 [(set (match_operand:MODEF 0 "memory_operand" "")
4789 (float_truncate:MODEF
4790 (match_operand:XF 1 "register_operand" "")))
4791 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4793 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4796 ;; Signed conversion to DImode.
4798 (define_expand "fix_truncxfdi2"
4799 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4800 (fix:DI (match_operand:XF 1 "register_operand" "")))
4801 (clobber (reg:CC FLAGS_REG))])]
4806 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4811 (define_expand "fix_trunc<mode>di2"
4812 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4813 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4814 (clobber (reg:CC FLAGS_REG))])]
4815 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4818 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4820 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4823 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4825 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4826 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4827 if (out != operands[0])
4828 emit_move_insn (operands[0], out);
4833 ;; Signed conversion to SImode.
4835 (define_expand "fix_truncxfsi2"
4836 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4837 (fix:SI (match_operand:XF 1 "register_operand" "")))
4838 (clobber (reg:CC FLAGS_REG))])]
4843 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4848 (define_expand "fix_trunc<mode>si2"
4849 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4850 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4851 (clobber (reg:CC FLAGS_REG))])]
4852 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4855 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4857 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4860 if (SSE_FLOAT_MODE_P (<MODE>mode))
4862 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4863 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4864 if (out != operands[0])
4865 emit_move_insn (operands[0], out);
4870 ;; Signed conversion to HImode.
4872 (define_expand "fix_trunc<mode>hi2"
4873 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4874 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4875 (clobber (reg:CC FLAGS_REG))])]
4877 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4881 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4886 ;; Unsigned conversion to SImode.
4888 (define_expand "fixuns_trunc<mode>si2"
4890 [(set (match_operand:SI 0 "register_operand" "")
4892 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4894 (clobber (match_scratch:<ssevecmode> 3 ""))
4895 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4896 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4898 enum machine_mode mode = <MODE>mode;
4899 enum machine_mode vecmode = <ssevecmode>mode;
4900 REAL_VALUE_TYPE TWO31r;
4903 if (optimize_insn_for_size_p ())
4906 real_ldexp (&TWO31r, &dconst1, 31);
4907 two31 = const_double_from_real_value (TWO31r, mode);
4908 two31 = ix86_build_const_vector (mode, true, two31);
4909 operands[2] = force_reg (vecmode, two31);
4912 (define_insn_and_split "*fixuns_trunc<mode>_1"
4913 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4915 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4916 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4917 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4918 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4919 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4920 && optimize_function_for_speed_p (cfun)"
4922 "&& reload_completed"
4925 ix86_split_convert_uns_si_sse (operands);
4929 ;; Unsigned conversion to HImode.
4930 ;; Without these patterns, we'll try the unsigned SI conversion which
4931 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4933 (define_expand "fixuns_trunc<mode>hi2"
4935 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4936 (set (match_operand:HI 0 "nonimmediate_operand" "")
4937 (subreg:HI (match_dup 2) 0))]
4938 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4939 "operands[2] = gen_reg_rtx (SImode);")
4941 ;; When SSE is available, it is always faster to use it!
4942 (define_insn "fix_trunc<mode>di_sse"
4943 [(set (match_operand:DI 0 "register_operand" "=r,r")
4944 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4945 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4946 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4947 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4948 [(set_attr "type" "sseicvt")
4949 (set_attr "prefix" "maybe_vex")
4950 (set_attr "prefix_rex" "1")
4951 (set_attr "mode" "<MODE>")
4952 (set_attr "athlon_decode" "double,vector")
4953 (set_attr "amdfam10_decode" "double,double")])
4955 (define_insn "fix_trunc<mode>si_sse"
4956 [(set (match_operand:SI 0 "register_operand" "=r,r")
4957 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4958 "SSE_FLOAT_MODE_P (<MODE>mode)
4959 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4960 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4961 [(set_attr "type" "sseicvt")
4962 (set_attr "prefix" "maybe_vex")
4963 (set_attr "mode" "<MODE>")
4964 (set_attr "athlon_decode" "double,vector")
4965 (set_attr "amdfam10_decode" "double,double")])
4967 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4969 [(set (match_operand:MODEF 0 "register_operand" "")
4970 (match_operand:MODEF 1 "memory_operand" ""))
4971 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4972 (fix:SSEMODEI24 (match_dup 0)))]
4973 "TARGET_SHORTEN_X87_SSE
4974 && peep2_reg_dead_p (2, operands[0])"
4975 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4978 ;; Avoid vector decoded forms of the instruction.
4980 [(match_scratch:DF 2 "Y2")
4981 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4982 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4983 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4984 [(set (match_dup 2) (match_dup 1))
4985 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4989 [(match_scratch:SF 2 "x")
4990 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4991 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4992 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4993 [(set (match_dup 2) (match_dup 1))
4994 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4997 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4998 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4999 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5000 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5002 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5003 && (TARGET_64BIT || <MODE>mode != DImode))
5005 && can_create_pseudo_p ()"
5010 if (memory_operand (operands[0], VOIDmode))
5011 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5014 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5015 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5021 [(set_attr "type" "fisttp")
5022 (set_attr "mode" "<MODE>")])
5024 (define_insn "fix_trunc<mode>_i387_fisttp"
5025 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5026 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5027 (clobber (match_scratch:XF 2 "=&1f"))]
5028 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5030 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5031 && (TARGET_64BIT || <MODE>mode != DImode))
5032 && TARGET_SSE_MATH)"
5033 "* return output_fix_trunc (insn, operands, 1);"
5034 [(set_attr "type" "fisttp")
5035 (set_attr "mode" "<MODE>")])
5037 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5038 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5039 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5040 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5041 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5042 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5044 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5045 && (TARGET_64BIT || <MODE>mode != DImode))
5046 && TARGET_SSE_MATH)"
5048 [(set_attr "type" "fisttp")
5049 (set_attr "mode" "<MODE>")])
5052 [(set (match_operand:X87MODEI 0 "register_operand" "")
5053 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5054 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5055 (clobber (match_scratch 3 ""))]
5057 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5058 (clobber (match_dup 3))])
5059 (set (match_dup 0) (match_dup 2))]
5063 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5064 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5065 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5066 (clobber (match_scratch 3 ""))]
5068 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5069 (clobber (match_dup 3))])]
5072 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5073 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5074 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5075 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5076 ;; function in i386.c.
5077 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5078 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5079 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5080 (clobber (reg:CC FLAGS_REG))]
5081 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5083 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5084 && (TARGET_64BIT || <MODE>mode != DImode))
5085 && can_create_pseudo_p ()"
5090 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5092 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5093 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5094 if (memory_operand (operands[0], VOIDmode))
5095 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5096 operands[2], operands[3]));
5099 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5100 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5101 operands[2], operands[3],
5106 [(set_attr "type" "fistp")
5107 (set_attr "i387_cw" "trunc")
5108 (set_attr "mode" "<MODE>")])
5110 (define_insn "fix_truncdi_i387"
5111 [(set (match_operand:DI 0 "memory_operand" "=m")
5112 (fix:DI (match_operand 1 "register_operand" "f")))
5113 (use (match_operand:HI 2 "memory_operand" "m"))
5114 (use (match_operand:HI 3 "memory_operand" "m"))
5115 (clobber (match_scratch:XF 4 "=&1f"))]
5116 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5118 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5119 "* return output_fix_trunc (insn, operands, 0);"
5120 [(set_attr "type" "fistp")
5121 (set_attr "i387_cw" "trunc")
5122 (set_attr "mode" "DI")])
5124 (define_insn "fix_truncdi_i387_with_temp"
5125 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5126 (fix:DI (match_operand 1 "register_operand" "f,f")))
5127 (use (match_operand:HI 2 "memory_operand" "m,m"))
5128 (use (match_operand:HI 3 "memory_operand" "m,m"))
5129 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5130 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5131 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5133 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5135 [(set_attr "type" "fistp")
5136 (set_attr "i387_cw" "trunc")
5137 (set_attr "mode" "DI")])
5140 [(set (match_operand:DI 0 "register_operand" "")
5141 (fix:DI (match_operand 1 "register_operand" "")))
5142 (use (match_operand:HI 2 "memory_operand" ""))
5143 (use (match_operand:HI 3 "memory_operand" ""))
5144 (clobber (match_operand:DI 4 "memory_operand" ""))
5145 (clobber (match_scratch 5 ""))]
5147 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5150 (clobber (match_dup 5))])
5151 (set (match_dup 0) (match_dup 4))]
5155 [(set (match_operand:DI 0 "memory_operand" "")
5156 (fix:DI (match_operand 1 "register_operand" "")))
5157 (use (match_operand:HI 2 "memory_operand" ""))
5158 (use (match_operand:HI 3 "memory_operand" ""))
5159 (clobber (match_operand:DI 4 "memory_operand" ""))
5160 (clobber (match_scratch 5 ""))]
5162 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5165 (clobber (match_dup 5))])]
5168 (define_insn "fix_trunc<mode>_i387"
5169 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5170 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5171 (use (match_operand:HI 2 "memory_operand" "m"))
5172 (use (match_operand:HI 3 "memory_operand" "m"))]
5173 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5175 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5176 "* return output_fix_trunc (insn, operands, 0);"
5177 [(set_attr "type" "fistp")
5178 (set_attr "i387_cw" "trunc")
5179 (set_attr "mode" "<MODE>")])
5181 (define_insn "fix_trunc<mode>_i387_with_temp"
5182 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5183 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5184 (use (match_operand:HI 2 "memory_operand" "m,m"))
5185 (use (match_operand:HI 3 "memory_operand" "m,m"))
5186 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5187 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5189 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5191 [(set_attr "type" "fistp")
5192 (set_attr "i387_cw" "trunc")
5193 (set_attr "mode" "<MODE>")])
5196 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5197 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5198 (use (match_operand:HI 2 "memory_operand" ""))
5199 (use (match_operand:HI 3 "memory_operand" ""))
5200 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5202 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5204 (use (match_dup 3))])
5205 (set (match_dup 0) (match_dup 4))]
5209 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5210 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5211 (use (match_operand:HI 2 "memory_operand" ""))
5212 (use (match_operand:HI 3 "memory_operand" ""))
5213 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5215 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5217 (use (match_dup 3))])]
5220 (define_insn "x86_fnstcw_1"
5221 [(set (match_operand:HI 0 "memory_operand" "=m")
5222 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5225 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5226 (set_attr "mode" "HI")
5227 (set_attr "unit" "i387")])
5229 (define_insn "x86_fldcw_1"
5230 [(set (reg:HI FPCR_REG)
5231 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5234 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5235 (set_attr "mode" "HI")
5236 (set_attr "unit" "i387")
5237 (set_attr "athlon_decode" "vector")
5238 (set_attr "amdfam10_decode" "vector")])
5240 ;; Conversion between fixed point and floating point.
5242 ;; Even though we only accept memory inputs, the backend _really_
5243 ;; wants to be able to do this between registers.
5245 (define_expand "floathi<mode>2"
5246 [(set (match_operand:X87MODEF 0 "register_operand" "")
5247 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5249 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5250 || TARGET_MIX_SSE_I387)"
5253 ;; Pre-reload splitter to add memory clobber to the pattern.
5254 (define_insn_and_split "*floathi<mode>2_1"
5255 [(set (match_operand:X87MODEF 0 "register_operand" "")
5256 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5258 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5259 || TARGET_MIX_SSE_I387)
5260 && can_create_pseudo_p ()"
5263 [(parallel [(set (match_dup 0)
5264 (float:X87MODEF (match_dup 1)))
5265 (clobber (match_dup 2))])]
5266 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5268 (define_insn "*floathi<mode>2_i387_with_temp"
5269 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5270 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5271 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5273 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5274 || TARGET_MIX_SSE_I387)"
5276 [(set_attr "type" "fmov,multi")
5277 (set_attr "mode" "<MODE>")
5278 (set_attr "unit" "*,i387")
5279 (set_attr "fp_int_src" "true")])
5281 (define_insn "*floathi<mode>2_i387"
5282 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5283 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5285 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5286 || TARGET_MIX_SSE_I387)"
5288 [(set_attr "type" "fmov")
5289 (set_attr "mode" "<MODE>")
5290 (set_attr "fp_int_src" "true")])
5293 [(set (match_operand:X87MODEF 0 "register_operand" "")
5294 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5295 (clobber (match_operand:HI 2 "memory_operand" ""))]
5297 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5298 || TARGET_MIX_SSE_I387)
5299 && reload_completed"
5300 [(set (match_dup 2) (match_dup 1))
5301 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5305 [(set (match_operand:X87MODEF 0 "register_operand" "")
5306 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5307 (clobber (match_operand:HI 2 "memory_operand" ""))]
5309 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5310 || TARGET_MIX_SSE_I387)
5311 && reload_completed"
5312 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5315 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5316 [(set (match_operand:X87MODEF 0 "register_operand" "")
5318 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5320 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5321 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5323 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5324 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5325 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5327 rtx reg = gen_reg_rtx (XFmode);
5330 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5332 if (<X87MODEF:MODE>mode == SFmode)
5333 insn = gen_truncxfsf2 (operands[0], reg);
5334 else if (<X87MODEF:MODE>mode == DFmode)
5335 insn = gen_truncxfdf2 (operands[0], reg);
5344 ;; Pre-reload splitter to add memory clobber to the pattern.
5345 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5346 [(set (match_operand:X87MODEF 0 "register_operand" "")
5347 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5349 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5350 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5351 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5352 || TARGET_MIX_SSE_I387))
5353 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5354 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5355 && ((<SSEMODEI24:MODE>mode == SImode
5356 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5357 && optimize_function_for_speed_p (cfun)
5358 && flag_trapping_math)
5359 || !(TARGET_INTER_UNIT_CONVERSIONS
5360 || optimize_function_for_size_p (cfun)))))
5361 && can_create_pseudo_p ()"
5364 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5365 (clobber (match_dup 2))])]
5367 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5369 /* Avoid store forwarding (partial memory) stall penalty
5370 by passing DImode value through XMM registers. */
5371 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5372 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5373 && optimize_function_for_speed_p (cfun))
5375 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5382 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5383 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5385 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5386 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5387 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5388 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5390 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5391 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5392 (set_attr "unit" "*,i387,*,*,*")
5393 (set_attr "athlon_decode" "*,*,double,direct,double")
5394 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5395 (set_attr "fp_int_src" "true")])
5397 (define_insn "*floatsi<mode>2_vector_mixed"
5398 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5399 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5400 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5401 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5405 [(set_attr "type" "fmov,sseicvt")
5406 (set_attr "mode" "<MODE>,<ssevecmode>")
5407 (set_attr "unit" "i387,*")
5408 (set_attr "athlon_decode" "*,direct")
5409 (set_attr "amdfam10_decode" "*,double")
5410 (set_attr "fp_int_src" "true")])
5412 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5413 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5415 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5416 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5417 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5418 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5420 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5421 (set_attr "mode" "<MODEF:MODE>")
5422 (set_attr "unit" "*,i387,*,*")
5423 (set_attr "athlon_decode" "*,*,double,direct")
5424 (set_attr "amdfam10_decode" "*,*,vector,double")
5425 (set_attr "fp_int_src" "true")])
5428 [(set (match_operand:MODEF 0 "register_operand" "")
5429 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5430 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5431 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5432 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5433 && TARGET_INTER_UNIT_CONVERSIONS
5435 && (SSE_REG_P (operands[0])
5436 || (GET_CODE (operands[0]) == SUBREG
5437 && SSE_REG_P (operands[0])))"
5438 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5442 [(set (match_operand:MODEF 0 "register_operand" "")
5443 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5444 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5445 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5446 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5447 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5449 && (SSE_REG_P (operands[0])
5450 || (GET_CODE (operands[0]) == SUBREG
5451 && SSE_REG_P (operands[0])))"
5452 [(set (match_dup 2) (match_dup 1))
5453 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5456 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5457 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5459 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5460 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5461 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5462 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5465 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5466 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5467 [(set_attr "type" "fmov,sseicvt,sseicvt")
5468 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5469 (set_attr "mode" "<MODEF:MODE>")
5470 (set (attr "prefix_rex")
5472 (and (eq_attr "prefix" "maybe_vex")
5473 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5475 (const_string "*")))
5476 (set_attr "unit" "i387,*,*")
5477 (set_attr "athlon_decode" "*,double,direct")
5478 (set_attr "amdfam10_decode" "*,vector,double")
5479 (set_attr "fp_int_src" "true")])
5481 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5482 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5484 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5485 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5486 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5487 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5490 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5491 [(set_attr "type" "fmov,sseicvt")
5492 (set_attr "prefix" "orig,maybe_vex")
5493 (set_attr "mode" "<MODEF:MODE>")
5494 (set (attr "prefix_rex")
5496 (and (eq_attr "prefix" "maybe_vex")
5497 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5499 (const_string "*")))
5500 (set_attr "athlon_decode" "*,direct")
5501 (set_attr "amdfam10_decode" "*,double")
5502 (set_attr "fp_int_src" "true")])
5504 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5505 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5507 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5508 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5509 "TARGET_SSE2 && TARGET_SSE_MATH
5510 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5512 [(set_attr "type" "sseicvt")
5513 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5514 (set_attr "athlon_decode" "double,direct,double")
5515 (set_attr "amdfam10_decode" "vector,double,double")
5516 (set_attr "fp_int_src" "true")])
5518 (define_insn "*floatsi<mode>2_vector_sse"
5519 [(set (match_operand:MODEF 0 "register_operand" "=x")
5520 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5521 "TARGET_SSE2 && TARGET_SSE_MATH
5522 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5524 [(set_attr "type" "sseicvt")
5525 (set_attr "mode" "<MODE>")
5526 (set_attr "athlon_decode" "direct")
5527 (set_attr "amdfam10_decode" "double")
5528 (set_attr "fp_int_src" "true")])
5531 [(set (match_operand:MODEF 0 "register_operand" "")
5532 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5533 (clobber (match_operand:SI 2 "memory_operand" ""))]
5534 "TARGET_SSE2 && TARGET_SSE_MATH
5535 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5537 && (SSE_REG_P (operands[0])
5538 || (GET_CODE (operands[0]) == SUBREG
5539 && SSE_REG_P (operands[0])))"
5542 rtx op1 = operands[1];
5544 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5546 if (GET_CODE (op1) == SUBREG)
5547 op1 = SUBREG_REG (op1);
5549 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5551 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5552 emit_insn (gen_sse2_loadld (operands[4],
5553 CONST0_RTX (V4SImode), operands[1]));
5555 /* We can ignore possible trapping value in the
5556 high part of SSE register for non-trapping math. */
5557 else if (SSE_REG_P (op1) && !flag_trapping_math)
5558 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5561 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5562 emit_move_insn (operands[2], operands[1]);
5563 emit_insn (gen_sse2_loadld (operands[4],
5564 CONST0_RTX (V4SImode), operands[2]));
5567 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5572 [(set (match_operand:MODEF 0 "register_operand" "")
5573 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5574 (clobber (match_operand:SI 2 "memory_operand" ""))]
5575 "TARGET_SSE2 && TARGET_SSE_MATH
5576 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5578 && (SSE_REG_P (operands[0])
5579 || (GET_CODE (operands[0]) == SUBREG
5580 && SSE_REG_P (operands[0])))"
5583 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5585 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5587 emit_insn (gen_sse2_loadld (operands[4],
5588 CONST0_RTX (V4SImode), operands[1]));
5590 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5595 [(set (match_operand:MODEF 0 "register_operand" "")
5596 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5597 "TARGET_SSE2 && TARGET_SSE_MATH
5598 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5600 && (SSE_REG_P (operands[0])
5601 || (GET_CODE (operands[0]) == SUBREG
5602 && SSE_REG_P (operands[0])))"
5605 rtx op1 = operands[1];
5607 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5609 if (GET_CODE (op1) == SUBREG)
5610 op1 = SUBREG_REG (op1);
5612 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5614 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5615 emit_insn (gen_sse2_loadld (operands[4],
5616 CONST0_RTX (V4SImode), operands[1]));
5618 /* We can ignore possible trapping value in the
5619 high part of SSE register for non-trapping math. */
5620 else if (SSE_REG_P (op1) && !flag_trapping_math)
5621 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5625 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5630 [(set (match_operand:MODEF 0 "register_operand" "")
5631 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5632 "TARGET_SSE2 && TARGET_SSE_MATH
5633 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5635 && (SSE_REG_P (operands[0])
5636 || (GET_CODE (operands[0]) == SUBREG
5637 && SSE_REG_P (operands[0])))"
5640 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5642 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5644 emit_insn (gen_sse2_loadld (operands[4],
5645 CONST0_RTX (V4SImode), operands[1]));
5647 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5651 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5652 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5654 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5655 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5656 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5657 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5659 [(set_attr "type" "sseicvt")
5660 (set_attr "mode" "<MODEF:MODE>")
5661 (set_attr "athlon_decode" "double,direct")
5662 (set_attr "amdfam10_decode" "vector,double")
5663 (set_attr "fp_int_src" "true")])
5665 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5666 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5668 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5669 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5670 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5671 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5672 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5673 [(set_attr "type" "sseicvt")
5674 (set_attr "prefix" "maybe_vex")
5675 (set_attr "mode" "<MODEF:MODE>")
5676 (set (attr "prefix_rex")
5678 (and (eq_attr "prefix" "maybe_vex")
5679 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5681 (const_string "*")))
5682 (set_attr "athlon_decode" "double,direct")
5683 (set_attr "amdfam10_decode" "vector,double")
5684 (set_attr "fp_int_src" "true")])
5687 [(set (match_operand:MODEF 0 "register_operand" "")
5688 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5689 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5690 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5691 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5692 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5694 && (SSE_REG_P (operands[0])
5695 || (GET_CODE (operands[0]) == SUBREG
5696 && SSE_REG_P (operands[0])))"
5697 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5700 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5701 [(set (match_operand:MODEF 0 "register_operand" "=x")
5703 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5704 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5705 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5706 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5707 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5708 [(set_attr "type" "sseicvt")
5709 (set_attr "prefix" "maybe_vex")
5710 (set_attr "mode" "<MODEF:MODE>")
5711 (set (attr "prefix_rex")
5713 (and (eq_attr "prefix" "maybe_vex")
5714 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5716 (const_string "*")))
5717 (set_attr "athlon_decode" "direct")
5718 (set_attr "amdfam10_decode" "double")
5719 (set_attr "fp_int_src" "true")])
5722 [(set (match_operand:MODEF 0 "register_operand" "")
5723 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5724 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5725 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5726 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5727 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5729 && (SSE_REG_P (operands[0])
5730 || (GET_CODE (operands[0]) == SUBREG
5731 && SSE_REG_P (operands[0])))"
5732 [(set (match_dup 2) (match_dup 1))
5733 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5737 [(set (match_operand:MODEF 0 "register_operand" "")
5738 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5739 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5740 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5741 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5743 && (SSE_REG_P (operands[0])
5744 || (GET_CODE (operands[0]) == SUBREG
5745 && SSE_REG_P (operands[0])))"
5746 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5749 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5750 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5752 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5753 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5755 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5759 [(set_attr "type" "fmov,multi")
5760 (set_attr "mode" "<X87MODEF:MODE>")
5761 (set_attr "unit" "*,i387")
5762 (set_attr "fp_int_src" "true")])
5764 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5765 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5767 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5769 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5771 [(set_attr "type" "fmov")
5772 (set_attr "mode" "<X87MODEF:MODE>")
5773 (set_attr "fp_int_src" "true")])
5776 [(set (match_operand:X87MODEF 0 "register_operand" "")
5777 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5778 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5780 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5782 && FP_REG_P (operands[0])"
5783 [(set (match_dup 2) (match_dup 1))
5784 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5788 [(set (match_operand:X87MODEF 0 "register_operand" "")
5789 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5790 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5792 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5794 && FP_REG_P (operands[0])"
5795 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5798 ;; Avoid store forwarding (partial memory) stall penalty
5799 ;; by passing DImode value through XMM registers. */
5801 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5802 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5804 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5805 (clobber (match_scratch:V4SI 3 "=X,x"))
5806 (clobber (match_scratch:V4SI 4 "=X,x"))
5807 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5808 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5809 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5810 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5812 [(set_attr "type" "multi")
5813 (set_attr "mode" "<X87MODEF:MODE>")
5814 (set_attr "unit" "i387")
5815 (set_attr "fp_int_src" "true")])
5818 [(set (match_operand:X87MODEF 0 "register_operand" "")
5819 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5820 (clobber (match_scratch:V4SI 3 ""))
5821 (clobber (match_scratch:V4SI 4 ""))
5822 (clobber (match_operand:DI 2 "memory_operand" ""))]
5823 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5824 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5825 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5827 && FP_REG_P (operands[0])"
5828 [(set (match_dup 2) (match_dup 3))
5829 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5831 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5832 Assemble the 64-bit DImode value in an xmm register. */
5833 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5834 gen_rtx_SUBREG (SImode, operands[1], 0)));
5835 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5836 gen_rtx_SUBREG (SImode, operands[1], 4)));
5837 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5840 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5844 [(set (match_operand:X87MODEF 0 "register_operand" "")
5845 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5846 (clobber (match_scratch:V4SI 3 ""))
5847 (clobber (match_scratch:V4SI 4 ""))
5848 (clobber (match_operand:DI 2 "memory_operand" ""))]
5849 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5850 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5851 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5853 && FP_REG_P (operands[0])"
5854 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5857 ;; Avoid store forwarding (partial memory) stall penalty by extending
5858 ;; SImode value to DImode through XMM register instead of pushing two
5859 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5860 ;; targets benefit from this optimization. Also note that fild
5861 ;; loads from memory only.
5863 (define_insn "*floatunssi<mode>2_1"
5864 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5865 (unsigned_float:X87MODEF
5866 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5867 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5868 (clobber (match_scratch:SI 3 "=X,x"))]
5870 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5873 [(set_attr "type" "multi")
5874 (set_attr "mode" "<MODE>")])
5877 [(set (match_operand:X87MODEF 0 "register_operand" "")
5878 (unsigned_float:X87MODEF
5879 (match_operand:SI 1 "register_operand" "")))
5880 (clobber (match_operand:DI 2 "memory_operand" ""))
5881 (clobber (match_scratch:SI 3 ""))]
5883 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5885 && reload_completed"
5886 [(set (match_dup 2) (match_dup 1))
5888 (float:X87MODEF (match_dup 2)))]
5889 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5892 [(set (match_operand:X87MODEF 0 "register_operand" "")
5893 (unsigned_float:X87MODEF
5894 (match_operand:SI 1 "memory_operand" "")))
5895 (clobber (match_operand:DI 2 "memory_operand" ""))
5896 (clobber (match_scratch:SI 3 ""))]
5898 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5900 && reload_completed"
5901 [(set (match_dup 2) (match_dup 3))
5903 (float:X87MODEF (match_dup 2)))]
5905 emit_move_insn (operands[3], operands[1]);
5906 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5909 (define_expand "floatunssi<mode>2"
5911 [(set (match_operand:X87MODEF 0 "register_operand" "")
5912 (unsigned_float:X87MODEF
5913 (match_operand:SI 1 "nonimmediate_operand" "")))
5914 (clobber (match_dup 2))
5915 (clobber (match_scratch:SI 3 ""))])]
5917 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5919 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5921 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5923 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5928 enum ix86_stack_slot slot = (virtuals_instantiated
5931 operands[2] = assign_386_stack_local (DImode, slot);
5935 (define_expand "floatunsdisf2"
5936 [(use (match_operand:SF 0 "register_operand" ""))
5937 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5938 "TARGET_64BIT && TARGET_SSE_MATH"
5939 "x86_emit_floatuns (operands); DONE;")
5941 (define_expand "floatunsdidf2"
5942 [(use (match_operand:DF 0 "register_operand" ""))
5943 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5944 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5945 && TARGET_SSE2 && TARGET_SSE_MATH"
5948 x86_emit_floatuns (operands);
5950 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5956 (define_expand "add<mode>3"
5957 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5958 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5959 (match_operand:SDWIM 2 "<general_operand>" "")))]
5961 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5963 (define_insn_and_split "*add<dwi>3_doubleword"
5964 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5966 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5967 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5968 (clobber (reg:CC FLAGS_REG))]
5969 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5972 [(parallel [(set (reg:CC FLAGS_REG)
5973 (unspec:CC [(match_dup 1) (match_dup 2)]
5976 (plus:DWIH (match_dup 1) (match_dup 2)))])
5977 (parallel [(set (match_dup 3)
5981 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5983 (clobber (reg:CC FLAGS_REG))])]
5984 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5986 (define_insn "*add<mode>3_cc"
5987 [(set (reg:CC FLAGS_REG)
5989 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5990 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5992 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5993 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5994 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5995 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5996 [(set_attr "type" "alu")
5997 (set_attr "mode" "<MODE>")])
5999 (define_insn "addqi3_cc"
6000 [(set (reg:CC FLAGS_REG)
6002 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6003 (match_operand:QI 2 "general_operand" "qn,qm")]
6005 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6006 (plus:QI (match_dup 1) (match_dup 2)))]
6007 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6008 "add{b}\t{%2, %0|%0, %2}"
6009 [(set_attr "type" "alu")
6010 (set_attr "mode" "QI")])
6012 (define_insn "*lea_1"
6013 [(set (match_operand:DWIH 0 "register_operand" "=r")
6014 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
6016 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
6017 [(set_attr "type" "lea")
6018 (set_attr "mode" "<MODE>")])
6020 (define_insn "*lea_2"
6021 [(set (match_operand:SI 0 "register_operand" "=r")
6022 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6024 "lea{l}\t{%a1, %0|%0, %a1}"
6025 [(set_attr "type" "lea")
6026 (set_attr "mode" "SI")])
6028 (define_insn "*lea_2_zext"
6029 [(set (match_operand:DI 0 "register_operand" "=r")
6031 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6033 "lea{l}\t{%a1, %k0|%k0, %a1}"
6034 [(set_attr "type" "lea")
6035 (set_attr "mode" "SI")])
6037 (define_insn "*add<mode>_1"
6038 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6040 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6041 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6042 (clobber (reg:CC FLAGS_REG))]
6043 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6045 switch (get_attr_type (insn))
6048 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6049 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6052 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6053 if (operands[2] == const1_rtx)
6054 return "inc{<imodesuffix>}\t%0";
6057 gcc_assert (operands[2] == constm1_rtx);
6058 return "dec{<imodesuffix>}\t%0";
6062 /* Use add as much as possible to replace lea for AGU optimization. */
6063 if (which_alternative == 2 && TARGET_OPT_AGU)
6064 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6066 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6067 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6068 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6070 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6074 (cond [(and (eq_attr "alternative" "2")
6075 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6076 (const_string "lea")
6077 (eq_attr "alternative" "3")
6078 (const_string "lea")
6079 ; Current assemblers are broken and do not allow @GOTOFF in
6080 ; ought but a memory context.
6081 (match_operand:SWI48 2 "pic_symbolic_operand" "")
6082 (const_string "lea")
6083 (match_operand:SWI48 2 "incdec_operand" "")
6084 (const_string "incdec")
6086 (const_string "alu")))
6087 (set (attr "length_immediate")
6089 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6091 (const_string "*")))
6092 (set_attr "mode" "<MODE>")])
6094 ;; It may seem that nonimmediate operand is proper one for operand 1.
6095 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6096 ;; we take care in ix86_binary_operator_ok to not allow two memory
6097 ;; operands so proper swapping will be done in reload. This allow
6098 ;; patterns constructed from addsi_1 to match.
6100 (define_insn "*addsi_1_zext"
6101 [(set (match_operand:DI 0 "register_operand" "=r,r")
6103 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6104 (match_operand:SI 2 "general_operand" "g,li"))))
6105 (clobber (reg:CC FLAGS_REG))]
6106 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6108 switch (get_attr_type (insn))
6111 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6112 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6115 if (operands[2] == const1_rtx)
6116 return "inc{l}\t%k0";
6119 gcc_assert (operands[2] == constm1_rtx);
6120 return "dec{l}\t%k0";
6124 if (x86_maybe_negate_const_int (&operands[2], SImode))
6125 return "sub{l}\t{%2, %k0|%k0, %2}";
6127 return "add{l}\t{%2, %k0|%k0, %2}";
6131 (cond [(eq_attr "alternative" "1")
6132 (const_string "lea")
6133 ; Current assemblers are broken and do not allow @GOTOFF in
6134 ; ought but a memory context.
6135 (match_operand:SI 2 "pic_symbolic_operand" "")
6136 (const_string "lea")
6137 (match_operand:SI 2 "incdec_operand" "")
6138 (const_string "incdec")
6140 (const_string "alu")))
6141 (set (attr "length_immediate")
6143 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6145 (const_string "*")))
6146 (set_attr "mode" "SI")])
6148 (define_insn "*addhi_1"
6149 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6150 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6151 (match_operand:HI 2 "general_operand" "rn,rm")))
6152 (clobber (reg:CC FLAGS_REG))]
6153 "TARGET_PARTIAL_REG_STALL
6154 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6156 switch (get_attr_type (insn))
6159 if (operands[2] == const1_rtx)
6160 return "inc{w}\t%0";
6163 gcc_assert (operands[2] == constm1_rtx);
6164 return "dec{w}\t%0";
6168 if (x86_maybe_negate_const_int (&operands[2], HImode))
6169 return "sub{w}\t{%2, %0|%0, %2}";
6171 return "add{w}\t{%2, %0|%0, %2}";
6175 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6176 (const_string "incdec")
6177 (const_string "alu")))
6178 (set (attr "length_immediate")
6180 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6182 (const_string "*")))
6183 (set_attr "mode" "HI")])
6185 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6186 ;; type optimizations enabled by define-splits. This is not important
6187 ;; for PII, and in fact harmful because of partial register stalls.
6189 (define_insn "*addhi_1_lea"
6190 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6191 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6192 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6193 (clobber (reg:CC FLAGS_REG))]
6194 "!TARGET_PARTIAL_REG_STALL
6195 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6197 switch (get_attr_type (insn))
6202 if (operands[2] == const1_rtx)
6203 return "inc{w}\t%0";
6206 gcc_assert (operands[2] == constm1_rtx);
6207 return "dec{w}\t%0";
6211 if (x86_maybe_negate_const_int (&operands[2], HImode))
6212 return "sub{w}\t{%2, %0|%0, %2}";
6214 return "add{w}\t{%2, %0|%0, %2}";
6218 (if_then_else (eq_attr "alternative" "2")
6219 (const_string "lea")
6220 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6221 (const_string "incdec")
6222 (const_string "alu"))))
6223 (set (attr "length_immediate")
6225 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6227 (const_string "*")))
6228 (set_attr "mode" "HI,HI,SI")])
6230 (define_insn "*addqi_1"
6231 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6232 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6233 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6234 (clobber (reg:CC FLAGS_REG))]
6235 "TARGET_PARTIAL_REG_STALL
6236 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6238 int widen = (which_alternative == 2);
6239 switch (get_attr_type (insn))
6242 if (operands[2] == const1_rtx)
6243 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6246 gcc_assert (operands[2] == constm1_rtx);
6247 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6251 if (x86_maybe_negate_const_int (&operands[2], QImode))
6254 return "sub{l}\t{%2, %k0|%k0, %2}";
6256 return "sub{b}\t{%2, %0|%0, %2}";
6259 return "add{l}\t{%k2, %k0|%k0, %k2}";
6261 return "add{b}\t{%2, %0|%0, %2}";
6265 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6266 (const_string "incdec")
6267 (const_string "alu")))
6268 (set (attr "length_immediate")
6270 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6272 (const_string "*")))
6273 (set_attr "mode" "QI,QI,SI")])
6275 ;; %%% Potential partial reg stall on alternative 2. What to do?
6276 (define_insn "*addqi_1_lea"
6277 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6278 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6279 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6280 (clobber (reg:CC FLAGS_REG))]
6281 "!TARGET_PARTIAL_REG_STALL
6282 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6284 int widen = (which_alternative == 2);
6285 switch (get_attr_type (insn))
6290 if (operands[2] == const1_rtx)
6291 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6294 gcc_assert (operands[2] == constm1_rtx);
6295 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6299 if (x86_maybe_negate_const_int (&operands[2], QImode))
6302 return "sub{l}\t{%2, %k0|%k0, %2}";
6304 return "sub{b}\t{%2, %0|%0, %2}";
6307 return "add{l}\t{%k2, %k0|%k0, %k2}";
6309 return "add{b}\t{%2, %0|%0, %2}";
6313 (if_then_else (eq_attr "alternative" "3")
6314 (const_string "lea")
6315 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6316 (const_string "incdec")
6317 (const_string "alu"))))
6318 (set (attr "length_immediate")
6320 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6322 (const_string "*")))
6323 (set_attr "mode" "QI,QI,SI,SI")])
6325 (define_insn "*addqi_1_slp"
6326 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6327 (plus:QI (match_dup 0)
6328 (match_operand:QI 1 "general_operand" "qn,qnm")))
6329 (clobber (reg:CC FLAGS_REG))]
6330 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6331 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6333 switch (get_attr_type (insn))
6336 if (operands[1] == const1_rtx)
6337 return "inc{b}\t%0";
6340 gcc_assert (operands[1] == constm1_rtx);
6341 return "dec{b}\t%0";
6345 if (x86_maybe_negate_const_int (&operands[1], QImode))
6346 return "sub{b}\t{%1, %0|%0, %1}";
6348 return "add{b}\t{%1, %0|%0, %1}";
6352 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6353 (const_string "incdec")
6354 (const_string "alu1")))
6355 (set (attr "memory")
6356 (if_then_else (match_operand 1 "memory_operand" "")
6357 (const_string "load")
6358 (const_string "none")))
6359 (set_attr "mode" "QI")])
6361 (define_insn "*add<mode>_2"
6362 [(set (reg FLAGS_REG)
6365 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6366 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6368 (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6369 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6370 "ix86_match_ccmode (insn, CCGOCmode)
6371 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6372 /* Current assemblers are broken and do not allow @GOTOFF in
6373 ought but a memory context. */
6374 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6376 switch (get_attr_type (insn))
6379 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6380 if (operands[2] == const1_rtx)
6381 return "inc{<imodesuffix>}\t%0";
6384 gcc_assert (operands[2] == constm1_rtx);
6385 return "dec{<imodesuffix>}\t%0";
6389 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6390 /* ???? In DImode, we ought to handle there the 32bit case too
6391 - do we need new constraint? */
6392 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6393 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6395 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6399 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6400 (const_string "incdec")
6401 (const_string "alu")))
6402 (set (attr "length_immediate")
6404 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6406 (const_string "*")))
6407 (set_attr "mode" "<MODE>")])
6409 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6410 (define_insn "*addsi_2_zext"
6411 [(set (reg FLAGS_REG)
6413 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6414 (match_operand:SI 2 "general_operand" "g"))
6416 (set (match_operand:DI 0 "register_operand" "=r")
6417 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6418 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6419 && ix86_binary_operator_ok (PLUS, SImode, operands)
6420 /* Current assemblers are broken and do not allow @GOTOFF in
6421 ought but a memory context. */
6422 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6424 switch (get_attr_type (insn))
6427 if (operands[2] == const1_rtx)
6428 return "inc{l}\t%k0";
6431 gcc_assert (operands[2] == constm1_rtx);
6432 return "dec{l}\t%k0";
6436 if (x86_maybe_negate_const_int (&operands[2], SImode))
6437 return "sub{l}\t{%2, %k0|%k0, %2}";
6439 return "add{l}\t{%2, %k0|%k0, %2}";
6443 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6444 (const_string "incdec")
6445 (const_string "alu")))
6446 (set (attr "length_immediate")
6448 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6450 (const_string "*")))
6451 (set_attr "mode" "SI")])
6453 (define_insn "*addhi_2"
6454 [(set (reg FLAGS_REG)
6456 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6457 (match_operand:HI 2 "general_operand" "rmn,rn"))
6459 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6460 (plus:HI (match_dup 1) (match_dup 2)))]
6461 "ix86_match_ccmode (insn, CCGOCmode)
6462 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6464 switch (get_attr_type (insn))
6467 if (operands[2] == const1_rtx)
6468 return "inc{w}\t%0";
6471 gcc_assert (operands[2] == constm1_rtx);
6472 return "dec{w}\t%0";
6476 if (x86_maybe_negate_const_int (&operands[2], HImode))
6477 return "sub{w}\t{%2, %0|%0, %2}";
6479 return "add{w}\t{%2, %0|%0, %2}";
6483 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6484 (const_string "incdec")
6485 (const_string "alu")))
6486 (set (attr "length_immediate")
6488 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6490 (const_string "*")))
6491 (set_attr "mode" "HI")])
6493 (define_insn "*addqi_2"
6494 [(set (reg FLAGS_REG)
6496 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6497 (match_operand:QI 2 "general_operand" "qmn,qn"))
6499 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6500 (plus:QI (match_dup 1) (match_dup 2)))]
6501 "ix86_match_ccmode (insn, CCGOCmode)
6502 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6504 switch (get_attr_type (insn))
6507 if (operands[2] == const1_rtx)
6508 return "inc{b}\t%0";
6511 gcc_assert (operands[2] == constm1_rtx
6512 || (CONST_INT_P (operands[2])
6513 && INTVAL (operands[2]) == 255));
6514 return "dec{b}\t%0";
6518 if (x86_maybe_negate_const_int (&operands[2], QImode))
6519 return "sub{b}\t{%2, %0|%0, %2}";
6521 return "add{b}\t{%2, %0|%0, %2}";
6525 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6526 (const_string "incdec")
6527 (const_string "alu")))
6528 (set_attr "mode" "QI")])
6530 (define_insn "*add<mode>_3"
6531 [(set (reg FLAGS_REG)
6533 (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6534 (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6535 (clobber (match_scratch:SWI48 0 "=r"))]
6536 "ix86_match_ccmode (insn, CCZmode)
6537 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6538 /* Current assemblers are broken and do not allow @GOTOFF in
6539 ought but a memory context. */
6540 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6542 switch (get_attr_type (insn))
6545 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6546 if (operands[2] == const1_rtx)
6547 return "inc{<imodesuffix>}\t%0";
6550 gcc_assert (operands[2] == constm1_rtx);
6551 return "dec{<imodesuffix>}\t%0";
6555 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6556 /* ???? In DImode, we ought to handle there the 32bit case too
6557 - do we need new constraint? */
6558 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6559 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6561 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6565 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6566 (const_string "incdec")
6567 (const_string "alu")))
6568 (set (attr "length_immediate")
6570 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6572 (const_string "*")))
6573 (set_attr "mode" "<MODE>")])
6575 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6576 (define_insn "*addsi_3_zext"
6577 [(set (reg FLAGS_REG)
6579 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6580 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6581 (set (match_operand:DI 0 "register_operand" "=r")
6582 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6583 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6584 && ix86_binary_operator_ok (PLUS, SImode, operands)
6585 /* Current assemblers are broken and do not allow @GOTOFF in
6586 ought but a memory context. */
6587 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6589 switch (get_attr_type (insn))
6592 if (operands[2] == const1_rtx)
6593 return "inc{l}\t%k0";
6596 gcc_assert (operands[2] == constm1_rtx);
6597 return "dec{l}\t%k0";
6601 if (x86_maybe_negate_const_int (&operands[2], SImode))
6602 return "sub{l}\t{%2, %k0|%k0, %2}";
6604 return "add{l}\t{%2, %k0|%k0, %2}";
6608 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6609 (const_string "incdec")
6610 (const_string "alu")))
6611 (set (attr "length_immediate")
6613 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6615 (const_string "*")))
6616 (set_attr "mode" "SI")])
6618 (define_insn "*addhi_3"
6619 [(set (reg FLAGS_REG)
6621 (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6622 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6623 (clobber (match_scratch:HI 0 "=r"))]
6624 "ix86_match_ccmode (insn, CCZmode)
6625 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6627 switch (get_attr_type (insn))
6630 if (operands[2] == const1_rtx)
6631 return "inc{w}\t%0";
6634 gcc_assert (operands[2] == constm1_rtx);
6635 return "dec{w}\t%0";
6639 if (x86_maybe_negate_const_int (&operands[2], HImode))
6640 return "sub{w}\t{%2, %0|%0, %2}";
6642 return "add{w}\t{%2, %0|%0, %2}";
6646 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6647 (const_string "incdec")
6648 (const_string "alu")))
6649 (set (attr "length_immediate")
6651 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6653 (const_string "*")))
6654 (set_attr "mode" "HI")])
6656 (define_insn "*addqi_3"
6657 [(set (reg FLAGS_REG)
6659 (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6660 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6661 (clobber (match_scratch:QI 0 "=q"))]
6662 "ix86_match_ccmode (insn, CCZmode)
6663 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6665 switch (get_attr_type (insn))
6668 if (operands[2] == const1_rtx)
6669 return "inc{b}\t%0";
6672 gcc_assert (operands[2] == constm1_rtx
6673 || (CONST_INT_P (operands[2])
6674 && INTVAL (operands[2]) == 255));
6675 return "dec{b}\t%0";
6679 if (x86_maybe_negate_const_int (&operands[2], QImode))
6680 return "sub{b}\t{%2, %0|%0, %2}";
6682 return "add{b}\t{%2, %0|%0, %2}";
6686 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6687 (const_string "incdec")
6688 (const_string "alu")))
6689 (set_attr "mode" "QI")])
6691 ; For comparisons against 1, -1 and 128, we may generate better code
6692 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6693 ; is matched then. We can't accept general immediate, because for
6694 ; case of overflows, the result is messed up.
6695 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6696 ; only for comparisons not depending on it.
6698 (define_insn "*adddi_4"
6699 [(set (reg FLAGS_REG)
6701 (match_operand:DI 1 "nonimmediate_operand" "0")
6702 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6703 (clobber (match_scratch:DI 0 "=rm"))]
6705 && ix86_match_ccmode (insn, CCGCmode)"
6707 switch (get_attr_type (insn))
6710 if (operands[2] == constm1_rtx)
6711 return "inc{q}\t%0";
6714 gcc_assert (operands[2] == const1_rtx);
6715 return "dec{q}\t%0";
6719 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6720 if (x86_maybe_negate_const_int (&operands[2], DImode))
6721 return "add{q}\t{%2, %0|%0, %2}";
6723 return "sub{q}\t{%2, %0|%0, %2}";
6727 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6728 (const_string "incdec")
6729 (const_string "alu")))
6730 (set (attr "length_immediate")
6732 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6734 (const_string "*")))
6735 (set_attr "mode" "DI")])
6737 ; For comparisons against 1, -1 and 128, we may generate better code
6738 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6739 ; is matched then. We can't accept general immediate, because for
6740 ; case of overflows, the result is messed up.
6741 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6742 ; only for comparisons not depending on it.
6744 (define_insn "*addsi_4"
6745 [(set (reg FLAGS_REG)
6747 (match_operand:SI 1 "nonimmediate_operand" "0")
6748 (match_operand:SI 2 "const_int_operand" "n")))
6749 (clobber (match_scratch:SI 0 "=rm"))]
6750 "ix86_match_ccmode (insn, CCGCmode)"
6752 switch (get_attr_type (insn))
6755 if (operands[2] == constm1_rtx)
6756 return "inc{l}\t%0";
6759 gcc_assert (operands[2] == const1_rtx);
6760 return "dec{l}\t%0";
6764 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6765 if (x86_maybe_negate_const_int (&operands[2], SImode))
6766 return "add{l}\t{%2, %0|%0, %2}";
6768 return "sub{l}\t{%2, %0|%0, %2}";
6772 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6773 (const_string "incdec")
6774 (const_string "alu")))
6775 (set (attr "length_immediate")
6777 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6779 (const_string "*")))
6780 (set_attr "mode" "SI")])
6782 ; See comments above addsi_4 for details.
6784 (define_insn "*addhi_4"
6785 [(set (reg FLAGS_REG)
6787 (match_operand:HI 1 "nonimmediate_operand" "0")
6788 (match_operand:HI 2 "const_int_operand" "n")))
6789 (clobber (match_scratch:HI 0 "=rm"))]
6790 "ix86_match_ccmode (insn, CCGCmode)"
6792 switch (get_attr_type (insn))
6795 if (operands[2] == constm1_rtx)
6796 return "inc{w}\t%0";
6799 gcc_assert (operands[2] == const1_rtx);
6800 return "dec{w}\t%0";
6804 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6805 if (x86_maybe_negate_const_int (&operands[2], HImode))
6806 return "add{w}\t{%2, %0|%0, %2}";
6808 return "sub{w}\t{%2, %0|%0, %2}";
6812 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6813 (const_string "incdec")
6814 (const_string "alu")))
6815 (set (attr "length_immediate")
6817 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6819 (const_string "*")))
6820 (set_attr "mode" "HI")])
6822 ; See comments above addsi_4 for details.
6824 (define_insn "*addqi_4"
6825 [(set (reg FLAGS_REG)
6827 (match_operand:QI 1 "nonimmediate_operand" "0")
6828 (match_operand:QI 2 "const_int_operand" "n")))
6829 (clobber (match_scratch:QI 0 "=qm"))]
6830 "ix86_match_ccmode (insn, CCGCmode)"
6832 switch (get_attr_type (insn))
6835 if (operands[2] == constm1_rtx
6836 || (CONST_INT_P (operands[2])
6837 && INTVAL (operands[2]) == 255))
6838 return "inc{b}\t%0";
6841 gcc_assert (operands[2] == const1_rtx);
6842 return "dec{b}\t%0";
6846 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6847 if (x86_maybe_negate_const_int (&operands[2], QImode))
6848 return "add{b}\t{%2, %0|%0, %2}";
6850 return "sub{b}\t{%2, %0|%0, %2}";
6854 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6855 (const_string "incdec")
6856 (const_string "alu")))
6857 (set_attr "mode" "QI")])
6859 (define_insn "*add<mode>_5"
6860 [(set (reg FLAGS_REG)
6863 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6864 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6866 (clobber (match_scratch:SWI48 0 "=r"))]
6867 "ix86_match_ccmode (insn, CCGOCmode)
6868 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6869 /* Current assemblers are broken and do not allow @GOTOFF in
6870 ought but a memory context. */
6871 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6873 switch (get_attr_type (insn))
6876 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6877 if (operands[2] == const1_rtx)
6878 return "inc{<imodesuffix>}\t%0";
6881 gcc_assert (operands[2] == constm1_rtx);
6882 return "dec{<imodesuffix>}\t%0";
6886 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6887 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6888 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6890 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6894 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6895 (const_string "incdec")
6896 (const_string "alu")))
6897 (set (attr "length_immediate")
6899 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6901 (const_string "*")))
6902 (set_attr "mode" "<MODE>")])
6904 (define_insn "*addhi_5"
6905 [(set (reg FLAGS_REG)
6907 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6908 (match_operand:HI 2 "general_operand" "rmn"))
6910 (clobber (match_scratch:HI 0 "=r"))]
6911 "ix86_match_ccmode (insn, CCGOCmode)
6912 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6914 switch (get_attr_type (insn))
6917 if (operands[2] == const1_rtx)
6918 return "inc{w}\t%0";
6921 gcc_assert (operands[2] == constm1_rtx);
6922 return "dec{w}\t%0";
6926 if (x86_maybe_negate_const_int (&operands[2], HImode))
6927 return "sub{w}\t{%2, %0|%0, %2}";
6929 return "add{w}\t{%2, %0|%0, %2}";
6933 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6934 (const_string "incdec")
6935 (const_string "alu")))
6936 (set (attr "length_immediate")
6938 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6940 (const_string "*")))
6941 (set_attr "mode" "HI")])
6943 (define_insn "*addqi_5"
6944 [(set (reg FLAGS_REG)
6946 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6947 (match_operand:QI 2 "general_operand" "qmn"))
6949 (clobber (match_scratch:QI 0 "=q"))]
6950 "ix86_match_ccmode (insn, CCGOCmode)
6951 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6953 switch (get_attr_type (insn))
6956 if (operands[2] == const1_rtx)
6957 return "inc{b}\t%0";
6960 gcc_assert (operands[2] == constm1_rtx
6961 || (CONST_INT_P (operands[2])
6962 && INTVAL (operands[2]) == 255));
6963 return "dec{b}\t%0";
6967 if (x86_maybe_negate_const_int (&operands[2], QImode))
6968 return "sub{b}\t{%2, %0|%0, %2}";
6970 return "add{b}\t{%2, %0|%0, %2}";
6974 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6975 (const_string "incdec")
6976 (const_string "alu")))
6977 (set_attr "mode" "QI")])
6979 (define_insn "*addqi_ext_1_rex64"
6980 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6985 (match_operand 1 "ext_register_operand" "0")
6988 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6989 (clobber (reg:CC FLAGS_REG))]
6992 switch (get_attr_type (insn))
6995 if (operands[2] == const1_rtx)
6996 return "inc{b}\t%h0";
6999 gcc_assert (operands[2] == constm1_rtx
7000 || (CONST_INT_P (operands[2])
7001 && INTVAL (operands[2]) == 255));
7002 return "dec{b}\t%h0";
7006 return "add{b}\t{%2, %h0|%h0, %2}";
7010 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7011 (const_string "incdec")
7012 (const_string "alu")))
7013 (set_attr "modrm" "1")
7014 (set_attr "mode" "QI")])
7016 (define_insn "addqi_ext_1"
7017 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7022 (match_operand 1 "ext_register_operand" "0")
7025 (match_operand:QI 2 "general_operand" "Qmn")))
7026 (clobber (reg:CC FLAGS_REG))]
7029 switch (get_attr_type (insn))
7032 if (operands[2] == const1_rtx)
7033 return "inc{b}\t%h0";
7036 gcc_assert (operands[2] == constm1_rtx
7037 || (CONST_INT_P (operands[2])
7038 && INTVAL (operands[2]) == 255));
7039 return "dec{b}\t%h0";
7043 return "add{b}\t{%2, %h0|%h0, %2}";
7047 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7048 (const_string "incdec")
7049 (const_string "alu")))
7050 (set_attr "modrm" "1")
7051 (set_attr "mode" "QI")])
7053 (define_insn "*addqi_ext_2"
7054 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7059 (match_operand 1 "ext_register_operand" "%0")
7063 (match_operand 2 "ext_register_operand" "Q")
7066 (clobber (reg:CC FLAGS_REG))]
7068 "add{b}\t{%h2, %h0|%h0, %h2}"
7069 [(set_attr "type" "alu")
7070 (set_attr "mode" "QI")])
7072 ;; The lea patterns for non-Pmodes needs to be matched by
7073 ;; several insns converted to real lea by splitters.
7075 (define_insn_and_split "*lea_general_1"
7076 [(set (match_operand 0 "register_operand" "=r")
7077 (plus (plus (match_operand 1 "index_register_operand" "l")
7078 (match_operand 2 "register_operand" "r"))
7079 (match_operand 3 "immediate_operand" "i")))]
7080 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7081 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7082 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7083 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7084 && GET_MODE (operands[0]) == GET_MODE (operands[2])
7085 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7086 || GET_MODE (operands[3]) == VOIDmode)"
7088 "&& reload_completed"
7092 operands[0] = gen_lowpart (SImode, operands[0]);
7093 operands[1] = gen_lowpart (Pmode, operands[1]);
7094 operands[2] = gen_lowpart (Pmode, operands[2]);
7095 operands[3] = gen_lowpart (Pmode, operands[3]);
7096 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7098 if (Pmode != SImode)
7099 pat = gen_rtx_SUBREG (SImode, pat, 0);
7100 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7103 [(set_attr "type" "lea")
7104 (set_attr "mode" "SI")])
7106 (define_insn_and_split "*lea_general_1_zext"
7107 [(set (match_operand:DI 0 "register_operand" "=r")
7110 (match_operand:SI 1 "index_register_operand" "l")
7111 (match_operand:SI 2 "register_operand" "r"))
7112 (match_operand:SI 3 "immediate_operand" "i"))))]
7115 "&& reload_completed"
7117 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7119 (match_dup 3)) 0)))]
7121 operands[1] = gen_lowpart (Pmode, operands[1]);
7122 operands[2] = gen_lowpart (Pmode, operands[2]);
7123 operands[3] = gen_lowpart (Pmode, operands[3]);
7125 [(set_attr "type" "lea")
7126 (set_attr "mode" "SI")])
7128 (define_insn_and_split "*lea_general_2"
7129 [(set (match_operand 0 "register_operand" "=r")
7130 (plus (mult (match_operand 1 "index_register_operand" "l")
7131 (match_operand 2 "const248_operand" "i"))
7132 (match_operand 3 "nonmemory_operand" "ri")))]
7133 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7134 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7135 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7136 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7137 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7138 || GET_MODE (operands[3]) == VOIDmode)"
7140 "&& reload_completed"
7144 operands[0] = gen_lowpart (SImode, operands[0]);
7145 operands[1] = gen_lowpart (Pmode, operands[1]);
7146 operands[3] = gen_lowpart (Pmode, operands[3]);
7147 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7149 if (Pmode != SImode)
7150 pat = gen_rtx_SUBREG (SImode, pat, 0);
7151 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7154 [(set_attr "type" "lea")
7155 (set_attr "mode" "SI")])
7157 (define_insn_and_split "*lea_general_2_zext"
7158 [(set (match_operand:DI 0 "register_operand" "=r")
7161 (match_operand:SI 1 "index_register_operand" "l")
7162 (match_operand:SI 2 "const248_operand" "n"))
7163 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7166 "&& reload_completed"
7168 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7170 (match_dup 3)) 0)))]
7172 operands[1] = gen_lowpart (Pmode, operands[1]);
7173 operands[3] = gen_lowpart (Pmode, operands[3]);
7175 [(set_attr "type" "lea")
7176 (set_attr "mode" "SI")])
7178 (define_insn_and_split "*lea_general_3"
7179 [(set (match_operand 0 "register_operand" "=r")
7180 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7181 (match_operand 2 "const248_operand" "i"))
7182 (match_operand 3 "register_operand" "r"))
7183 (match_operand 4 "immediate_operand" "i")))]
7184 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7185 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7186 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7187 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7188 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7190 "&& reload_completed"
7194 operands[0] = gen_lowpart (SImode, operands[0]);
7195 operands[1] = gen_lowpart (Pmode, operands[1]);
7196 operands[3] = gen_lowpart (Pmode, operands[3]);
7197 operands[4] = gen_lowpart (Pmode, operands[4]);
7198 pat = gen_rtx_PLUS (Pmode,
7199 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7203 if (Pmode != SImode)
7204 pat = gen_rtx_SUBREG (SImode, pat, 0);
7205 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7208 [(set_attr "type" "lea")
7209 (set_attr "mode" "SI")])
7211 (define_insn_and_split "*lea_general_3_zext"
7212 [(set (match_operand:DI 0 "register_operand" "=r")
7216 (match_operand:SI 1 "index_register_operand" "l")
7217 (match_operand:SI 2 "const248_operand" "n"))
7218 (match_operand:SI 3 "register_operand" "r"))
7219 (match_operand:SI 4 "immediate_operand" "i"))))]
7222 "&& reload_completed"
7224 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7227 (match_dup 4)) 0)))]
7229 operands[1] = gen_lowpart (Pmode, operands[1]);
7230 operands[3] = gen_lowpart (Pmode, operands[3]);
7231 operands[4] = gen_lowpart (Pmode, operands[4]);
7233 [(set_attr "type" "lea")
7234 (set_attr "mode" "SI")])
7236 ;; Convert lea to the lea pattern to avoid flags dependency.
7238 [(set (match_operand:DI 0 "register_operand" "")
7239 (plus:DI (match_operand:DI 1 "register_operand" "")
7240 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7241 (clobber (reg:CC FLAGS_REG))]
7242 "TARGET_64BIT && reload_completed
7243 && ix86_lea_for_add_ok (PLUS, insn, operands)"
7245 (plus:DI (match_dup 1)
7249 ;; Convert lea to the lea pattern to avoid flags dependency.
7251 [(set (match_operand 0 "register_operand" "")
7252 (plus (match_operand 1 "register_operand" "")
7253 (match_operand 2 "nonmemory_operand" "")))
7254 (clobber (reg:CC FLAGS_REG))]
7255 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
7259 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7260 may confuse gen_lowpart. */
7261 if (GET_MODE (operands[0]) != Pmode)
7263 operands[1] = gen_lowpart (Pmode, operands[1]);
7264 operands[2] = gen_lowpart (Pmode, operands[2]);
7266 operands[0] = gen_lowpart (SImode, operands[0]);
7267 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7268 if (Pmode != SImode)
7269 pat = gen_rtx_SUBREG (SImode, pat, 0);
7270 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7274 ;; Convert lea to the lea pattern to avoid flags dependency.
7276 [(set (match_operand:DI 0 "register_operand" "")
7278 (plus:SI (match_operand:SI 1 "register_operand" "")
7279 (match_operand:SI 2 "nonmemory_operand" ""))))
7280 (clobber (reg:CC FLAGS_REG))]
7281 "TARGET_64BIT && reload_completed
7282 && true_regnum (operands[0]) != true_regnum (operands[1])"
7284 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7286 operands[1] = gen_lowpart (Pmode, operands[1]);
7287 operands[2] = gen_lowpart (Pmode, operands[2]);
7290 ;; Subtract instructions
7292 (define_expand "sub<mode>3"
7293 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7294 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7295 (match_operand:SDWIM 2 "<general_operand>" "")))]
7297 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7299 (define_insn_and_split "*sub<dwi>3_doubleword"
7300 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7302 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7303 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7304 (clobber (reg:CC FLAGS_REG))]
7305 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7308 [(parallel [(set (reg:CC FLAGS_REG)
7309 (compare:CC (match_dup 1) (match_dup 2)))
7311 (minus:DWIH (match_dup 1) (match_dup 2)))])
7312 (parallel [(set (match_dup 3)
7316 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7318 (clobber (reg:CC FLAGS_REG))])]
7319 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7321 (define_insn "*sub<mode>_1"
7322 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7324 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7325 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7326 (clobber (reg:CC FLAGS_REG))]
7327 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7328 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7329 [(set_attr "type" "alu")
7330 (set_attr "mode" "<MODE>")])
7332 (define_insn "*subsi_1_zext"
7333 [(set (match_operand:DI 0 "register_operand" "=r")
7335 (minus:SI (match_operand:SI 1 "register_operand" "0")
7336 (match_operand:SI 2 "general_operand" "g"))))
7337 (clobber (reg:CC FLAGS_REG))]
7338 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7339 "sub{l}\t{%2, %k0|%k0, %2}"
7340 [(set_attr "type" "alu")
7341 (set_attr "mode" "SI")])
7343 (define_insn "*subqi_1_slp"
7344 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7345 (minus:QI (match_dup 0)
7346 (match_operand:QI 1 "general_operand" "qn,qm")))
7347 (clobber (reg:CC FLAGS_REG))]
7348 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7349 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7350 "sub{b}\t{%1, %0|%0, %1}"
7351 [(set_attr "type" "alu1")
7352 (set_attr "mode" "QI")])
7354 (define_insn "*sub<mode>_2"
7355 [(set (reg FLAGS_REG)
7358 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7359 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7361 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7362 (minus:SWI (match_dup 1) (match_dup 2)))]
7363 "ix86_match_ccmode (insn, CCGOCmode)
7364 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7365 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7366 [(set_attr "type" "alu")
7367 (set_attr "mode" "<MODE>")])
7369 (define_insn "*subsi_2_zext"
7370 [(set (reg FLAGS_REG)
7372 (minus:SI (match_operand:SI 1 "register_operand" "0")
7373 (match_operand:SI 2 "general_operand" "g"))
7375 (set (match_operand:DI 0 "register_operand" "=r")
7377 (minus:SI (match_dup 1)
7379 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7380 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7381 "sub{l}\t{%2, %k0|%k0, %2}"
7382 [(set_attr "type" "alu")
7383 (set_attr "mode" "SI")])
7385 (define_insn "*sub<mode>_3"
7386 [(set (reg FLAGS_REG)
7387 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7388 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7389 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7390 (minus:SWI (match_dup 1) (match_dup 2)))]
7391 "ix86_match_ccmode (insn, CCmode)
7392 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7393 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7394 [(set_attr "type" "alu")
7395 (set_attr "mode" "<MODE>")])
7397 (define_insn "*subsi_3_zext"
7398 [(set (reg FLAGS_REG)
7399 (compare (match_operand:SI 1 "register_operand" "0")
7400 (match_operand:SI 2 "general_operand" "g")))
7401 (set (match_operand:DI 0 "register_operand" "=r")
7403 (minus:SI (match_dup 1)
7405 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7406 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7407 "sub{l}\t{%2, %1|%1, %2}"
7408 [(set_attr "type" "alu")
7409 (set_attr "mode" "SI")])
7411 ;; Add with carry and subtract with borrow
7413 (define_expand "<plusminus_insn><mode>3_carry"
7415 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7417 (match_operand:SWI 1 "nonimmediate_operand" "")
7418 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7419 [(match_operand 3 "flags_reg_operand" "")
7421 (match_operand:SWI 2 "<general_operand>" ""))))
7422 (clobber (reg:CC FLAGS_REG))])]
7423 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7426 (define_insn "*<plusminus_insn><mode>3_carry"
7427 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7429 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7431 (match_operator 3 "ix86_carry_flag_operator"
7432 [(reg FLAGS_REG) (const_int 0)])
7433 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7434 (clobber (reg:CC FLAGS_REG))]
7435 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7436 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7437 [(set_attr "type" "alu")
7438 (set_attr "use_carry" "1")
7439 (set_attr "pent_pair" "pu")
7440 (set_attr "mode" "<MODE>")])
7442 (define_insn "*addsi3_carry_zext"
7443 [(set (match_operand:DI 0 "register_operand" "=r")
7445 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7446 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7447 [(reg FLAGS_REG) (const_int 0)])
7448 (match_operand:SI 2 "general_operand" "g")))))
7449 (clobber (reg:CC FLAGS_REG))]
7450 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7451 "adc{l}\t{%2, %k0|%k0, %2}"
7452 [(set_attr "type" "alu")
7453 (set_attr "use_carry" "1")
7454 (set_attr "pent_pair" "pu")
7455 (set_attr "mode" "SI")])
7457 (define_insn "*subsi3_carry_zext"
7458 [(set (match_operand:DI 0 "register_operand" "=r")
7460 (minus:SI (match_operand:SI 1 "register_operand" "0")
7461 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7462 [(reg FLAGS_REG) (const_int 0)])
7463 (match_operand:SI 2 "general_operand" "g")))))
7464 (clobber (reg:CC FLAGS_REG))]
7465 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7466 "sbb{l}\t{%2, %k0|%k0, %2}"
7467 [(set_attr "type" "alu")
7468 (set_attr "pent_pair" "pu")
7469 (set_attr "mode" "SI")])
7471 ;; Overflow setting add and subtract instructions
7473 (define_insn "*add<mode>3_cconly_overflow"
7474 [(set (reg:CCC FLAGS_REG)
7477 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7478 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7480 (clobber (match_scratch:SWI 0 "=<r>"))]
7481 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7482 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7483 [(set_attr "type" "alu")
7484 (set_attr "mode" "<MODE>")])
7486 (define_insn "*sub<mode>3_cconly_overflow"
7487 [(set (reg:CCC FLAGS_REG)
7490 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7491 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7494 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7495 [(set_attr "type" "icmp")
7496 (set_attr "mode" "<MODE>")])
7498 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7499 [(set (reg:CCC FLAGS_REG)
7502 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7503 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7505 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7506 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7507 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7508 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7509 [(set_attr "type" "alu")
7510 (set_attr "mode" "<MODE>")])
7512 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7513 [(set (reg:CCC FLAGS_REG)
7516 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7517 (match_operand:SI 2 "general_operand" "g"))
7519 (set (match_operand:DI 0 "register_operand" "=r")
7520 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7521 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7522 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7523 [(set_attr "type" "alu")
7524 (set_attr "mode" "SI")])
7526 ;; The patterns that match these are at the end of this file.
7528 (define_expand "<plusminus_insn>xf3"
7529 [(set (match_operand:XF 0 "register_operand" "")
7531 (match_operand:XF 1 "register_operand" "")
7532 (match_operand:XF 2 "register_operand" "")))]
7536 (define_expand "<plusminus_insn><mode>3"
7537 [(set (match_operand:MODEF 0 "register_operand" "")
7539 (match_operand:MODEF 1 "register_operand" "")
7540 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7541 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7542 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7545 ;; Multiply instructions
7547 (define_expand "mul<mode>3"
7548 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7550 (match_operand:SWIM248 1 "register_operand" "")
7551 (match_operand:SWIM248 2 "<general_operand>" "")))
7552 (clobber (reg:CC FLAGS_REG))])]
7556 (define_expand "mulqi3"
7557 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7559 (match_operand:QI 1 "register_operand" "")
7560 (match_operand:QI 2 "nonimmediate_operand" "")))
7561 (clobber (reg:CC FLAGS_REG))])]
7562 "TARGET_QIMODE_MATH"
7566 ;; IMUL reg32/64, reg32/64, imm8 Direct
7567 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7568 ;; IMUL reg32/64, reg32/64, imm32 Direct
7569 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7570 ;; IMUL reg32/64, reg32/64 Direct
7571 ;; IMUL reg32/64, mem32/64 Direct
7573 (define_insn "*mul<mode>3_1"
7574 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7576 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7577 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7578 (clobber (reg:CC FLAGS_REG))]
7579 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7581 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7582 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7583 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7584 [(set_attr "type" "imul")
7585 (set_attr "prefix_0f" "0,0,1")
7586 (set (attr "athlon_decode")
7587 (cond [(eq_attr "cpu" "athlon")
7588 (const_string "vector")
7589 (eq_attr "alternative" "1")
7590 (const_string "vector")
7591 (and (eq_attr "alternative" "2")
7592 (match_operand 1 "memory_operand" ""))
7593 (const_string "vector")]
7594 (const_string "direct")))
7595 (set (attr "amdfam10_decode")
7596 (cond [(and (eq_attr "alternative" "0,1")
7597 (match_operand 1 "memory_operand" ""))
7598 (const_string "vector")]
7599 (const_string "direct")))
7600 (set_attr "mode" "<MODE>")])
7602 (define_insn "*mulsi3_1_zext"
7603 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7605 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7606 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7607 (clobber (reg:CC FLAGS_REG))]
7609 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7611 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7612 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7613 imul{l}\t{%2, %k0|%k0, %2}"
7614 [(set_attr "type" "imul")
7615 (set_attr "prefix_0f" "0,0,1")
7616 (set (attr "athlon_decode")
7617 (cond [(eq_attr "cpu" "athlon")
7618 (const_string "vector")
7619 (eq_attr "alternative" "1")
7620 (const_string "vector")
7621 (and (eq_attr "alternative" "2")
7622 (match_operand 1 "memory_operand" ""))
7623 (const_string "vector")]
7624 (const_string "direct")))
7625 (set (attr "amdfam10_decode")
7626 (cond [(and (eq_attr "alternative" "0,1")
7627 (match_operand 1 "memory_operand" ""))
7628 (const_string "vector")]
7629 (const_string "direct")))
7630 (set_attr "mode" "SI")])
7633 ;; IMUL reg16, reg16, imm8 VectorPath
7634 ;; IMUL reg16, mem16, imm8 VectorPath
7635 ;; IMUL reg16, reg16, imm16 VectorPath
7636 ;; IMUL reg16, mem16, imm16 VectorPath
7637 ;; IMUL reg16, reg16 Direct
7638 ;; IMUL reg16, mem16 Direct
7640 (define_insn "*mulhi3_1"
7641 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7642 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7643 (match_operand:HI 2 "general_operand" "K,n,mr")))
7644 (clobber (reg:CC FLAGS_REG))]
7646 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7648 imul{w}\t{%2, %1, %0|%0, %1, %2}
7649 imul{w}\t{%2, %1, %0|%0, %1, %2}
7650 imul{w}\t{%2, %0|%0, %2}"
7651 [(set_attr "type" "imul")
7652 (set_attr "prefix_0f" "0,0,1")
7653 (set (attr "athlon_decode")
7654 (cond [(eq_attr "cpu" "athlon")
7655 (const_string "vector")
7656 (eq_attr "alternative" "1,2")
7657 (const_string "vector")]
7658 (const_string "direct")))
7659 (set (attr "amdfam10_decode")
7660 (cond [(eq_attr "alternative" "0,1")
7661 (const_string "vector")]
7662 (const_string "direct")))
7663 (set_attr "mode" "HI")])
7669 (define_insn "*mulqi3_1"
7670 [(set (match_operand:QI 0 "register_operand" "=a")
7671 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7672 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7673 (clobber (reg:CC FLAGS_REG))]
7675 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7677 [(set_attr "type" "imul")
7678 (set_attr "length_immediate" "0")
7679 (set (attr "athlon_decode")
7680 (if_then_else (eq_attr "cpu" "athlon")
7681 (const_string "vector")
7682 (const_string "direct")))
7683 (set_attr "amdfam10_decode" "direct")
7684 (set_attr "mode" "QI")])
7686 (define_expand "<u>mul<mode><dwi>3"
7687 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7690 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7692 (match_operand:DWIH 2 "register_operand" ""))))
7693 (clobber (reg:CC FLAGS_REG))])]
7697 (define_expand "<u>mulqihi3"
7698 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7701 (match_operand:QI 1 "nonimmediate_operand" ""))
7703 (match_operand:QI 2 "register_operand" ""))))
7704 (clobber (reg:CC FLAGS_REG))])]
7705 "TARGET_QIMODE_MATH"
7708 (define_insn "*<u>mul<mode><dwi>3_1"
7709 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7712 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7714 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7715 (clobber (reg:CC FLAGS_REG))]
7716 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7717 "<sgnprefix>mul{<imodesuffix>}\t%2"
7718 [(set_attr "type" "imul")
7719 (set_attr "length_immediate" "0")
7720 (set (attr "athlon_decode")
7721 (if_then_else (eq_attr "cpu" "athlon")
7722 (const_string "vector")
7723 (const_string "double")))
7724 (set_attr "amdfam10_decode" "double")
7725 (set_attr "mode" "<MODE>")])
7727 (define_insn "*<u>mulqihi3_1"
7728 [(set (match_operand:HI 0 "register_operand" "=a")
7731 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7733 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7734 (clobber (reg:CC FLAGS_REG))]
7736 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7737 "<sgnprefix>mul{b}\t%2"
7738 [(set_attr "type" "imul")
7739 (set_attr "length_immediate" "0")
7740 (set (attr "athlon_decode")
7741 (if_then_else (eq_attr "cpu" "athlon")
7742 (const_string "vector")
7743 (const_string "direct")))
7744 (set_attr "amdfam10_decode" "direct")
7745 (set_attr "mode" "QI")])
7747 (define_expand "<s>mul<mode>3_highpart"
7748 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7753 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7755 (match_operand:SWI48 2 "register_operand" "")))
7757 (clobber (match_scratch:SWI48 3 ""))
7758 (clobber (reg:CC FLAGS_REG))])]
7760 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7762 (define_insn "*<s>muldi3_highpart_1"
7763 [(set (match_operand:DI 0 "register_operand" "=d")
7768 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7770 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7772 (clobber (match_scratch:DI 3 "=1"))
7773 (clobber (reg:CC FLAGS_REG))]
7775 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7776 "<sgnprefix>mul{q}\t%2"
7777 [(set_attr "type" "imul")
7778 (set_attr "length_immediate" "0")
7779 (set (attr "athlon_decode")
7780 (if_then_else (eq_attr "cpu" "athlon")
7781 (const_string "vector")
7782 (const_string "double")))
7783 (set_attr "amdfam10_decode" "double")
7784 (set_attr "mode" "DI")])
7786 (define_insn "*<s>mulsi3_highpart_1"
7787 [(set (match_operand:SI 0 "register_operand" "=d")
7792 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7794 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7796 (clobber (match_scratch:SI 3 "=1"))
7797 (clobber (reg:CC FLAGS_REG))]
7798 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7799 "<sgnprefix>mul{l}\t%2"
7800 [(set_attr "type" "imul")
7801 (set_attr "length_immediate" "0")
7802 (set (attr "athlon_decode")
7803 (if_then_else (eq_attr "cpu" "athlon")
7804 (const_string "vector")
7805 (const_string "double")))
7806 (set_attr "amdfam10_decode" "double")
7807 (set_attr "mode" "SI")])
7809 (define_insn "*<s>mulsi3_highpart_zext"
7810 [(set (match_operand:DI 0 "register_operand" "=d")
7811 (zero_extend:DI (truncate:SI
7813 (mult:DI (any_extend:DI
7814 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7816 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7818 (clobber (match_scratch:SI 3 "=1"))
7819 (clobber (reg:CC FLAGS_REG))]
7821 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7822 "<sgnprefix>mul{l}\t%2"
7823 [(set_attr "type" "imul")
7824 (set_attr "length_immediate" "0")
7825 (set (attr "athlon_decode")
7826 (if_then_else (eq_attr "cpu" "athlon")
7827 (const_string "vector")
7828 (const_string "double")))
7829 (set_attr "amdfam10_decode" "double")
7830 (set_attr "mode" "SI")])
7832 ;; The patterns that match these are at the end of this file.
7834 (define_expand "mulxf3"
7835 [(set (match_operand:XF 0 "register_operand" "")
7836 (mult:XF (match_operand:XF 1 "register_operand" "")
7837 (match_operand:XF 2 "register_operand" "")))]
7841 (define_expand "mul<mode>3"
7842 [(set (match_operand:MODEF 0 "register_operand" "")
7843 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7844 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7845 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7846 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7849 ;; Divide instructions
7851 (define_insn "<u>divqi3"
7852 [(set (match_operand:QI 0 "register_operand" "=a")
7854 (match_operand:HI 1 "register_operand" "0")
7855 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7856 (clobber (reg:CC FLAGS_REG))]
7857 "TARGET_QIMODE_MATH"
7858 "<sgnprefix>div{b}\t%2"
7859 [(set_attr "type" "idiv")
7860 (set_attr "mode" "QI")])
7862 ;; The patterns that match these are at the end of this file.
7864 (define_expand "divxf3"
7865 [(set (match_operand:XF 0 "register_operand" "")
7866 (div:XF (match_operand:XF 1 "register_operand" "")
7867 (match_operand:XF 2 "register_operand" "")))]
7871 (define_expand "divdf3"
7872 [(set (match_operand:DF 0 "register_operand" "")
7873 (div:DF (match_operand:DF 1 "register_operand" "")
7874 (match_operand:DF 2 "nonimmediate_operand" "")))]
7875 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7876 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7879 (define_expand "divsf3"
7880 [(set (match_operand:SF 0 "register_operand" "")
7881 (div:SF (match_operand:SF 1 "register_operand" "")
7882 (match_operand:SF 2 "nonimmediate_operand" "")))]
7883 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7886 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7887 && flag_finite_math_only && !flag_trapping_math
7888 && flag_unsafe_math_optimizations)
7890 ix86_emit_swdivsf (operands[0], operands[1],
7891 operands[2], SFmode);
7896 ;; Divmod instructions.
7898 (define_expand "divmod<mode>4"
7899 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7901 (match_operand:SWIM248 1 "register_operand" "")
7902 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7903 (set (match_operand:SWIM248 3 "register_operand" "")
7904 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7905 (clobber (reg:CC FLAGS_REG))])]
7909 (define_insn_and_split "*divmod<mode>4"
7910 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7911 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7912 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7913 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7914 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7915 (clobber (reg:CC FLAGS_REG))]
7918 "&& reload_completed"
7919 [(parallel [(set (match_dup 1)
7920 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7921 (clobber (reg:CC FLAGS_REG))])
7922 (parallel [(set (match_dup 0)
7923 (div:SWIM248 (match_dup 2) (match_dup 3)))
7925 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7927 (clobber (reg:CC FLAGS_REG))])]
7929 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
7931 if (<MODE>mode != HImode
7932 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7933 operands[4] = operands[2];
7936 /* Avoid use of cltd in favor of a mov+shift. */
7937 emit_move_insn (operands[1], operands[2]);
7938 operands[4] = operands[1];
7941 [(set_attr "type" "multi")
7942 (set_attr "mode" "<MODE>")])
7944 (define_insn "*divmod<mode>4_noext"
7945 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7946 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7947 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7948 (set (match_operand:SWIM248 1 "register_operand" "=d")
7949 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7950 (use (match_operand:SWIM248 4 "register_operand" "1"))
7951 (clobber (reg:CC FLAGS_REG))]
7953 "idiv{<imodesuffix>}\t%3"
7954 [(set_attr "type" "idiv")
7955 (set_attr "mode" "<MODE>")])
7957 (define_expand "udivmod<mode>4"
7958 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7960 (match_operand:SWIM248 1 "register_operand" "")
7961 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7962 (set (match_operand:SWIM248 3 "register_operand" "")
7963 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7964 (clobber (reg:CC FLAGS_REG))])]
7968 (define_insn_and_split "*udivmod<mode>4"
7969 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7970 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7971 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7972 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7973 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7974 (clobber (reg:CC FLAGS_REG))]
7977 "&& reload_completed"
7978 [(set (match_dup 1) (const_int 0))
7979 (parallel [(set (match_dup 0)
7980 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7982 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7984 (clobber (reg:CC FLAGS_REG))])]
7986 [(set_attr "type" "multi")
7987 (set_attr "mode" "<MODE>")])
7989 (define_insn "*udivmod<mode>4_noext"
7990 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7991 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7992 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7993 (set (match_operand:SWIM248 1 "register_operand" "=d")
7994 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7995 (use (match_operand:SWIM248 4 "register_operand" "1"))
7996 (clobber (reg:CC FLAGS_REG))]
7998 "div{<imodesuffix>}\t%3"
7999 [(set_attr "type" "idiv")
8000 (set_attr "mode" "<MODE>")])
8002 ;; We cannot use div/idiv for double division, because it causes
8003 ;; "division by zero" on the overflow and that's not what we expect
8004 ;; from truncate. Because true (non truncating) double division is
8005 ;; never generated, we can't create this insn anyway.
8008 ; [(set (match_operand:SI 0 "register_operand" "=a")
8010 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8012 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8013 ; (set (match_operand:SI 3 "register_operand" "=d")
8015 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8016 ; (clobber (reg:CC FLAGS_REG))]
8018 ; "div{l}\t{%2, %0|%0, %2}"
8019 ; [(set_attr "type" "idiv")])
8021 ;;- Logical AND instructions
8023 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8024 ;; Note that this excludes ah.
8026 (define_expand "testsi_ccno_1"
8027 [(set (reg:CCNO FLAGS_REG)
8029 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8030 (match_operand:SI 1 "nonmemory_operand" ""))
8035 (define_expand "testqi_ccz_1"
8036 [(set (reg:CCZ FLAGS_REG)
8037 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8038 (match_operand:QI 1 "nonmemory_operand" ""))
8043 (define_insn "*testdi_1"
8044 [(set (reg FLAGS_REG)
8047 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8048 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8050 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8051 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8053 test{l}\t{%k1, %k0|%k0, %k1}
8054 test{l}\t{%k1, %k0|%k0, %k1}
8055 test{q}\t{%1, %0|%0, %1}
8056 test{q}\t{%1, %0|%0, %1}
8057 test{q}\t{%1, %0|%0, %1}"
8058 [(set_attr "type" "test")
8059 (set_attr "modrm" "0,1,0,1,1")
8060 (set_attr "mode" "SI,SI,DI,DI,DI")])
8062 (define_insn "*testqi_1_maybe_si"
8063 [(set (reg FLAGS_REG)
8066 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8067 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8069 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8070 && ix86_match_ccmode (insn,
8071 CONST_INT_P (operands[1])
8072 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8074 if (which_alternative == 3)
8076 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8077 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8078 return "test{l}\t{%1, %k0|%k0, %1}";
8080 return "test{b}\t{%1, %0|%0, %1}";
8082 [(set_attr "type" "test")
8083 (set_attr "modrm" "0,1,1,1")
8084 (set_attr "mode" "QI,QI,QI,SI")
8085 (set_attr "pent_pair" "uv,np,uv,np")])
8087 (define_insn "*test<mode>_1"
8088 [(set (reg FLAGS_REG)
8091 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8092 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8094 "ix86_match_ccmode (insn, CCNOmode)
8095 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8096 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8097 [(set_attr "type" "test")
8098 (set_attr "modrm" "0,1,1")
8099 (set_attr "mode" "<MODE>")
8100 (set_attr "pent_pair" "uv,np,uv")])
8102 (define_expand "testqi_ext_ccno_0"
8103 [(set (reg:CCNO FLAGS_REG)
8107 (match_operand 0 "ext_register_operand" "")
8110 (match_operand 1 "const_int_operand" ""))
8115 (define_insn "*testqi_ext_0"
8116 [(set (reg FLAGS_REG)
8120 (match_operand 0 "ext_register_operand" "Q")
8123 (match_operand 1 "const_int_operand" "n"))
8125 "ix86_match_ccmode (insn, CCNOmode)"
8126 "test{b}\t{%1, %h0|%h0, %1}"
8127 [(set_attr "type" "test")
8128 (set_attr "mode" "QI")
8129 (set_attr "length_immediate" "1")
8130 (set_attr "modrm" "1")
8131 (set_attr "pent_pair" "np")])
8133 (define_insn "*testqi_ext_1_rex64"
8134 [(set (reg FLAGS_REG)
8138 (match_operand 0 "ext_register_operand" "Q")
8142 (match_operand:QI 1 "register_operand" "Q")))
8144 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8145 "test{b}\t{%1, %h0|%h0, %1}"
8146 [(set_attr "type" "test")
8147 (set_attr "mode" "QI")])
8149 (define_insn "*testqi_ext_1"
8150 [(set (reg FLAGS_REG)
8154 (match_operand 0 "ext_register_operand" "Q")
8158 (match_operand:QI 1 "general_operand" "Qm")))
8160 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8161 "test{b}\t{%1, %h0|%h0, %1}"
8162 [(set_attr "type" "test")
8163 (set_attr "mode" "QI")])
8165 (define_insn "*testqi_ext_2"
8166 [(set (reg FLAGS_REG)
8170 (match_operand 0 "ext_register_operand" "Q")
8174 (match_operand 1 "ext_register_operand" "Q")
8178 "ix86_match_ccmode (insn, CCNOmode)"
8179 "test{b}\t{%h1, %h0|%h0, %h1}"
8180 [(set_attr "type" "test")
8181 (set_attr "mode" "QI")])
8183 (define_insn "*testqi_ext_3_rex64"
8184 [(set (reg FLAGS_REG)
8185 (compare (zero_extract:DI
8186 (match_operand 0 "nonimmediate_operand" "rm")
8187 (match_operand:DI 1 "const_int_operand" "")
8188 (match_operand:DI 2 "const_int_operand" ""))
8191 && ix86_match_ccmode (insn, CCNOmode)
8192 && INTVAL (operands[1]) > 0
8193 && INTVAL (operands[2]) >= 0
8194 /* Ensure that resulting mask is zero or sign extended operand. */
8195 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8196 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8197 && INTVAL (operands[1]) > 32))
8198 && (GET_MODE (operands[0]) == SImode
8199 || GET_MODE (operands[0]) == DImode
8200 || GET_MODE (operands[0]) == HImode
8201 || GET_MODE (operands[0]) == QImode)"
8204 ;; Combine likes to form bit extractions for some tests. Humor it.
8205 (define_insn "*testqi_ext_3"
8206 [(set (reg FLAGS_REG)
8207 (compare (zero_extract:SI
8208 (match_operand 0 "nonimmediate_operand" "rm")
8209 (match_operand:SI 1 "const_int_operand" "")
8210 (match_operand:SI 2 "const_int_operand" ""))
8212 "ix86_match_ccmode (insn, CCNOmode)
8213 && INTVAL (operands[1]) > 0
8214 && INTVAL (operands[2]) >= 0
8215 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8216 && (GET_MODE (operands[0]) == SImode
8217 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8218 || GET_MODE (operands[0]) == HImode
8219 || GET_MODE (operands[0]) == QImode)"
8223 [(set (match_operand 0 "flags_reg_operand" "")
8224 (match_operator 1 "compare_operator"
8226 (match_operand 2 "nonimmediate_operand" "")
8227 (match_operand 3 "const_int_operand" "")
8228 (match_operand 4 "const_int_operand" ""))
8230 "ix86_match_ccmode (insn, CCNOmode)"
8231 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8233 rtx val = operands[2];
8234 HOST_WIDE_INT len = INTVAL (operands[3]);
8235 HOST_WIDE_INT pos = INTVAL (operands[4]);
8237 enum machine_mode mode, submode;
8239 mode = GET_MODE (val);
8242 /* ??? Combine likes to put non-volatile mem extractions in QImode
8243 no matter the size of the test. So find a mode that works. */
8244 if (! MEM_VOLATILE_P (val))
8246 mode = smallest_mode_for_size (pos + len, MODE_INT);
8247 val = adjust_address (val, mode, 0);
8250 else if (GET_CODE (val) == SUBREG
8251 && (submode = GET_MODE (SUBREG_REG (val)),
8252 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8253 && pos + len <= GET_MODE_BITSIZE (submode)
8254 && GET_MODE_CLASS (submode) == MODE_INT)
8256 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8258 val = SUBREG_REG (val);
8260 else if (mode == HImode && pos + len <= 8)
8262 /* Small HImode tests can be converted to QImode. */
8264 val = gen_lowpart (QImode, val);
8267 if (len == HOST_BITS_PER_WIDE_INT)
8270 mask = ((HOST_WIDE_INT)1 << len) - 1;
8273 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8276 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8277 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8278 ;; this is relatively important trick.
8279 ;; Do the conversion only post-reload to avoid limiting of the register class
8282 [(set (match_operand 0 "flags_reg_operand" "")
8283 (match_operator 1 "compare_operator"
8284 [(and (match_operand 2 "register_operand" "")
8285 (match_operand 3 "const_int_operand" ""))
8288 && QI_REG_P (operands[2])
8289 && GET_MODE (operands[2]) != QImode
8290 && ((ix86_match_ccmode (insn, CCZmode)
8291 && !(INTVAL (operands[3]) & ~(255 << 8)))
8292 || (ix86_match_ccmode (insn, CCNOmode)
8293 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8296 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8299 "operands[2] = gen_lowpart (SImode, operands[2]);
8300 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8303 [(set (match_operand 0 "flags_reg_operand" "")
8304 (match_operator 1 "compare_operator"
8305 [(and (match_operand 2 "nonimmediate_operand" "")
8306 (match_operand 3 "const_int_operand" ""))
8309 && GET_MODE (operands[2]) != QImode
8310 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8311 && ((ix86_match_ccmode (insn, CCZmode)
8312 && !(INTVAL (operands[3]) & ~255))
8313 || (ix86_match_ccmode (insn, CCNOmode)
8314 && !(INTVAL (operands[3]) & ~127)))"
8316 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8318 "operands[2] = gen_lowpart (QImode, operands[2]);
8319 operands[3] = gen_lowpart (QImode, operands[3]);")
8321 ;; %%% This used to optimize known byte-wide and operations to memory,
8322 ;; and sometimes to QImode registers. If this is considered useful,
8323 ;; it should be done with splitters.
8325 (define_expand "and<mode>3"
8326 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8327 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8328 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8330 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8332 (define_insn "*anddi_1"
8333 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8335 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8336 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8337 (clobber (reg:CC FLAGS_REG))]
8338 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8340 switch (get_attr_type (insn))
8344 enum machine_mode mode;
8346 gcc_assert (CONST_INT_P (operands[2]));
8347 if (INTVAL (operands[2]) == 0xff)
8351 gcc_assert (INTVAL (operands[2]) == 0xffff);
8355 operands[1] = gen_lowpart (mode, operands[1]);
8357 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8359 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8363 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8364 if (get_attr_mode (insn) == MODE_SI)
8365 return "and{l}\t{%k2, %k0|%k0, %k2}";
8367 return "and{q}\t{%2, %0|%0, %2}";
8370 [(set_attr "type" "alu,alu,alu,imovx")
8371 (set_attr "length_immediate" "*,*,*,0")
8372 (set (attr "prefix_rex")
8374 (and (eq_attr "type" "imovx")
8375 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8376 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8378 (const_string "*")))
8379 (set_attr "mode" "SI,DI,DI,SI")])
8381 (define_insn "*andsi_1"
8382 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8383 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8384 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8385 (clobber (reg:CC FLAGS_REG))]
8386 "ix86_binary_operator_ok (AND, SImode, operands)"
8388 switch (get_attr_type (insn))
8392 enum machine_mode mode;
8394 gcc_assert (CONST_INT_P (operands[2]));
8395 if (INTVAL (operands[2]) == 0xff)
8399 gcc_assert (INTVAL (operands[2]) == 0xffff);
8403 operands[1] = gen_lowpart (mode, operands[1]);
8405 return "movz{bl|x}\t{%1, %0|%0, %1}";
8407 return "movz{wl|x}\t{%1, %0|%0, %1}";
8411 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8412 return "and{l}\t{%2, %0|%0, %2}";
8415 [(set_attr "type" "alu,alu,imovx")
8416 (set (attr "prefix_rex")
8418 (and (eq_attr "type" "imovx")
8419 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8420 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8422 (const_string "*")))
8423 (set_attr "length_immediate" "*,*,0")
8424 (set_attr "mode" "SI")])
8426 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8427 (define_insn "*andsi_1_zext"
8428 [(set (match_operand:DI 0 "register_operand" "=r")
8430 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8431 (match_operand:SI 2 "general_operand" "g"))))
8432 (clobber (reg:CC FLAGS_REG))]
8433 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8434 "and{l}\t{%2, %k0|%k0, %2}"
8435 [(set_attr "type" "alu")
8436 (set_attr "mode" "SI")])
8438 (define_insn "*andhi_1"
8439 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8440 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8441 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8442 (clobber (reg:CC FLAGS_REG))]
8443 "ix86_binary_operator_ok (AND, HImode, operands)"
8445 switch (get_attr_type (insn))
8448 gcc_assert (CONST_INT_P (operands[2]));
8449 gcc_assert (INTVAL (operands[2]) == 0xff);
8450 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8453 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8455 return "and{w}\t{%2, %0|%0, %2}";
8458 [(set_attr "type" "alu,alu,imovx")
8459 (set_attr "length_immediate" "*,*,0")
8460 (set (attr "prefix_rex")
8462 (and (eq_attr "type" "imovx")
8463 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8465 (const_string "*")))
8466 (set_attr "mode" "HI,HI,SI")])
8468 ;; %%% Potential partial reg stall on alternative 2. What to do?
8469 (define_insn "*andqi_1"
8470 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8471 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8472 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8473 (clobber (reg:CC FLAGS_REG))]
8474 "ix86_binary_operator_ok (AND, QImode, operands)"
8476 and{b}\t{%2, %0|%0, %2}
8477 and{b}\t{%2, %0|%0, %2}
8478 and{l}\t{%k2, %k0|%k0, %k2}"
8479 [(set_attr "type" "alu")
8480 (set_attr "mode" "QI,QI,SI")])
8482 (define_insn "*andqi_1_slp"
8483 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8484 (and:QI (match_dup 0)
8485 (match_operand:QI 1 "general_operand" "qn,qmn")))
8486 (clobber (reg:CC FLAGS_REG))]
8487 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8488 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8489 "and{b}\t{%1, %0|%0, %1}"
8490 [(set_attr "type" "alu1")
8491 (set_attr "mode" "QI")])
8494 [(set (match_operand 0 "register_operand" "")
8496 (const_int -65536)))
8497 (clobber (reg:CC FLAGS_REG))]
8498 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8499 || optimize_function_for_size_p (cfun)"
8500 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8501 "operands[1] = gen_lowpart (HImode, operands[0]);")
8504 [(set (match_operand 0 "ext_register_operand" "")
8507 (clobber (reg:CC FLAGS_REG))]
8508 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8509 && reload_completed"
8510 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8511 "operands[1] = gen_lowpart (QImode, operands[0]);")
8514 [(set (match_operand 0 "ext_register_operand" "")
8516 (const_int -65281)))
8517 (clobber (reg:CC FLAGS_REG))]
8518 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8519 && reload_completed"
8520 [(parallel [(set (zero_extract:SI (match_dup 0)
8524 (zero_extract:SI (match_dup 0)
8527 (zero_extract:SI (match_dup 0)
8530 (clobber (reg:CC FLAGS_REG))])]
8531 "operands[0] = gen_lowpart (SImode, operands[0]);")
8533 (define_insn "*anddi_2"
8534 [(set (reg FLAGS_REG)
8537 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8538 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8540 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8541 (and:DI (match_dup 1) (match_dup 2)))]
8542 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8543 && ix86_binary_operator_ok (AND, DImode, operands)"
8545 and{l}\t{%k2, %k0|%k0, %k2}
8546 and{q}\t{%2, %0|%0, %2}
8547 and{q}\t{%2, %0|%0, %2}"
8548 [(set_attr "type" "alu")
8549 (set_attr "mode" "SI,DI,DI")])
8551 (define_insn "*andqi_2_maybe_si"
8552 [(set (reg FLAGS_REG)
8554 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8555 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8557 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8558 (and:QI (match_dup 1) (match_dup 2)))]
8559 "ix86_binary_operator_ok (AND, QImode, operands)
8560 && ix86_match_ccmode (insn,
8561 CONST_INT_P (operands[2])
8562 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8564 if (which_alternative == 2)
8566 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8567 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8568 return "and{l}\t{%2, %k0|%k0, %2}";
8570 return "and{b}\t{%2, %0|%0, %2}";
8572 [(set_attr "type" "alu")
8573 (set_attr "mode" "QI,QI,SI")])
8575 (define_insn "*and<mode>_2"
8576 [(set (reg FLAGS_REG)
8577 (compare (and:SWI124
8578 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8579 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8581 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8582 (and:SWI124 (match_dup 1) (match_dup 2)))]
8583 "ix86_match_ccmode (insn, CCNOmode)
8584 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8585 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8586 [(set_attr "type" "alu")
8587 (set_attr "mode" "<MODE>")])
8589 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8590 (define_insn "*andsi_2_zext"
8591 [(set (reg FLAGS_REG)
8593 (match_operand:SI 1 "nonimmediate_operand" "%0")
8594 (match_operand:SI 2 "general_operand" "g"))
8596 (set (match_operand:DI 0 "register_operand" "=r")
8597 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8598 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8599 && ix86_binary_operator_ok (AND, SImode, operands)"
8600 "and{l}\t{%2, %k0|%k0, %2}"
8601 [(set_attr "type" "alu")
8602 (set_attr "mode" "SI")])
8604 (define_insn "*andqi_2_slp"
8605 [(set (reg FLAGS_REG)
8607 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8608 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8610 (set (strict_low_part (match_dup 0))
8611 (and:QI (match_dup 0) (match_dup 1)))]
8612 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8613 && ix86_match_ccmode (insn, CCNOmode)
8614 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8615 "and{b}\t{%1, %0|%0, %1}"
8616 [(set_attr "type" "alu1")
8617 (set_attr "mode" "QI")])
8619 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8620 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8621 ;; for a QImode operand, which of course failed.
8622 (define_insn "andqi_ext_0"
8623 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8628 (match_operand 1 "ext_register_operand" "0")
8631 (match_operand 2 "const_int_operand" "n")))
8632 (clobber (reg:CC FLAGS_REG))]
8634 "and{b}\t{%2, %h0|%h0, %2}"
8635 [(set_attr "type" "alu")
8636 (set_attr "length_immediate" "1")
8637 (set_attr "modrm" "1")
8638 (set_attr "mode" "QI")])
8640 ;; Generated by peephole translating test to and. This shows up
8641 ;; often in fp comparisons.
8642 (define_insn "*andqi_ext_0_cc"
8643 [(set (reg FLAGS_REG)
8647 (match_operand 1 "ext_register_operand" "0")
8650 (match_operand 2 "const_int_operand" "n"))
8652 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8661 "ix86_match_ccmode (insn, CCNOmode)"
8662 "and{b}\t{%2, %h0|%h0, %2}"
8663 [(set_attr "type" "alu")
8664 (set_attr "length_immediate" "1")
8665 (set_attr "modrm" "1")
8666 (set_attr "mode" "QI")])
8668 (define_insn "*andqi_ext_1_rex64"
8669 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8674 (match_operand 1 "ext_register_operand" "0")
8678 (match_operand 2 "ext_register_operand" "Q"))))
8679 (clobber (reg:CC FLAGS_REG))]
8681 "and{b}\t{%2, %h0|%h0, %2}"
8682 [(set_attr "type" "alu")
8683 (set_attr "length_immediate" "0")
8684 (set_attr "mode" "QI")])
8686 (define_insn "*andqi_ext_1"
8687 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8692 (match_operand 1 "ext_register_operand" "0")
8696 (match_operand:QI 2 "general_operand" "Qm"))))
8697 (clobber (reg:CC FLAGS_REG))]
8699 "and{b}\t{%2, %h0|%h0, %2}"
8700 [(set_attr "type" "alu")
8701 (set_attr "length_immediate" "0")
8702 (set_attr "mode" "QI")])
8704 (define_insn "*andqi_ext_2"
8705 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8710 (match_operand 1 "ext_register_operand" "%0")
8714 (match_operand 2 "ext_register_operand" "Q")
8717 (clobber (reg:CC FLAGS_REG))]
8719 "and{b}\t{%h2, %h0|%h0, %h2}"
8720 [(set_attr "type" "alu")
8721 (set_attr "length_immediate" "0")
8722 (set_attr "mode" "QI")])
8724 ;; Convert wide AND instructions with immediate operand to shorter QImode
8725 ;; equivalents when possible.
8726 ;; Don't do the splitting with memory operands, since it introduces risk
8727 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8728 ;; for size, but that can (should?) be handled by generic code instead.
8730 [(set (match_operand 0 "register_operand" "")
8731 (and (match_operand 1 "register_operand" "")
8732 (match_operand 2 "const_int_operand" "")))
8733 (clobber (reg:CC FLAGS_REG))]
8735 && QI_REG_P (operands[0])
8736 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8737 && !(~INTVAL (operands[2]) & ~(255 << 8))
8738 && GET_MODE (operands[0]) != QImode"
8739 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8740 (and:SI (zero_extract:SI (match_dup 1)
8741 (const_int 8) (const_int 8))
8743 (clobber (reg:CC FLAGS_REG))])]
8744 "operands[0] = gen_lowpart (SImode, operands[0]);
8745 operands[1] = gen_lowpart (SImode, operands[1]);
8746 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8748 ;; Since AND can be encoded with sign extended immediate, this is only
8749 ;; profitable when 7th bit is not set.
8751 [(set (match_operand 0 "register_operand" "")
8752 (and (match_operand 1 "general_operand" "")
8753 (match_operand 2 "const_int_operand" "")))
8754 (clobber (reg:CC FLAGS_REG))]
8756 && ANY_QI_REG_P (operands[0])
8757 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8758 && !(~INTVAL (operands[2]) & ~255)
8759 && !(INTVAL (operands[2]) & 128)
8760 && GET_MODE (operands[0]) != QImode"
8761 [(parallel [(set (strict_low_part (match_dup 0))
8762 (and:QI (match_dup 1)
8764 (clobber (reg:CC FLAGS_REG))])]
8765 "operands[0] = gen_lowpart (QImode, operands[0]);
8766 operands[1] = gen_lowpart (QImode, operands[1]);
8767 operands[2] = gen_lowpart (QImode, operands[2]);")
8769 ;; Logical inclusive and exclusive OR instructions
8771 ;; %%% This used to optimize known byte-wide and operations to memory.
8772 ;; If this is considered useful, it should be done with splitters.
8774 (define_expand "<code><mode>3"
8775 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8776 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8777 (match_operand:SWIM 2 "<general_operand>" "")))]
8779 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8781 (define_insn "*<code><mode>_1"
8782 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8784 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8785 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8786 (clobber (reg:CC FLAGS_REG))]
8787 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8788 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8789 [(set_attr "type" "alu")
8790 (set_attr "mode" "<MODE>")])
8792 ;; %%% Potential partial reg stall on alternative 2. What to do?
8793 (define_insn "*<code>qi_1"
8794 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8795 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8796 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8797 (clobber (reg:CC FLAGS_REG))]
8798 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8800 <logicprefix>{b}\t{%2, %0|%0, %2}
8801 <logicprefix>{b}\t{%2, %0|%0, %2}
8802 <logicprefix>{l}\t{%k2, %k0|%k0, %k2}"
8803 [(set_attr "type" "alu")
8804 (set_attr "mode" "QI,QI,SI")])
8806 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8807 (define_insn "*<code>si_1_zext"
8808 [(set (match_operand:DI 0 "register_operand" "=r")
8810 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8811 (match_operand:SI 2 "general_operand" "g"))))
8812 (clobber (reg:CC FLAGS_REG))]
8813 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8814 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8815 [(set_attr "type" "alu")
8816 (set_attr "mode" "SI")])
8818 (define_insn "*<code>si_1_zext_imm"
8819 [(set (match_operand:DI 0 "register_operand" "=r")
8821 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8822 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8823 (clobber (reg:CC FLAGS_REG))]
8824 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8825 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8826 [(set_attr "type" "alu")
8827 (set_attr "mode" "SI")])
8829 (define_insn "*<code>qi_1_slp"
8830 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8831 (any_or:QI (match_dup 0)
8832 (match_operand:QI 1 "general_operand" "qmn,qn")))
8833 (clobber (reg:CC FLAGS_REG))]
8834 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8835 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8836 "<logicprefix>{b}\t{%1, %0|%0, %1}"
8837 [(set_attr "type" "alu1")
8838 (set_attr "mode" "QI")])
8840 (define_insn "*<code><mode>_2"
8841 [(set (reg FLAGS_REG)
8842 (compare (any_or:SWI
8843 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8844 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8846 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8847 (any_or:SWI (match_dup 1) (match_dup 2)))]
8848 "ix86_match_ccmode (insn, CCNOmode)
8849 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8850 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8851 [(set_attr "type" "alu")
8852 (set_attr "mode" "<MODE>")])
8854 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8855 ;; ??? Special case for immediate operand is missing - it is tricky.
8856 (define_insn "*<code>si_2_zext"
8857 [(set (reg FLAGS_REG)
8858 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8859 (match_operand:SI 2 "general_operand" "g"))
8861 (set (match_operand:DI 0 "register_operand" "=r")
8862 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8863 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8864 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8865 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8866 [(set_attr "type" "alu")
8867 (set_attr "mode" "SI")])
8869 (define_insn "*<code>si_2_zext_imm"
8870 [(set (reg FLAGS_REG)
8872 (match_operand:SI 1 "nonimmediate_operand" "%0")
8873 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8875 (set (match_operand:DI 0 "register_operand" "=r")
8876 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8877 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8878 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8879 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8880 [(set_attr "type" "alu")
8881 (set_attr "mode" "SI")])
8883 (define_insn "*<code>qi_2_slp"
8884 [(set (reg FLAGS_REG)
8885 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8886 (match_operand:QI 1 "general_operand" "qmn,qn"))
8888 (set (strict_low_part (match_dup 0))
8889 (any_or:QI (match_dup 0) (match_dup 1)))]
8890 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8891 && ix86_match_ccmode (insn, CCNOmode)
8892 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8893 "<logicprefix>{b}\t{%1, %0|%0, %1}"
8894 [(set_attr "type" "alu1")
8895 (set_attr "mode" "QI")])
8897 (define_insn "*<code><mode>_3"
8898 [(set (reg FLAGS_REG)
8899 (compare (any_or:SWI
8900 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8901 (match_operand:SWI 2 "<general_operand>" "<g>"))
8903 (clobber (match_scratch:SWI 0 "=<r>"))]
8904 "ix86_match_ccmode (insn, CCNOmode)
8905 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8906 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8907 [(set_attr "type" "alu")
8908 (set_attr "mode" "<MODE>")])
8910 (define_insn "*<code>qi_ext_0"
8911 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8916 (match_operand 1 "ext_register_operand" "0")
8919 (match_operand 2 "const_int_operand" "n")))
8920 (clobber (reg:CC FLAGS_REG))]
8921 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8922 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8923 [(set_attr "type" "alu")
8924 (set_attr "length_immediate" "1")
8925 (set_attr "modrm" "1")
8926 (set_attr "mode" "QI")])
8928 (define_insn "*<code>qi_ext_1_rex64"
8929 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8934 (match_operand 1 "ext_register_operand" "0")
8938 (match_operand 2 "ext_register_operand" "Q"))))
8939 (clobber (reg:CC FLAGS_REG))]
8941 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8942 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8943 [(set_attr "type" "alu")
8944 (set_attr "length_immediate" "0")
8945 (set_attr "mode" "QI")])
8947 (define_insn "*<code>qi_ext_1"
8948 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8953 (match_operand 1 "ext_register_operand" "0")
8957 (match_operand:QI 2 "general_operand" "Qm"))))
8958 (clobber (reg:CC FLAGS_REG))]
8960 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8961 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8962 [(set_attr "type" "alu")
8963 (set_attr "length_immediate" "0")
8964 (set_attr "mode" "QI")])
8966 (define_insn "*<code>qi_ext_2"
8967 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8971 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8974 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8977 (clobber (reg:CC FLAGS_REG))]
8978 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8979 "<logicprefix>{b}\t{%h2, %h0|%h0, %h2}"
8980 [(set_attr "type" "alu")
8981 (set_attr "length_immediate" "0")
8982 (set_attr "mode" "QI")])
8985 [(set (match_operand 0 "register_operand" "")
8986 (any_or (match_operand 1 "register_operand" "")
8987 (match_operand 2 "const_int_operand" "")))
8988 (clobber (reg:CC FLAGS_REG))]
8990 && QI_REG_P (operands[0])
8991 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8992 && !(INTVAL (operands[2]) & ~(255 << 8))
8993 && GET_MODE (operands[0]) != QImode"
8994 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8995 (any_or:SI (zero_extract:SI (match_dup 1)
8996 (const_int 8) (const_int 8))
8998 (clobber (reg:CC FLAGS_REG))])]
8999 "operands[0] = gen_lowpart (SImode, operands[0]);
9000 operands[1] = gen_lowpart (SImode, operands[1]);
9001 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9003 ;; Since OR can be encoded with sign extended immediate, this is only
9004 ;; profitable when 7th bit is set.
9006 [(set (match_operand 0 "register_operand" "")
9007 (any_or (match_operand 1 "general_operand" "")
9008 (match_operand 2 "const_int_operand" "")))
9009 (clobber (reg:CC FLAGS_REG))]
9011 && ANY_QI_REG_P (operands[0])
9012 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9013 && !(INTVAL (operands[2]) & ~255)
9014 && (INTVAL (operands[2]) & 128)
9015 && GET_MODE (operands[0]) != QImode"
9016 [(parallel [(set (strict_low_part (match_dup 0))
9017 (any_or:QI (match_dup 1)
9019 (clobber (reg:CC FLAGS_REG))])]
9020 "operands[0] = gen_lowpart (QImode, operands[0]);
9021 operands[1] = gen_lowpart (QImode, operands[1]);
9022 operands[2] = gen_lowpart (QImode, operands[2]);")
9024 (define_expand "xorqi_cc_ext_1"
9026 (set (reg:CCNO FLAGS_REG)
9030 (match_operand 1 "ext_register_operand" "")
9033 (match_operand:QI 2 "general_operand" ""))
9035 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9047 (define_insn "*xorqi_cc_ext_1_rex64"
9048 [(set (reg FLAGS_REG)
9052 (match_operand 1 "ext_register_operand" "0")
9055 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9057 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9066 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9067 "xor{b}\t{%2, %h0|%h0, %2}"
9068 [(set_attr "type" "alu")
9069 (set_attr "modrm" "1")
9070 (set_attr "mode" "QI")])
9072 (define_insn "*xorqi_cc_ext_1"
9073 [(set (reg FLAGS_REG)
9077 (match_operand 1 "ext_register_operand" "0")
9080 (match_operand:QI 2 "general_operand" "qmn"))
9082 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9091 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9092 "xor{b}\t{%2, %h0|%h0, %2}"
9093 [(set_attr "type" "alu")
9094 (set_attr "modrm" "1")
9095 (set_attr "mode" "QI")])
9097 ;; Negation instructions
9099 (define_expand "neg<mode>2"
9100 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9101 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9103 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9105 (define_insn_and_split "*neg<dwi>2_doubleword"
9106 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9107 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9108 (clobber (reg:CC FLAGS_REG))]
9109 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9113 [(set (reg:CCZ FLAGS_REG)
9114 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9115 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9118 (plus:DWIH (match_dup 3)
9119 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9121 (clobber (reg:CC FLAGS_REG))])
9124 (neg:DWIH (match_dup 2)))
9125 (clobber (reg:CC FLAGS_REG))])]
9126 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9128 (define_insn "*neg<mode>2_1"
9129 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9130 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9131 (clobber (reg:CC FLAGS_REG))]
9132 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9133 "neg{<imodesuffix>}\t%0"
9134 [(set_attr "type" "negnot")
9135 (set_attr "mode" "<MODE>")])
9137 ;; Combine is quite creative about this pattern.
9138 (define_insn "*negsi2_1_zext"
9139 [(set (match_operand:DI 0 "register_operand" "=r")
9141 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9144 (clobber (reg:CC FLAGS_REG))]
9145 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9147 [(set_attr "type" "negnot")
9148 (set_attr "mode" "SI")])
9150 ;; The problem with neg is that it does not perform (compare x 0),
9151 ;; it really performs (compare 0 x), which leaves us with the zero
9152 ;; flag being the only useful item.
9154 (define_insn "*neg<mode>2_cmpz"
9155 [(set (reg:CCZ FLAGS_REG)
9157 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9159 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9160 (neg:SWI (match_dup 1)))]
9161 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9162 "neg{<imodesuffix>}\t%0"
9163 [(set_attr "type" "negnot")
9164 (set_attr "mode" "<MODE>")])
9166 (define_insn "*negsi2_cmpz_zext"
9167 [(set (reg:CCZ FLAGS_REG)
9171 (match_operand:DI 1 "register_operand" "0")
9175 (set (match_operand:DI 0 "register_operand" "=r")
9176 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9179 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9181 [(set_attr "type" "negnot")
9182 (set_attr "mode" "SI")])
9184 ;; Changing of sign for FP values is doable using integer unit too.
9186 (define_expand "<code><mode>2"
9187 [(set (match_operand:X87MODEF 0 "register_operand" "")
9188 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9189 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9190 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9192 (define_insn "*absneg<mode>2_mixed"
9193 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9194 (match_operator:MODEF 3 "absneg_operator"
9195 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9196 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9197 (clobber (reg:CC FLAGS_REG))]
9198 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9201 (define_insn "*absneg<mode>2_sse"
9202 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9203 (match_operator:MODEF 3 "absneg_operator"
9204 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9205 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9206 (clobber (reg:CC FLAGS_REG))]
9207 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9210 (define_insn "*absneg<mode>2_i387"
9211 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9212 (match_operator:X87MODEF 3 "absneg_operator"
9213 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9214 (use (match_operand 2 "" ""))
9215 (clobber (reg:CC FLAGS_REG))]
9216 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9219 (define_expand "<code>tf2"
9220 [(set (match_operand:TF 0 "register_operand" "")
9221 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9223 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9225 (define_insn "*absnegtf2_sse"
9226 [(set (match_operand:TF 0 "register_operand" "=x,x")
9227 (match_operator:TF 3 "absneg_operator"
9228 [(match_operand:TF 1 "register_operand" "0,x")]))
9229 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9230 (clobber (reg:CC FLAGS_REG))]
9234 ;; Splitters for fp abs and neg.
9237 [(set (match_operand 0 "fp_register_operand" "")
9238 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9239 (use (match_operand 2 "" ""))
9240 (clobber (reg:CC FLAGS_REG))]
9242 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9245 [(set (match_operand 0 "register_operand" "")
9246 (match_operator 3 "absneg_operator"
9247 [(match_operand 1 "register_operand" "")]))
9248 (use (match_operand 2 "nonimmediate_operand" ""))
9249 (clobber (reg:CC FLAGS_REG))]
9250 "reload_completed && SSE_REG_P (operands[0])"
9251 [(set (match_dup 0) (match_dup 3))]
9253 enum machine_mode mode = GET_MODE (operands[0]);
9254 enum machine_mode vmode = GET_MODE (operands[2]);
9257 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9258 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9259 if (operands_match_p (operands[0], operands[2]))
9262 operands[1] = operands[2];
9265 if (GET_CODE (operands[3]) == ABS)
9266 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9268 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9273 [(set (match_operand:SF 0 "register_operand" "")
9274 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9275 (use (match_operand:V4SF 2 "" ""))
9276 (clobber (reg:CC FLAGS_REG))]
9278 [(parallel [(set (match_dup 0) (match_dup 1))
9279 (clobber (reg:CC FLAGS_REG))])]
9282 operands[0] = gen_lowpart (SImode, operands[0]);
9283 if (GET_CODE (operands[1]) == ABS)
9285 tmp = gen_int_mode (0x7fffffff, SImode);
9286 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9290 tmp = gen_int_mode (0x80000000, SImode);
9291 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9297 [(set (match_operand:DF 0 "register_operand" "")
9298 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9299 (use (match_operand 2 "" ""))
9300 (clobber (reg:CC FLAGS_REG))]
9302 [(parallel [(set (match_dup 0) (match_dup 1))
9303 (clobber (reg:CC FLAGS_REG))])]
9308 tmp = gen_lowpart (DImode, operands[0]);
9309 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9312 if (GET_CODE (operands[1]) == ABS)
9315 tmp = gen_rtx_NOT (DImode, tmp);
9319 operands[0] = gen_highpart (SImode, operands[0]);
9320 if (GET_CODE (operands[1]) == ABS)
9322 tmp = gen_int_mode (0x7fffffff, SImode);
9323 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9327 tmp = gen_int_mode (0x80000000, SImode);
9328 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9335 [(set (match_operand:XF 0 "register_operand" "")
9336 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9337 (use (match_operand 2 "" ""))
9338 (clobber (reg:CC FLAGS_REG))]
9340 [(parallel [(set (match_dup 0) (match_dup 1))
9341 (clobber (reg:CC FLAGS_REG))])]
9344 operands[0] = gen_rtx_REG (SImode,
9345 true_regnum (operands[0])
9346 + (TARGET_64BIT ? 1 : 2));
9347 if (GET_CODE (operands[1]) == ABS)
9349 tmp = GEN_INT (0x7fff);
9350 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9354 tmp = GEN_INT (0x8000);
9355 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9360 ;; Conditionalize these after reload. If they match before reload, we
9361 ;; lose the clobber and ability to use integer instructions.
9363 (define_insn "*<code><mode>2_1"
9364 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9365 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9367 && (reload_completed
9368 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9370 [(set_attr "type" "fsgn")
9371 (set_attr "mode" "<MODE>")])
9373 (define_insn "*<code>extendsfdf2"
9374 [(set (match_operand:DF 0 "register_operand" "=f")
9375 (absneg:DF (float_extend:DF
9376 (match_operand:SF 1 "register_operand" "0"))))]
9377 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9379 [(set_attr "type" "fsgn")
9380 (set_attr "mode" "DF")])
9382 (define_insn "*<code>extendsfxf2"
9383 [(set (match_operand:XF 0 "register_operand" "=f")
9384 (absneg:XF (float_extend:XF
9385 (match_operand:SF 1 "register_operand" "0"))))]
9388 [(set_attr "type" "fsgn")
9389 (set_attr "mode" "XF")])
9391 (define_insn "*<code>extenddfxf2"
9392 [(set (match_operand:XF 0 "register_operand" "=f")
9393 (absneg:XF (float_extend:XF
9394 (match_operand:DF 1 "register_operand" "0"))))]
9397 [(set_attr "type" "fsgn")
9398 (set_attr "mode" "XF")])
9400 ;; Copysign instructions
9402 (define_mode_iterator CSGNMODE [SF DF TF])
9403 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9405 (define_expand "copysign<mode>3"
9406 [(match_operand:CSGNMODE 0 "register_operand" "")
9407 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9408 (match_operand:CSGNMODE 2 "register_operand" "")]
9409 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9410 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9412 ix86_expand_copysign (operands);
9416 (define_insn_and_split "copysign<mode>3_const"
9417 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9419 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9420 (match_operand:CSGNMODE 2 "register_operand" "0")
9421 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9423 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9424 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9426 "&& reload_completed"
9429 ix86_split_copysign_const (operands);
9433 (define_insn "copysign<mode>3_var"
9434 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9436 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9437 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9438 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9439 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9441 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9442 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9443 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9447 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9449 [(match_operand:CSGNMODE 2 "register_operand" "")
9450 (match_operand:CSGNMODE 3 "register_operand" "")
9451 (match_operand:<CSGNVMODE> 4 "" "")
9452 (match_operand:<CSGNVMODE> 5 "" "")]
9454 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9455 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9456 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9457 && reload_completed"
9460 ix86_split_copysign_var (operands);
9464 ;; One complement instructions
9466 (define_expand "one_cmpl<mode>2"
9467 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9468 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9470 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9472 (define_insn "*one_cmpl<mode>2_1"
9473 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9474 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9475 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9476 "not{<imodesuffix>}\t%0"
9477 [(set_attr "type" "negnot")
9478 (set_attr "mode" "<MODE>")])
9480 ;; %%% Potential partial reg stall on alternative 1. What to do?
9481 (define_insn "*one_cmplqi2_1"
9482 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9483 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9484 "ix86_unary_operator_ok (NOT, QImode, operands)"
9488 [(set_attr "type" "negnot")
9489 (set_attr "mode" "QI,SI")])
9491 ;; ??? Currently never generated - xor is used instead.
9492 (define_insn "*one_cmplsi2_1_zext"
9493 [(set (match_operand:DI 0 "register_operand" "=r")
9495 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9496 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9498 [(set_attr "type" "negnot")
9499 (set_attr "mode" "SI")])
9501 (define_insn "*one_cmpl<mode>2_2"
9502 [(set (reg FLAGS_REG)
9503 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9505 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9506 (not:SWI (match_dup 1)))]
9507 "ix86_match_ccmode (insn, CCNOmode)
9508 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9510 [(set_attr "type" "alu1")
9511 (set_attr "mode" "<MODE>")])
9514 [(set (match_operand 0 "flags_reg_operand" "")
9515 (match_operator 2 "compare_operator"
9516 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9518 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9519 (not:SWI (match_dup 3)))]
9520 "ix86_match_ccmode (insn, CCNOmode)"
9521 [(parallel [(set (match_dup 0)
9522 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9525 (xor:SWI (match_dup 3) (const_int -1)))])]
9528 ;; ??? Currently never generated - xor is used instead.
9529 (define_insn "*one_cmplsi2_2_zext"
9530 [(set (reg FLAGS_REG)
9531 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9533 (set (match_operand:DI 0 "register_operand" "=r")
9534 (zero_extend:DI (not:SI (match_dup 1))))]
9535 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9536 && ix86_unary_operator_ok (NOT, SImode, operands)"
9538 [(set_attr "type" "alu1")
9539 (set_attr "mode" "SI")])
9542 [(set (match_operand 0 "flags_reg_operand" "")
9543 (match_operator 2 "compare_operator"
9544 [(not:SI (match_operand:SI 3 "register_operand" ""))
9546 (set (match_operand:DI 1 "register_operand" "")
9547 (zero_extend:DI (not:SI (match_dup 3))))]
9548 "ix86_match_ccmode (insn, CCNOmode)"
9549 [(parallel [(set (match_dup 0)
9550 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9553 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9556 ;; Shift instructions
9558 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9559 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9560 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9561 ;; from the assembler input.
9563 ;; This instruction shifts the target reg/mem as usual, but instead of
9564 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9565 ;; is a left shift double, bits are taken from the high order bits of
9566 ;; reg, else if the insn is a shift right double, bits are taken from the
9567 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9568 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9570 ;; Since sh[lr]d does not change the `reg' operand, that is done
9571 ;; separately, making all shifts emit pairs of shift double and normal
9572 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9573 ;; support a 63 bit shift, each shift where the count is in a reg expands
9574 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9576 ;; If the shift count is a constant, we need never emit more than one
9577 ;; shift pair, instead using moves and sign extension for counts greater
9580 (define_expand "ashl<mode>3"
9581 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9582 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9583 (match_operand:QI 2 "nonmemory_operand" "")))]
9585 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9587 (define_insn "*ashl<mode>3_doubleword"
9588 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9589 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9590 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9591 (clobber (reg:CC FLAGS_REG))]
9594 [(set_attr "type" "multi")])
9597 [(set (match_operand:DWI 0 "register_operand" "")
9598 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9599 (match_operand:QI 2 "nonmemory_operand" "")))
9600 (clobber (reg:CC FLAGS_REG))]
9601 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9603 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9605 ;; By default we don't ask for a scratch register, because when DWImode
9606 ;; values are manipulated, registers are already at a premium. But if
9607 ;; we have one handy, we won't turn it away.
9610 [(match_scratch:DWIH 3 "r")
9611 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9613 (match_operand:<DWI> 1 "nonmemory_operand" "")
9614 (match_operand:QI 2 "nonmemory_operand" "")))
9615 (clobber (reg:CC FLAGS_REG))])
9619 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9621 (define_insn "x86_64_shld"
9622 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9623 (ior:DI (ashift:DI (match_dup 0)
9624 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9625 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9626 (minus:QI (const_int 64) (match_dup 2)))))
9627 (clobber (reg:CC FLAGS_REG))]
9629 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9630 [(set_attr "type" "ishift")
9631 (set_attr "prefix_0f" "1")
9632 (set_attr "mode" "DI")
9633 (set_attr "athlon_decode" "vector")
9634 (set_attr "amdfam10_decode" "vector")])
9636 (define_insn "x86_shld"
9637 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9638 (ior:SI (ashift:SI (match_dup 0)
9639 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9640 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9641 (minus:QI (const_int 32) (match_dup 2)))))
9642 (clobber (reg:CC FLAGS_REG))]
9644 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9645 [(set_attr "type" "ishift")
9646 (set_attr "prefix_0f" "1")
9647 (set_attr "mode" "SI")
9648 (set_attr "pent_pair" "np")
9649 (set_attr "athlon_decode" "vector")
9650 (set_attr "amdfam10_decode" "vector")])
9652 (define_expand "x86_shift<mode>_adj_1"
9653 [(set (reg:CCZ FLAGS_REG)
9654 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9657 (set (match_operand:SWI48 0 "register_operand" "")
9658 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9659 (match_operand:SWI48 1 "register_operand" "")
9662 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9663 (match_operand:SWI48 3 "register_operand" "r")
9666 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9668 (define_expand "x86_shift<mode>_adj_2"
9669 [(use (match_operand:SWI48 0 "register_operand" ""))
9670 (use (match_operand:SWI48 1 "register_operand" ""))
9671 (use (match_operand:QI 2 "register_operand" ""))]
9674 rtx label = gen_label_rtx ();
9677 emit_insn (gen_testqi_ccz_1 (operands[2],
9678 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9680 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9681 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9682 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9683 gen_rtx_LABEL_REF (VOIDmode, label),
9685 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9686 JUMP_LABEL (tmp) = label;
9688 emit_move_insn (operands[0], operands[1]);
9689 ix86_expand_clear (operands[1]);
9692 LABEL_NUSES (label) = 1;
9697 (define_insn "*ashl<mode>3_1"
9698 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9699 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9700 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9701 (clobber (reg:CC FLAGS_REG))]
9702 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9704 switch (get_attr_type (insn))
9710 gcc_assert (operands[2] == const1_rtx);
9711 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9712 return "add{<imodesuffix>}\t%0, %0";
9715 if (operands[2] == const1_rtx
9716 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9717 return "sal{<imodesuffix>}\t%0";
9719 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9723 (cond [(eq_attr "alternative" "1")
9724 (const_string "lea")
9725 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9727 (match_operand 0 "register_operand" ""))
9728 (match_operand 2 "const1_operand" ""))
9729 (const_string "alu")
9731 (const_string "ishift")))
9732 (set (attr "length_immediate")
9734 (ior (eq_attr "type" "alu")
9735 (and (eq_attr "type" "ishift")
9736 (and (match_operand 2 "const1_operand" "")
9737 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9740 (const_string "*")))
9741 (set_attr "mode" "<MODE>")])
9743 (define_insn "*ashlsi3_1_zext"
9744 [(set (match_operand:DI 0 "register_operand" "=r,r")
9746 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9747 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9748 (clobber (reg:CC FLAGS_REG))]
9749 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9751 switch (get_attr_type (insn))
9757 gcc_assert (operands[2] == const1_rtx);
9758 return "add{l}\t%k0, %k0";
9761 if (operands[2] == const1_rtx
9762 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9763 return "sal{l}\t%k0";
9765 return "sal{l}\t{%2, %k0|%k0, %2}";
9769 (cond [(eq_attr "alternative" "1")
9770 (const_string "lea")
9771 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9773 (match_operand 2 "const1_operand" ""))
9774 (const_string "alu")
9776 (const_string "ishift")))
9777 (set (attr "length_immediate")
9779 (ior (eq_attr "type" "alu")
9780 (and (eq_attr "type" "ishift")
9781 (and (match_operand 2 "const1_operand" "")
9782 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9785 (const_string "*")))
9786 (set_attr "mode" "SI")])
9788 (define_insn "*ashlhi3_1"
9789 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9790 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9791 (match_operand:QI 2 "nonmemory_operand" "cI")))
9792 (clobber (reg:CC FLAGS_REG))]
9793 "TARGET_PARTIAL_REG_STALL
9794 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9796 switch (get_attr_type (insn))
9799 gcc_assert (operands[2] == const1_rtx);
9800 return "add{w}\t%0, %0";
9803 if (operands[2] == const1_rtx
9804 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9805 return "sal{w}\t%0";
9807 return "sal{w}\t{%2, %0|%0, %2}";
9811 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9813 (match_operand 0 "register_operand" ""))
9814 (match_operand 2 "const1_operand" ""))
9815 (const_string "alu")
9817 (const_string "ishift")))
9818 (set (attr "length_immediate")
9820 (ior (eq_attr "type" "alu")
9821 (and (eq_attr "type" "ishift")
9822 (and (match_operand 2 "const1_operand" "")
9823 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9826 (const_string "*")))
9827 (set_attr "mode" "HI")])
9829 (define_insn "*ashlhi3_1_lea"
9830 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9831 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9832 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9833 (clobber (reg:CC FLAGS_REG))]
9834 "!TARGET_PARTIAL_REG_STALL
9835 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9837 switch (get_attr_type (insn))
9843 gcc_assert (operands[2] == const1_rtx);
9844 return "add{w}\t%0, %0";
9847 if (operands[2] == const1_rtx
9848 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9849 return "sal{w}\t%0";
9851 return "sal{w}\t{%2, %0|%0, %2}";
9855 (cond [(eq_attr "alternative" "1")
9856 (const_string "lea")
9857 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9859 (match_operand 0 "register_operand" ""))
9860 (match_operand 2 "const1_operand" ""))
9861 (const_string "alu")
9863 (const_string "ishift")))
9864 (set (attr "length_immediate")
9866 (ior (eq_attr "type" "alu")
9867 (and (eq_attr "type" "ishift")
9868 (and (match_operand 2 "const1_operand" "")
9869 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9872 (const_string "*")))
9873 (set_attr "mode" "HI,SI")])
9875 (define_insn "*ashlqi3_1"
9876 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9877 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9878 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9879 (clobber (reg:CC FLAGS_REG))]
9880 "TARGET_PARTIAL_REG_STALL
9881 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9883 switch (get_attr_type (insn))
9886 gcc_assert (operands[2] == const1_rtx);
9887 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9888 return "add{l}\t%k0, %k0";
9890 return "add{b}\t%0, %0";
9893 if (operands[2] == const1_rtx
9894 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9896 if (get_attr_mode (insn) == MODE_SI)
9897 return "sal{l}\t%k0";
9899 return "sal{b}\t%0";
9903 if (get_attr_mode (insn) == MODE_SI)
9904 return "sal{l}\t{%2, %k0|%k0, %2}";
9906 return "sal{b}\t{%2, %0|%0, %2}";
9911 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9913 (match_operand 0 "register_operand" ""))
9914 (match_operand 2 "const1_operand" ""))
9915 (const_string "alu")
9917 (const_string "ishift")))
9918 (set (attr "length_immediate")
9920 (ior (eq_attr "type" "alu")
9921 (and (eq_attr "type" "ishift")
9922 (and (match_operand 2 "const1_operand" "")
9923 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9926 (const_string "*")))
9927 (set_attr "mode" "QI,SI")])
9929 ;; %%% Potential partial reg stall on alternative 2. What to do?
9930 (define_insn "*ashlqi3_1_lea"
9931 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9932 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9933 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9934 (clobber (reg:CC FLAGS_REG))]
9935 "!TARGET_PARTIAL_REG_STALL
9936 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9938 switch (get_attr_type (insn))
9944 gcc_assert (operands[2] == const1_rtx);
9945 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9946 return "add{l}\t%k0, %k0";
9948 return "add{b}\t%0, %0";
9951 if (operands[2] == const1_rtx
9952 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9954 if (get_attr_mode (insn) == MODE_SI)
9955 return "sal{l}\t%k0";
9957 return "sal{b}\t%0";
9961 if (get_attr_mode (insn) == MODE_SI)
9962 return "sal{l}\t{%2, %k0|%k0, %2}";
9964 return "sal{b}\t{%2, %0|%0, %2}";
9969 (cond [(eq_attr "alternative" "2")
9970 (const_string "lea")
9971 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9973 (match_operand 0 "register_operand" ""))
9974 (match_operand 2 "const1_operand" ""))
9975 (const_string "alu")
9977 (const_string "ishift")))
9978 (set (attr "length_immediate")
9980 (ior (eq_attr "type" "alu")
9981 (and (eq_attr "type" "ishift")
9982 (and (match_operand 2 "const1_operand" "")
9983 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9986 (const_string "*")))
9987 (set_attr "mode" "QI,SI,SI")])
9989 ;; Convert lea to the lea pattern to avoid flags dependency.
9991 [(set (match_operand:DI 0 "register_operand" "")
9992 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9993 (match_operand:QI 2 "const_int_operand" "")))
9994 (clobber (reg:CC FLAGS_REG))]
9995 "TARGET_64BIT && reload_completed
9996 && true_regnum (operands[0]) != true_regnum (operands[1])"
9998 (mult:DI (match_dup 1)
10000 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10002 ;; Convert lea to the lea pattern to avoid flags dependency.
10004 [(set (match_operand 0 "register_operand" "")
10005 (ashift (match_operand 1 "index_register_operand" "")
10006 (match_operand:QI 2 "const_int_operand" "")))
10007 (clobber (reg:CC FLAGS_REG))]
10009 && true_regnum (operands[0]) != true_regnum (operands[1])
10010 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10014 enum machine_mode mode = GET_MODE (operands[0]);
10016 if (GET_MODE_SIZE (mode) < 4)
10017 operands[0] = gen_lowpart (SImode, operands[0]);
10019 operands[1] = gen_lowpart (Pmode, operands[1]);
10020 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10022 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10023 if (Pmode != SImode)
10024 pat = gen_rtx_SUBREG (SImode, pat, 0);
10025 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10029 ;; Rare case of shifting RSP is handled by generating move and shift
10031 [(set (match_operand 0 "register_operand" "")
10032 (ashift (match_operand 1 "register_operand" "")
10033 (match_operand:QI 2 "const_int_operand" "")))
10034 (clobber (reg:CC FLAGS_REG))]
10036 && true_regnum (operands[0]) != true_regnum (operands[1])"
10040 emit_move_insn (operands[0], operands[1]);
10041 pat = gen_rtx_SET (VOIDmode, operands[0],
10042 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10043 operands[0], operands[2]));
10044 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10045 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10049 ;; Convert lea to the lea pattern to avoid flags dependency.
10051 [(set (match_operand:DI 0 "register_operand" "")
10053 (ashift:SI (match_operand:SI 1 "register_operand" "")
10054 (match_operand:QI 2 "const_int_operand" ""))))
10055 (clobber (reg:CC FLAGS_REG))]
10056 "TARGET_64BIT && reload_completed
10057 && true_regnum (operands[0]) != true_regnum (operands[1])"
10058 [(set (match_dup 0)
10059 (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10061 operands[1] = gen_lowpart (Pmode, operands[1]);
10062 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10065 ;; This pattern can't accept a variable shift count, since shifts by
10066 ;; zero don't affect the flags. We assume that shifts by constant
10067 ;; zero are optimized away.
10068 (define_insn "*ashl<mode>3_cmp"
10069 [(set (reg FLAGS_REG)
10071 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10072 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10074 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10075 (ashift:SWI (match_dup 1) (match_dup 2)))]
10076 "(optimize_function_for_size_p (cfun)
10077 || !TARGET_PARTIAL_FLAG_REG_STALL
10078 || (operands[2] == const1_rtx
10080 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10081 && ix86_match_ccmode (insn, CCGOCmode)
10082 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10084 switch (get_attr_type (insn))
10087 gcc_assert (operands[2] == const1_rtx);
10088 return "add{<imodesuffix>}\t%0, %0";
10091 if (operands[2] == const1_rtx
10092 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10093 return "sal{<imodesuffix>}\t%0";
10095 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10098 [(set (attr "type")
10099 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10101 (match_operand 0 "register_operand" ""))
10102 (match_operand 2 "const1_operand" ""))
10103 (const_string "alu")
10105 (const_string "ishift")))
10106 (set (attr "length_immediate")
10108 (ior (eq_attr "type" "alu")
10109 (and (eq_attr "type" "ishift")
10110 (and (match_operand 2 "const1_operand" "")
10111 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10114 (const_string "*")))
10115 (set_attr "mode" "<MODE>")])
10117 (define_insn "*ashlsi3_cmp_zext"
10118 [(set (reg FLAGS_REG)
10120 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10121 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10123 (set (match_operand:DI 0 "register_operand" "=r")
10124 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10126 && (optimize_function_for_size_p (cfun)
10127 || !TARGET_PARTIAL_FLAG_REG_STALL
10128 || (operands[2] == const1_rtx
10130 || TARGET_DOUBLE_WITH_ADD)))
10131 && ix86_match_ccmode (insn, CCGOCmode)
10132 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10134 switch (get_attr_type (insn))
10137 gcc_assert (operands[2] == const1_rtx);
10138 return "add{l}\t%k0, %k0";
10141 if (operands[2] == const1_rtx
10142 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10143 return "sal{l}\t%k0";
10145 return "sal{l}\t{%2, %k0|%k0, %2}";
10148 [(set (attr "type")
10149 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10151 (match_operand 2 "const1_operand" ""))
10152 (const_string "alu")
10154 (const_string "ishift")))
10155 (set (attr "length_immediate")
10157 (ior (eq_attr "type" "alu")
10158 (and (eq_attr "type" "ishift")
10159 (and (match_operand 2 "const1_operand" "")
10160 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10163 (const_string "*")))
10164 (set_attr "mode" "SI")])
10166 (define_insn "*ashl<mode>3_cconly"
10167 [(set (reg FLAGS_REG)
10169 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10170 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10172 (clobber (match_scratch:SWI 0 "=<r>"))]
10173 "(optimize_function_for_size_p (cfun)
10174 || !TARGET_PARTIAL_FLAG_REG_STALL
10175 || (operands[2] == const1_rtx
10177 || TARGET_DOUBLE_WITH_ADD)))
10178 && ix86_match_ccmode (insn, CCGOCmode)
10179 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10181 switch (get_attr_type (insn))
10184 gcc_assert (operands[2] == const1_rtx);
10185 return "add{<imodesuffix>}\t%0, %0";
10188 if (operands[2] == const1_rtx
10189 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10190 return "sal{<imodesuffix>}\t%0";
10192 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10195 [(set (attr "type")
10196 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10198 (match_operand 0 "register_operand" ""))
10199 (match_operand 2 "const1_operand" ""))
10200 (const_string "alu")
10202 (const_string "ishift")))
10203 (set (attr "length_immediate")
10205 (ior (eq_attr "type" "alu")
10206 (and (eq_attr "type" "ishift")
10207 (and (match_operand 2 "const1_operand" "")
10208 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10211 (const_string "*")))
10212 (set_attr "mode" "<MODE>")])
10214 ;; See comment above `ashl<mode>3' about how this works.
10216 (define_expand "<shiftrt_insn><mode>3"
10217 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
10218 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
10219 (match_operand:QI 2 "nonmemory_operand" "")))]
10221 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10223 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
10224 [(set (match_operand:DWI 0 "register_operand" "=r")
10225 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10226 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10227 (clobber (reg:CC FLAGS_REG))]
10230 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10232 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10233 [(set_attr "type" "multi")])
10235 ;; By default we don't ask for a scratch register, because when DWImode
10236 ;; values are manipulated, registers are already at a premium. But if
10237 ;; we have one handy, we won't turn it away.
10240 [(match_scratch:DWIH 3 "r")
10241 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
10243 (match_operand:<DWI> 1 "register_operand" "")
10244 (match_operand:QI 2 "nonmemory_operand" "")))
10245 (clobber (reg:CC FLAGS_REG))])
10249 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
10251 (define_insn "x86_64_shrd"
10252 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10253 (ior:DI (ashiftrt:DI (match_dup 0)
10254 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10255 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10256 (minus:QI (const_int 64) (match_dup 2)))))
10257 (clobber (reg:CC FLAGS_REG))]
10259 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10260 [(set_attr "type" "ishift")
10261 (set_attr "prefix_0f" "1")
10262 (set_attr "mode" "DI")
10263 (set_attr "athlon_decode" "vector")
10264 (set_attr "amdfam10_decode" "vector")])
10266 (define_insn "x86_shrd"
10267 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10268 (ior:SI (ashiftrt:SI (match_dup 0)
10269 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10270 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10271 (minus:QI (const_int 32) (match_dup 2)))))
10272 (clobber (reg:CC FLAGS_REG))]
10274 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10275 [(set_attr "type" "ishift")
10276 (set_attr "prefix_0f" "1")
10277 (set_attr "pent_pair" "np")
10278 (set_attr "mode" "SI")])
10280 (define_insn "ashrdi3_cvt"
10281 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10282 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10283 (match_operand:QI 2 "const_int_operand" "")))
10284 (clobber (reg:CC FLAGS_REG))]
10285 "TARGET_64BIT && INTVAL (operands[2]) == 63
10286 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10287 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10290 sar{q}\t{%2, %0|%0, %2}"
10291 [(set_attr "type" "imovx,ishift")
10292 (set_attr "prefix_0f" "0,*")
10293 (set_attr "length_immediate" "0,*")
10294 (set_attr "modrm" "0,1")
10295 (set_attr "mode" "DI")])
10297 (define_insn "ashrsi3_cvt"
10298 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10299 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10300 (match_operand:QI 2 "const_int_operand" "")))
10301 (clobber (reg:CC FLAGS_REG))]
10302 "INTVAL (operands[2]) == 31
10303 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10304 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10307 sar{l}\t{%2, %0|%0, %2}"
10308 [(set_attr "type" "imovx,ishift")
10309 (set_attr "prefix_0f" "0,*")
10310 (set_attr "length_immediate" "0,*")
10311 (set_attr "modrm" "0,1")
10312 (set_attr "mode" "SI")])
10314 (define_insn "*ashrsi3_cvt_zext"
10315 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10317 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10318 (match_operand:QI 2 "const_int_operand" ""))))
10319 (clobber (reg:CC FLAGS_REG))]
10320 "TARGET_64BIT && INTVAL (operands[2]) == 31
10321 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10322 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10325 sar{l}\t{%2, %k0|%k0, %2}"
10326 [(set_attr "type" "imovx,ishift")
10327 (set_attr "prefix_0f" "0,*")
10328 (set_attr "length_immediate" "0,*")
10329 (set_attr "modrm" "0,1")
10330 (set_attr "mode" "SI")])
10332 (define_expand "x86_shift<mode>_adj_3"
10333 [(use (match_operand:SWI48 0 "register_operand" ""))
10334 (use (match_operand:SWI48 1 "register_operand" ""))
10335 (use (match_operand:QI 2 "register_operand" ""))]
10338 rtx label = gen_label_rtx ();
10341 emit_insn (gen_testqi_ccz_1 (operands[2],
10342 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10344 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10345 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10346 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10347 gen_rtx_LABEL_REF (VOIDmode, label),
10349 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10350 JUMP_LABEL (tmp) = label;
10352 emit_move_insn (operands[0], operands[1]);
10353 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10354 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10355 emit_label (label);
10356 LABEL_NUSES (label) = 1;
10361 (define_insn "*<shiftrt_insn><mode>3_1"
10362 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10363 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10364 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10365 (clobber (reg:CC FLAGS_REG))]
10366 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10368 if (operands[2] == const1_rtx
10369 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10370 return "<shiftrt>{<imodesuffix>}\t%0";
10372 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10374 [(set_attr "type" "ishift")
10375 (set (attr "length_immediate")
10377 (and (match_operand 2 "const1_operand" "")
10378 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10381 (const_string "*")))
10382 (set_attr "mode" "<MODE>")])
10384 (define_insn "*<shiftrt_insn>si3_1_zext"
10385 [(set (match_operand:DI 0 "register_operand" "=r")
10387 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10388 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10389 (clobber (reg:CC FLAGS_REG))]
10390 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10392 if (operands[2] == const1_rtx
10393 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10394 return "<shiftrt>{l}\t%k0";
10396 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10398 [(set_attr "type" "ishift")
10399 (set (attr "length_immediate")
10401 (and (match_operand 2 "const1_operand" "")
10402 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10405 (const_string "*")))
10406 (set_attr "mode" "SI")])
10408 (define_insn "*<shiftrt_insn>qi3_1_slp"
10409 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10410 (any_shiftrt:QI (match_dup 0)
10411 (match_operand:QI 1 "nonmemory_operand" "cI")))
10412 (clobber (reg:CC FLAGS_REG))]
10413 "(optimize_function_for_size_p (cfun)
10414 || !TARGET_PARTIAL_REG_STALL
10415 || (operands[1] == const1_rtx
10416 && TARGET_SHIFT1))"
10418 if (operands[1] == const1_rtx
10419 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10420 return "<shiftrt>{b}\t%0";
10422 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10424 [(set_attr "type" "ishift1")
10425 (set (attr "length_immediate")
10427 (and (match_operand 1 "const1_operand" "")
10428 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10431 (const_string "*")))
10432 (set_attr "mode" "QI")])
10434 ;; This pattern can't accept a variable shift count, since shifts by
10435 ;; zero don't affect the flags. We assume that shifts by constant
10436 ;; zero are optimized away.
10437 (define_insn "*<shiftrt_insn><mode>3_cmp"
10438 [(set (reg FLAGS_REG)
10441 (match_operand:SWI 1 "nonimmediate_operand" "0")
10442 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10444 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10445 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10446 "(optimize_function_for_size_p (cfun)
10447 || !TARGET_PARTIAL_FLAG_REG_STALL
10448 || (operands[2] == const1_rtx
10450 && ix86_match_ccmode (insn, CCGOCmode)
10451 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10453 if (operands[2] == const1_rtx
10454 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10455 return "<shiftrt>{<imodesuffix>}\t%0";
10457 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10459 [(set_attr "type" "ishift")
10460 (set (attr "length_immediate")
10462 (and (match_operand 2 "const1_operand" "")
10463 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10466 (const_string "*")))
10467 (set_attr "mode" "<MODE>")])
10469 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10470 [(set (reg FLAGS_REG)
10472 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10473 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10475 (set (match_operand:DI 0 "register_operand" "=r")
10476 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10478 && (optimize_function_for_size_p (cfun)
10479 || !TARGET_PARTIAL_FLAG_REG_STALL
10480 || (operands[2] == const1_rtx
10482 && ix86_match_ccmode (insn, CCGOCmode)
10483 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10485 if (operands[2] == const1_rtx
10486 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10487 return "<shiftrt>{l}\t%k0";
10489 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10491 [(set_attr "type" "ishift")
10492 (set (attr "length_immediate")
10494 (and (match_operand 2 "const1_operand" "")
10495 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10498 (const_string "*")))
10499 (set_attr "mode" "SI")])
10501 (define_insn "*<shiftrt_insn><mode>3_cconly"
10502 [(set (reg FLAGS_REG)
10505 (match_operand:SWI 1 "nonimmediate_operand" "0")
10506 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10508 (clobber (match_scratch:SWI 0 "=<r>"))]
10509 "(optimize_function_for_size_p (cfun)
10510 || !TARGET_PARTIAL_FLAG_REG_STALL
10511 || (operands[2] == const1_rtx
10513 && ix86_match_ccmode (insn, CCGOCmode)
10514 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10516 if (operands[2] == const1_rtx
10517 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10518 return "<shiftrt>{<imodesuffix>}\t%0";
10520 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10522 [(set_attr "type" "ishift")
10523 (set (attr "length_immediate")
10525 (and (match_operand 2 "const1_operand" "")
10526 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10529 (const_string "*")))
10530 (set_attr "mode" "<MODE>")])
10532 ;; Rotate instructions
10534 (define_expand "<rotate_insn>ti3"
10535 [(set (match_operand:TI 0 "register_operand" "")
10536 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10537 (match_operand:QI 2 "nonmemory_operand" "")))]
10540 if (const_1_to_63_operand (operands[2], VOIDmode))
10541 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10542 (operands[0], operands[1], operands[2]));
10549 (define_expand "<rotate_insn>di3"
10550 [(set (match_operand:DI 0 "shiftdi_operand" "")
10551 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10552 (match_operand:QI 2 "nonmemory_operand" "")))]
10556 ix86_expand_binary_operator (<CODE>, DImode, operands);
10557 else if (const_1_to_31_operand (operands[2], VOIDmode))
10558 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10559 (operands[0], operands[1], operands[2]));
10566 (define_expand "<rotate_insn><mode>3"
10567 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10568 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10569 (match_operand:QI 2 "nonmemory_operand" "")))]
10571 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10573 ;; Implement rotation using two double-precision
10574 ;; shift instructions and a scratch register.
10576 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10577 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10578 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10579 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10580 (clobber (reg:CC FLAGS_REG))
10581 (clobber (match_scratch:DWIH 3 "=&r"))]
10585 [(set (match_dup 3) (match_dup 4))
10587 [(set (match_dup 4)
10588 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10589 (lshiftrt:DWIH (match_dup 5)
10590 (minus:QI (match_dup 6) (match_dup 2)))))
10591 (clobber (reg:CC FLAGS_REG))])
10593 [(set (match_dup 5)
10594 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10595 (lshiftrt:DWIH (match_dup 3)
10596 (minus:QI (match_dup 6) (match_dup 2)))))
10597 (clobber (reg:CC FLAGS_REG))])]
10599 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10601 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10604 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10605 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10606 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10607 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10608 (clobber (reg:CC FLAGS_REG))
10609 (clobber (match_scratch:DWIH 3 "=&r"))]
10613 [(set (match_dup 3) (match_dup 4))
10615 [(set (match_dup 4)
10616 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10617 (ashift:DWIH (match_dup 5)
10618 (minus:QI (match_dup 6) (match_dup 2)))))
10619 (clobber (reg:CC FLAGS_REG))])
10621 [(set (match_dup 5)
10622 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10623 (ashift:DWIH (match_dup 3)
10624 (minus:QI (match_dup 6) (match_dup 2)))))
10625 (clobber (reg:CC FLAGS_REG))])]
10627 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10629 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10632 (define_insn "*<rotate_insn><mode>3_1"
10633 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10634 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10635 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10636 (clobber (reg:CC FLAGS_REG))]
10637 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10639 if (operands[2] == const1_rtx
10640 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10641 return "<rotate>{<imodesuffix>}\t%0";
10643 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10645 [(set_attr "type" "rotate")
10646 (set (attr "length_immediate")
10648 (and (match_operand 2 "const1_operand" "")
10649 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10652 (const_string "*")))
10653 (set_attr "mode" "<MODE>")])
10655 (define_insn "*<rotate_insn>si3_1_zext"
10656 [(set (match_operand:DI 0 "register_operand" "=r")
10658 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10659 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10660 (clobber (reg:CC FLAGS_REG))]
10661 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10663 if (operands[2] == const1_rtx
10664 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10665 return "<rotate>{l}\t%k0";
10667 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10669 [(set_attr "type" "rotate")
10670 (set (attr "length_immediate")
10672 (and (match_operand 2 "const1_operand" "")
10673 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10676 (const_string "*")))
10677 (set_attr "mode" "SI")])
10679 (define_insn "*<rotate_insn>qi3_1_slp"
10680 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10681 (any_rotate:QI (match_dup 0)
10682 (match_operand:QI 1 "nonmemory_operand" "cI")))
10683 (clobber (reg:CC FLAGS_REG))]
10684 "(optimize_function_for_size_p (cfun)
10685 || !TARGET_PARTIAL_REG_STALL
10686 || (operands[1] == const1_rtx
10687 && TARGET_SHIFT1))"
10689 if (operands[1] == const1_rtx
10690 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10691 return "<rotate>{b}\t%0";
10693 return "<rotate>{b}\t{%1, %0|%0, %1}";
10695 [(set_attr "type" "rotate1")
10696 (set (attr "length_immediate")
10698 (and (match_operand 1 "const1_operand" "")
10699 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10702 (const_string "*")))
10703 (set_attr "mode" "QI")])
10706 [(set (match_operand:HI 0 "register_operand" "")
10707 (any_rotate:HI (match_dup 0) (const_int 8)))
10708 (clobber (reg:CC FLAGS_REG))]
10710 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10711 [(parallel [(set (strict_low_part (match_dup 0))
10712 (bswap:HI (match_dup 0)))
10713 (clobber (reg:CC FLAGS_REG))])]
10716 ;; Bit set / bit test instructions
10718 (define_expand "extv"
10719 [(set (match_operand:SI 0 "register_operand" "")
10720 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10721 (match_operand:SI 2 "const8_operand" "")
10722 (match_operand:SI 3 "const8_operand" "")))]
10725 /* Handle extractions from %ah et al. */
10726 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10729 /* From mips.md: extract_bit_field doesn't verify that our source
10730 matches the predicate, so check it again here. */
10731 if (! ext_register_operand (operands[1], VOIDmode))
10735 (define_expand "extzv"
10736 [(set (match_operand:SI 0 "register_operand" "")
10737 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10738 (match_operand:SI 2 "const8_operand" "")
10739 (match_operand:SI 3 "const8_operand" "")))]
10742 /* Handle extractions from %ah et al. */
10743 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10746 /* From mips.md: extract_bit_field doesn't verify that our source
10747 matches the predicate, so check it again here. */
10748 if (! ext_register_operand (operands[1], VOIDmode))
10752 (define_expand "insv"
10753 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10754 (match_operand 1 "const8_operand" "")
10755 (match_operand 2 "const8_operand" ""))
10756 (match_operand 3 "register_operand" ""))]
10759 /* Handle insertions to %ah et al. */
10760 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10763 /* From mips.md: insert_bit_field doesn't verify that our source
10764 matches the predicate, so check it again here. */
10765 if (! ext_register_operand (operands[0], VOIDmode))
10769 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
10771 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10776 ;; %%% bts, btr, btc, bt.
10777 ;; In general these instructions are *slow* when applied to memory,
10778 ;; since they enforce atomic operation. When applied to registers,
10779 ;; it depends on the cpu implementation. They're never faster than
10780 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10781 ;; no point. But in 64-bit, we can't hold the relevant immediates
10782 ;; within the instruction itself, so operating on bits in the high
10783 ;; 32-bits of a register becomes easier.
10785 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10786 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10787 ;; negdf respectively, so they can never be disabled entirely.
10789 (define_insn "*btsq"
10790 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10792 (match_operand:DI 1 "const_0_to_63_operand" ""))
10794 (clobber (reg:CC FLAGS_REG))]
10795 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10796 "bts{q}\t{%1, %0|%0, %1}"
10797 [(set_attr "type" "alu1")
10798 (set_attr "prefix_0f" "1")
10799 (set_attr "mode" "DI")])
10801 (define_insn "*btrq"
10802 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10804 (match_operand:DI 1 "const_0_to_63_operand" ""))
10806 (clobber (reg:CC FLAGS_REG))]
10807 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10808 "btr{q}\t{%1, %0|%0, %1}"
10809 [(set_attr "type" "alu1")
10810 (set_attr "prefix_0f" "1")
10811 (set_attr "mode" "DI")])
10813 (define_insn "*btcq"
10814 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10816 (match_operand:DI 1 "const_0_to_63_operand" ""))
10817 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10818 (clobber (reg:CC FLAGS_REG))]
10819 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10820 "btc{q}\t{%1, %0|%0, %1}"
10821 [(set_attr "type" "alu1")
10822 (set_attr "prefix_0f" "1")
10823 (set_attr "mode" "DI")])
10825 ;; Allow Nocona to avoid these instructions if a register is available.
10828 [(match_scratch:DI 2 "r")
10829 (parallel [(set (zero_extract:DI
10830 (match_operand:DI 0 "register_operand" "")
10832 (match_operand:DI 1 "const_0_to_63_operand" ""))
10834 (clobber (reg:CC FLAGS_REG))])]
10835 "TARGET_64BIT && !TARGET_USE_BT"
10838 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10841 if (HOST_BITS_PER_WIDE_INT >= 64)
10842 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10843 else if (i < HOST_BITS_PER_WIDE_INT)
10844 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10846 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10848 op1 = immed_double_const (lo, hi, DImode);
10851 emit_move_insn (operands[2], op1);
10855 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10860 [(match_scratch:DI 2 "r")
10861 (parallel [(set (zero_extract:DI
10862 (match_operand:DI 0 "register_operand" "")
10864 (match_operand:DI 1 "const_0_to_63_operand" ""))
10866 (clobber (reg:CC FLAGS_REG))])]
10867 "TARGET_64BIT && !TARGET_USE_BT"
10870 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10873 if (HOST_BITS_PER_WIDE_INT >= 64)
10874 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10875 else if (i < HOST_BITS_PER_WIDE_INT)
10876 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10878 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10880 op1 = immed_double_const (~lo, ~hi, DImode);
10883 emit_move_insn (operands[2], op1);
10887 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10892 [(match_scratch:DI 2 "r")
10893 (parallel [(set (zero_extract:DI
10894 (match_operand:DI 0 "register_operand" "")
10896 (match_operand:DI 1 "const_0_to_63_operand" ""))
10897 (not:DI (zero_extract:DI
10898 (match_dup 0) (const_int 1) (match_dup 1))))
10899 (clobber (reg:CC FLAGS_REG))])]
10900 "TARGET_64BIT && !TARGET_USE_BT"
10903 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10906 if (HOST_BITS_PER_WIDE_INT >= 64)
10907 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10908 else if (i < HOST_BITS_PER_WIDE_INT)
10909 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10911 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10913 op1 = immed_double_const (lo, hi, DImode);
10916 emit_move_insn (operands[2], op1);
10920 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10924 (define_insn "*btdi_rex64"
10925 [(set (reg:CCC FLAGS_REG)
10928 (match_operand:DI 0 "register_operand" "r")
10930 (match_operand:DI 1 "nonmemory_operand" "rN"))
10932 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
10933 "bt{q}\t{%1, %0|%0, %1}"
10934 [(set_attr "type" "alu1")
10935 (set_attr "prefix_0f" "1")
10936 (set_attr "mode" "DI")])
10938 (define_insn "*btsi"
10939 [(set (reg:CCC FLAGS_REG)
10942 (match_operand:SI 0 "register_operand" "r")
10944 (match_operand:SI 1 "nonmemory_operand" "rN"))
10946 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10947 "bt{l}\t{%1, %0|%0, %1}"
10948 [(set_attr "type" "alu1")
10949 (set_attr "prefix_0f" "1")
10950 (set_attr "mode" "SI")])
10952 ;; Store-flag instructions.
10954 ;; For all sCOND expanders, also expand the compare or test insn that
10955 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10957 (define_insn_and_split "*setcc_di_1"
10958 [(set (match_operand:DI 0 "register_operand" "=q")
10959 (match_operator:DI 1 "ix86_comparison_operator"
10960 [(reg FLAGS_REG) (const_int 0)]))]
10961 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10963 "&& reload_completed"
10964 [(set (match_dup 2) (match_dup 1))
10965 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10967 PUT_MODE (operands[1], QImode);
10968 operands[2] = gen_lowpart (QImode, operands[0]);
10971 (define_insn_and_split "*setcc_si_1_and"
10972 [(set (match_operand:SI 0 "register_operand" "=q")
10973 (match_operator:SI 1 "ix86_comparison_operator"
10974 [(reg FLAGS_REG) (const_int 0)]))
10975 (clobber (reg:CC FLAGS_REG))]
10976 "!TARGET_PARTIAL_REG_STALL
10977 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10979 "&& reload_completed"
10980 [(set (match_dup 2) (match_dup 1))
10981 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10982 (clobber (reg:CC FLAGS_REG))])]
10984 PUT_MODE (operands[1], QImode);
10985 operands[2] = gen_lowpart (QImode, operands[0]);
10988 (define_insn_and_split "*setcc_si_1_movzbl"
10989 [(set (match_operand:SI 0 "register_operand" "=q")
10990 (match_operator:SI 1 "ix86_comparison_operator"
10991 [(reg FLAGS_REG) (const_int 0)]))]
10992 "!TARGET_PARTIAL_REG_STALL
10993 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10995 "&& reload_completed"
10996 [(set (match_dup 2) (match_dup 1))
10997 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10999 PUT_MODE (operands[1], QImode);
11000 operands[2] = gen_lowpart (QImode, operands[0]);
11003 (define_insn "*setcc_qi"
11004 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11005 (match_operator:QI 1 "ix86_comparison_operator"
11006 [(reg FLAGS_REG) (const_int 0)]))]
11009 [(set_attr "type" "setcc")
11010 (set_attr "mode" "QI")])
11012 (define_insn "*setcc_qi_slp"
11013 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11014 (match_operator:QI 1 "ix86_comparison_operator"
11015 [(reg FLAGS_REG) (const_int 0)]))]
11018 [(set_attr "type" "setcc")
11019 (set_attr "mode" "QI")])
11021 ;; In general it is not safe to assume too much about CCmode registers,
11022 ;; so simplify-rtx stops when it sees a second one. Under certain
11023 ;; conditions this is safe on x86, so help combine not create
11030 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11031 (ne:QI (match_operator 1 "ix86_comparison_operator"
11032 [(reg FLAGS_REG) (const_int 0)])
11035 [(set (match_dup 0) (match_dup 1))]
11037 PUT_MODE (operands[1], QImode);
11041 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11042 (ne:QI (match_operator 1 "ix86_comparison_operator"
11043 [(reg FLAGS_REG) (const_int 0)])
11046 [(set (match_dup 0) (match_dup 1))]
11048 PUT_MODE (operands[1], QImode);
11052 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11053 (eq:QI (match_operator 1 "ix86_comparison_operator"
11054 [(reg FLAGS_REG) (const_int 0)])
11057 [(set (match_dup 0) (match_dup 1))]
11059 rtx new_op1 = copy_rtx (operands[1]);
11060 operands[1] = new_op1;
11061 PUT_MODE (new_op1, QImode);
11062 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11063 GET_MODE (XEXP (new_op1, 0))));
11065 /* Make sure that (a) the CCmode we have for the flags is strong
11066 enough for the reversed compare or (b) we have a valid FP compare. */
11067 if (! ix86_comparison_operator (new_op1, VOIDmode))
11072 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11073 (eq:QI (match_operator 1 "ix86_comparison_operator"
11074 [(reg FLAGS_REG) (const_int 0)])
11077 [(set (match_dup 0) (match_dup 1))]
11079 rtx new_op1 = copy_rtx (operands[1]);
11080 operands[1] = new_op1;
11081 PUT_MODE (new_op1, QImode);
11082 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11083 GET_MODE (XEXP (new_op1, 0))));
11085 /* Make sure that (a) the CCmode we have for the flags is strong
11086 enough for the reversed compare or (b) we have a valid FP compare. */
11087 if (! ix86_comparison_operator (new_op1, VOIDmode))
11091 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11092 ;; subsequent logical operations are used to imitate conditional moves.
11093 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11096 (define_insn "*avx_setcc<mode>"
11097 [(set (match_operand:MODEF 0 "register_operand" "=x")
11098 (match_operator:MODEF 1 "avx_comparison_float_operator"
11099 [(match_operand:MODEF 2 "register_operand" "x")
11100 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11102 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
11103 [(set_attr "type" "ssecmp")
11104 (set_attr "prefix" "vex")
11105 (set_attr "length_immediate" "1")
11106 (set_attr "mode" "<MODE>")])
11108 (define_insn "*sse_setcc<mode>"
11109 [(set (match_operand:MODEF 0 "register_operand" "=x")
11110 (match_operator:MODEF 1 "sse_comparison_operator"
11111 [(match_operand:MODEF 2 "register_operand" "0")
11112 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11113 "SSE_FLOAT_MODE_P (<MODE>mode)"
11114 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
11115 [(set_attr "type" "ssecmp")
11116 (set_attr "length_immediate" "1")
11117 (set_attr "mode" "<MODE>")])
11119 ;; Basic conditional jump instructions.
11120 ;; We ignore the overflow flag for signed branch instructions.
11122 (define_insn "*jcc_1"
11124 (if_then_else (match_operator 1 "ix86_comparison_operator"
11125 [(reg FLAGS_REG) (const_int 0)])
11126 (label_ref (match_operand 0 "" ""))
11130 [(set_attr "type" "ibr")
11131 (set_attr "modrm" "0")
11132 (set (attr "length")
11133 (if_then_else (and (ge (minus (match_dup 0) (pc))
11135 (lt (minus (match_dup 0) (pc))
11140 (define_insn "*jcc_2"
11142 (if_then_else (match_operator 1 "ix86_comparison_operator"
11143 [(reg FLAGS_REG) (const_int 0)])
11145 (label_ref (match_operand 0 "" ""))))]
11148 [(set_attr "type" "ibr")
11149 (set_attr "modrm" "0")
11150 (set (attr "length")
11151 (if_then_else (and (ge (minus (match_dup 0) (pc))
11153 (lt (minus (match_dup 0) (pc))
11158 ;; In general it is not safe to assume too much about CCmode registers,
11159 ;; so simplify-rtx stops when it sees a second one. Under certain
11160 ;; conditions this is safe on x86, so help combine not create
11168 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11169 [(reg FLAGS_REG) (const_int 0)])
11171 (label_ref (match_operand 1 "" ""))
11175 (if_then_else (match_dup 0)
11176 (label_ref (match_dup 1))
11179 PUT_MODE (operands[0], VOIDmode);
11184 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11185 [(reg FLAGS_REG) (const_int 0)])
11187 (label_ref (match_operand 1 "" ""))
11191 (if_then_else (match_dup 0)
11192 (label_ref (match_dup 1))
11195 rtx new_op0 = copy_rtx (operands[0]);
11196 operands[0] = new_op0;
11197 PUT_MODE (new_op0, VOIDmode);
11198 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11199 GET_MODE (XEXP (new_op0, 0))));
11201 /* Make sure that (a) the CCmode we have for the flags is strong
11202 enough for the reversed compare or (b) we have a valid FP compare. */
11203 if (! ix86_comparison_operator (new_op0, VOIDmode))
11207 ;; zero_extend in SImode is correct, since this is what combine pass
11208 ;; generates from shift insn with QImode operand. Actually, the mode of
11209 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
11210 ;; appropriate modulo of the bit offset value.
11212 (define_insn_and_split "*jcc_btdi_rex64"
11214 (if_then_else (match_operator 0 "bt_comparison_operator"
11216 (match_operand:DI 1 "register_operand" "r")
11219 (match_operand:QI 2 "register_operand" "r")))
11221 (label_ref (match_operand 3 "" ""))
11223 (clobber (reg:CC FLAGS_REG))]
11224 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
11227 [(set (reg:CCC FLAGS_REG)
11235 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11236 (label_ref (match_dup 3))
11239 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
11241 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11244 ;; avoid useless masking of bit offset operand
11245 (define_insn_and_split "*jcc_btdi_mask_rex64"
11247 (if_then_else (match_operator 0 "bt_comparison_operator"
11249 (match_operand:DI 1 "register_operand" "r")
11252 (match_operand:SI 2 "register_operand" "r")
11253 (match_operand:SI 3 "const_int_operand" "n")))])
11254 (label_ref (match_operand 4 "" ""))
11256 (clobber (reg:CC FLAGS_REG))]
11257 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
11258 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
11261 [(set (reg:CCC FLAGS_REG)
11269 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11270 (label_ref (match_dup 4))
11273 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
11275 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11278 (define_insn_and_split "*jcc_btsi"
11280 (if_then_else (match_operator 0 "bt_comparison_operator"
11282 (match_operand:SI 1 "register_operand" "r")
11285 (match_operand:QI 2 "register_operand" "r")))
11287 (label_ref (match_operand 3 "" ""))
11289 (clobber (reg:CC FLAGS_REG))]
11290 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11293 [(set (reg:CCC FLAGS_REG)
11301 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11302 (label_ref (match_dup 3))
11305 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11307 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11310 ;; avoid useless masking of bit offset operand
11311 (define_insn_and_split "*jcc_btsi_mask"
11313 (if_then_else (match_operator 0 "bt_comparison_operator"
11315 (match_operand:SI 1 "register_operand" "r")
11318 (match_operand:SI 2 "register_operand" "r")
11319 (match_operand:SI 3 "const_int_operand" "n")))])
11320 (label_ref (match_operand 4 "" ""))
11322 (clobber (reg:CC FLAGS_REG))]
11323 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11324 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11327 [(set (reg:CCC FLAGS_REG)
11335 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11336 (label_ref (match_dup 4))
11338 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11340 (define_insn_and_split "*jcc_btsi_1"
11342 (if_then_else (match_operator 0 "bt_comparison_operator"
11345 (match_operand:SI 1 "register_operand" "r")
11346 (match_operand:QI 2 "register_operand" "r"))
11349 (label_ref (match_operand 3 "" ""))
11351 (clobber (reg:CC FLAGS_REG))]
11352 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11355 [(set (reg:CCC FLAGS_REG)
11363 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11364 (label_ref (match_dup 3))
11367 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11369 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11372 ;; avoid useless masking of bit offset operand
11373 (define_insn_and_split "*jcc_btsi_mask_1"
11376 (match_operator 0 "bt_comparison_operator"
11379 (match_operand:SI 1 "register_operand" "r")
11382 (match_operand:SI 2 "register_operand" "r")
11383 (match_operand:SI 3 "const_int_operand" "n")) 0))
11386 (label_ref (match_operand 4 "" ""))
11388 (clobber (reg:CC FLAGS_REG))]
11389 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11390 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11393 [(set (reg:CCC FLAGS_REG)
11401 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11402 (label_ref (match_dup 4))
11404 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11406 ;; Define combination compare-and-branch fp compare instructions to help
11409 (define_insn "*fp_jcc_3_387"
11411 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11412 [(match_operand 1 "register_operand" "f")
11413 (match_operand 2 "nonimmediate_operand" "fm")])
11414 (label_ref (match_operand 3 "" ""))
11416 (clobber (reg:CCFP FPSR_REG))
11417 (clobber (reg:CCFP FLAGS_REG))
11418 (clobber (match_scratch:HI 4 "=a"))]
11420 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11421 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11422 && SELECT_CC_MODE (GET_CODE (operands[0]),
11423 operands[1], operands[2]) == CCFPmode
11427 (define_insn "*fp_jcc_4_387"
11429 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11430 [(match_operand 1 "register_operand" "f")
11431 (match_operand 2 "nonimmediate_operand" "fm")])
11433 (label_ref (match_operand 3 "" ""))))
11434 (clobber (reg:CCFP FPSR_REG))
11435 (clobber (reg:CCFP FLAGS_REG))
11436 (clobber (match_scratch:HI 4 "=a"))]
11438 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11439 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11440 && SELECT_CC_MODE (GET_CODE (operands[0]),
11441 operands[1], operands[2]) == CCFPmode
11445 (define_insn "*fp_jcc_5_387"
11447 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11448 [(match_operand 1 "register_operand" "f")
11449 (match_operand 2 "register_operand" "f")])
11450 (label_ref (match_operand 3 "" ""))
11452 (clobber (reg:CCFP FPSR_REG))
11453 (clobber (reg:CCFP FLAGS_REG))
11454 (clobber (match_scratch:HI 4 "=a"))]
11455 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11456 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11460 (define_insn "*fp_jcc_6_387"
11462 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11463 [(match_operand 1 "register_operand" "f")
11464 (match_operand 2 "register_operand" "f")])
11466 (label_ref (match_operand 3 "" ""))))
11467 (clobber (reg:CCFP FPSR_REG))
11468 (clobber (reg:CCFP FLAGS_REG))
11469 (clobber (match_scratch:HI 4 "=a"))]
11470 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11471 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11475 (define_insn "*fp_jcc_7_387"
11477 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11478 [(match_operand 1 "register_operand" "f")
11479 (match_operand 2 "const0_operand" "")])
11480 (label_ref (match_operand 3 "" ""))
11482 (clobber (reg:CCFP FPSR_REG))
11483 (clobber (reg:CCFP FLAGS_REG))
11484 (clobber (match_scratch:HI 4 "=a"))]
11485 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11486 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11487 && SELECT_CC_MODE (GET_CODE (operands[0]),
11488 operands[1], operands[2]) == CCFPmode
11492 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
11493 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11494 ;; with a precedence over other operators and is always put in the first
11495 ;; place. Swap condition and operands to match ficom instruction.
11497 (define_insn "*fp_jcc_8<mode>_387"
11499 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11500 [(match_operator 1 "float_operator"
11501 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11502 (match_operand 3 "register_operand" "f,f")])
11503 (label_ref (match_operand 4 "" ""))
11505 (clobber (reg:CCFP FPSR_REG))
11506 (clobber (reg:CCFP FLAGS_REG))
11507 (clobber (match_scratch:HI 5 "=a,a"))]
11508 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11509 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11510 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11511 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11517 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11518 [(match_operand 1 "register_operand" "")
11519 (match_operand 2 "nonimmediate_operand" "")])
11520 (match_operand 3 "" "")
11521 (match_operand 4 "" "")))
11522 (clobber (reg:CCFP FPSR_REG))
11523 (clobber (reg:CCFP FLAGS_REG))]
11527 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11528 operands[3], operands[4], NULL_RTX, NULL_RTX);
11534 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11535 [(match_operand 1 "register_operand" "")
11536 (match_operand 2 "general_operand" "")])
11537 (match_operand 3 "" "")
11538 (match_operand 4 "" "")))
11539 (clobber (reg:CCFP FPSR_REG))
11540 (clobber (reg:CCFP FLAGS_REG))
11541 (clobber (match_scratch:HI 5 "=a"))]
11545 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11546 operands[3], operands[4], operands[5], NULL_RTX);
11552 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11553 [(match_operator 1 "float_operator"
11554 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11555 (match_operand 3 "register_operand" "")])
11556 (match_operand 4 "" "")
11557 (match_operand 5 "" "")))
11558 (clobber (reg:CCFP FPSR_REG))
11559 (clobber (reg:CCFP FLAGS_REG))
11560 (clobber (match_scratch:HI 6 "=a"))]
11564 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11565 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11566 operands[3], operands[7],
11567 operands[4], operands[5], operands[6], NULL_RTX);
11571 ;; %%% Kill this when reload knows how to do it.
11574 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11575 [(match_operator 1 "float_operator"
11576 [(match_operand:X87MODEI12 2 "register_operand" "")])
11577 (match_operand 3 "register_operand" "")])
11578 (match_operand 4 "" "")
11579 (match_operand 5 "" "")))
11580 (clobber (reg:CCFP FPSR_REG))
11581 (clobber (reg:CCFP FLAGS_REG))
11582 (clobber (match_scratch:HI 6 "=a"))]
11586 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11587 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11588 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11589 operands[3], operands[7],
11590 operands[4], operands[5], operands[6], operands[2]);
11594 ;; Unconditional and other jump instructions
11596 (define_insn "jump"
11598 (label_ref (match_operand 0 "" "")))]
11601 [(set_attr "type" "ibr")
11602 (set (attr "length")
11603 (if_then_else (and (ge (minus (match_dup 0) (pc))
11605 (lt (minus (match_dup 0) (pc))
11609 (set_attr "modrm" "0")])
11611 (define_expand "indirect_jump"
11612 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11616 (define_insn "*indirect_jump"
11617 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11620 [(set_attr "type" "ibr")
11621 (set_attr "length_immediate" "0")])
11623 (define_expand "tablejump"
11624 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11625 (use (label_ref (match_operand 1 "" "")))])]
11628 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11629 relative. Convert the relative address to an absolute address. */
11633 enum rtx_code code;
11635 /* We can't use @GOTOFF for text labels on VxWorks;
11636 see gotoff_operand. */
11637 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11641 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11643 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11647 op1 = pic_offset_table_rtx;
11652 op0 = pic_offset_table_rtx;
11656 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11661 (define_insn "*tablejump_1"
11662 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11663 (use (label_ref (match_operand 1 "" "")))]
11666 [(set_attr "type" "ibr")
11667 (set_attr "length_immediate" "0")])
11669 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11672 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11673 (set (match_operand:QI 1 "register_operand" "")
11674 (match_operator:QI 2 "ix86_comparison_operator"
11675 [(reg FLAGS_REG) (const_int 0)]))
11676 (set (match_operand 3 "q_regs_operand" "")
11677 (zero_extend (match_dup 1)))]
11678 "(peep2_reg_dead_p (3, operands[1])
11679 || operands_match_p (operands[1], operands[3]))
11680 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11681 [(set (match_dup 4) (match_dup 0))
11682 (set (strict_low_part (match_dup 5))
11685 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11686 operands[5] = gen_lowpart (QImode, operands[3]);
11687 ix86_expand_clear (operands[3]);
11690 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11693 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11694 (set (match_operand:QI 1 "register_operand" "")
11695 (match_operator:QI 2 "ix86_comparison_operator"
11696 [(reg FLAGS_REG) (const_int 0)]))
11697 (parallel [(set (match_operand 3 "q_regs_operand" "")
11698 (zero_extend (match_dup 1)))
11699 (clobber (reg:CC FLAGS_REG))])]
11700 "(peep2_reg_dead_p (3, operands[1])
11701 || operands_match_p (operands[1], operands[3]))
11702 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11703 [(set (match_dup 4) (match_dup 0))
11704 (set (strict_low_part (match_dup 5))
11707 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11708 operands[5] = gen_lowpart (QImode, operands[3]);
11709 ix86_expand_clear (operands[3]);
11712 ;; Call instructions.
11714 ;; The predicates normally associated with named expanders are not properly
11715 ;; checked for calls. This is a bug in the generic code, but it isn't that
11716 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11718 ;; P6 processors will jump to the address after the decrement when %esp
11719 ;; is used as a call operand, so they will execute return address as a code.
11720 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11722 ;; Call subroutine returning no value.
11724 (define_expand "call_pop"
11725 [(parallel [(call (match_operand:QI 0 "" "")
11726 (match_operand:SI 1 "" ""))
11727 (set (reg:SI SP_REG)
11728 (plus:SI (reg:SI SP_REG)
11729 (match_operand:SI 3 "" "")))])]
11732 ix86_expand_call (NULL, operands[0], operands[1],
11733 operands[2], operands[3], 0);
11737 (define_insn "*call_pop_0"
11738 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11739 (match_operand:SI 1 "" ""))
11740 (set (reg:SI SP_REG)
11741 (plus:SI (reg:SI SP_REG)
11742 (match_operand:SI 2 "immediate_operand" "")))]
11745 if (SIBLING_CALL_P (insn))
11748 return "call\t%P0";
11750 [(set_attr "type" "call")])
11752 (define_insn "*call_pop_1"
11753 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11754 (match_operand:SI 1 "" ""))
11755 (set (reg:SI SP_REG)
11756 (plus:SI (reg:SI SP_REG)
11757 (match_operand:SI 2 "immediate_operand" "i")))]
11758 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11760 if (constant_call_address_operand (operands[0], Pmode))
11761 return "call\t%P0";
11762 return "call\t%A0";
11764 [(set_attr "type" "call")])
11766 (define_insn "*sibcall_pop_1"
11767 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11768 (match_operand:SI 1 "" ""))
11769 (set (reg:SI SP_REG)
11770 (plus:SI (reg:SI SP_REG)
11771 (match_operand:SI 2 "immediate_operand" "i,i")))]
11772 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11776 [(set_attr "type" "call")])
11778 (define_expand "call"
11779 [(call (match_operand:QI 0 "" "")
11780 (match_operand 1 "" ""))
11781 (use (match_operand 2 "" ""))]
11784 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11788 (define_expand "sibcall"
11789 [(call (match_operand:QI 0 "" "")
11790 (match_operand 1 "" ""))
11791 (use (match_operand 2 "" ""))]
11794 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11798 (define_insn "*call_0"
11799 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11800 (match_operand 1 "" ""))]
11803 if (SIBLING_CALL_P (insn))
11806 return "call\t%P0";
11808 [(set_attr "type" "call")])
11810 (define_insn "*call_1"
11811 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11812 (match_operand 1 "" ""))]
11813 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11815 if (constant_call_address_operand (operands[0], Pmode))
11816 return "call\t%P0";
11817 return "call\t%A0";
11819 [(set_attr "type" "call")])
11821 (define_insn "*sibcall_1"
11822 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11823 (match_operand 1 "" ""))]
11824 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11828 [(set_attr "type" "call")])
11830 (define_insn "*call_1_rex64"
11831 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11832 (match_operand 1 "" ""))]
11833 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11834 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11836 if (constant_call_address_operand (operands[0], Pmode))
11837 return "call\t%P0";
11838 return "call\t%A0";
11840 [(set_attr "type" "call")])
11842 (define_insn "*call_1_rex64_ms_sysv"
11843 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11844 (match_operand 1 "" ""))
11845 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11846 (clobber (reg:TI XMM6_REG))
11847 (clobber (reg:TI XMM7_REG))
11848 (clobber (reg:TI XMM8_REG))
11849 (clobber (reg:TI XMM9_REG))
11850 (clobber (reg:TI XMM10_REG))
11851 (clobber (reg:TI XMM11_REG))
11852 (clobber (reg:TI XMM12_REG))
11853 (clobber (reg:TI XMM13_REG))
11854 (clobber (reg:TI XMM14_REG))
11855 (clobber (reg:TI XMM15_REG))
11856 (clobber (reg:DI SI_REG))
11857 (clobber (reg:DI DI_REG))]
11858 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11860 if (constant_call_address_operand (operands[0], Pmode))
11861 return "call\t%P0";
11862 return "call\t%A0";
11864 [(set_attr "type" "call")])
11866 (define_insn "*call_1_rex64_large"
11867 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11868 (match_operand 1 "" ""))]
11869 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11871 [(set_attr "type" "call")])
11873 (define_insn "*sibcall_1_rex64"
11874 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11875 (match_operand 1 "" ""))]
11876 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11880 [(set_attr "type" "call")])
11882 ;; Call subroutine, returning value in operand 0
11883 (define_expand "call_value_pop"
11884 [(parallel [(set (match_operand 0 "" "")
11885 (call (match_operand:QI 1 "" "")
11886 (match_operand:SI 2 "" "")))
11887 (set (reg:SI SP_REG)
11888 (plus:SI (reg:SI SP_REG)
11889 (match_operand:SI 4 "" "")))])]
11892 ix86_expand_call (operands[0], operands[1], operands[2],
11893 operands[3], operands[4], 0);
11897 (define_expand "call_value"
11898 [(set (match_operand 0 "" "")
11899 (call (match_operand:QI 1 "" "")
11900 (match_operand:SI 2 "" "")))
11901 (use (match_operand:SI 3 "" ""))]
11902 ;; Operand 3 is not used on the i386.
11905 ix86_expand_call (operands[0], operands[1], operands[2],
11906 operands[3], NULL, 0);
11910 (define_expand "sibcall_value"
11911 [(set (match_operand 0 "" "")
11912 (call (match_operand:QI 1 "" "")
11913 (match_operand:SI 2 "" "")))
11914 (use (match_operand:SI 3 "" ""))]
11915 ;; Operand 3 is not used on the i386.
11918 ix86_expand_call (operands[0], operands[1], operands[2],
11919 operands[3], NULL, 1);
11923 ;; Call subroutine returning any type.
11925 (define_expand "untyped_call"
11926 [(parallel [(call (match_operand 0 "" "")
11928 (match_operand 1 "" "")
11929 (match_operand 2 "" "")])]
11934 /* In order to give reg-stack an easier job in validating two
11935 coprocessor registers as containing a possible return value,
11936 simply pretend the untyped call returns a complex long double
11939 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11940 and should have the default ABI. */
11942 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11943 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11944 operands[0], const0_rtx,
11945 GEN_INT ((TARGET_64BIT
11946 ? (ix86_abi == SYSV_ABI
11947 ? X86_64_SSE_REGPARM_MAX
11948 : X86_64_MS_SSE_REGPARM_MAX)
11949 : X86_32_SSE_REGPARM_MAX)
11953 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11955 rtx set = XVECEXP (operands[2], 0, i);
11956 emit_move_insn (SET_DEST (set), SET_SRC (set));
11959 /* The optimizer does not know that the call sets the function value
11960 registers we stored in the result block. We avoid problems by
11961 claiming that all hard registers are used and clobbered at this
11963 emit_insn (gen_blockage ());
11968 ;; Prologue and epilogue instructions
11970 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11971 ;; all of memory. This blocks insns from being moved across this point.
11973 (define_insn "blockage"
11974 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11977 [(set_attr "length" "0")])
11979 ;; Do not schedule instructions accessing memory across this point.
11981 (define_expand "memory_blockage"
11982 [(set (match_dup 0)
11983 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11986 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11987 MEM_VOLATILE_P (operands[0]) = 1;
11990 (define_insn "*memory_blockage"
11991 [(set (match_operand:BLK 0 "" "")
11992 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11995 [(set_attr "length" "0")])
11997 ;; As USE insns aren't meaningful after reload, this is used instead
11998 ;; to prevent deleting instructions setting registers for PIC code
11999 (define_insn "prologue_use"
12000 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
12003 [(set_attr "length" "0")])
12005 ;; Insn emitted into the body of a function to return from a function.
12006 ;; This is only done if the function's epilogue is known to be simple.
12007 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12009 (define_expand "return"
12011 "ix86_can_use_return_insn_p ()"
12013 if (crtl->args.pops_args)
12015 rtx popc = GEN_INT (crtl->args.pops_args);
12016 emit_jump_insn (gen_return_pop_internal (popc));
12021 (define_insn "return_internal"
12025 [(set_attr "length" "1")
12026 (set_attr "atom_unit" "jeu")
12027 (set_attr "length_immediate" "0")
12028 (set_attr "modrm" "0")])
12030 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12031 ;; instruction Athlon and K8 have.
12033 (define_insn "return_internal_long"
12035 (unspec [(const_int 0)] UNSPEC_REP)]
12038 [(set_attr "length" "2")
12039 (set_attr "atom_unit" "jeu")
12040 (set_attr "length_immediate" "0")
12041 (set_attr "prefix_rep" "1")
12042 (set_attr "modrm" "0")])
12044 (define_insn "return_pop_internal"
12046 (use (match_operand:SI 0 "const_int_operand" ""))]
12049 [(set_attr "length" "3")
12050 (set_attr "atom_unit" "jeu")
12051 (set_attr "length_immediate" "2")
12052 (set_attr "modrm" "0")])
12054 (define_insn "return_indirect_internal"
12056 (use (match_operand:SI 0 "register_operand" "r"))]
12059 [(set_attr "type" "ibr")
12060 (set_attr "length_immediate" "0")])
12066 [(set_attr "length" "1")
12067 (set_attr "length_immediate" "0")
12068 (set_attr "modrm" "0")])
12070 (define_insn "vswapmov"
12071 [(set (match_operand:SI 0 "register_operand" "=r")
12072 (match_operand:SI 1 "register_operand" "r"))
12073 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
12075 "movl.s\t{%1, %0|%0, %1}"
12076 [(set_attr "length" "2")
12077 (set_attr "length_immediate" "0")
12078 (set_attr "modrm" "0")])
12080 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12081 ;; branch prediction penalty for the third jump in a 16-byte
12085 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
12088 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12089 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12091 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12092 The align insn is used to avoid 3 jump instructions in the row to improve
12093 branch prediction and the benefits hardly outweigh the cost of extra 8
12094 nops on the average inserted by full alignment pseudo operation. */
12098 [(set_attr "length" "16")])
12100 (define_expand "prologue"
12103 "ix86_expand_prologue (); DONE;")
12105 (define_insn "set_got"
12106 [(set (match_operand:SI 0 "register_operand" "=r")
12107 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12108 (clobber (reg:CC FLAGS_REG))]
12110 { return output_set_got (operands[0], NULL_RTX); }
12111 [(set_attr "type" "multi")
12112 (set_attr "length" "12")])
12114 (define_insn "set_got_labelled"
12115 [(set (match_operand:SI 0 "register_operand" "=r")
12116 (unspec:SI [(label_ref (match_operand 1 "" ""))]
12118 (clobber (reg:CC FLAGS_REG))]
12120 { return output_set_got (operands[0], operands[1]); }
12121 [(set_attr "type" "multi")
12122 (set_attr "length" "12")])
12124 (define_insn "set_got_rex64"
12125 [(set (match_operand:DI 0 "register_operand" "=r")
12126 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12128 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12129 [(set_attr "type" "lea")
12130 (set_attr "length_address" "4")
12131 (set_attr "mode" "DI")])
12133 (define_insn "set_rip_rex64"
12134 [(set (match_operand:DI 0 "register_operand" "=r")
12135 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
12137 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12138 [(set_attr "type" "lea")
12139 (set_attr "length_address" "4")
12140 (set_attr "mode" "DI")])
12142 (define_insn "set_got_offset_rex64"
12143 [(set (match_operand:DI 0 "register_operand" "=r")
12145 [(label_ref (match_operand 1 "" ""))]
12146 UNSPEC_SET_GOT_OFFSET))]
12148 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12149 [(set_attr "type" "imov")
12150 (set_attr "length_immediate" "0")
12151 (set_attr "length_address" "8")
12152 (set_attr "mode" "DI")])
12154 (define_expand "epilogue"
12157 "ix86_expand_epilogue (1); DONE;")
12159 (define_expand "sibcall_epilogue"
12162 "ix86_expand_epilogue (0); DONE;")
12164 (define_expand "eh_return"
12165 [(use (match_operand 0 "register_operand" ""))]
12168 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12170 /* Tricky bit: we write the address of the handler to which we will
12171 be returning into someone else's stack frame, one word below the
12172 stack address we wish to restore. */
12173 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12174 tmp = plus_constant (tmp, -UNITS_PER_WORD);
12175 tmp = gen_rtx_MEM (Pmode, tmp);
12176 emit_move_insn (tmp, ra);
12178 emit_jump_insn (gen_eh_return_internal ());
12183 (define_insn_and_split "eh_return_internal"
12187 "epilogue_completed"
12189 "ix86_expand_epilogue (2); DONE;")
12191 (define_insn "leave"
12192 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12193 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12194 (clobber (mem:BLK (scratch)))]
12197 [(set_attr "type" "leave")])
12199 (define_insn "leave_rex64"
12200 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12201 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12202 (clobber (mem:BLK (scratch)))]
12205 [(set_attr "type" "leave")])
12207 (define_expand "ffssi2"
12209 [(set (match_operand:SI 0 "register_operand" "")
12210 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
12211 (clobber (match_scratch:SI 2 ""))
12212 (clobber (reg:CC FLAGS_REG))])]
12217 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
12222 (define_expand "ffs_cmove"
12223 [(set (match_dup 2) (const_int -1))
12224 (parallel [(set (reg:CCZ FLAGS_REG)
12225 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
12227 (set (match_operand:SI 0 "register_operand" "")
12228 (ctz:SI (match_dup 1)))])
12229 (set (match_dup 0) (if_then_else:SI
12230 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12233 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12234 (clobber (reg:CC FLAGS_REG))])]
12236 "operands[2] = gen_reg_rtx (SImode);")
12238 (define_insn_and_split "*ffs_no_cmove"
12239 [(set (match_operand:SI 0 "register_operand" "=r")
12240 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12241 (clobber (match_scratch:SI 2 "=&q"))
12242 (clobber (reg:CC FLAGS_REG))]
12245 "&& reload_completed"
12246 [(parallel [(set (reg:CCZ FLAGS_REG)
12247 (compare:CCZ (match_dup 1) (const_int 0)))
12248 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12249 (set (strict_low_part (match_dup 3))
12250 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12251 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12252 (clobber (reg:CC FLAGS_REG))])
12253 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12254 (clobber (reg:CC FLAGS_REG))])
12255 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12256 (clobber (reg:CC FLAGS_REG))])]
12258 operands[3] = gen_lowpart (QImode, operands[2]);
12259 ix86_expand_clear (operands[2]);
12262 (define_insn "*ffssi_1"
12263 [(set (reg:CCZ FLAGS_REG)
12264 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
12266 (set (match_operand:SI 0 "register_operand" "=r")
12267 (ctz:SI (match_dup 1)))]
12269 "bsf{l}\t{%1, %0|%0, %1}"
12270 [(set_attr "type" "alu1")
12271 (set_attr "prefix_0f" "1")
12272 (set_attr "mode" "SI")])
12274 (define_expand "ffsdi2"
12275 [(set (match_dup 2) (const_int -1))
12276 (parallel [(set (reg:CCZ FLAGS_REG)
12277 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
12279 (set (match_operand:DI 0 "register_operand" "")
12280 (ctz:DI (match_dup 1)))])
12281 (set (match_dup 0) (if_then_else:DI
12282 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12285 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
12286 (clobber (reg:CC FLAGS_REG))])]
12288 "operands[2] = gen_reg_rtx (DImode);")
12290 (define_insn "*ffsdi_1"
12291 [(set (reg:CCZ FLAGS_REG)
12292 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
12294 (set (match_operand:DI 0 "register_operand" "=r")
12295 (ctz:DI (match_dup 1)))]
12297 "bsf{q}\t{%1, %0|%0, %1}"
12298 [(set_attr "type" "alu1")
12299 (set_attr "prefix_0f" "1")
12300 (set_attr "mode" "DI")])
12302 (define_insn "ctzsi2"
12303 [(set (match_operand:SI 0 "register_operand" "=r")
12304 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12305 (clobber (reg:CC FLAGS_REG))]
12307 "bsf{l}\t{%1, %0|%0, %1}"
12308 [(set_attr "type" "alu1")
12309 (set_attr "prefix_0f" "1")
12310 (set_attr "mode" "SI")])
12312 (define_insn "ctzdi2"
12313 [(set (match_operand:DI 0 "register_operand" "=r")
12314 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
12315 (clobber (reg:CC FLAGS_REG))]
12317 "bsf{q}\t{%1, %0|%0, %1}"
12318 [(set_attr "type" "alu1")
12319 (set_attr "prefix_0f" "1")
12320 (set_attr "mode" "DI")])
12322 (define_expand "clzsi2"
12324 [(set (match_operand:SI 0 "register_operand" "")
12325 (minus:SI (const_int 31)
12326 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
12327 (clobber (reg:CC FLAGS_REG))])
12329 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
12330 (clobber (reg:CC FLAGS_REG))])]
12335 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
12340 (define_insn "clzsi2_abm"
12341 [(set (match_operand:SI 0 "register_operand" "=r")
12342 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12343 (clobber (reg:CC FLAGS_REG))]
12345 "lzcnt{l}\t{%1, %0|%0, %1}"
12346 [(set_attr "prefix_rep" "1")
12347 (set_attr "type" "bitmanip")
12348 (set_attr "mode" "SI")])
12351 [(set (match_operand:SI 0 "register_operand" "=r")
12352 (minus:SI (const_int 31)
12353 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12354 (clobber (reg:CC FLAGS_REG))]
12356 "bsr{l}\t{%1, %0|%0, %1}"
12357 [(set_attr "type" "alu1")
12358 (set_attr "prefix_0f" "1")
12359 (set_attr "mode" "SI")])
12361 (define_insn "popcount<mode>2"
12362 [(set (match_operand:SWI248 0 "register_operand" "=r")
12364 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12365 (clobber (reg:CC FLAGS_REG))]
12369 return "popcnt\t{%1, %0|%0, %1}";
12371 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12374 [(set_attr "prefix_rep" "1")
12375 (set_attr "type" "bitmanip")
12376 (set_attr "mode" "<MODE>")])
12378 (define_insn "*popcount<mode>2_cmp"
12379 [(set (reg FLAGS_REG)
12382 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12384 (set (match_operand:SWI248 0 "register_operand" "=r")
12385 (popcount:SWI248 (match_dup 1)))]
12386 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12389 return "popcnt\t{%1, %0|%0, %1}";
12391 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12394 [(set_attr "prefix_rep" "1")
12395 (set_attr "type" "bitmanip")
12396 (set_attr "mode" "<MODE>")])
12398 (define_insn "*popcountsi2_cmp_zext"
12399 [(set (reg FLAGS_REG)
12401 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12403 (set (match_operand:DI 0 "register_operand" "=r")
12404 (zero_extend:DI(popcount:SI (match_dup 1))))]
12405 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12408 return "popcnt\t{%1, %0|%0, %1}";
12410 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12413 [(set_attr "prefix_rep" "1")
12414 (set_attr "type" "bitmanip")
12415 (set_attr "mode" "SI")])
12417 (define_expand "bswapsi2"
12418 [(set (match_operand:SI 0 "register_operand" "")
12419 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
12422 if (!(TARGET_BSWAP || TARGET_MOVBE))
12424 rtx x = operands[0];
12426 emit_move_insn (x, operands[1]);
12427 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12428 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12429 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12434 (define_insn "*bswapsi_movbe"
12435 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
12436 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
12437 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12440 movbe\t{%1, %0|%0, %1}
12441 movbe\t{%1, %0|%0, %1}"
12442 [(set_attr "type" "*,imov,imov")
12443 (set_attr "modrm" "*,1,1")
12444 (set_attr "prefix_0f" "1")
12445 (set_attr "prefix_extra" "*,1,1")
12446 (set_attr "length" "2,*,*")
12447 (set_attr "mode" "SI")])
12449 (define_insn "*bswapsi_1"
12450 [(set (match_operand:SI 0 "register_operand" "=r")
12451 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
12454 [(set_attr "prefix_0f" "1")
12455 (set_attr "length" "2")])
12457 (define_insn "*bswaphi_lowpart_1"
12458 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12459 (bswap:HI (match_dup 0)))
12460 (clobber (reg:CC FLAGS_REG))]
12461 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12463 xchg{b}\t{%h0, %b0|%b0, %h0}
12464 rol{w}\t{$8, %0|%0, 8}"
12465 [(set_attr "length" "2,4")
12466 (set_attr "mode" "QI,HI")])
12468 (define_insn "bswaphi_lowpart"
12469 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12470 (bswap:HI (match_dup 0)))
12471 (clobber (reg:CC FLAGS_REG))]
12473 "rol{w}\t{$8, %0|%0, 8}"
12474 [(set_attr "length" "4")
12475 (set_attr "mode" "HI")])
12477 (define_expand "bswapdi2"
12478 [(set (match_operand:DI 0 "register_operand" "")
12479 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
12483 (define_insn "*bswapdi_movbe"
12484 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12485 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12486 "TARGET_64BIT && TARGET_MOVBE
12487 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12490 movbe\t{%1, %0|%0, %1}
12491 movbe\t{%1, %0|%0, %1}"
12492 [(set_attr "type" "*,imov,imov")
12493 (set_attr "modrm" "*,1,1")
12494 (set_attr "prefix_0f" "1")
12495 (set_attr "prefix_extra" "*,1,1")
12496 (set_attr "length" "3,*,*")
12497 (set_attr "mode" "DI")])
12499 (define_insn "*bswapdi_1"
12500 [(set (match_operand:DI 0 "register_operand" "=r")
12501 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
12504 [(set_attr "prefix_0f" "1")
12505 (set_attr "length" "3")])
12507 (define_expand "clzdi2"
12509 [(set (match_operand:DI 0 "register_operand" "")
12510 (minus:DI (const_int 63)
12511 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
12512 (clobber (reg:CC FLAGS_REG))])
12514 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
12515 (clobber (reg:CC FLAGS_REG))])]
12520 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
12525 (define_insn "clzdi2_abm"
12526 [(set (match_operand:DI 0 "register_operand" "=r")
12527 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
12528 (clobber (reg:CC FLAGS_REG))]
12529 "TARGET_64BIT && TARGET_ABM"
12530 "lzcnt{q}\t{%1, %0|%0, %1}"
12531 [(set_attr "prefix_rep" "1")
12532 (set_attr "type" "bitmanip")
12533 (set_attr "mode" "DI")])
12535 (define_insn "bsr_rex64"
12536 [(set (match_operand:DI 0 "register_operand" "=r")
12537 (minus:DI (const_int 63)
12538 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12539 (clobber (reg:CC FLAGS_REG))]
12541 "bsr{q}\t{%1, %0|%0, %1}"
12542 [(set_attr "type" "alu1")
12543 (set_attr "prefix_0f" "1")
12544 (set_attr "mode" "DI")])
12546 (define_expand "clzhi2"
12548 [(set (match_operand:HI 0 "register_operand" "")
12549 (minus:HI (const_int 15)
12550 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
12551 (clobber (reg:CC FLAGS_REG))])
12553 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
12554 (clobber (reg:CC FLAGS_REG))])]
12559 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
12564 (define_insn "clzhi2_abm"
12565 [(set (match_operand:HI 0 "register_operand" "=r")
12566 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
12567 (clobber (reg:CC FLAGS_REG))]
12569 "lzcnt{w}\t{%1, %0|%0, %1}"
12570 [(set_attr "prefix_rep" "1")
12571 (set_attr "type" "bitmanip")
12572 (set_attr "mode" "HI")])
12574 (define_insn "*bsrhi"
12575 [(set (match_operand:HI 0 "register_operand" "=r")
12576 (minus:HI (const_int 15)
12577 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12578 (clobber (reg:CC FLAGS_REG))]
12580 "bsr{w}\t{%1, %0|%0, %1}"
12581 [(set_attr "type" "alu1")
12582 (set_attr "prefix_0f" "1")
12583 (set_attr "mode" "HI")])
12585 (define_expand "paritydi2"
12586 [(set (match_operand:DI 0 "register_operand" "")
12587 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12590 rtx scratch = gen_reg_rtx (QImode);
12593 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12594 NULL_RTX, operands[1]));
12596 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12597 gen_rtx_REG (CCmode, FLAGS_REG),
12599 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12602 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12605 rtx tmp = gen_reg_rtx (SImode);
12607 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12608 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12613 (define_insn_and_split "paritydi2_cmp"
12614 [(set (reg:CC FLAGS_REG)
12615 (parity:CC (match_operand:DI 3 "register_operand" "0")))
12616 (clobber (match_scratch:DI 0 "=r"))
12617 (clobber (match_scratch:SI 1 "=&r"))
12618 (clobber (match_scratch:HI 2 "=Q"))]
12621 "&& reload_completed"
12623 [(set (match_dup 1)
12624 (xor:SI (match_dup 1) (match_dup 4)))
12625 (clobber (reg:CC FLAGS_REG))])
12627 [(set (reg:CC FLAGS_REG)
12628 (parity:CC (match_dup 1)))
12629 (clobber (match_dup 1))
12630 (clobber (match_dup 2))])]
12632 operands[4] = gen_lowpart (SImode, operands[3]);
12636 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12637 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12640 operands[1] = gen_highpart (SImode, operands[3]);
12643 (define_expand "paritysi2"
12644 [(set (match_operand:SI 0 "register_operand" "")
12645 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12648 rtx scratch = gen_reg_rtx (QImode);
12651 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12653 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12654 gen_rtx_REG (CCmode, FLAGS_REG),
12656 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12658 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12662 (define_insn_and_split "paritysi2_cmp"
12663 [(set (reg:CC FLAGS_REG)
12664 (parity:CC (match_operand:SI 2 "register_operand" "0")))
12665 (clobber (match_scratch:SI 0 "=r"))
12666 (clobber (match_scratch:HI 1 "=&Q"))]
12669 "&& reload_completed"
12671 [(set (match_dup 1)
12672 (xor:HI (match_dup 1) (match_dup 3)))
12673 (clobber (reg:CC FLAGS_REG))])
12675 [(set (reg:CC FLAGS_REG)
12676 (parity:CC (match_dup 1)))
12677 (clobber (match_dup 1))])]
12679 operands[3] = gen_lowpart (HImode, operands[2]);
12681 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12682 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12685 (define_insn "*parityhi2_cmp"
12686 [(set (reg:CC FLAGS_REG)
12687 (parity:CC (match_operand:HI 1 "register_operand" "0")))
12688 (clobber (match_scratch:HI 0 "=Q"))]
12690 "xor{b}\t{%h0, %b0|%b0, %h0}"
12691 [(set_attr "length" "2")
12692 (set_attr "mode" "HI")])
12694 (define_insn "*parityqi2_cmp"
12695 [(set (reg:CC FLAGS_REG)
12696 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
12699 [(set_attr "length" "2")
12700 (set_attr "mode" "QI")])
12702 ;; Thread-local storage patterns for ELF.
12704 ;; Note that these code sequences must appear exactly as shown
12705 ;; in order to allow linker relaxation.
12707 (define_insn "*tls_global_dynamic_32_gnu"
12708 [(set (match_operand:SI 0 "register_operand" "=a")
12709 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12710 (match_operand:SI 2 "tls_symbolic_operand" "")
12711 (match_operand:SI 3 "call_insn_operand" "")]
12713 (clobber (match_scratch:SI 4 "=d"))
12714 (clobber (match_scratch:SI 5 "=c"))
12715 (clobber (reg:CC FLAGS_REG))]
12716 "!TARGET_64BIT && TARGET_GNU_TLS"
12717 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12718 [(set_attr "type" "multi")
12719 (set_attr "length" "12")])
12721 (define_expand "tls_global_dynamic_32"
12722 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12725 (match_operand:SI 1 "tls_symbolic_operand" "")
12728 (clobber (match_scratch:SI 4 ""))
12729 (clobber (match_scratch:SI 5 ""))
12730 (clobber (reg:CC FLAGS_REG))])]
12734 operands[2] = pic_offset_table_rtx;
12737 operands[2] = gen_reg_rtx (Pmode);
12738 emit_insn (gen_set_got (operands[2]));
12740 if (TARGET_GNU2_TLS)
12742 emit_insn (gen_tls_dynamic_gnu2_32
12743 (operands[0], operands[1], operands[2]));
12746 operands[3] = ix86_tls_get_addr ();
12749 (define_insn "*tls_global_dynamic_64"
12750 [(set (match_operand:DI 0 "register_operand" "=a")
12751 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12752 (match_operand:DI 3 "" "")))
12753 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12756 { 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"; }
12757 [(set_attr "type" "multi")
12758 (set_attr "length" "16")])
12760 (define_expand "tls_global_dynamic_64"
12761 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12762 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12763 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12767 if (TARGET_GNU2_TLS)
12769 emit_insn (gen_tls_dynamic_gnu2_64
12770 (operands[0], operands[1]));
12773 operands[2] = ix86_tls_get_addr ();
12776 (define_insn "*tls_local_dynamic_base_32_gnu"
12777 [(set (match_operand:SI 0 "register_operand" "=a")
12778 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12779 (match_operand:SI 2 "call_insn_operand" "")]
12780 UNSPEC_TLS_LD_BASE))
12781 (clobber (match_scratch:SI 3 "=d"))
12782 (clobber (match_scratch:SI 4 "=c"))
12783 (clobber (reg:CC FLAGS_REG))]
12784 "!TARGET_64BIT && TARGET_GNU_TLS"
12785 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12786 [(set_attr "type" "multi")
12787 (set_attr "length" "11")])
12789 (define_expand "tls_local_dynamic_base_32"
12790 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12791 (unspec:SI [(match_dup 1) (match_dup 2)]
12792 UNSPEC_TLS_LD_BASE))
12793 (clobber (match_scratch:SI 3 ""))
12794 (clobber (match_scratch:SI 4 ""))
12795 (clobber (reg:CC FLAGS_REG))])]
12799 operands[1] = pic_offset_table_rtx;
12802 operands[1] = gen_reg_rtx (Pmode);
12803 emit_insn (gen_set_got (operands[1]));
12805 if (TARGET_GNU2_TLS)
12807 emit_insn (gen_tls_dynamic_gnu2_32
12808 (operands[0], ix86_tls_module_base (), operands[1]));
12811 operands[2] = ix86_tls_get_addr ();
12814 (define_insn "*tls_local_dynamic_base_64"
12815 [(set (match_operand:DI 0 "register_operand" "=a")
12816 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12817 (match_operand:DI 2 "" "")))
12818 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12820 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12821 [(set_attr "type" "multi")
12822 (set_attr "length" "12")])
12824 (define_expand "tls_local_dynamic_base_64"
12825 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12826 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12827 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12830 if (TARGET_GNU2_TLS)
12832 emit_insn (gen_tls_dynamic_gnu2_64
12833 (operands[0], ix86_tls_module_base ()));
12836 operands[1] = ix86_tls_get_addr ();
12839 ;; Local dynamic of a single variable is a lose. Show combine how
12840 ;; to convert that back to global dynamic.
12842 (define_insn_and_split "*tls_local_dynamic_32_once"
12843 [(set (match_operand:SI 0 "register_operand" "=a")
12844 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12845 (match_operand:SI 2 "call_insn_operand" "")]
12846 UNSPEC_TLS_LD_BASE)
12847 (const:SI (unspec:SI
12848 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12850 (clobber (match_scratch:SI 4 "=d"))
12851 (clobber (match_scratch:SI 5 "=c"))
12852 (clobber (reg:CC FLAGS_REG))]
12856 [(parallel [(set (match_dup 0)
12857 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12859 (clobber (match_dup 4))
12860 (clobber (match_dup 5))
12861 (clobber (reg:CC FLAGS_REG))])]
12864 ;; Load and add the thread base pointer from %gs:0.
12866 (define_insn "*load_tp_si"
12867 [(set (match_operand:SI 0 "register_operand" "=r")
12868 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12870 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12871 [(set_attr "type" "imov")
12872 (set_attr "modrm" "0")
12873 (set_attr "length" "7")
12874 (set_attr "memory" "load")
12875 (set_attr "imm_disp" "false")])
12877 (define_insn "*add_tp_si"
12878 [(set (match_operand:SI 0 "register_operand" "=r")
12879 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12880 (match_operand:SI 1 "register_operand" "0")))
12881 (clobber (reg:CC FLAGS_REG))]
12883 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12884 [(set_attr "type" "alu")
12885 (set_attr "modrm" "0")
12886 (set_attr "length" "7")
12887 (set_attr "memory" "load")
12888 (set_attr "imm_disp" "false")])
12890 (define_insn "*load_tp_di"
12891 [(set (match_operand:DI 0 "register_operand" "=r")
12892 (unspec:DI [(const_int 0)] UNSPEC_TP))]
12894 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12895 [(set_attr "type" "imov")
12896 (set_attr "modrm" "0")
12897 (set_attr "length" "7")
12898 (set_attr "memory" "load")
12899 (set_attr "imm_disp" "false")])
12901 (define_insn "*add_tp_di"
12902 [(set (match_operand:DI 0 "register_operand" "=r")
12903 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12904 (match_operand:DI 1 "register_operand" "0")))
12905 (clobber (reg:CC FLAGS_REG))]
12907 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12908 [(set_attr "type" "alu")
12909 (set_attr "modrm" "0")
12910 (set_attr "length" "7")
12911 (set_attr "memory" "load")
12912 (set_attr "imm_disp" "false")])
12914 ;; GNU2 TLS patterns can be split.
12916 (define_expand "tls_dynamic_gnu2_32"
12917 [(set (match_dup 3)
12918 (plus:SI (match_operand:SI 2 "register_operand" "")
12920 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12923 [(set (match_operand:SI 0 "register_operand" "")
12924 (unspec:SI [(match_dup 1) (match_dup 3)
12925 (match_dup 2) (reg:SI SP_REG)]
12927 (clobber (reg:CC FLAGS_REG))])]
12928 "!TARGET_64BIT && TARGET_GNU2_TLS"
12930 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12931 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12934 (define_insn "*tls_dynamic_lea_32"
12935 [(set (match_operand:SI 0 "register_operand" "=r")
12936 (plus:SI (match_operand:SI 1 "register_operand" "b")
12938 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12939 UNSPEC_TLSDESC))))]
12940 "!TARGET_64BIT && TARGET_GNU2_TLS"
12941 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12942 [(set_attr "type" "lea")
12943 (set_attr "mode" "SI")
12944 (set_attr "length" "6")
12945 (set_attr "length_address" "4")])
12947 (define_insn "*tls_dynamic_call_32"
12948 [(set (match_operand:SI 0 "register_operand" "=a")
12949 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12950 (match_operand:SI 2 "register_operand" "0")
12951 ;; we have to make sure %ebx still points to the GOT
12952 (match_operand:SI 3 "register_operand" "b")
12955 (clobber (reg:CC FLAGS_REG))]
12956 "!TARGET_64BIT && TARGET_GNU2_TLS"
12957 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12958 [(set_attr "type" "call")
12959 (set_attr "length" "2")
12960 (set_attr "length_address" "0")])
12962 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12963 [(set (match_operand:SI 0 "register_operand" "=&a")
12965 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12966 (match_operand:SI 4 "" "")
12967 (match_operand:SI 2 "register_operand" "b")
12970 (const:SI (unspec:SI
12971 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12973 (clobber (reg:CC FLAGS_REG))]
12974 "!TARGET_64BIT && TARGET_GNU2_TLS"
12977 [(set (match_dup 0) (match_dup 5))]
12979 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12980 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12983 (define_expand "tls_dynamic_gnu2_64"
12984 [(set (match_dup 2)
12985 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12988 [(set (match_operand:DI 0 "register_operand" "")
12989 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12991 (clobber (reg:CC FLAGS_REG))])]
12992 "TARGET_64BIT && TARGET_GNU2_TLS"
12994 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12995 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12998 (define_insn "*tls_dynamic_lea_64"
12999 [(set (match_operand:DI 0 "register_operand" "=r")
13000 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13002 "TARGET_64BIT && TARGET_GNU2_TLS"
13003 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
13004 [(set_attr "type" "lea")
13005 (set_attr "mode" "DI")
13006 (set_attr "length" "7")
13007 (set_attr "length_address" "4")])
13009 (define_insn "*tls_dynamic_call_64"
13010 [(set (match_operand:DI 0 "register_operand" "=a")
13011 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
13012 (match_operand:DI 2 "register_operand" "0")
13015 (clobber (reg:CC FLAGS_REG))]
13016 "TARGET_64BIT && TARGET_GNU2_TLS"
13017 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13018 [(set_attr "type" "call")
13019 (set_attr "length" "2")
13020 (set_attr "length_address" "0")])
13022 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13023 [(set (match_operand:DI 0 "register_operand" "=&a")
13025 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
13026 (match_operand:DI 3 "" "")
13029 (const:DI (unspec:DI
13030 [(match_operand:DI 1 "tls_symbolic_operand" "")]
13032 (clobber (reg:CC FLAGS_REG))]
13033 "TARGET_64BIT && TARGET_GNU2_TLS"
13036 [(set (match_dup 0) (match_dup 4))]
13038 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13039 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13044 ;; These patterns match the binary 387 instructions for addM3, subM3,
13045 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13046 ;; SFmode. The first is the normal insn, the second the same insn but
13047 ;; with one operand a conversion, and the third the same insn but with
13048 ;; the other operand a conversion. The conversion may be SFmode or
13049 ;; SImode if the target mode DFmode, but only SImode if the target mode
13052 ;; Gcc is slightly more smart about handling normal two address instructions
13053 ;; so use special patterns for add and mull.
13055 (define_insn "*fop_<mode>_comm_mixed_avx"
13056 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
13057 (match_operator:MODEF 3 "binary_fp_operator"
13058 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13059 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
13060 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13061 && COMMUTATIVE_ARITH_P (operands[3])
13062 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13063 "* return output_387_binary_op (insn, operands);"
13064 [(set (attr "type")
13065 (if_then_else (eq_attr "alternative" "1")
13066 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13067 (const_string "ssemul")
13068 (const_string "sseadd"))
13069 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13070 (const_string "fmul")
13071 (const_string "fop"))))
13072 (set_attr "prefix" "orig,maybe_vex")
13073 (set_attr "mode" "<MODE>")])
13075 (define_insn "*fop_<mode>_comm_mixed"
13076 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
13077 (match_operator:MODEF 3 "binary_fp_operator"
13078 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
13079 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
13080 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13081 && COMMUTATIVE_ARITH_P (operands[3])
13082 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13083 "* return output_387_binary_op (insn, operands);"
13084 [(set (attr "type")
13085 (if_then_else (eq_attr "alternative" "1")
13086 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13087 (const_string "ssemul")
13088 (const_string "sseadd"))
13089 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13090 (const_string "fmul")
13091 (const_string "fop"))))
13092 (set_attr "mode" "<MODE>")])
13094 (define_insn "*fop_<mode>_comm_avx"
13095 [(set (match_operand:MODEF 0 "register_operand" "=x")
13096 (match_operator:MODEF 3 "binary_fp_operator"
13097 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
13098 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13099 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13100 && COMMUTATIVE_ARITH_P (operands[3])
13101 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13102 "* return output_387_binary_op (insn, operands);"
13103 [(set (attr "type")
13104 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13105 (const_string "ssemul")
13106 (const_string "sseadd")))
13107 (set_attr "prefix" "vex")
13108 (set_attr "mode" "<MODE>")])
13110 (define_insn "*fop_<mode>_comm_sse"
13111 [(set (match_operand:MODEF 0 "register_operand" "=x")
13112 (match_operator:MODEF 3 "binary_fp_operator"
13113 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13114 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13115 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13116 && COMMUTATIVE_ARITH_P (operands[3])
13117 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13118 "* return output_387_binary_op (insn, operands);"
13119 [(set (attr "type")
13120 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13121 (const_string "ssemul")
13122 (const_string "sseadd")))
13123 (set_attr "mode" "<MODE>")])
13125 (define_insn "*fop_<mode>_comm_i387"
13126 [(set (match_operand:MODEF 0 "register_operand" "=f")
13127 (match_operator:MODEF 3 "binary_fp_operator"
13128 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13129 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13130 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13131 && COMMUTATIVE_ARITH_P (operands[3])
13132 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13133 "* return output_387_binary_op (insn, operands);"
13134 [(set (attr "type")
13135 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13136 (const_string "fmul")
13137 (const_string "fop")))
13138 (set_attr "mode" "<MODE>")])
13140 (define_insn "*fop_<mode>_1_mixed_avx"
13141 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13142 (match_operator:MODEF 3 "binary_fp_operator"
13143 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
13144 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13145 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13146 && !COMMUTATIVE_ARITH_P (operands[3])
13147 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13148 "* return output_387_binary_op (insn, operands);"
13149 [(set (attr "type")
13150 (cond [(and (eq_attr "alternative" "2")
13151 (match_operand:MODEF 3 "mult_operator" ""))
13152 (const_string "ssemul")
13153 (and (eq_attr "alternative" "2")
13154 (match_operand:MODEF 3 "div_operator" ""))
13155 (const_string "ssediv")
13156 (eq_attr "alternative" "2")
13157 (const_string "sseadd")
13158 (match_operand:MODEF 3 "mult_operator" "")
13159 (const_string "fmul")
13160 (match_operand:MODEF 3 "div_operator" "")
13161 (const_string "fdiv")
13163 (const_string "fop")))
13164 (set_attr "prefix" "orig,orig,maybe_vex")
13165 (set_attr "mode" "<MODE>")])
13167 (define_insn "*fop_<mode>_1_mixed"
13168 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13169 (match_operator:MODEF 3 "binary_fp_operator"
13170 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
13171 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13172 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13173 && !COMMUTATIVE_ARITH_P (operands[3])
13174 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13175 "* return output_387_binary_op (insn, operands);"
13176 [(set (attr "type")
13177 (cond [(and (eq_attr "alternative" "2")
13178 (match_operand:MODEF 3 "mult_operator" ""))
13179 (const_string "ssemul")
13180 (and (eq_attr "alternative" "2")
13181 (match_operand:MODEF 3 "div_operator" ""))
13182 (const_string "ssediv")
13183 (eq_attr "alternative" "2")
13184 (const_string "sseadd")
13185 (match_operand:MODEF 3 "mult_operator" "")
13186 (const_string "fmul")
13187 (match_operand:MODEF 3 "div_operator" "")
13188 (const_string "fdiv")
13190 (const_string "fop")))
13191 (set_attr "mode" "<MODE>")])
13193 (define_insn "*rcpsf2_sse"
13194 [(set (match_operand:SF 0 "register_operand" "=x")
13195 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13198 "%vrcpss\t{%1, %d0|%d0, %1}"
13199 [(set_attr "type" "sse")
13200 (set_attr "atom_sse_attr" "rcp")
13201 (set_attr "prefix" "maybe_vex")
13202 (set_attr "mode" "SF")])
13204 (define_insn "*fop_<mode>_1_avx"
13205 [(set (match_operand:MODEF 0 "register_operand" "=x")
13206 (match_operator:MODEF 3 "binary_fp_operator"
13207 [(match_operand:MODEF 1 "register_operand" "x")
13208 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13209 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13210 && !COMMUTATIVE_ARITH_P (operands[3])"
13211 "* return output_387_binary_op (insn, operands);"
13212 [(set (attr "type")
13213 (cond [(match_operand:MODEF 3 "mult_operator" "")
13214 (const_string "ssemul")
13215 (match_operand:MODEF 3 "div_operator" "")
13216 (const_string "ssediv")
13218 (const_string "sseadd")))
13219 (set_attr "prefix" "vex")
13220 (set_attr "mode" "<MODE>")])
13222 (define_insn "*fop_<mode>_1_sse"
13223 [(set (match_operand:MODEF 0 "register_operand" "=x")
13224 (match_operator:MODEF 3 "binary_fp_operator"
13225 [(match_operand:MODEF 1 "register_operand" "0")
13226 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13227 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13228 && !COMMUTATIVE_ARITH_P (operands[3])"
13229 "* return output_387_binary_op (insn, operands);"
13230 [(set (attr "type")
13231 (cond [(match_operand:MODEF 3 "mult_operator" "")
13232 (const_string "ssemul")
13233 (match_operand:MODEF 3 "div_operator" "")
13234 (const_string "ssediv")
13236 (const_string "sseadd")))
13237 (set_attr "mode" "<MODE>")])
13239 ;; This pattern is not fully shadowed by the pattern above.
13240 (define_insn "*fop_<mode>_1_i387"
13241 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13242 (match_operator:MODEF 3 "binary_fp_operator"
13243 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13244 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13245 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13246 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13247 && !COMMUTATIVE_ARITH_P (operands[3])
13248 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13249 "* return output_387_binary_op (insn, operands);"
13250 [(set (attr "type")
13251 (cond [(match_operand:MODEF 3 "mult_operator" "")
13252 (const_string "fmul")
13253 (match_operand:MODEF 3 "div_operator" "")
13254 (const_string "fdiv")
13256 (const_string "fop")))
13257 (set_attr "mode" "<MODE>")])
13259 ;; ??? Add SSE splitters for these!
13260 (define_insn "*fop_<MODEF:mode>_2_i387"
13261 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13262 (match_operator:MODEF 3 "binary_fp_operator"
13264 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13265 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13266 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13267 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13268 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13269 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13270 [(set (attr "type")
13271 (cond [(match_operand:MODEF 3 "mult_operator" "")
13272 (const_string "fmul")
13273 (match_operand:MODEF 3 "div_operator" "")
13274 (const_string "fdiv")
13276 (const_string "fop")))
13277 (set_attr "fp_int_src" "true")
13278 (set_attr "mode" "<X87MODEI12:MODE>")])
13280 (define_insn "*fop_<MODEF:mode>_3_i387"
13281 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13282 (match_operator:MODEF 3 "binary_fp_operator"
13283 [(match_operand:MODEF 1 "register_operand" "0,0")
13285 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13286 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13287 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13288 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13289 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13290 [(set (attr "type")
13291 (cond [(match_operand:MODEF 3 "mult_operator" "")
13292 (const_string "fmul")
13293 (match_operand:MODEF 3 "div_operator" "")
13294 (const_string "fdiv")
13296 (const_string "fop")))
13297 (set_attr "fp_int_src" "true")
13298 (set_attr "mode" "<MODE>")])
13300 (define_insn "*fop_df_4_i387"
13301 [(set (match_operand:DF 0 "register_operand" "=f,f")
13302 (match_operator:DF 3 "binary_fp_operator"
13304 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13305 (match_operand:DF 2 "register_operand" "0,f")]))]
13306 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13307 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13308 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13309 "* return output_387_binary_op (insn, operands);"
13310 [(set (attr "type")
13311 (cond [(match_operand:DF 3 "mult_operator" "")
13312 (const_string "fmul")
13313 (match_operand:DF 3 "div_operator" "")
13314 (const_string "fdiv")
13316 (const_string "fop")))
13317 (set_attr "mode" "SF")])
13319 (define_insn "*fop_df_5_i387"
13320 [(set (match_operand:DF 0 "register_operand" "=f,f")
13321 (match_operator:DF 3 "binary_fp_operator"
13322 [(match_operand:DF 1 "register_operand" "0,f")
13324 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13325 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13326 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13327 "* return output_387_binary_op (insn, operands);"
13328 [(set (attr "type")
13329 (cond [(match_operand:DF 3 "mult_operator" "")
13330 (const_string "fmul")
13331 (match_operand:DF 3 "div_operator" "")
13332 (const_string "fdiv")
13334 (const_string "fop")))
13335 (set_attr "mode" "SF")])
13337 (define_insn "*fop_df_6_i387"
13338 [(set (match_operand:DF 0 "register_operand" "=f,f")
13339 (match_operator:DF 3 "binary_fp_operator"
13341 (match_operand:SF 1 "register_operand" "0,f"))
13343 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13344 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13345 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13346 "* return output_387_binary_op (insn, operands);"
13347 [(set (attr "type")
13348 (cond [(match_operand:DF 3 "mult_operator" "")
13349 (const_string "fmul")
13350 (match_operand:DF 3 "div_operator" "")
13351 (const_string "fdiv")
13353 (const_string "fop")))
13354 (set_attr "mode" "SF")])
13356 (define_insn "*fop_xf_comm_i387"
13357 [(set (match_operand:XF 0 "register_operand" "=f")
13358 (match_operator:XF 3 "binary_fp_operator"
13359 [(match_operand:XF 1 "register_operand" "%0")
13360 (match_operand:XF 2 "register_operand" "f")]))]
13362 && COMMUTATIVE_ARITH_P (operands[3])"
13363 "* return output_387_binary_op (insn, operands);"
13364 [(set (attr "type")
13365 (if_then_else (match_operand:XF 3 "mult_operator" "")
13366 (const_string "fmul")
13367 (const_string "fop")))
13368 (set_attr "mode" "XF")])
13370 (define_insn "*fop_xf_1_i387"
13371 [(set (match_operand:XF 0 "register_operand" "=f,f")
13372 (match_operator:XF 3 "binary_fp_operator"
13373 [(match_operand:XF 1 "register_operand" "0,f")
13374 (match_operand:XF 2 "register_operand" "f,0")]))]
13376 && !COMMUTATIVE_ARITH_P (operands[3])"
13377 "* return output_387_binary_op (insn, operands);"
13378 [(set (attr "type")
13379 (cond [(match_operand:XF 3 "mult_operator" "")
13380 (const_string "fmul")
13381 (match_operand:XF 3 "div_operator" "")
13382 (const_string "fdiv")
13384 (const_string "fop")))
13385 (set_attr "mode" "XF")])
13387 (define_insn "*fop_xf_2_i387"
13388 [(set (match_operand:XF 0 "register_operand" "=f,f")
13389 (match_operator:XF 3 "binary_fp_operator"
13391 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13392 (match_operand:XF 2 "register_operand" "0,0")]))]
13393 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13394 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13395 [(set (attr "type")
13396 (cond [(match_operand:XF 3 "mult_operator" "")
13397 (const_string "fmul")
13398 (match_operand:XF 3 "div_operator" "")
13399 (const_string "fdiv")
13401 (const_string "fop")))
13402 (set_attr "fp_int_src" "true")
13403 (set_attr "mode" "<MODE>")])
13405 (define_insn "*fop_xf_3_i387"
13406 [(set (match_operand:XF 0 "register_operand" "=f,f")
13407 (match_operator:XF 3 "binary_fp_operator"
13408 [(match_operand:XF 1 "register_operand" "0,0")
13410 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13411 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13412 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13413 [(set (attr "type")
13414 (cond [(match_operand:XF 3 "mult_operator" "")
13415 (const_string "fmul")
13416 (match_operand:XF 3 "div_operator" "")
13417 (const_string "fdiv")
13419 (const_string "fop")))
13420 (set_attr "fp_int_src" "true")
13421 (set_attr "mode" "<MODE>")])
13423 (define_insn "*fop_xf_4_i387"
13424 [(set (match_operand:XF 0 "register_operand" "=f,f")
13425 (match_operator:XF 3 "binary_fp_operator"
13427 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13428 (match_operand:XF 2 "register_operand" "0,f")]))]
13430 "* return output_387_binary_op (insn, operands);"
13431 [(set (attr "type")
13432 (cond [(match_operand:XF 3 "mult_operator" "")
13433 (const_string "fmul")
13434 (match_operand:XF 3 "div_operator" "")
13435 (const_string "fdiv")
13437 (const_string "fop")))
13438 (set_attr "mode" "<MODE>")])
13440 (define_insn "*fop_xf_5_i387"
13441 [(set (match_operand:XF 0 "register_operand" "=f,f")
13442 (match_operator:XF 3 "binary_fp_operator"
13443 [(match_operand:XF 1 "register_operand" "0,f")
13445 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13447 "* return output_387_binary_op (insn, operands);"
13448 [(set (attr "type")
13449 (cond [(match_operand:XF 3 "mult_operator" "")
13450 (const_string "fmul")
13451 (match_operand:XF 3 "div_operator" "")
13452 (const_string "fdiv")
13454 (const_string "fop")))
13455 (set_attr "mode" "<MODE>")])
13457 (define_insn "*fop_xf_6_i387"
13458 [(set (match_operand:XF 0 "register_operand" "=f,f")
13459 (match_operator:XF 3 "binary_fp_operator"
13461 (match_operand:MODEF 1 "register_operand" "0,f"))
13463 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13465 "* return output_387_binary_op (insn, operands);"
13466 [(set (attr "type")
13467 (cond [(match_operand:XF 3 "mult_operator" "")
13468 (const_string "fmul")
13469 (match_operand:XF 3 "div_operator" "")
13470 (const_string "fdiv")
13472 (const_string "fop")))
13473 (set_attr "mode" "<MODE>")])
13476 [(set (match_operand 0 "register_operand" "")
13477 (match_operator 3 "binary_fp_operator"
13478 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13479 (match_operand 2 "register_operand" "")]))]
13481 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13482 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13485 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13486 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13487 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13488 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13489 GET_MODE (operands[3]),
13492 ix86_free_from_memory (GET_MODE (operands[1]));
13497 [(set (match_operand 0 "register_operand" "")
13498 (match_operator 3 "binary_fp_operator"
13499 [(match_operand 1 "register_operand" "")
13500 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13502 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13503 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13506 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13507 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13508 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13509 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13510 GET_MODE (operands[3]),
13513 ix86_free_from_memory (GET_MODE (operands[2]));
13517 ;; FPU special functions.
13519 ;; This pattern implements a no-op XFmode truncation for
13520 ;; all fancy i386 XFmode math functions.
13522 (define_insn "truncxf<mode>2_i387_noop_unspec"
13523 [(set (match_operand:MODEF 0 "register_operand" "=f")
13524 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13525 UNSPEC_TRUNC_NOOP))]
13526 "TARGET_USE_FANCY_MATH_387"
13527 "* return output_387_reg_move (insn, operands);"
13528 [(set_attr "type" "fmov")
13529 (set_attr "mode" "<MODE>")])
13531 (define_insn "sqrtxf2"
13532 [(set (match_operand:XF 0 "register_operand" "=f")
13533 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13534 "TARGET_USE_FANCY_MATH_387"
13536 [(set_attr "type" "fpspc")
13537 (set_attr "mode" "XF")
13538 (set_attr "athlon_decode" "direct")
13539 (set_attr "amdfam10_decode" "direct")])
13541 (define_insn "sqrt_extend<mode>xf2_i387"
13542 [(set (match_operand:XF 0 "register_operand" "=f")
13545 (match_operand:MODEF 1 "register_operand" "0"))))]
13546 "TARGET_USE_FANCY_MATH_387"
13548 [(set_attr "type" "fpspc")
13549 (set_attr "mode" "XF")
13550 (set_attr "athlon_decode" "direct")
13551 (set_attr "amdfam10_decode" "direct")])
13553 (define_insn "*rsqrtsf2_sse"
13554 [(set (match_operand:SF 0 "register_operand" "=x")
13555 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13558 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13559 [(set_attr "type" "sse")
13560 (set_attr "atom_sse_attr" "rcp")
13561 (set_attr "prefix" "maybe_vex")
13562 (set_attr "mode" "SF")])
13564 (define_expand "rsqrtsf2"
13565 [(set (match_operand:SF 0 "register_operand" "")
13566 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13570 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13574 (define_insn "*sqrt<mode>2_sse"
13575 [(set (match_operand:MODEF 0 "register_operand" "=x")
13577 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13578 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13579 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13580 [(set_attr "type" "sse")
13581 (set_attr "atom_sse_attr" "sqrt")
13582 (set_attr "prefix" "maybe_vex")
13583 (set_attr "mode" "<MODE>")
13584 (set_attr "athlon_decode" "*")
13585 (set_attr "amdfam10_decode" "*")])
13587 (define_expand "sqrt<mode>2"
13588 [(set (match_operand:MODEF 0 "register_operand" "")
13590 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13591 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13592 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13594 if (<MODE>mode == SFmode
13595 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13596 && flag_finite_math_only && !flag_trapping_math
13597 && flag_unsafe_math_optimizations)
13599 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13603 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13605 rtx op0 = gen_reg_rtx (XFmode);
13606 rtx op1 = force_reg (<MODE>mode, operands[1]);
13608 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13609 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13614 (define_insn "fpremxf4_i387"
13615 [(set (match_operand:XF 0 "register_operand" "=f")
13616 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13617 (match_operand:XF 3 "register_operand" "1")]
13619 (set (match_operand:XF 1 "register_operand" "=u")
13620 (unspec:XF [(match_dup 2) (match_dup 3)]
13622 (set (reg:CCFP FPSR_REG)
13623 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13625 "TARGET_USE_FANCY_MATH_387"
13627 [(set_attr "type" "fpspc")
13628 (set_attr "mode" "XF")])
13630 (define_expand "fmodxf3"
13631 [(use (match_operand:XF 0 "register_operand" ""))
13632 (use (match_operand:XF 1 "general_operand" ""))
13633 (use (match_operand:XF 2 "general_operand" ""))]
13634 "TARGET_USE_FANCY_MATH_387"
13636 rtx label = gen_label_rtx ();
13638 rtx op1 = gen_reg_rtx (XFmode);
13639 rtx op2 = gen_reg_rtx (XFmode);
13641 emit_move_insn (op2, operands[2]);
13642 emit_move_insn (op1, operands[1]);
13644 emit_label (label);
13645 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13646 ix86_emit_fp_unordered_jump (label);
13647 LABEL_NUSES (label) = 1;
13649 emit_move_insn (operands[0], op1);
13653 (define_expand "fmod<mode>3"
13654 [(use (match_operand:MODEF 0 "register_operand" ""))
13655 (use (match_operand:MODEF 1 "general_operand" ""))
13656 (use (match_operand:MODEF 2 "general_operand" ""))]
13657 "TARGET_USE_FANCY_MATH_387"
13659 rtx label = gen_label_rtx ();
13661 rtx op1 = gen_reg_rtx (XFmode);
13662 rtx op2 = gen_reg_rtx (XFmode);
13664 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13665 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13667 emit_label (label);
13668 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13669 ix86_emit_fp_unordered_jump (label);
13670 LABEL_NUSES (label) = 1;
13672 /* Truncate the result properly for strict SSE math. */
13673 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13674 && !TARGET_MIX_SSE_I387)
13675 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13677 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13682 (define_insn "fprem1xf4_i387"
13683 [(set (match_operand:XF 0 "register_operand" "=f")
13684 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13685 (match_operand:XF 3 "register_operand" "1")]
13687 (set (match_operand:XF 1 "register_operand" "=u")
13688 (unspec:XF [(match_dup 2) (match_dup 3)]
13690 (set (reg:CCFP FPSR_REG)
13691 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13693 "TARGET_USE_FANCY_MATH_387"
13695 [(set_attr "type" "fpspc")
13696 (set_attr "mode" "XF")])
13698 (define_expand "remainderxf3"
13699 [(use (match_operand:XF 0 "register_operand" ""))
13700 (use (match_operand:XF 1 "general_operand" ""))
13701 (use (match_operand:XF 2 "general_operand" ""))]
13702 "TARGET_USE_FANCY_MATH_387"
13704 rtx label = gen_label_rtx ();
13706 rtx op1 = gen_reg_rtx (XFmode);
13707 rtx op2 = gen_reg_rtx (XFmode);
13709 emit_move_insn (op2, operands[2]);
13710 emit_move_insn (op1, operands[1]);
13712 emit_label (label);
13713 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13714 ix86_emit_fp_unordered_jump (label);
13715 LABEL_NUSES (label) = 1;
13717 emit_move_insn (operands[0], op1);
13721 (define_expand "remainder<mode>3"
13722 [(use (match_operand:MODEF 0 "register_operand" ""))
13723 (use (match_operand:MODEF 1 "general_operand" ""))
13724 (use (match_operand:MODEF 2 "general_operand" ""))]
13725 "TARGET_USE_FANCY_MATH_387"
13727 rtx label = gen_label_rtx ();
13729 rtx op1 = gen_reg_rtx (XFmode);
13730 rtx op2 = gen_reg_rtx (XFmode);
13732 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13733 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13735 emit_label (label);
13737 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13738 ix86_emit_fp_unordered_jump (label);
13739 LABEL_NUSES (label) = 1;
13741 /* Truncate the result properly for strict SSE math. */
13742 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13743 && !TARGET_MIX_SSE_I387)
13744 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13746 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13751 (define_insn "*sinxf2_i387"
13752 [(set (match_operand:XF 0 "register_operand" "=f")
13753 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13754 "TARGET_USE_FANCY_MATH_387
13755 && flag_unsafe_math_optimizations"
13757 [(set_attr "type" "fpspc")
13758 (set_attr "mode" "XF")])
13760 (define_insn "*sin_extend<mode>xf2_i387"
13761 [(set (match_operand:XF 0 "register_operand" "=f")
13762 (unspec:XF [(float_extend:XF
13763 (match_operand:MODEF 1 "register_operand" "0"))]
13765 "TARGET_USE_FANCY_MATH_387
13766 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13767 || TARGET_MIX_SSE_I387)
13768 && flag_unsafe_math_optimizations"
13770 [(set_attr "type" "fpspc")
13771 (set_attr "mode" "XF")])
13773 (define_insn "*cosxf2_i387"
13774 [(set (match_operand:XF 0 "register_operand" "=f")
13775 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13776 "TARGET_USE_FANCY_MATH_387
13777 && flag_unsafe_math_optimizations"
13779 [(set_attr "type" "fpspc")
13780 (set_attr "mode" "XF")])
13782 (define_insn "*cos_extend<mode>xf2_i387"
13783 [(set (match_operand:XF 0 "register_operand" "=f")
13784 (unspec:XF [(float_extend:XF
13785 (match_operand:MODEF 1 "register_operand" "0"))]
13787 "TARGET_USE_FANCY_MATH_387
13788 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13789 || TARGET_MIX_SSE_I387)
13790 && flag_unsafe_math_optimizations"
13792 [(set_attr "type" "fpspc")
13793 (set_attr "mode" "XF")])
13795 ;; When sincos pattern is defined, sin and cos builtin functions will be
13796 ;; expanded to sincos pattern with one of its outputs left unused.
13797 ;; CSE pass will figure out if two sincos patterns can be combined,
13798 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13799 ;; depending on the unused output.
13801 (define_insn "sincosxf3"
13802 [(set (match_operand:XF 0 "register_operand" "=f")
13803 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13804 UNSPEC_SINCOS_COS))
13805 (set (match_operand:XF 1 "register_operand" "=u")
13806 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13807 "TARGET_USE_FANCY_MATH_387
13808 && flag_unsafe_math_optimizations"
13810 [(set_attr "type" "fpspc")
13811 (set_attr "mode" "XF")])
13814 [(set (match_operand:XF 0 "register_operand" "")
13815 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13816 UNSPEC_SINCOS_COS))
13817 (set (match_operand:XF 1 "register_operand" "")
13818 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13819 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13820 && !(reload_completed || reload_in_progress)"
13821 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13825 [(set (match_operand:XF 0 "register_operand" "")
13826 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13827 UNSPEC_SINCOS_COS))
13828 (set (match_operand:XF 1 "register_operand" "")
13829 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13830 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13831 && !(reload_completed || reload_in_progress)"
13832 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13835 (define_insn "sincos_extend<mode>xf3_i387"
13836 [(set (match_operand:XF 0 "register_operand" "=f")
13837 (unspec:XF [(float_extend:XF
13838 (match_operand:MODEF 2 "register_operand" "0"))]
13839 UNSPEC_SINCOS_COS))
13840 (set (match_operand:XF 1 "register_operand" "=u")
13841 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13842 "TARGET_USE_FANCY_MATH_387
13843 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13844 || TARGET_MIX_SSE_I387)
13845 && flag_unsafe_math_optimizations"
13847 [(set_attr "type" "fpspc")
13848 (set_attr "mode" "XF")])
13851 [(set (match_operand:XF 0 "register_operand" "")
13852 (unspec:XF [(float_extend:XF
13853 (match_operand:MODEF 2 "register_operand" ""))]
13854 UNSPEC_SINCOS_COS))
13855 (set (match_operand:XF 1 "register_operand" "")
13856 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13857 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13858 && !(reload_completed || reload_in_progress)"
13859 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13863 [(set (match_operand:XF 0 "register_operand" "")
13864 (unspec:XF [(float_extend:XF
13865 (match_operand:MODEF 2 "register_operand" ""))]
13866 UNSPEC_SINCOS_COS))
13867 (set (match_operand:XF 1 "register_operand" "")
13868 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13869 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13870 && !(reload_completed || reload_in_progress)"
13871 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13874 (define_expand "sincos<mode>3"
13875 [(use (match_operand:MODEF 0 "register_operand" ""))
13876 (use (match_operand:MODEF 1 "register_operand" ""))
13877 (use (match_operand:MODEF 2 "register_operand" ""))]
13878 "TARGET_USE_FANCY_MATH_387
13879 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13880 || TARGET_MIX_SSE_I387)
13881 && flag_unsafe_math_optimizations"
13883 rtx op0 = gen_reg_rtx (XFmode);
13884 rtx op1 = gen_reg_rtx (XFmode);
13886 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13887 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13888 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13892 (define_insn "fptanxf4_i387"
13893 [(set (match_operand:XF 0 "register_operand" "=f")
13894 (match_operand:XF 3 "const_double_operand" "F"))
13895 (set (match_operand:XF 1 "register_operand" "=u")
13896 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13898 "TARGET_USE_FANCY_MATH_387
13899 && flag_unsafe_math_optimizations
13900 && standard_80387_constant_p (operands[3]) == 2"
13902 [(set_attr "type" "fpspc")
13903 (set_attr "mode" "XF")])
13905 (define_insn "fptan_extend<mode>xf4_i387"
13906 [(set (match_operand:MODEF 0 "register_operand" "=f")
13907 (match_operand:MODEF 3 "const_double_operand" "F"))
13908 (set (match_operand:XF 1 "register_operand" "=u")
13909 (unspec:XF [(float_extend:XF
13910 (match_operand:MODEF 2 "register_operand" "0"))]
13912 "TARGET_USE_FANCY_MATH_387
13913 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13914 || TARGET_MIX_SSE_I387)
13915 && flag_unsafe_math_optimizations
13916 && standard_80387_constant_p (operands[3]) == 2"
13918 [(set_attr "type" "fpspc")
13919 (set_attr "mode" "XF")])
13921 (define_expand "tanxf2"
13922 [(use (match_operand:XF 0 "register_operand" ""))
13923 (use (match_operand:XF 1 "register_operand" ""))]
13924 "TARGET_USE_FANCY_MATH_387
13925 && flag_unsafe_math_optimizations"
13927 rtx one = gen_reg_rtx (XFmode);
13928 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13930 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13934 (define_expand "tan<mode>2"
13935 [(use (match_operand:MODEF 0 "register_operand" ""))
13936 (use (match_operand:MODEF 1 "register_operand" ""))]
13937 "TARGET_USE_FANCY_MATH_387
13938 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13939 || TARGET_MIX_SSE_I387)
13940 && flag_unsafe_math_optimizations"
13942 rtx op0 = gen_reg_rtx (XFmode);
13944 rtx one = gen_reg_rtx (<MODE>mode);
13945 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13947 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13948 operands[1], op2));
13949 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13953 (define_insn "*fpatanxf3_i387"
13954 [(set (match_operand:XF 0 "register_operand" "=f")
13955 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13956 (match_operand:XF 2 "register_operand" "u")]
13958 (clobber (match_scratch:XF 3 "=2"))]
13959 "TARGET_USE_FANCY_MATH_387
13960 && flag_unsafe_math_optimizations"
13962 [(set_attr "type" "fpspc")
13963 (set_attr "mode" "XF")])
13965 (define_insn "fpatan_extend<mode>xf3_i387"
13966 [(set (match_operand:XF 0 "register_operand" "=f")
13967 (unspec:XF [(float_extend:XF
13968 (match_operand:MODEF 1 "register_operand" "0"))
13970 (match_operand:MODEF 2 "register_operand" "u"))]
13972 (clobber (match_scratch:XF 3 "=2"))]
13973 "TARGET_USE_FANCY_MATH_387
13974 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13975 || TARGET_MIX_SSE_I387)
13976 && flag_unsafe_math_optimizations"
13978 [(set_attr "type" "fpspc")
13979 (set_attr "mode" "XF")])
13981 (define_expand "atan2xf3"
13982 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13983 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13984 (match_operand:XF 1 "register_operand" "")]
13986 (clobber (match_scratch:XF 3 ""))])]
13987 "TARGET_USE_FANCY_MATH_387
13988 && flag_unsafe_math_optimizations"
13991 (define_expand "atan2<mode>3"
13992 [(use (match_operand:MODEF 0 "register_operand" ""))
13993 (use (match_operand:MODEF 1 "register_operand" ""))
13994 (use (match_operand:MODEF 2 "register_operand" ""))]
13995 "TARGET_USE_FANCY_MATH_387
13996 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13997 || TARGET_MIX_SSE_I387)
13998 && flag_unsafe_math_optimizations"
14000 rtx op0 = gen_reg_rtx (XFmode);
14002 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14003 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14007 (define_expand "atanxf2"
14008 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14009 (unspec:XF [(match_dup 2)
14010 (match_operand:XF 1 "register_operand" "")]
14012 (clobber (match_scratch:XF 3 ""))])]
14013 "TARGET_USE_FANCY_MATH_387
14014 && flag_unsafe_math_optimizations"
14016 operands[2] = gen_reg_rtx (XFmode);
14017 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14020 (define_expand "atan<mode>2"
14021 [(use (match_operand:MODEF 0 "register_operand" ""))
14022 (use (match_operand:MODEF 1 "register_operand" ""))]
14023 "TARGET_USE_FANCY_MATH_387
14024 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14025 || TARGET_MIX_SSE_I387)
14026 && flag_unsafe_math_optimizations"
14028 rtx op0 = gen_reg_rtx (XFmode);
14030 rtx op2 = gen_reg_rtx (<MODE>mode);
14031 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14033 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14034 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14038 (define_expand "asinxf2"
14039 [(set (match_dup 2)
14040 (mult:XF (match_operand:XF 1 "register_operand" "")
14042 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14043 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14044 (parallel [(set (match_operand:XF 0 "register_operand" "")
14045 (unspec:XF [(match_dup 5) (match_dup 1)]
14047 (clobber (match_scratch:XF 6 ""))])]
14048 "TARGET_USE_FANCY_MATH_387
14049 && flag_unsafe_math_optimizations"
14053 if (optimize_insn_for_size_p ())
14056 for (i = 2; i < 6; i++)
14057 operands[i] = gen_reg_rtx (XFmode);
14059 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14062 (define_expand "asin<mode>2"
14063 [(use (match_operand:MODEF 0 "register_operand" ""))
14064 (use (match_operand:MODEF 1 "general_operand" ""))]
14065 "TARGET_USE_FANCY_MATH_387
14066 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14067 || TARGET_MIX_SSE_I387)
14068 && flag_unsafe_math_optimizations"
14070 rtx op0 = gen_reg_rtx (XFmode);
14071 rtx op1 = gen_reg_rtx (XFmode);
14073 if (optimize_insn_for_size_p ())
14076 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14077 emit_insn (gen_asinxf2 (op0, op1));
14078 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14082 (define_expand "acosxf2"
14083 [(set (match_dup 2)
14084 (mult:XF (match_operand:XF 1 "register_operand" "")
14086 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14087 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14088 (parallel [(set (match_operand:XF 0 "register_operand" "")
14089 (unspec:XF [(match_dup 1) (match_dup 5)]
14091 (clobber (match_scratch:XF 6 ""))])]
14092 "TARGET_USE_FANCY_MATH_387
14093 && flag_unsafe_math_optimizations"
14097 if (optimize_insn_for_size_p ())
14100 for (i = 2; i < 6; i++)
14101 operands[i] = gen_reg_rtx (XFmode);
14103 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14106 (define_expand "acos<mode>2"
14107 [(use (match_operand:MODEF 0 "register_operand" ""))
14108 (use (match_operand:MODEF 1 "general_operand" ""))]
14109 "TARGET_USE_FANCY_MATH_387
14110 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14111 || TARGET_MIX_SSE_I387)
14112 && flag_unsafe_math_optimizations"
14114 rtx op0 = gen_reg_rtx (XFmode);
14115 rtx op1 = gen_reg_rtx (XFmode);
14117 if (optimize_insn_for_size_p ())
14120 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14121 emit_insn (gen_acosxf2 (op0, op1));
14122 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14126 (define_insn "fyl2xxf3_i387"
14127 [(set (match_operand:XF 0 "register_operand" "=f")
14128 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14129 (match_operand:XF 2 "register_operand" "u")]
14131 (clobber (match_scratch:XF 3 "=2"))]
14132 "TARGET_USE_FANCY_MATH_387
14133 && flag_unsafe_math_optimizations"
14135 [(set_attr "type" "fpspc")
14136 (set_attr "mode" "XF")])
14138 (define_insn "fyl2x_extend<mode>xf3_i387"
14139 [(set (match_operand:XF 0 "register_operand" "=f")
14140 (unspec:XF [(float_extend:XF
14141 (match_operand:MODEF 1 "register_operand" "0"))
14142 (match_operand:XF 2 "register_operand" "u")]
14144 (clobber (match_scratch:XF 3 "=2"))]
14145 "TARGET_USE_FANCY_MATH_387
14146 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14147 || TARGET_MIX_SSE_I387)
14148 && flag_unsafe_math_optimizations"
14150 [(set_attr "type" "fpspc")
14151 (set_attr "mode" "XF")])
14153 (define_expand "logxf2"
14154 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14155 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14156 (match_dup 2)] UNSPEC_FYL2X))
14157 (clobber (match_scratch:XF 3 ""))])]
14158 "TARGET_USE_FANCY_MATH_387
14159 && flag_unsafe_math_optimizations"
14161 operands[2] = gen_reg_rtx (XFmode);
14162 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14165 (define_expand "log<mode>2"
14166 [(use (match_operand:MODEF 0 "register_operand" ""))
14167 (use (match_operand:MODEF 1 "register_operand" ""))]
14168 "TARGET_USE_FANCY_MATH_387
14169 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14170 || TARGET_MIX_SSE_I387)
14171 && flag_unsafe_math_optimizations"
14173 rtx op0 = gen_reg_rtx (XFmode);
14175 rtx op2 = gen_reg_rtx (XFmode);
14176 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14178 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14179 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14183 (define_expand "log10xf2"
14184 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14185 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14186 (match_dup 2)] UNSPEC_FYL2X))
14187 (clobber (match_scratch:XF 3 ""))])]
14188 "TARGET_USE_FANCY_MATH_387
14189 && flag_unsafe_math_optimizations"
14191 operands[2] = gen_reg_rtx (XFmode);
14192 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14195 (define_expand "log10<mode>2"
14196 [(use (match_operand:MODEF 0 "register_operand" ""))
14197 (use (match_operand:MODEF 1 "register_operand" ""))]
14198 "TARGET_USE_FANCY_MATH_387
14199 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14200 || TARGET_MIX_SSE_I387)
14201 && flag_unsafe_math_optimizations"
14203 rtx op0 = gen_reg_rtx (XFmode);
14205 rtx op2 = gen_reg_rtx (XFmode);
14206 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14208 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14209 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14213 (define_expand "log2xf2"
14214 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14215 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14216 (match_dup 2)] UNSPEC_FYL2X))
14217 (clobber (match_scratch:XF 3 ""))])]
14218 "TARGET_USE_FANCY_MATH_387
14219 && flag_unsafe_math_optimizations"
14221 operands[2] = gen_reg_rtx (XFmode);
14222 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14225 (define_expand "log2<mode>2"
14226 [(use (match_operand:MODEF 0 "register_operand" ""))
14227 (use (match_operand:MODEF 1 "register_operand" ""))]
14228 "TARGET_USE_FANCY_MATH_387
14229 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14230 || TARGET_MIX_SSE_I387)
14231 && flag_unsafe_math_optimizations"
14233 rtx op0 = gen_reg_rtx (XFmode);
14235 rtx op2 = gen_reg_rtx (XFmode);
14236 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14238 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14239 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14243 (define_insn "fyl2xp1xf3_i387"
14244 [(set (match_operand:XF 0 "register_operand" "=f")
14245 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14246 (match_operand:XF 2 "register_operand" "u")]
14248 (clobber (match_scratch:XF 3 "=2"))]
14249 "TARGET_USE_FANCY_MATH_387
14250 && flag_unsafe_math_optimizations"
14252 [(set_attr "type" "fpspc")
14253 (set_attr "mode" "XF")])
14255 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14256 [(set (match_operand:XF 0 "register_operand" "=f")
14257 (unspec:XF [(float_extend:XF
14258 (match_operand:MODEF 1 "register_operand" "0"))
14259 (match_operand:XF 2 "register_operand" "u")]
14261 (clobber (match_scratch:XF 3 "=2"))]
14262 "TARGET_USE_FANCY_MATH_387
14263 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14264 || TARGET_MIX_SSE_I387)
14265 && flag_unsafe_math_optimizations"
14267 [(set_attr "type" "fpspc")
14268 (set_attr "mode" "XF")])
14270 (define_expand "log1pxf2"
14271 [(use (match_operand:XF 0 "register_operand" ""))
14272 (use (match_operand:XF 1 "register_operand" ""))]
14273 "TARGET_USE_FANCY_MATH_387
14274 && flag_unsafe_math_optimizations"
14276 if (optimize_insn_for_size_p ())
14279 ix86_emit_i387_log1p (operands[0], operands[1]);
14283 (define_expand "log1p<mode>2"
14284 [(use (match_operand:MODEF 0 "register_operand" ""))
14285 (use (match_operand:MODEF 1 "register_operand" ""))]
14286 "TARGET_USE_FANCY_MATH_387
14287 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14288 || TARGET_MIX_SSE_I387)
14289 && flag_unsafe_math_optimizations"
14293 if (optimize_insn_for_size_p ())
14296 op0 = gen_reg_rtx (XFmode);
14298 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14300 ix86_emit_i387_log1p (op0, operands[1]);
14301 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14305 (define_insn "fxtractxf3_i387"
14306 [(set (match_operand:XF 0 "register_operand" "=f")
14307 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14308 UNSPEC_XTRACT_FRACT))
14309 (set (match_operand:XF 1 "register_operand" "=u")
14310 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14311 "TARGET_USE_FANCY_MATH_387
14312 && flag_unsafe_math_optimizations"
14314 [(set_attr "type" "fpspc")
14315 (set_attr "mode" "XF")])
14317 (define_insn "fxtract_extend<mode>xf3_i387"
14318 [(set (match_operand:XF 0 "register_operand" "=f")
14319 (unspec:XF [(float_extend:XF
14320 (match_operand:MODEF 2 "register_operand" "0"))]
14321 UNSPEC_XTRACT_FRACT))
14322 (set (match_operand:XF 1 "register_operand" "=u")
14323 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14324 "TARGET_USE_FANCY_MATH_387
14325 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14326 || TARGET_MIX_SSE_I387)
14327 && flag_unsafe_math_optimizations"
14329 [(set_attr "type" "fpspc")
14330 (set_attr "mode" "XF")])
14332 (define_expand "logbxf2"
14333 [(parallel [(set (match_dup 2)
14334 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14335 UNSPEC_XTRACT_FRACT))
14336 (set (match_operand:XF 0 "register_operand" "")
14337 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14338 "TARGET_USE_FANCY_MATH_387
14339 && flag_unsafe_math_optimizations"
14341 operands[2] = gen_reg_rtx (XFmode);
14344 (define_expand "logb<mode>2"
14345 [(use (match_operand:MODEF 0 "register_operand" ""))
14346 (use (match_operand:MODEF 1 "register_operand" ""))]
14347 "TARGET_USE_FANCY_MATH_387
14348 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14349 || TARGET_MIX_SSE_I387)
14350 && flag_unsafe_math_optimizations"
14352 rtx op0 = gen_reg_rtx (XFmode);
14353 rtx op1 = gen_reg_rtx (XFmode);
14355 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14356 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14360 (define_expand "ilogbxf2"
14361 [(use (match_operand:SI 0 "register_operand" ""))
14362 (use (match_operand:XF 1 "register_operand" ""))]
14363 "TARGET_USE_FANCY_MATH_387
14364 && flag_unsafe_math_optimizations"
14368 if (optimize_insn_for_size_p ())
14371 op0 = gen_reg_rtx (XFmode);
14372 op1 = gen_reg_rtx (XFmode);
14374 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14375 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14379 (define_expand "ilogb<mode>2"
14380 [(use (match_operand:SI 0 "register_operand" ""))
14381 (use (match_operand:MODEF 1 "register_operand" ""))]
14382 "TARGET_USE_FANCY_MATH_387
14383 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14384 || TARGET_MIX_SSE_I387)
14385 && flag_unsafe_math_optimizations"
14389 if (optimize_insn_for_size_p ())
14392 op0 = gen_reg_rtx (XFmode);
14393 op1 = gen_reg_rtx (XFmode);
14395 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14396 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14400 (define_insn "*f2xm1xf2_i387"
14401 [(set (match_operand:XF 0 "register_operand" "=f")
14402 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14404 "TARGET_USE_FANCY_MATH_387
14405 && flag_unsafe_math_optimizations"
14407 [(set_attr "type" "fpspc")
14408 (set_attr "mode" "XF")])
14410 (define_insn "*fscalexf4_i387"
14411 [(set (match_operand:XF 0 "register_operand" "=f")
14412 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14413 (match_operand:XF 3 "register_operand" "1")]
14414 UNSPEC_FSCALE_FRACT))
14415 (set (match_operand:XF 1 "register_operand" "=u")
14416 (unspec:XF [(match_dup 2) (match_dup 3)]
14417 UNSPEC_FSCALE_EXP))]
14418 "TARGET_USE_FANCY_MATH_387
14419 && flag_unsafe_math_optimizations"
14421 [(set_attr "type" "fpspc")
14422 (set_attr "mode" "XF")])
14424 (define_expand "expNcorexf3"
14425 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14426 (match_operand:XF 2 "register_operand" "")))
14427 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14428 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14429 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14430 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14431 (parallel [(set (match_operand:XF 0 "register_operand" "")
14432 (unspec:XF [(match_dup 8) (match_dup 4)]
14433 UNSPEC_FSCALE_FRACT))
14435 (unspec:XF [(match_dup 8) (match_dup 4)]
14436 UNSPEC_FSCALE_EXP))])]
14437 "TARGET_USE_FANCY_MATH_387
14438 && flag_unsafe_math_optimizations"
14442 if (optimize_insn_for_size_p ())
14445 for (i = 3; i < 10; i++)
14446 operands[i] = gen_reg_rtx (XFmode);
14448 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14451 (define_expand "expxf2"
14452 [(use (match_operand:XF 0 "register_operand" ""))
14453 (use (match_operand:XF 1 "register_operand" ""))]
14454 "TARGET_USE_FANCY_MATH_387
14455 && flag_unsafe_math_optimizations"
14459 if (optimize_insn_for_size_p ())
14462 op2 = gen_reg_rtx (XFmode);
14463 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14465 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14469 (define_expand "exp<mode>2"
14470 [(use (match_operand:MODEF 0 "register_operand" ""))
14471 (use (match_operand:MODEF 1 "general_operand" ""))]
14472 "TARGET_USE_FANCY_MATH_387
14473 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14474 || TARGET_MIX_SSE_I387)
14475 && flag_unsafe_math_optimizations"
14479 if (optimize_insn_for_size_p ())
14482 op0 = gen_reg_rtx (XFmode);
14483 op1 = gen_reg_rtx (XFmode);
14485 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14486 emit_insn (gen_expxf2 (op0, op1));
14487 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14491 (define_expand "exp10xf2"
14492 [(use (match_operand:XF 0 "register_operand" ""))
14493 (use (match_operand:XF 1 "register_operand" ""))]
14494 "TARGET_USE_FANCY_MATH_387
14495 && flag_unsafe_math_optimizations"
14499 if (optimize_insn_for_size_p ())
14502 op2 = gen_reg_rtx (XFmode);
14503 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14505 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14509 (define_expand "exp10<mode>2"
14510 [(use (match_operand:MODEF 0 "register_operand" ""))
14511 (use (match_operand:MODEF 1 "general_operand" ""))]
14512 "TARGET_USE_FANCY_MATH_387
14513 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14514 || TARGET_MIX_SSE_I387)
14515 && flag_unsafe_math_optimizations"
14519 if (optimize_insn_for_size_p ())
14522 op0 = gen_reg_rtx (XFmode);
14523 op1 = gen_reg_rtx (XFmode);
14525 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14526 emit_insn (gen_exp10xf2 (op0, op1));
14527 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14531 (define_expand "exp2xf2"
14532 [(use (match_operand:XF 0 "register_operand" ""))
14533 (use (match_operand:XF 1 "register_operand" ""))]
14534 "TARGET_USE_FANCY_MATH_387
14535 && flag_unsafe_math_optimizations"
14539 if (optimize_insn_for_size_p ())
14542 op2 = gen_reg_rtx (XFmode);
14543 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14545 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14549 (define_expand "exp2<mode>2"
14550 [(use (match_operand:MODEF 0 "register_operand" ""))
14551 (use (match_operand:MODEF 1 "general_operand" ""))]
14552 "TARGET_USE_FANCY_MATH_387
14553 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14554 || TARGET_MIX_SSE_I387)
14555 && flag_unsafe_math_optimizations"
14559 if (optimize_insn_for_size_p ())
14562 op0 = gen_reg_rtx (XFmode);
14563 op1 = gen_reg_rtx (XFmode);
14565 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14566 emit_insn (gen_exp2xf2 (op0, op1));
14567 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14571 (define_expand "expm1xf2"
14572 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14574 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14575 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14576 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14577 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14578 (parallel [(set (match_dup 7)
14579 (unspec:XF [(match_dup 6) (match_dup 4)]
14580 UNSPEC_FSCALE_FRACT))
14582 (unspec:XF [(match_dup 6) (match_dup 4)]
14583 UNSPEC_FSCALE_EXP))])
14584 (parallel [(set (match_dup 10)
14585 (unspec:XF [(match_dup 9) (match_dup 8)]
14586 UNSPEC_FSCALE_FRACT))
14587 (set (match_dup 11)
14588 (unspec:XF [(match_dup 9) (match_dup 8)]
14589 UNSPEC_FSCALE_EXP))])
14590 (set (match_dup 12) (minus:XF (match_dup 10)
14591 (float_extend:XF (match_dup 13))))
14592 (set (match_operand:XF 0 "register_operand" "")
14593 (plus:XF (match_dup 12) (match_dup 7)))]
14594 "TARGET_USE_FANCY_MATH_387
14595 && flag_unsafe_math_optimizations"
14599 if (optimize_insn_for_size_p ())
14602 for (i = 2; i < 13; i++)
14603 operands[i] = gen_reg_rtx (XFmode);
14606 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14608 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14611 (define_expand "expm1<mode>2"
14612 [(use (match_operand:MODEF 0 "register_operand" ""))
14613 (use (match_operand:MODEF 1 "general_operand" ""))]
14614 "TARGET_USE_FANCY_MATH_387
14615 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14616 || TARGET_MIX_SSE_I387)
14617 && flag_unsafe_math_optimizations"
14621 if (optimize_insn_for_size_p ())
14624 op0 = gen_reg_rtx (XFmode);
14625 op1 = gen_reg_rtx (XFmode);
14627 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14628 emit_insn (gen_expm1xf2 (op0, op1));
14629 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14633 (define_expand "ldexpxf3"
14634 [(set (match_dup 3)
14635 (float:XF (match_operand:SI 2 "register_operand" "")))
14636 (parallel [(set (match_operand:XF 0 " register_operand" "")
14637 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14639 UNSPEC_FSCALE_FRACT))
14641 (unspec:XF [(match_dup 1) (match_dup 3)]
14642 UNSPEC_FSCALE_EXP))])]
14643 "TARGET_USE_FANCY_MATH_387
14644 && flag_unsafe_math_optimizations"
14646 if (optimize_insn_for_size_p ())
14649 operands[3] = gen_reg_rtx (XFmode);
14650 operands[4] = gen_reg_rtx (XFmode);
14653 (define_expand "ldexp<mode>3"
14654 [(use (match_operand:MODEF 0 "register_operand" ""))
14655 (use (match_operand:MODEF 1 "general_operand" ""))
14656 (use (match_operand:SI 2 "register_operand" ""))]
14657 "TARGET_USE_FANCY_MATH_387
14658 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14659 || TARGET_MIX_SSE_I387)
14660 && flag_unsafe_math_optimizations"
14664 if (optimize_insn_for_size_p ())
14667 op0 = gen_reg_rtx (XFmode);
14668 op1 = gen_reg_rtx (XFmode);
14670 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14671 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14672 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14676 (define_expand "scalbxf3"
14677 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14678 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14679 (match_operand:XF 2 "register_operand" "")]
14680 UNSPEC_FSCALE_FRACT))
14682 (unspec:XF [(match_dup 1) (match_dup 2)]
14683 UNSPEC_FSCALE_EXP))])]
14684 "TARGET_USE_FANCY_MATH_387
14685 && flag_unsafe_math_optimizations"
14687 if (optimize_insn_for_size_p ())
14690 operands[3] = gen_reg_rtx (XFmode);
14693 (define_expand "scalb<mode>3"
14694 [(use (match_operand:MODEF 0 "register_operand" ""))
14695 (use (match_operand:MODEF 1 "general_operand" ""))
14696 (use (match_operand:MODEF 2 "general_operand" ""))]
14697 "TARGET_USE_FANCY_MATH_387
14698 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14699 || TARGET_MIX_SSE_I387)
14700 && flag_unsafe_math_optimizations"
14704 if (optimize_insn_for_size_p ())
14707 op0 = gen_reg_rtx (XFmode);
14708 op1 = gen_reg_rtx (XFmode);
14709 op2 = gen_reg_rtx (XFmode);
14711 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14712 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14713 emit_insn (gen_scalbxf3 (op0, op1, op2));
14714 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14718 (define_expand "significandxf2"
14719 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14720 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14721 UNSPEC_XTRACT_FRACT))
14723 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14724 "TARGET_USE_FANCY_MATH_387
14725 && flag_unsafe_math_optimizations"
14727 operands[2] = gen_reg_rtx (XFmode);
14730 (define_expand "significand<mode>2"
14731 [(use (match_operand:MODEF 0 "register_operand" ""))
14732 (use (match_operand:MODEF 1 "register_operand" ""))]
14733 "TARGET_USE_FANCY_MATH_387
14734 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14735 || TARGET_MIX_SSE_I387)
14736 && flag_unsafe_math_optimizations"
14738 rtx op0 = gen_reg_rtx (XFmode);
14739 rtx op1 = gen_reg_rtx (XFmode);
14741 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14742 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14747 (define_insn "sse4_1_round<mode>2"
14748 [(set (match_operand:MODEF 0 "register_operand" "=x")
14749 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14750 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14753 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14754 [(set_attr "type" "ssecvt")
14755 (set_attr "prefix_extra" "1")
14756 (set_attr "prefix" "maybe_vex")
14757 (set_attr "mode" "<MODE>")])
14759 (define_insn "rintxf2"
14760 [(set (match_operand:XF 0 "register_operand" "=f")
14761 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14763 "TARGET_USE_FANCY_MATH_387
14764 && flag_unsafe_math_optimizations"
14766 [(set_attr "type" "fpspc")
14767 (set_attr "mode" "XF")])
14769 (define_expand "rint<mode>2"
14770 [(use (match_operand:MODEF 0 "register_operand" ""))
14771 (use (match_operand:MODEF 1 "register_operand" ""))]
14772 "(TARGET_USE_FANCY_MATH_387
14773 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14774 || TARGET_MIX_SSE_I387)
14775 && flag_unsafe_math_optimizations)
14776 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14777 && !flag_trapping_math)"
14779 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14780 && !flag_trapping_math)
14782 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14785 emit_insn (gen_sse4_1_round<mode>2
14786 (operands[0], operands[1], GEN_INT (0x04)));
14788 ix86_expand_rint (operand0, operand1);
14792 rtx op0 = gen_reg_rtx (XFmode);
14793 rtx op1 = gen_reg_rtx (XFmode);
14795 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14796 emit_insn (gen_rintxf2 (op0, op1));
14798 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14803 (define_expand "round<mode>2"
14804 [(match_operand:MODEF 0 "register_operand" "")
14805 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14806 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14807 && !flag_trapping_math && !flag_rounding_math"
14809 if (optimize_insn_for_size_p ())
14811 if (TARGET_64BIT || (<MODE>mode != DFmode))
14812 ix86_expand_round (operand0, operand1);
14814 ix86_expand_rounddf_32 (operand0, operand1);
14818 (define_insn_and_split "*fistdi2_1"
14819 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14820 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14822 "TARGET_USE_FANCY_MATH_387
14823 && can_create_pseudo_p ()"
14828 if (memory_operand (operands[0], VOIDmode))
14829 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14832 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14833 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14838 [(set_attr "type" "fpspc")
14839 (set_attr "mode" "DI")])
14841 (define_insn "fistdi2"
14842 [(set (match_operand:DI 0 "memory_operand" "=m")
14843 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14845 (clobber (match_scratch:XF 2 "=&1f"))]
14846 "TARGET_USE_FANCY_MATH_387"
14847 "* return output_fix_trunc (insn, operands, 0);"
14848 [(set_attr "type" "fpspc")
14849 (set_attr "mode" "DI")])
14851 (define_insn "fistdi2_with_temp"
14852 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14853 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14855 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14856 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14857 "TARGET_USE_FANCY_MATH_387"
14859 [(set_attr "type" "fpspc")
14860 (set_attr "mode" "DI")])
14863 [(set (match_operand:DI 0 "register_operand" "")
14864 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14866 (clobber (match_operand:DI 2 "memory_operand" ""))
14867 (clobber (match_scratch 3 ""))]
14869 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14870 (clobber (match_dup 3))])
14871 (set (match_dup 0) (match_dup 2))]
14875 [(set (match_operand:DI 0 "memory_operand" "")
14876 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14878 (clobber (match_operand:DI 2 "memory_operand" ""))
14879 (clobber (match_scratch 3 ""))]
14881 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14882 (clobber (match_dup 3))])]
14885 (define_insn_and_split "*fist<mode>2_1"
14886 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14887 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14889 "TARGET_USE_FANCY_MATH_387
14890 && can_create_pseudo_p ()"
14895 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14896 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14900 [(set_attr "type" "fpspc")
14901 (set_attr "mode" "<MODE>")])
14903 (define_insn "fist<mode>2"
14904 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14905 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14907 "TARGET_USE_FANCY_MATH_387"
14908 "* return output_fix_trunc (insn, operands, 0);"
14909 [(set_attr "type" "fpspc")
14910 (set_attr "mode" "<MODE>")])
14912 (define_insn "fist<mode>2_with_temp"
14913 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14914 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14916 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14917 "TARGET_USE_FANCY_MATH_387"
14919 [(set_attr "type" "fpspc")
14920 (set_attr "mode" "<MODE>")])
14923 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14924 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14926 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14928 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14929 (set (match_dup 0) (match_dup 2))]
14933 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14934 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14936 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14938 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14941 (define_expand "lrintxf<mode>2"
14942 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14943 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14945 "TARGET_USE_FANCY_MATH_387"
14948 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14949 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14950 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14951 UNSPEC_FIX_NOTRUNC))]
14952 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14953 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14956 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14957 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14958 (match_operand:MODEF 1 "register_operand" "")]
14959 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14960 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14961 && !flag_trapping_math && !flag_rounding_math"
14963 if (optimize_insn_for_size_p ())
14965 ix86_expand_lround (operand0, operand1);
14969 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14970 (define_insn_and_split "frndintxf2_floor"
14971 [(set (match_operand:XF 0 "register_operand" "")
14972 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14973 UNSPEC_FRNDINT_FLOOR))
14974 (clobber (reg:CC FLAGS_REG))]
14975 "TARGET_USE_FANCY_MATH_387
14976 && flag_unsafe_math_optimizations
14977 && can_create_pseudo_p ()"
14982 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14984 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14985 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14987 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14988 operands[2], operands[3]));
14991 [(set_attr "type" "frndint")
14992 (set_attr "i387_cw" "floor")
14993 (set_attr "mode" "XF")])
14995 (define_insn "frndintxf2_floor_i387"
14996 [(set (match_operand:XF 0 "register_operand" "=f")
14997 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14998 UNSPEC_FRNDINT_FLOOR))
14999 (use (match_operand:HI 2 "memory_operand" "m"))
15000 (use (match_operand:HI 3 "memory_operand" "m"))]
15001 "TARGET_USE_FANCY_MATH_387
15002 && flag_unsafe_math_optimizations"
15003 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15004 [(set_attr "type" "frndint")
15005 (set_attr "i387_cw" "floor")
15006 (set_attr "mode" "XF")])
15008 (define_expand "floorxf2"
15009 [(use (match_operand:XF 0 "register_operand" ""))
15010 (use (match_operand:XF 1 "register_operand" ""))]
15011 "TARGET_USE_FANCY_MATH_387
15012 && flag_unsafe_math_optimizations"
15014 if (optimize_insn_for_size_p ())
15016 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
15020 (define_expand "floor<mode>2"
15021 [(use (match_operand:MODEF 0 "register_operand" ""))
15022 (use (match_operand:MODEF 1 "register_operand" ""))]
15023 "(TARGET_USE_FANCY_MATH_387
15024 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15025 || TARGET_MIX_SSE_I387)
15026 && flag_unsafe_math_optimizations)
15027 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15028 && !flag_trapping_math)"
15030 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15031 && !flag_trapping_math
15032 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15034 if (!TARGET_ROUND && optimize_insn_for_size_p ())
15037 emit_insn (gen_sse4_1_round<mode>2
15038 (operands[0], operands[1], GEN_INT (0x01)));
15039 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15040 ix86_expand_floorceil (operand0, operand1, true);
15042 ix86_expand_floorceildf_32 (operand0, operand1, true);
15048 if (optimize_insn_for_size_p ())
15051 op0 = gen_reg_rtx (XFmode);
15052 op1 = gen_reg_rtx (XFmode);
15053 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15054 emit_insn (gen_frndintxf2_floor (op0, op1));
15056 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15061 (define_insn_and_split "*fist<mode>2_floor_1"
15062 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15063 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15064 UNSPEC_FIST_FLOOR))
15065 (clobber (reg:CC FLAGS_REG))]
15066 "TARGET_USE_FANCY_MATH_387
15067 && flag_unsafe_math_optimizations
15068 && can_create_pseudo_p ()"
15073 ix86_optimize_mode_switching[I387_FLOOR] = 1;
15075 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15076 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
15077 if (memory_operand (operands[0], VOIDmode))
15078 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
15079 operands[2], operands[3]));
15082 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15083 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
15084 operands[2], operands[3],
15089 [(set_attr "type" "fistp")
15090 (set_attr "i387_cw" "floor")
15091 (set_attr "mode" "<MODE>")])
15093 (define_insn "fistdi2_floor"
15094 [(set (match_operand:DI 0 "memory_operand" "=m")
15095 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15096 UNSPEC_FIST_FLOOR))
15097 (use (match_operand:HI 2 "memory_operand" "m"))
15098 (use (match_operand:HI 3 "memory_operand" "m"))
15099 (clobber (match_scratch:XF 4 "=&1f"))]
15100 "TARGET_USE_FANCY_MATH_387
15101 && flag_unsafe_math_optimizations"
15102 "* return output_fix_trunc (insn, operands, 0);"
15103 [(set_attr "type" "fistp")
15104 (set_attr "i387_cw" "floor")
15105 (set_attr "mode" "DI")])
15107 (define_insn "fistdi2_floor_with_temp"
15108 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15109 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15110 UNSPEC_FIST_FLOOR))
15111 (use (match_operand:HI 2 "memory_operand" "m,m"))
15112 (use (match_operand:HI 3 "memory_operand" "m,m"))
15113 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15114 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15115 "TARGET_USE_FANCY_MATH_387
15116 && flag_unsafe_math_optimizations"
15118 [(set_attr "type" "fistp")
15119 (set_attr "i387_cw" "floor")
15120 (set_attr "mode" "DI")])
15123 [(set (match_operand:DI 0 "register_operand" "")
15124 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15125 UNSPEC_FIST_FLOOR))
15126 (use (match_operand:HI 2 "memory_operand" ""))
15127 (use (match_operand:HI 3 "memory_operand" ""))
15128 (clobber (match_operand:DI 4 "memory_operand" ""))
15129 (clobber (match_scratch 5 ""))]
15131 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15132 (use (match_dup 2))
15133 (use (match_dup 3))
15134 (clobber (match_dup 5))])
15135 (set (match_dup 0) (match_dup 4))]
15139 [(set (match_operand:DI 0 "memory_operand" "")
15140 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15141 UNSPEC_FIST_FLOOR))
15142 (use (match_operand:HI 2 "memory_operand" ""))
15143 (use (match_operand:HI 3 "memory_operand" ""))
15144 (clobber (match_operand:DI 4 "memory_operand" ""))
15145 (clobber (match_scratch 5 ""))]
15147 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15148 (use (match_dup 2))
15149 (use (match_dup 3))
15150 (clobber (match_dup 5))])]
15153 (define_insn "fist<mode>2_floor"
15154 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15155 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15156 UNSPEC_FIST_FLOOR))
15157 (use (match_operand:HI 2 "memory_operand" "m"))
15158 (use (match_operand:HI 3 "memory_operand" "m"))]
15159 "TARGET_USE_FANCY_MATH_387
15160 && flag_unsafe_math_optimizations"
15161 "* return output_fix_trunc (insn, operands, 0);"
15162 [(set_attr "type" "fistp")
15163 (set_attr "i387_cw" "floor")
15164 (set_attr "mode" "<MODE>")])
15166 (define_insn "fist<mode>2_floor_with_temp"
15167 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15168 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15169 UNSPEC_FIST_FLOOR))
15170 (use (match_operand:HI 2 "memory_operand" "m,m"))
15171 (use (match_operand:HI 3 "memory_operand" "m,m"))
15172 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15173 "TARGET_USE_FANCY_MATH_387
15174 && flag_unsafe_math_optimizations"
15176 [(set_attr "type" "fistp")
15177 (set_attr "i387_cw" "floor")
15178 (set_attr "mode" "<MODE>")])
15181 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15182 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15183 UNSPEC_FIST_FLOOR))
15184 (use (match_operand:HI 2 "memory_operand" ""))
15185 (use (match_operand:HI 3 "memory_operand" ""))
15186 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15188 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15189 UNSPEC_FIST_FLOOR))
15190 (use (match_dup 2))
15191 (use (match_dup 3))])
15192 (set (match_dup 0) (match_dup 4))]
15196 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15197 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15198 UNSPEC_FIST_FLOOR))
15199 (use (match_operand:HI 2 "memory_operand" ""))
15200 (use (match_operand:HI 3 "memory_operand" ""))
15201 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15203 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15204 UNSPEC_FIST_FLOOR))
15205 (use (match_dup 2))
15206 (use (match_dup 3))])]
15209 (define_expand "lfloorxf<mode>2"
15210 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15211 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15212 UNSPEC_FIST_FLOOR))
15213 (clobber (reg:CC FLAGS_REG))])]
15214 "TARGET_USE_FANCY_MATH_387
15215 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15216 && flag_unsafe_math_optimizations"
15219 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15220 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15221 (match_operand:MODEF 1 "register_operand" "")]
15222 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15223 && !flag_trapping_math"
15225 if (TARGET_64BIT && optimize_insn_for_size_p ())
15227 ix86_expand_lfloorceil (operand0, operand1, true);
15231 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15232 (define_insn_and_split "frndintxf2_ceil"
15233 [(set (match_operand:XF 0 "register_operand" "")
15234 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15235 UNSPEC_FRNDINT_CEIL))
15236 (clobber (reg:CC FLAGS_REG))]
15237 "TARGET_USE_FANCY_MATH_387
15238 && flag_unsafe_math_optimizations
15239 && can_create_pseudo_p ()"
15244 ix86_optimize_mode_switching[I387_CEIL] = 1;
15246 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15247 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15249 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15250 operands[2], operands[3]));
15253 [(set_attr "type" "frndint")
15254 (set_attr "i387_cw" "ceil")
15255 (set_attr "mode" "XF")])
15257 (define_insn "frndintxf2_ceil_i387"
15258 [(set (match_operand:XF 0 "register_operand" "=f")
15259 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15260 UNSPEC_FRNDINT_CEIL))
15261 (use (match_operand:HI 2 "memory_operand" "m"))
15262 (use (match_operand:HI 3 "memory_operand" "m"))]
15263 "TARGET_USE_FANCY_MATH_387
15264 && flag_unsafe_math_optimizations"
15265 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15266 [(set_attr "type" "frndint")
15267 (set_attr "i387_cw" "ceil")
15268 (set_attr "mode" "XF")])
15270 (define_expand "ceilxf2"
15271 [(use (match_operand:XF 0 "register_operand" ""))
15272 (use (match_operand:XF 1 "register_operand" ""))]
15273 "TARGET_USE_FANCY_MATH_387
15274 && flag_unsafe_math_optimizations"
15276 if (optimize_insn_for_size_p ())
15278 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15282 (define_expand "ceil<mode>2"
15283 [(use (match_operand:MODEF 0 "register_operand" ""))
15284 (use (match_operand:MODEF 1 "register_operand" ""))]
15285 "(TARGET_USE_FANCY_MATH_387
15286 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15287 || TARGET_MIX_SSE_I387)
15288 && flag_unsafe_math_optimizations)
15289 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15290 && !flag_trapping_math)"
15292 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15293 && !flag_trapping_math
15294 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15297 emit_insn (gen_sse4_1_round<mode>2
15298 (operands[0], operands[1], GEN_INT (0x02)));
15299 else if (optimize_insn_for_size_p ())
15301 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15302 ix86_expand_floorceil (operand0, operand1, false);
15304 ix86_expand_floorceildf_32 (operand0, operand1, false);
15310 if (optimize_insn_for_size_p ())
15313 op0 = gen_reg_rtx (XFmode);
15314 op1 = gen_reg_rtx (XFmode);
15315 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15316 emit_insn (gen_frndintxf2_ceil (op0, op1));
15318 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15323 (define_insn_and_split "*fist<mode>2_ceil_1"
15324 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15325 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15327 (clobber (reg:CC FLAGS_REG))]
15328 "TARGET_USE_FANCY_MATH_387
15329 && flag_unsafe_math_optimizations
15330 && can_create_pseudo_p ()"
15335 ix86_optimize_mode_switching[I387_CEIL] = 1;
15337 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15338 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15339 if (memory_operand (operands[0], VOIDmode))
15340 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15341 operands[2], operands[3]));
15344 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15345 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15346 operands[2], operands[3],
15351 [(set_attr "type" "fistp")
15352 (set_attr "i387_cw" "ceil")
15353 (set_attr "mode" "<MODE>")])
15355 (define_insn "fistdi2_ceil"
15356 [(set (match_operand:DI 0 "memory_operand" "=m")
15357 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15359 (use (match_operand:HI 2 "memory_operand" "m"))
15360 (use (match_operand:HI 3 "memory_operand" "m"))
15361 (clobber (match_scratch:XF 4 "=&1f"))]
15362 "TARGET_USE_FANCY_MATH_387
15363 && flag_unsafe_math_optimizations"
15364 "* return output_fix_trunc (insn, operands, 0);"
15365 [(set_attr "type" "fistp")
15366 (set_attr "i387_cw" "ceil")
15367 (set_attr "mode" "DI")])
15369 (define_insn "fistdi2_ceil_with_temp"
15370 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15371 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15373 (use (match_operand:HI 2 "memory_operand" "m,m"))
15374 (use (match_operand:HI 3 "memory_operand" "m,m"))
15375 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15376 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15377 "TARGET_USE_FANCY_MATH_387
15378 && flag_unsafe_math_optimizations"
15380 [(set_attr "type" "fistp")
15381 (set_attr "i387_cw" "ceil")
15382 (set_attr "mode" "DI")])
15385 [(set (match_operand:DI 0 "register_operand" "")
15386 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15388 (use (match_operand:HI 2 "memory_operand" ""))
15389 (use (match_operand:HI 3 "memory_operand" ""))
15390 (clobber (match_operand:DI 4 "memory_operand" ""))
15391 (clobber (match_scratch 5 ""))]
15393 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15394 (use (match_dup 2))
15395 (use (match_dup 3))
15396 (clobber (match_dup 5))])
15397 (set (match_dup 0) (match_dup 4))]
15401 [(set (match_operand:DI 0 "memory_operand" "")
15402 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15404 (use (match_operand:HI 2 "memory_operand" ""))
15405 (use (match_operand:HI 3 "memory_operand" ""))
15406 (clobber (match_operand:DI 4 "memory_operand" ""))
15407 (clobber (match_scratch 5 ""))]
15409 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15410 (use (match_dup 2))
15411 (use (match_dup 3))
15412 (clobber (match_dup 5))])]
15415 (define_insn "fist<mode>2_ceil"
15416 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15417 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15419 (use (match_operand:HI 2 "memory_operand" "m"))
15420 (use (match_operand:HI 3 "memory_operand" "m"))]
15421 "TARGET_USE_FANCY_MATH_387
15422 && flag_unsafe_math_optimizations"
15423 "* return output_fix_trunc (insn, operands, 0);"
15424 [(set_attr "type" "fistp")
15425 (set_attr "i387_cw" "ceil")
15426 (set_attr "mode" "<MODE>")])
15428 (define_insn "fist<mode>2_ceil_with_temp"
15429 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15430 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15432 (use (match_operand:HI 2 "memory_operand" "m,m"))
15433 (use (match_operand:HI 3 "memory_operand" "m,m"))
15434 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15435 "TARGET_USE_FANCY_MATH_387
15436 && flag_unsafe_math_optimizations"
15438 [(set_attr "type" "fistp")
15439 (set_attr "i387_cw" "ceil")
15440 (set_attr "mode" "<MODE>")])
15443 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15444 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15446 (use (match_operand:HI 2 "memory_operand" ""))
15447 (use (match_operand:HI 3 "memory_operand" ""))
15448 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15450 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15452 (use (match_dup 2))
15453 (use (match_dup 3))])
15454 (set (match_dup 0) (match_dup 4))]
15458 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15459 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15461 (use (match_operand:HI 2 "memory_operand" ""))
15462 (use (match_operand:HI 3 "memory_operand" ""))
15463 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15465 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15467 (use (match_dup 2))
15468 (use (match_dup 3))])]
15471 (define_expand "lceilxf<mode>2"
15472 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15473 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15475 (clobber (reg:CC FLAGS_REG))])]
15476 "TARGET_USE_FANCY_MATH_387
15477 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15478 && flag_unsafe_math_optimizations"
15481 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15482 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15483 (match_operand:MODEF 1 "register_operand" "")]
15484 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15485 && !flag_trapping_math"
15487 ix86_expand_lfloorceil (operand0, operand1, false);
15491 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15492 (define_insn_and_split "frndintxf2_trunc"
15493 [(set (match_operand:XF 0 "register_operand" "")
15494 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15495 UNSPEC_FRNDINT_TRUNC))
15496 (clobber (reg:CC FLAGS_REG))]
15497 "TARGET_USE_FANCY_MATH_387
15498 && flag_unsafe_math_optimizations
15499 && can_create_pseudo_p ()"
15504 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15506 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15507 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15509 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15510 operands[2], operands[3]));
15513 [(set_attr "type" "frndint")
15514 (set_attr "i387_cw" "trunc")
15515 (set_attr "mode" "XF")])
15517 (define_insn "frndintxf2_trunc_i387"
15518 [(set (match_operand:XF 0 "register_operand" "=f")
15519 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15520 UNSPEC_FRNDINT_TRUNC))
15521 (use (match_operand:HI 2 "memory_operand" "m"))
15522 (use (match_operand:HI 3 "memory_operand" "m"))]
15523 "TARGET_USE_FANCY_MATH_387
15524 && flag_unsafe_math_optimizations"
15525 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15526 [(set_attr "type" "frndint")
15527 (set_attr "i387_cw" "trunc")
15528 (set_attr "mode" "XF")])
15530 (define_expand "btruncxf2"
15531 [(use (match_operand:XF 0 "register_operand" ""))
15532 (use (match_operand:XF 1 "register_operand" ""))]
15533 "TARGET_USE_FANCY_MATH_387
15534 && flag_unsafe_math_optimizations"
15536 if (optimize_insn_for_size_p ())
15538 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15542 (define_expand "btrunc<mode>2"
15543 [(use (match_operand:MODEF 0 "register_operand" ""))
15544 (use (match_operand:MODEF 1 "register_operand" ""))]
15545 "(TARGET_USE_FANCY_MATH_387
15546 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15547 || TARGET_MIX_SSE_I387)
15548 && flag_unsafe_math_optimizations)
15549 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15550 && !flag_trapping_math)"
15552 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15553 && !flag_trapping_math
15554 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15557 emit_insn (gen_sse4_1_round<mode>2
15558 (operands[0], operands[1], GEN_INT (0x03)));
15559 else if (optimize_insn_for_size_p ())
15561 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15562 ix86_expand_trunc (operand0, operand1);
15564 ix86_expand_truncdf_32 (operand0, operand1);
15570 if (optimize_insn_for_size_p ())
15573 op0 = gen_reg_rtx (XFmode);
15574 op1 = gen_reg_rtx (XFmode);
15575 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15576 emit_insn (gen_frndintxf2_trunc (op0, op1));
15578 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15583 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15584 (define_insn_and_split "frndintxf2_mask_pm"
15585 [(set (match_operand:XF 0 "register_operand" "")
15586 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15587 UNSPEC_FRNDINT_MASK_PM))
15588 (clobber (reg:CC FLAGS_REG))]
15589 "TARGET_USE_FANCY_MATH_387
15590 && flag_unsafe_math_optimizations
15591 && can_create_pseudo_p ()"
15596 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15598 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15599 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15601 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15602 operands[2], operands[3]));
15605 [(set_attr "type" "frndint")
15606 (set_attr "i387_cw" "mask_pm")
15607 (set_attr "mode" "XF")])
15609 (define_insn "frndintxf2_mask_pm_i387"
15610 [(set (match_operand:XF 0 "register_operand" "=f")
15611 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15612 UNSPEC_FRNDINT_MASK_PM))
15613 (use (match_operand:HI 2 "memory_operand" "m"))
15614 (use (match_operand:HI 3 "memory_operand" "m"))]
15615 "TARGET_USE_FANCY_MATH_387
15616 && flag_unsafe_math_optimizations"
15617 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15618 [(set_attr "type" "frndint")
15619 (set_attr "i387_cw" "mask_pm")
15620 (set_attr "mode" "XF")])
15622 (define_expand "nearbyintxf2"
15623 [(use (match_operand:XF 0 "register_operand" ""))
15624 (use (match_operand:XF 1 "register_operand" ""))]
15625 "TARGET_USE_FANCY_MATH_387
15626 && flag_unsafe_math_optimizations"
15628 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15633 (define_expand "nearbyint<mode>2"
15634 [(use (match_operand:MODEF 0 "register_operand" ""))
15635 (use (match_operand:MODEF 1 "register_operand" ""))]
15636 "TARGET_USE_FANCY_MATH_387
15637 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15638 || TARGET_MIX_SSE_I387)
15639 && flag_unsafe_math_optimizations"
15641 rtx op0 = gen_reg_rtx (XFmode);
15642 rtx op1 = gen_reg_rtx (XFmode);
15644 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15645 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15647 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15651 (define_insn "fxam<mode>2_i387"
15652 [(set (match_operand:HI 0 "register_operand" "=a")
15654 [(match_operand:X87MODEF 1 "register_operand" "f")]
15656 "TARGET_USE_FANCY_MATH_387"
15657 "fxam\n\tfnstsw\t%0"
15658 [(set_attr "type" "multi")
15659 (set_attr "length" "4")
15660 (set_attr "unit" "i387")
15661 (set_attr "mode" "<MODE>")])
15663 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15664 [(set (match_operand:HI 0 "register_operand" "")
15666 [(match_operand:MODEF 1 "memory_operand" "")]
15668 "TARGET_USE_FANCY_MATH_387
15669 && can_create_pseudo_p ()"
15672 [(set (match_dup 2)(match_dup 1))
15674 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15676 operands[2] = gen_reg_rtx (<MODE>mode);
15678 MEM_VOLATILE_P (operands[1]) = 1;
15680 [(set_attr "type" "multi")
15681 (set_attr "unit" "i387")
15682 (set_attr "mode" "<MODE>")])
15684 (define_expand "isinfxf2"
15685 [(use (match_operand:SI 0 "register_operand" ""))
15686 (use (match_operand:XF 1 "register_operand" ""))]
15687 "TARGET_USE_FANCY_MATH_387
15688 && TARGET_C99_FUNCTIONS"
15690 rtx mask = GEN_INT (0x45);
15691 rtx val = GEN_INT (0x05);
15695 rtx scratch = gen_reg_rtx (HImode);
15696 rtx res = gen_reg_rtx (QImode);
15698 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15700 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15701 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15702 cond = gen_rtx_fmt_ee (EQ, QImode,
15703 gen_rtx_REG (CCmode, FLAGS_REG),
15705 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15706 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15710 (define_expand "isinf<mode>2"
15711 [(use (match_operand:SI 0 "register_operand" ""))
15712 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15713 "TARGET_USE_FANCY_MATH_387
15714 && TARGET_C99_FUNCTIONS
15715 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15717 rtx mask = GEN_INT (0x45);
15718 rtx val = GEN_INT (0x05);
15722 rtx scratch = gen_reg_rtx (HImode);
15723 rtx res = gen_reg_rtx (QImode);
15725 /* Remove excess precision by forcing value through memory. */
15726 if (memory_operand (operands[1], VOIDmode))
15727 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15730 enum ix86_stack_slot slot = (virtuals_instantiated
15733 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15735 emit_move_insn (temp, operands[1]);
15736 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15739 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15740 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15741 cond = gen_rtx_fmt_ee (EQ, QImode,
15742 gen_rtx_REG (CCmode, FLAGS_REG),
15744 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15745 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15749 (define_expand "signbit<mode>2"
15750 [(use (match_operand:SI 0 "register_operand" ""))
15751 (use (match_operand:X87MODEF 1 "register_operand" ""))]
15752 "TARGET_USE_FANCY_MATH_387
15753 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15755 rtx mask = GEN_INT (0x0200);
15757 rtx scratch = gen_reg_rtx (HImode);
15759 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15760 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15764 ;; Block operation instructions
15767 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15770 [(set_attr "length" "1")
15771 (set_attr "length_immediate" "0")
15772 (set_attr "modrm" "0")])
15774 (define_expand "movmemsi"
15775 [(use (match_operand:BLK 0 "memory_operand" ""))
15776 (use (match_operand:BLK 1 "memory_operand" ""))
15777 (use (match_operand:SI 2 "nonmemory_operand" ""))
15778 (use (match_operand:SI 3 "const_int_operand" ""))
15779 (use (match_operand:SI 4 "const_int_operand" ""))
15780 (use (match_operand:SI 5 "const_int_operand" ""))]
15783 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15784 operands[4], operands[5]))
15790 (define_expand "movmemdi"
15791 [(use (match_operand:BLK 0 "memory_operand" ""))
15792 (use (match_operand:BLK 1 "memory_operand" ""))
15793 (use (match_operand:DI 2 "nonmemory_operand" ""))
15794 (use (match_operand:DI 3 "const_int_operand" ""))
15795 (use (match_operand:SI 4 "const_int_operand" ""))
15796 (use (match_operand:SI 5 "const_int_operand" ""))]
15799 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15800 operands[4], operands[5]))
15806 ;; Most CPUs don't like single string operations
15807 ;; Handle this case here to simplify previous expander.
15809 (define_expand "strmov"
15810 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15811 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15812 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15813 (clobber (reg:CC FLAGS_REG))])
15814 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15815 (clobber (reg:CC FLAGS_REG))])]
15818 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15820 /* If .md ever supports :P for Pmode, these can be directly
15821 in the pattern above. */
15822 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15823 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15825 /* Can't use this if the user has appropriated esi or edi. */
15826 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15827 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15829 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15830 operands[2], operands[3],
15831 operands[5], operands[6]));
15835 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15838 (define_expand "strmov_singleop"
15839 [(parallel [(set (match_operand 1 "memory_operand" "")
15840 (match_operand 3 "memory_operand" ""))
15841 (set (match_operand 0 "register_operand" "")
15842 (match_operand 4 "" ""))
15843 (set (match_operand 2 "register_operand" "")
15844 (match_operand 5 "" ""))])]
15846 "ix86_current_function_needs_cld = 1;")
15848 (define_insn "*strmovdi_rex_1"
15849 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15850 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15851 (set (match_operand:DI 0 "register_operand" "=D")
15852 (plus:DI (match_dup 2)
15854 (set (match_operand:DI 1 "register_operand" "=S")
15855 (plus:DI (match_dup 3)
15859 [(set_attr "type" "str")
15860 (set_attr "mode" "DI")
15861 (set_attr "memory" "both")])
15863 (define_insn "*strmovsi_1"
15864 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15865 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15866 (set (match_operand:SI 0 "register_operand" "=D")
15867 (plus:SI (match_dup 2)
15869 (set (match_operand:SI 1 "register_operand" "=S")
15870 (plus:SI (match_dup 3)
15874 [(set_attr "type" "str")
15875 (set_attr "mode" "SI")
15876 (set_attr "memory" "both")])
15878 (define_insn "*strmovsi_rex_1"
15879 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15880 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15881 (set (match_operand:DI 0 "register_operand" "=D")
15882 (plus:DI (match_dup 2)
15884 (set (match_operand:DI 1 "register_operand" "=S")
15885 (plus:DI (match_dup 3)
15889 [(set_attr "type" "str")
15890 (set_attr "mode" "SI")
15891 (set_attr "memory" "both")])
15893 (define_insn "*strmovhi_1"
15894 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15895 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15896 (set (match_operand:SI 0 "register_operand" "=D")
15897 (plus:SI (match_dup 2)
15899 (set (match_operand:SI 1 "register_operand" "=S")
15900 (plus:SI (match_dup 3)
15904 [(set_attr "type" "str")
15905 (set_attr "memory" "both")
15906 (set_attr "mode" "HI")])
15908 (define_insn "*strmovhi_rex_1"
15909 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15910 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15911 (set (match_operand:DI 0 "register_operand" "=D")
15912 (plus:DI (match_dup 2)
15914 (set (match_operand:DI 1 "register_operand" "=S")
15915 (plus:DI (match_dup 3)
15919 [(set_attr "type" "str")
15920 (set_attr "memory" "both")
15921 (set_attr "mode" "HI")])
15923 (define_insn "*strmovqi_1"
15924 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15925 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15926 (set (match_operand:SI 0 "register_operand" "=D")
15927 (plus:SI (match_dup 2)
15929 (set (match_operand:SI 1 "register_operand" "=S")
15930 (plus:SI (match_dup 3)
15934 [(set_attr "type" "str")
15935 (set_attr "memory" "both")
15936 (set_attr "mode" "QI")])
15938 (define_insn "*strmovqi_rex_1"
15939 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15940 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15941 (set (match_operand:DI 0 "register_operand" "=D")
15942 (plus:DI (match_dup 2)
15944 (set (match_operand:DI 1 "register_operand" "=S")
15945 (plus:DI (match_dup 3)
15949 [(set_attr "type" "str")
15950 (set_attr "memory" "both")
15951 (set_attr "prefix_rex" "0")
15952 (set_attr "mode" "QI")])
15954 (define_expand "rep_mov"
15955 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15956 (set (match_operand 0 "register_operand" "")
15957 (match_operand 5 "" ""))
15958 (set (match_operand 2 "register_operand" "")
15959 (match_operand 6 "" ""))
15960 (set (match_operand 1 "memory_operand" "")
15961 (match_operand 3 "memory_operand" ""))
15962 (use (match_dup 4))])]
15964 "ix86_current_function_needs_cld = 1;")
15966 (define_insn "*rep_movdi_rex64"
15967 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15968 (set (match_operand:DI 0 "register_operand" "=D")
15969 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15971 (match_operand:DI 3 "register_operand" "0")))
15972 (set (match_operand:DI 1 "register_operand" "=S")
15973 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15974 (match_operand:DI 4 "register_operand" "1")))
15975 (set (mem:BLK (match_dup 3))
15976 (mem:BLK (match_dup 4)))
15977 (use (match_dup 5))]
15980 [(set_attr "type" "str")
15981 (set_attr "prefix_rep" "1")
15982 (set_attr "memory" "both")
15983 (set_attr "mode" "DI")])
15985 (define_insn "*rep_movsi"
15986 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15987 (set (match_operand:SI 0 "register_operand" "=D")
15988 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15990 (match_operand:SI 3 "register_operand" "0")))
15991 (set (match_operand:SI 1 "register_operand" "=S")
15992 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15993 (match_operand:SI 4 "register_operand" "1")))
15994 (set (mem:BLK (match_dup 3))
15995 (mem:BLK (match_dup 4)))
15996 (use (match_dup 5))]
15999 [(set_attr "type" "str")
16000 (set_attr "prefix_rep" "1")
16001 (set_attr "memory" "both")
16002 (set_attr "mode" "SI")])
16004 (define_insn "*rep_movsi_rex64"
16005 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16006 (set (match_operand:DI 0 "register_operand" "=D")
16007 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16009 (match_operand:DI 3 "register_operand" "0")))
16010 (set (match_operand:DI 1 "register_operand" "=S")
16011 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16012 (match_operand:DI 4 "register_operand" "1")))
16013 (set (mem:BLK (match_dup 3))
16014 (mem:BLK (match_dup 4)))
16015 (use (match_dup 5))]
16018 [(set_attr "type" "str")
16019 (set_attr "prefix_rep" "1")
16020 (set_attr "memory" "both")
16021 (set_attr "mode" "SI")])
16023 (define_insn "*rep_movqi"
16024 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16025 (set (match_operand:SI 0 "register_operand" "=D")
16026 (plus:SI (match_operand:SI 3 "register_operand" "0")
16027 (match_operand:SI 5 "register_operand" "2")))
16028 (set (match_operand:SI 1 "register_operand" "=S")
16029 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16030 (set (mem:BLK (match_dup 3))
16031 (mem:BLK (match_dup 4)))
16032 (use (match_dup 5))]
16035 [(set_attr "type" "str")
16036 (set_attr "prefix_rep" "1")
16037 (set_attr "memory" "both")
16038 (set_attr "mode" "SI")])
16040 (define_insn "*rep_movqi_rex64"
16041 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16042 (set (match_operand:DI 0 "register_operand" "=D")
16043 (plus:DI (match_operand:DI 3 "register_operand" "0")
16044 (match_operand:DI 5 "register_operand" "2")))
16045 (set (match_operand:DI 1 "register_operand" "=S")
16046 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16047 (set (mem:BLK (match_dup 3))
16048 (mem:BLK (match_dup 4)))
16049 (use (match_dup 5))]
16052 [(set_attr "type" "str")
16053 (set_attr "prefix_rep" "1")
16054 (set_attr "memory" "both")
16055 (set_attr "mode" "SI")])
16057 (define_expand "setmemsi"
16058 [(use (match_operand:BLK 0 "memory_operand" ""))
16059 (use (match_operand:SI 1 "nonmemory_operand" ""))
16060 (use (match_operand 2 "const_int_operand" ""))
16061 (use (match_operand 3 "const_int_operand" ""))
16062 (use (match_operand:SI 4 "const_int_operand" ""))
16063 (use (match_operand:SI 5 "const_int_operand" ""))]
16066 if (ix86_expand_setmem (operands[0], operands[1],
16067 operands[2], operands[3],
16068 operands[4], operands[5]))
16074 (define_expand "setmemdi"
16075 [(use (match_operand:BLK 0 "memory_operand" ""))
16076 (use (match_operand:DI 1 "nonmemory_operand" ""))
16077 (use (match_operand 2 "const_int_operand" ""))
16078 (use (match_operand 3 "const_int_operand" ""))
16079 (use (match_operand 4 "const_int_operand" ""))
16080 (use (match_operand 5 "const_int_operand" ""))]
16083 if (ix86_expand_setmem (operands[0], operands[1],
16084 operands[2], operands[3],
16085 operands[4], operands[5]))
16091 ;; Most CPUs don't like single string operations
16092 ;; Handle this case here to simplify previous expander.
16094 (define_expand "strset"
16095 [(set (match_operand 1 "memory_operand" "")
16096 (match_operand 2 "register_operand" ""))
16097 (parallel [(set (match_operand 0 "register_operand" "")
16099 (clobber (reg:CC FLAGS_REG))])]
16102 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16103 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16105 /* If .md ever supports :P for Pmode, this can be directly
16106 in the pattern above. */
16107 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16108 GEN_INT (GET_MODE_SIZE (GET_MODE
16110 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16112 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16118 (define_expand "strset_singleop"
16119 [(parallel [(set (match_operand 1 "memory_operand" "")
16120 (match_operand 2 "register_operand" ""))
16121 (set (match_operand 0 "register_operand" "")
16122 (match_operand 3 "" ""))])]
16124 "ix86_current_function_needs_cld = 1;")
16126 (define_insn "*strsetdi_rex_1"
16127 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16128 (match_operand:DI 2 "register_operand" "a"))
16129 (set (match_operand:DI 0 "register_operand" "=D")
16130 (plus:DI (match_dup 1)
16134 [(set_attr "type" "str")
16135 (set_attr "memory" "store")
16136 (set_attr "mode" "DI")])
16138 (define_insn "*strsetsi_1"
16139 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16140 (match_operand:SI 2 "register_operand" "a"))
16141 (set (match_operand:SI 0 "register_operand" "=D")
16142 (plus:SI (match_dup 1)
16146 [(set_attr "type" "str")
16147 (set_attr "memory" "store")
16148 (set_attr "mode" "SI")])
16150 (define_insn "*strsetsi_rex_1"
16151 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16152 (match_operand:SI 2 "register_operand" "a"))
16153 (set (match_operand:DI 0 "register_operand" "=D")
16154 (plus:DI (match_dup 1)
16158 [(set_attr "type" "str")
16159 (set_attr "memory" "store")
16160 (set_attr "mode" "SI")])
16162 (define_insn "*strsethi_1"
16163 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16164 (match_operand:HI 2 "register_operand" "a"))
16165 (set (match_operand:SI 0 "register_operand" "=D")
16166 (plus:SI (match_dup 1)
16170 [(set_attr "type" "str")
16171 (set_attr "memory" "store")
16172 (set_attr "mode" "HI")])
16174 (define_insn "*strsethi_rex_1"
16175 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16176 (match_operand:HI 2 "register_operand" "a"))
16177 (set (match_operand:DI 0 "register_operand" "=D")
16178 (plus:DI (match_dup 1)
16182 [(set_attr "type" "str")
16183 (set_attr "memory" "store")
16184 (set_attr "mode" "HI")])
16186 (define_insn "*strsetqi_1"
16187 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16188 (match_operand:QI 2 "register_operand" "a"))
16189 (set (match_operand:SI 0 "register_operand" "=D")
16190 (plus:SI (match_dup 1)
16194 [(set_attr "type" "str")
16195 (set_attr "memory" "store")
16196 (set_attr "mode" "QI")])
16198 (define_insn "*strsetqi_rex_1"
16199 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16200 (match_operand:QI 2 "register_operand" "a"))
16201 (set (match_operand:DI 0 "register_operand" "=D")
16202 (plus:DI (match_dup 1)
16206 [(set_attr "type" "str")
16207 (set_attr "memory" "store")
16208 (set_attr "prefix_rex" "0")
16209 (set_attr "mode" "QI")])
16211 (define_expand "rep_stos"
16212 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16213 (set (match_operand 0 "register_operand" "")
16214 (match_operand 4 "" ""))
16215 (set (match_operand 2 "memory_operand" "") (const_int 0))
16216 (use (match_operand 3 "register_operand" ""))
16217 (use (match_dup 1))])]
16219 "ix86_current_function_needs_cld = 1;")
16221 (define_insn "*rep_stosdi_rex64"
16222 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16223 (set (match_operand:DI 0 "register_operand" "=D")
16224 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16226 (match_operand:DI 3 "register_operand" "0")))
16227 (set (mem:BLK (match_dup 3))
16229 (use (match_operand:DI 2 "register_operand" "a"))
16230 (use (match_dup 4))]
16233 [(set_attr "type" "str")
16234 (set_attr "prefix_rep" "1")
16235 (set_attr "memory" "store")
16236 (set_attr "mode" "DI")])
16238 (define_insn "*rep_stossi"
16239 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16240 (set (match_operand:SI 0 "register_operand" "=D")
16241 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16243 (match_operand:SI 3 "register_operand" "0")))
16244 (set (mem:BLK (match_dup 3))
16246 (use (match_operand:SI 2 "register_operand" "a"))
16247 (use (match_dup 4))]
16250 [(set_attr "type" "str")
16251 (set_attr "prefix_rep" "1")
16252 (set_attr "memory" "store")
16253 (set_attr "mode" "SI")])
16255 (define_insn "*rep_stossi_rex64"
16256 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16257 (set (match_operand:DI 0 "register_operand" "=D")
16258 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16260 (match_operand:DI 3 "register_operand" "0")))
16261 (set (mem:BLK (match_dup 3))
16263 (use (match_operand:SI 2 "register_operand" "a"))
16264 (use (match_dup 4))]
16267 [(set_attr "type" "str")
16268 (set_attr "prefix_rep" "1")
16269 (set_attr "memory" "store")
16270 (set_attr "mode" "SI")])
16272 (define_insn "*rep_stosqi"
16273 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16274 (set (match_operand:SI 0 "register_operand" "=D")
16275 (plus:SI (match_operand:SI 3 "register_operand" "0")
16276 (match_operand:SI 4 "register_operand" "1")))
16277 (set (mem:BLK (match_dup 3))
16279 (use (match_operand:QI 2 "register_operand" "a"))
16280 (use (match_dup 4))]
16283 [(set_attr "type" "str")
16284 (set_attr "prefix_rep" "1")
16285 (set_attr "memory" "store")
16286 (set_attr "mode" "QI")])
16288 (define_insn "*rep_stosqi_rex64"
16289 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16290 (set (match_operand:DI 0 "register_operand" "=D")
16291 (plus:DI (match_operand:DI 3 "register_operand" "0")
16292 (match_operand:DI 4 "register_operand" "1")))
16293 (set (mem:BLK (match_dup 3))
16295 (use (match_operand:QI 2 "register_operand" "a"))
16296 (use (match_dup 4))]
16299 [(set_attr "type" "str")
16300 (set_attr "prefix_rep" "1")
16301 (set_attr "memory" "store")
16302 (set_attr "prefix_rex" "0")
16303 (set_attr "mode" "QI")])
16305 (define_expand "cmpstrnsi"
16306 [(set (match_operand:SI 0 "register_operand" "")
16307 (compare:SI (match_operand:BLK 1 "general_operand" "")
16308 (match_operand:BLK 2 "general_operand" "")))
16309 (use (match_operand 3 "general_operand" ""))
16310 (use (match_operand 4 "immediate_operand" ""))]
16313 rtx addr1, addr2, out, outlow, count, countreg, align;
16315 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16318 /* Can't use this if the user has appropriated esi or edi. */
16319 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
16324 out = gen_reg_rtx (SImode);
16326 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16327 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16328 if (addr1 != XEXP (operands[1], 0))
16329 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16330 if (addr2 != XEXP (operands[2], 0))
16331 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16333 count = operands[3];
16334 countreg = ix86_zero_extend_to_Pmode (count);
16336 /* %%% Iff we are testing strict equality, we can use known alignment
16337 to good advantage. This may be possible with combine, particularly
16338 once cc0 is dead. */
16339 align = operands[4];
16341 if (CONST_INT_P (count))
16343 if (INTVAL (count) == 0)
16345 emit_move_insn (operands[0], const0_rtx);
16348 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16349 operands[1], operands[2]));
16353 rtx (*cmp_insn)(rtx, rtx);
16356 cmp_insn = gen_cmpdi_1;
16358 cmp_insn = gen_cmpsi_1;
16359 emit_insn (cmp_insn (countreg, countreg));
16360 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16361 operands[1], operands[2]));
16364 outlow = gen_lowpart (QImode, out);
16365 emit_insn (gen_cmpintqi (outlow));
16366 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16368 if (operands[0] != out)
16369 emit_move_insn (operands[0], out);
16374 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16376 (define_expand "cmpintqi"
16377 [(set (match_dup 1)
16378 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16380 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16381 (parallel [(set (match_operand:QI 0 "register_operand" "")
16382 (minus:QI (match_dup 1)
16384 (clobber (reg:CC FLAGS_REG))])]
16386 "operands[1] = gen_reg_rtx (QImode);
16387 operands[2] = gen_reg_rtx (QImode);")
16389 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16390 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16392 (define_expand "cmpstrnqi_nz_1"
16393 [(parallel [(set (reg:CC FLAGS_REG)
16394 (compare:CC (match_operand 4 "memory_operand" "")
16395 (match_operand 5 "memory_operand" "")))
16396 (use (match_operand 2 "register_operand" ""))
16397 (use (match_operand:SI 3 "immediate_operand" ""))
16398 (clobber (match_operand 0 "register_operand" ""))
16399 (clobber (match_operand 1 "register_operand" ""))
16400 (clobber (match_dup 2))])]
16402 "ix86_current_function_needs_cld = 1;")
16404 (define_insn "*cmpstrnqi_nz_1"
16405 [(set (reg:CC FLAGS_REG)
16406 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16407 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16408 (use (match_operand:SI 6 "register_operand" "2"))
16409 (use (match_operand:SI 3 "immediate_operand" "i"))
16410 (clobber (match_operand:SI 0 "register_operand" "=S"))
16411 (clobber (match_operand:SI 1 "register_operand" "=D"))
16412 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16415 [(set_attr "type" "str")
16416 (set_attr "mode" "QI")
16417 (set_attr "prefix_rep" "1")])
16419 (define_insn "*cmpstrnqi_nz_rex_1"
16420 [(set (reg:CC FLAGS_REG)
16421 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16422 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16423 (use (match_operand:DI 6 "register_operand" "2"))
16424 (use (match_operand:SI 3 "immediate_operand" "i"))
16425 (clobber (match_operand:DI 0 "register_operand" "=S"))
16426 (clobber (match_operand:DI 1 "register_operand" "=D"))
16427 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16430 [(set_attr "type" "str")
16431 (set_attr "mode" "QI")
16432 (set_attr "prefix_rex" "0")
16433 (set_attr "prefix_rep" "1")])
16435 ;; The same, but the count is not known to not be zero.
16437 (define_expand "cmpstrnqi_1"
16438 [(parallel [(set (reg:CC FLAGS_REG)
16439 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16441 (compare:CC (match_operand 4 "memory_operand" "")
16442 (match_operand 5 "memory_operand" ""))
16444 (use (match_operand:SI 3 "immediate_operand" ""))
16445 (use (reg:CC FLAGS_REG))
16446 (clobber (match_operand 0 "register_operand" ""))
16447 (clobber (match_operand 1 "register_operand" ""))
16448 (clobber (match_dup 2))])]
16450 "ix86_current_function_needs_cld = 1;")
16452 (define_insn "*cmpstrnqi_1"
16453 [(set (reg:CC FLAGS_REG)
16454 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16456 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16457 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16459 (use (match_operand:SI 3 "immediate_operand" "i"))
16460 (use (reg:CC FLAGS_REG))
16461 (clobber (match_operand:SI 0 "register_operand" "=S"))
16462 (clobber (match_operand:SI 1 "register_operand" "=D"))
16463 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16466 [(set_attr "type" "str")
16467 (set_attr "mode" "QI")
16468 (set_attr "prefix_rep" "1")])
16470 (define_insn "*cmpstrnqi_rex_1"
16471 [(set (reg:CC FLAGS_REG)
16472 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16474 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16475 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16477 (use (match_operand:SI 3 "immediate_operand" "i"))
16478 (use (reg:CC FLAGS_REG))
16479 (clobber (match_operand:DI 0 "register_operand" "=S"))
16480 (clobber (match_operand:DI 1 "register_operand" "=D"))
16481 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16484 [(set_attr "type" "str")
16485 (set_attr "mode" "QI")
16486 (set_attr "prefix_rex" "0")
16487 (set_attr "prefix_rep" "1")])
16489 (define_expand "strlensi"
16490 [(set (match_operand:SI 0 "register_operand" "")
16491 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16492 (match_operand:QI 2 "immediate_operand" "")
16493 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16496 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16502 (define_expand "strlendi"
16503 [(set (match_operand:DI 0 "register_operand" "")
16504 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16505 (match_operand:QI 2 "immediate_operand" "")
16506 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16509 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16515 (define_expand "strlenqi_1"
16516 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16517 (clobber (match_operand 1 "register_operand" ""))
16518 (clobber (reg:CC FLAGS_REG))])]
16520 "ix86_current_function_needs_cld = 1;")
16522 (define_insn "*strlenqi_1"
16523 [(set (match_operand:SI 0 "register_operand" "=&c")
16524 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16525 (match_operand:QI 2 "register_operand" "a")
16526 (match_operand:SI 3 "immediate_operand" "i")
16527 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16528 (clobber (match_operand:SI 1 "register_operand" "=D"))
16529 (clobber (reg:CC FLAGS_REG))]
16532 [(set_attr "type" "str")
16533 (set_attr "mode" "QI")
16534 (set_attr "prefix_rep" "1")])
16536 (define_insn "*strlenqi_rex_1"
16537 [(set (match_operand:DI 0 "register_operand" "=&c")
16538 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16539 (match_operand:QI 2 "register_operand" "a")
16540 (match_operand:DI 3 "immediate_operand" "i")
16541 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16542 (clobber (match_operand:DI 1 "register_operand" "=D"))
16543 (clobber (reg:CC FLAGS_REG))]
16546 [(set_attr "type" "str")
16547 (set_attr "mode" "QI")
16548 (set_attr "prefix_rex" "0")
16549 (set_attr "prefix_rep" "1")])
16551 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16552 ;; handled in combine, but it is not currently up to the task.
16553 ;; When used for their truth value, the cmpstrn* expanders generate
16562 ;; The intermediate three instructions are unnecessary.
16564 ;; This one handles cmpstrn*_nz_1...
16567 (set (reg:CC FLAGS_REG)
16568 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16569 (mem:BLK (match_operand 5 "register_operand" ""))))
16570 (use (match_operand 6 "register_operand" ""))
16571 (use (match_operand:SI 3 "immediate_operand" ""))
16572 (clobber (match_operand 0 "register_operand" ""))
16573 (clobber (match_operand 1 "register_operand" ""))
16574 (clobber (match_operand 2 "register_operand" ""))])
16575 (set (match_operand:QI 7 "register_operand" "")
16576 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16577 (set (match_operand:QI 8 "register_operand" "")
16578 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16579 (set (reg FLAGS_REG)
16580 (compare (match_dup 7) (match_dup 8)))
16582 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16584 (set (reg:CC FLAGS_REG)
16585 (compare:CC (mem:BLK (match_dup 4))
16586 (mem:BLK (match_dup 5))))
16587 (use (match_dup 6))
16588 (use (match_dup 3))
16589 (clobber (match_dup 0))
16590 (clobber (match_dup 1))
16591 (clobber (match_dup 2))])]
16594 ;; ...and this one handles cmpstrn*_1.
16597 (set (reg:CC FLAGS_REG)
16598 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16600 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16601 (mem:BLK (match_operand 5 "register_operand" "")))
16603 (use (match_operand:SI 3 "immediate_operand" ""))
16604 (use (reg:CC FLAGS_REG))
16605 (clobber (match_operand 0 "register_operand" ""))
16606 (clobber (match_operand 1 "register_operand" ""))
16607 (clobber (match_operand 2 "register_operand" ""))])
16608 (set (match_operand:QI 7 "register_operand" "")
16609 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16610 (set (match_operand:QI 8 "register_operand" "")
16611 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16612 (set (reg FLAGS_REG)
16613 (compare (match_dup 7) (match_dup 8)))
16615 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16617 (set (reg:CC FLAGS_REG)
16618 (if_then_else:CC (ne (match_dup 6)
16620 (compare:CC (mem:BLK (match_dup 4))
16621 (mem:BLK (match_dup 5)))
16623 (use (match_dup 3))
16624 (use (reg:CC FLAGS_REG))
16625 (clobber (match_dup 0))
16626 (clobber (match_dup 1))
16627 (clobber (match_dup 2))])]
16632 ;; Conditional move instructions.
16634 (define_expand "mov<mode>cc"
16635 [(set (match_operand:SWIM 0 "register_operand" "")
16636 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16637 (match_operand:SWIM 2 "general_operand" "")
16638 (match_operand:SWIM 3 "general_operand" "")))]
16640 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16642 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16643 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16644 ;; So just document what we're doing explicitly.
16646 (define_expand "x86_mov<mode>cc_0_m1"
16648 [(set (match_operand:SWI48 0 "register_operand" "")
16649 (if_then_else:SWI48
16650 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16651 [(match_operand 1 "flags_reg_operand" "")
16655 (clobber (reg:CC FLAGS_REG))])]
16659 (define_insn "*x86_mov<mode>cc_0_m1"
16660 [(set (match_operand:SWI48 0 "register_operand" "=r")
16661 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16662 [(reg FLAGS_REG) (const_int 0)])
16665 (clobber (reg:CC FLAGS_REG))]
16667 "sbb{<imodesuffix>}\t%0, %0"
16668 ; Since we don't have the proper number of operands for an alu insn,
16669 ; fill in all the blanks.
16670 [(set_attr "type" "alu")
16671 (set_attr "use_carry" "1")
16672 (set_attr "pent_pair" "pu")
16673 (set_attr "memory" "none")
16674 (set_attr "imm_disp" "false")
16675 (set_attr "mode" "<MODE>")
16676 (set_attr "length_immediate" "0")])
16678 (define_insn "*x86_mov<mode>cc_0_m1_se"
16679 [(set (match_operand:SWI48 0 "register_operand" "=r")
16680 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16681 [(reg FLAGS_REG) (const_int 0)])
16684 (clobber (reg:CC FLAGS_REG))]
16686 "sbb{<imodesuffix>}\t%0, %0"
16687 [(set_attr "type" "alu")
16688 (set_attr "use_carry" "1")
16689 (set_attr "pent_pair" "pu")
16690 (set_attr "memory" "none")
16691 (set_attr "imm_disp" "false")
16692 (set_attr "mode" "<MODE>")
16693 (set_attr "length_immediate" "0")])
16695 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16696 [(set (match_operand:SWI48 0 "register_operand" "=r")
16697 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16698 [(reg FLAGS_REG) (const_int 0)])))]
16700 "sbb{<imodesuffix>}\t%0, %0"
16701 [(set_attr "type" "alu")
16702 (set_attr "use_carry" "1")
16703 (set_attr "pent_pair" "pu")
16704 (set_attr "memory" "none")
16705 (set_attr "imm_disp" "false")
16706 (set_attr "mode" "<MODE>")
16707 (set_attr "length_immediate" "0")])
16709 (define_insn "*mov<mode>cc_noc"
16710 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16711 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16712 [(reg FLAGS_REG) (const_int 0)])
16713 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16714 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16715 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16717 cmov%O2%C1\t{%2, %0|%0, %2}
16718 cmov%O2%c1\t{%3, %0|%0, %3}"
16719 [(set_attr "type" "icmov")
16720 (set_attr "mode" "<MODE>")])
16722 (define_insn_and_split "*movqicc_noc"
16723 [(set (match_operand:QI 0 "register_operand" "=r,r")
16724 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16725 [(match_operand 4 "flags_reg_operand" "")
16727 (match_operand:QI 2 "register_operand" "r,0")
16728 (match_operand:QI 3 "register_operand" "0,r")))]
16729 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16731 "&& reload_completed"
16732 [(set (match_dup 0)
16733 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16736 "operands[0] = gen_lowpart (SImode, operands[0]);
16737 operands[2] = gen_lowpart (SImode, operands[2]);
16738 operands[3] = gen_lowpart (SImode, operands[3]);"
16739 [(set_attr "type" "icmov")
16740 (set_attr "mode" "SI")])
16742 (define_expand "mov<mode>cc"
16743 [(set (match_operand:X87MODEF 0 "register_operand" "")
16744 (if_then_else:X87MODEF
16745 (match_operand 1 "ix86_fp_comparison_operator" "")
16746 (match_operand:X87MODEF 2 "register_operand" "")
16747 (match_operand:X87MODEF 3 "register_operand" "")))]
16748 "(TARGET_80387 && TARGET_CMOVE)
16749 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16750 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16752 (define_insn "*movsfcc_1_387"
16753 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16754 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16755 [(reg FLAGS_REG) (const_int 0)])
16756 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16757 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16758 "TARGET_80387 && TARGET_CMOVE
16759 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16761 fcmov%F1\t{%2, %0|%0, %2}
16762 fcmov%f1\t{%3, %0|%0, %3}
16763 cmov%O2%C1\t{%2, %0|%0, %2}
16764 cmov%O2%c1\t{%3, %0|%0, %3}"
16765 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16766 (set_attr "mode" "SF,SF,SI,SI")])
16768 (define_insn "*movdfcc_1"
16769 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16770 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16771 [(reg FLAGS_REG) (const_int 0)])
16772 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16773 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16774 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16775 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16777 fcmov%F1\t{%2, %0|%0, %2}
16778 fcmov%f1\t{%3, %0|%0, %3}
16781 [(set_attr "type" "fcmov,fcmov,multi,multi")
16782 (set_attr "mode" "DF")])
16784 (define_insn "*movdfcc_1_rex64"
16785 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16786 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16787 [(reg FLAGS_REG) (const_int 0)])
16788 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16789 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16790 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16791 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16793 fcmov%F1\t{%2, %0|%0, %2}
16794 fcmov%f1\t{%3, %0|%0, %3}
16795 cmov%O2%C1\t{%2, %0|%0, %2}
16796 cmov%O2%c1\t{%3, %0|%0, %3}"
16797 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16798 (set_attr "mode" "DF")])
16801 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16802 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16803 [(match_operand 4 "flags_reg_operand" "")
16805 (match_operand:DF 2 "nonimmediate_operand" "")
16806 (match_operand:DF 3 "nonimmediate_operand" "")))]
16807 "!TARGET_64BIT && reload_completed"
16808 [(set (match_dup 2)
16809 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16813 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16816 "split_di (&operands[2], 2, &operands[5], &operands[7]);
16817 split_di (&operands[0], 1, &operands[2], &operands[3]);")
16819 (define_insn "*movxfcc_1"
16820 [(set (match_operand:XF 0 "register_operand" "=f,f")
16821 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16822 [(reg FLAGS_REG) (const_int 0)])
16823 (match_operand:XF 2 "register_operand" "f,0")
16824 (match_operand:XF 3 "register_operand" "0,f")))]
16825 "TARGET_80387 && TARGET_CMOVE"
16827 fcmov%F1\t{%2, %0|%0, %2}
16828 fcmov%f1\t{%3, %0|%0, %3}"
16829 [(set_attr "type" "fcmov")
16830 (set_attr "mode" "XF")])
16832 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16833 ;; the scalar versions to have only XMM registers as operands.
16835 ;; XOP conditional move
16836 (define_insn "*xop_pcmov_<mode>"
16837 [(set (match_operand:MODEF 0 "register_operand" "=x")
16838 (if_then_else:MODEF
16839 (match_operand:MODEF 1 "register_operand" "x")
16840 (match_operand:MODEF 2 "register_operand" "x")
16841 (match_operand:MODEF 3 "register_operand" "x")))]
16843 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16844 [(set_attr "type" "sse4arg")])
16846 ;; These versions of the min/max patterns are intentionally ignorant of
16847 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16848 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16849 ;; are undefined in this condition, we're certain this is correct.
16851 (define_insn "*avx_<code><mode>3"
16852 [(set (match_operand:MODEF 0 "register_operand" "=x")
16854 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16855 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16856 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16857 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16858 [(set_attr "type" "sseadd")
16859 (set_attr "prefix" "vex")
16860 (set_attr "mode" "<MODE>")])
16862 (define_insn "<code><mode>3"
16863 [(set (match_operand:MODEF 0 "register_operand" "=x")
16865 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16866 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16867 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16868 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16869 [(set_attr "type" "sseadd")
16870 (set_attr "mode" "<MODE>")])
16872 ;; These versions of the min/max patterns implement exactly the operations
16873 ;; min = (op1 < op2 ? op1 : op2)
16874 ;; max = (!(op1 < op2) ? op1 : op2)
16875 ;; Their operands are not commutative, and thus they may be used in the
16876 ;; presence of -0.0 and NaN.
16878 (define_insn "*avx_ieee_smin<mode>3"
16879 [(set (match_operand:MODEF 0 "register_operand" "=x")
16881 [(match_operand:MODEF 1 "register_operand" "x")
16882 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16884 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16885 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16886 [(set_attr "type" "sseadd")
16887 (set_attr "prefix" "vex")
16888 (set_attr "mode" "<MODE>")])
16890 (define_insn "*ieee_smin<mode>3"
16891 [(set (match_operand:MODEF 0 "register_operand" "=x")
16893 [(match_operand:MODEF 1 "register_operand" "0")
16894 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16896 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16897 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16898 [(set_attr "type" "sseadd")
16899 (set_attr "mode" "<MODE>")])
16901 (define_insn "*avx_ieee_smax<mode>3"
16902 [(set (match_operand:MODEF 0 "register_operand" "=x")
16904 [(match_operand:MODEF 1 "register_operand" "0")
16905 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16907 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16908 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16909 [(set_attr "type" "sseadd")
16910 (set_attr "prefix" "vex")
16911 (set_attr "mode" "<MODE>")])
16913 (define_insn "*ieee_smax<mode>3"
16914 [(set (match_operand:MODEF 0 "register_operand" "=x")
16916 [(match_operand:MODEF 1 "register_operand" "0")
16917 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16919 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16920 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16921 [(set_attr "type" "sseadd")
16922 (set_attr "mode" "<MODE>")])
16924 ;; Make two stack loads independent:
16926 ;; fld %st(0) -> fld bb
16927 ;; fmul bb fmul %st(1), %st
16929 ;; Actually we only match the last two instructions for simplicity.
16931 [(set (match_operand 0 "fp_register_operand" "")
16932 (match_operand 1 "fp_register_operand" ""))
16934 (match_operator 2 "binary_fp_operator"
16936 (match_operand 3 "memory_operand" "")]))]
16937 "REGNO (operands[0]) != REGNO (operands[1])"
16938 [(set (match_dup 0) (match_dup 3))
16939 (set (match_dup 0) (match_dup 4))]
16941 ;; The % modifier is not operational anymore in peephole2's, so we have to
16942 ;; swap the operands manually in the case of addition and multiplication.
16943 "if (COMMUTATIVE_ARITH_P (operands[2]))
16944 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16945 operands[0], operands[1]);
16947 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16948 operands[1], operands[0]);")
16950 ;; Conditional addition patterns
16951 (define_expand "add<mode>cc"
16952 [(match_operand:SWI 0 "register_operand" "")
16953 (match_operand 1 "comparison_operator" "")
16954 (match_operand:SWI 2 "register_operand" "")
16955 (match_operand:SWI 3 "const_int_operand" "")]
16957 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16960 ;; Misc patterns (?)
16962 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16963 ;; Otherwise there will be nothing to keep
16965 ;; [(set (reg ebp) (reg esp))]
16966 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16967 ;; (clobber (eflags)]
16968 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16970 ;; in proper program order.
16971 (define_insn "pro_epilogue_adjust_stack_1"
16972 [(set (match_operand:SI 0 "register_operand" "=r,r")
16973 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16974 (match_operand:SI 2 "immediate_operand" "i,i")))
16975 (clobber (reg:CC FLAGS_REG))
16976 (clobber (mem:BLK (scratch)))]
16979 switch (get_attr_type (insn))
16982 return "mov{l}\t{%1, %0|%0, %1}";
16985 if (CONST_INT_P (operands[2])
16986 && (INTVAL (operands[2]) == 128
16987 || (INTVAL (operands[2]) < 0
16988 && INTVAL (operands[2]) != -128)))
16990 operands[2] = GEN_INT (-INTVAL (operands[2]));
16991 return "sub{l}\t{%2, %0|%0, %2}";
16993 return "add{l}\t{%2, %0|%0, %2}";
16996 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16997 return "lea{l}\t{%a2, %0|%0, %a2}";
17000 gcc_unreachable ();
17003 [(set (attr "type")
17004 (cond [(and (eq_attr "alternative" "0")
17005 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
17006 (const_string "alu")
17007 (match_operand:SI 2 "const0_operand" "")
17008 (const_string "imov")
17010 (const_string "lea")))
17011 (set (attr "length_immediate")
17012 (cond [(eq_attr "type" "imov")
17014 (and (eq_attr "type" "alu")
17015 (match_operand 2 "const128_operand" ""))
17018 (const_string "*")))
17019 (set_attr "mode" "SI")])
17021 (define_insn "pro_epilogue_adjust_stack_rex64"
17022 [(set (match_operand:DI 0 "register_operand" "=r,r")
17023 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17024 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17025 (clobber (reg:CC FLAGS_REG))
17026 (clobber (mem:BLK (scratch)))]
17029 switch (get_attr_type (insn))
17032 return "mov{q}\t{%1, %0|%0, %1}";
17035 if (CONST_INT_P (operands[2])
17036 /* Avoid overflows. */
17037 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17038 && (INTVAL (operands[2]) == 128
17039 || (INTVAL (operands[2]) < 0
17040 && INTVAL (operands[2]) != -128)))
17042 operands[2] = GEN_INT (-INTVAL (operands[2]));
17043 return "sub{q}\t{%2, %0|%0, %2}";
17045 return "add{q}\t{%2, %0|%0, %2}";
17048 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17049 return "lea{q}\t{%a2, %0|%0, %a2}";
17052 gcc_unreachable ();
17055 [(set (attr "type")
17056 (cond [(and (eq_attr "alternative" "0")
17057 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
17058 (const_string "alu")
17059 (match_operand:DI 2 "const0_operand" "")
17060 (const_string "imov")
17062 (const_string "lea")))
17063 (set (attr "length_immediate")
17064 (cond [(eq_attr "type" "imov")
17066 (and (eq_attr "type" "alu")
17067 (match_operand 2 "const128_operand" ""))
17070 (const_string "*")))
17071 (set_attr "mode" "DI")])
17073 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17074 [(set (match_operand:DI 0 "register_operand" "=r,r")
17075 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17076 (match_operand:DI 3 "immediate_operand" "i,i")))
17077 (use (match_operand:DI 2 "register_operand" "r,r"))
17078 (clobber (reg:CC FLAGS_REG))
17079 (clobber (mem:BLK (scratch)))]
17082 switch (get_attr_type (insn))
17085 return "add{q}\t{%2, %0|%0, %2}";
17088 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17089 return "lea{q}\t{%a2, %0|%0, %a2}";
17092 gcc_unreachable ();
17095 [(set_attr "type" "alu,lea")
17096 (set_attr "mode" "DI")])
17098 (define_insn "allocate_stack_worker_32"
17099 [(set (match_operand:SI 0 "register_operand" "=a")
17100 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
17101 UNSPECV_STACK_PROBE))
17102 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
17103 (clobber (reg:CC FLAGS_REG))]
17104 "!TARGET_64BIT && TARGET_STACK_PROBE"
17106 [(set_attr "type" "multi")
17107 (set_attr "length" "5")])
17109 (define_insn "allocate_stack_worker_64"
17110 [(set (match_operand:DI 0 "register_operand" "=a")
17111 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
17112 UNSPECV_STACK_PROBE))
17113 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
17114 (clobber (reg:DI R10_REG))
17115 (clobber (reg:DI R11_REG))
17116 (clobber (reg:CC FLAGS_REG))]
17117 "TARGET_64BIT && TARGET_STACK_PROBE"
17119 [(set_attr "type" "multi")
17120 (set_attr "length" "5")])
17122 (define_expand "allocate_stack"
17123 [(match_operand 0 "register_operand" "")
17124 (match_operand 1 "general_operand" "")]
17125 "TARGET_STACK_PROBE"
17129 #ifndef CHECK_STACK_LIMIT
17130 #define CHECK_STACK_LIMIT 0
17133 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17134 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17136 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
17137 stack_pointer_rtx, 0, OPTAB_DIRECT);
17138 if (x != stack_pointer_rtx)
17139 emit_move_insn (stack_pointer_rtx, x);
17143 x = copy_to_mode_reg (Pmode, operands[1]);
17145 x = gen_allocate_stack_worker_64 (x, x);
17147 x = gen_allocate_stack_worker_32 (x, x);
17151 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17155 ;; Use IOR for stack probes, this is shorter.
17156 (define_expand "probe_stack"
17157 [(match_operand 0 "memory_operand" "")]
17160 if (GET_MODE (operands[0]) == DImode)
17161 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
17163 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
17167 (define_expand "builtin_setjmp_receiver"
17168 [(label_ref (match_operand 0 "" ""))]
17169 "!TARGET_64BIT && flag_pic"
17175 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
17176 rtx label_rtx = gen_label_rtx ();
17177 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17178 xops[0] = xops[1] = picreg;
17179 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17180 ix86_expand_binary_operator (MINUS, SImode, xops);
17184 emit_insn (gen_set_got (pic_offset_table_rtx));
17188 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17191 [(set (match_operand 0 "register_operand" "")
17192 (match_operator 3 "promotable_binary_operator"
17193 [(match_operand 1 "register_operand" "")
17194 (match_operand 2 "aligned_operand" "")]))
17195 (clobber (reg:CC FLAGS_REG))]
17196 "! TARGET_PARTIAL_REG_STALL && reload_completed
17197 && ((GET_MODE (operands[0]) == HImode
17198 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17199 /* ??? next two lines just !satisfies_constraint_K (...) */
17200 || !CONST_INT_P (operands[2])
17201 || satisfies_constraint_K (operands[2])))
17202 || (GET_MODE (operands[0]) == QImode
17203 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17204 [(parallel [(set (match_dup 0)
17205 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17206 (clobber (reg:CC FLAGS_REG))])]
17207 "operands[0] = gen_lowpart (SImode, operands[0]);
17208 operands[1] = gen_lowpart (SImode, operands[1]);
17209 if (GET_CODE (operands[3]) != ASHIFT)
17210 operands[2] = gen_lowpart (SImode, operands[2]);
17211 PUT_MODE (operands[3], SImode);")
17213 ; Promote the QImode tests, as i386 has encoding of the AND
17214 ; instruction with 32-bit sign-extended immediate and thus the
17215 ; instruction size is unchanged, except in the %eax case for
17216 ; which it is increased by one byte, hence the ! optimize_size.
17218 [(set (match_operand 0 "flags_reg_operand" "")
17219 (match_operator 2 "compare_operator"
17220 [(and (match_operand 3 "aligned_operand" "")
17221 (match_operand 4 "const_int_operand" ""))
17223 (set (match_operand 1 "register_operand" "")
17224 (and (match_dup 3) (match_dup 4)))]
17225 "! TARGET_PARTIAL_REG_STALL && reload_completed
17226 && optimize_insn_for_speed_p ()
17227 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17228 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17229 /* Ensure that the operand will remain sign-extended immediate. */
17230 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17231 [(parallel [(set (match_dup 0)
17232 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17235 (and:SI (match_dup 3) (match_dup 4)))])]
17238 = gen_int_mode (INTVAL (operands[4])
17239 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17240 operands[1] = gen_lowpart (SImode, operands[1]);
17241 operands[3] = gen_lowpart (SImode, operands[3]);
17244 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17245 ; the TEST instruction with 32-bit sign-extended immediate and thus
17246 ; the instruction size would at least double, which is not what we
17247 ; want even with ! optimize_size.
17249 [(set (match_operand 0 "flags_reg_operand" "")
17250 (match_operator 1 "compare_operator"
17251 [(and (match_operand:HI 2 "aligned_operand" "")
17252 (match_operand:HI 3 "const_int_operand" ""))
17254 "! TARGET_PARTIAL_REG_STALL && reload_completed
17255 && ! TARGET_FAST_PREFIX
17256 && optimize_insn_for_speed_p ()
17257 /* Ensure that the operand will remain sign-extended immediate. */
17258 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17259 [(set (match_dup 0)
17260 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17264 = gen_int_mode (INTVAL (operands[3])
17265 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17266 operands[2] = gen_lowpart (SImode, operands[2]);
17270 [(set (match_operand 0 "register_operand" "")
17271 (neg (match_operand 1 "register_operand" "")))
17272 (clobber (reg:CC FLAGS_REG))]
17273 "! TARGET_PARTIAL_REG_STALL && reload_completed
17274 && (GET_MODE (operands[0]) == HImode
17275 || (GET_MODE (operands[0]) == QImode
17276 && (TARGET_PROMOTE_QImode
17277 || optimize_insn_for_size_p ())))"
17278 [(parallel [(set (match_dup 0)
17279 (neg:SI (match_dup 1)))
17280 (clobber (reg:CC FLAGS_REG))])]
17281 "operands[0] = gen_lowpart (SImode, operands[0]);
17282 operands[1] = gen_lowpart (SImode, operands[1]);")
17285 [(set (match_operand 0 "register_operand" "")
17286 (not (match_operand 1 "register_operand" "")))]
17287 "! TARGET_PARTIAL_REG_STALL && reload_completed
17288 && (GET_MODE (operands[0]) == HImode
17289 || (GET_MODE (operands[0]) == QImode
17290 && (TARGET_PROMOTE_QImode
17291 || optimize_insn_for_size_p ())))"
17292 [(set (match_dup 0)
17293 (not:SI (match_dup 1)))]
17294 "operands[0] = gen_lowpart (SImode, operands[0]);
17295 operands[1] = gen_lowpart (SImode, operands[1]);")
17298 [(set (match_operand 0 "register_operand" "")
17299 (if_then_else (match_operator 1 "comparison_operator"
17300 [(reg FLAGS_REG) (const_int 0)])
17301 (match_operand 2 "register_operand" "")
17302 (match_operand 3 "register_operand" "")))]
17303 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17304 && (GET_MODE (operands[0]) == HImode
17305 || (GET_MODE (operands[0]) == QImode
17306 && (TARGET_PROMOTE_QImode
17307 || optimize_insn_for_size_p ())))"
17308 [(set (match_dup 0)
17309 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17310 "operands[0] = gen_lowpart (SImode, operands[0]);
17311 operands[2] = gen_lowpart (SImode, operands[2]);
17312 operands[3] = gen_lowpart (SImode, operands[3]);")
17315 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17316 ;; transform a complex memory operation into two memory to register operations.
17318 ;; Don't push memory operands
17320 [(set (match_operand:SI 0 "push_operand" "")
17321 (match_operand:SI 1 "memory_operand" ""))
17322 (match_scratch:SI 2 "r")]
17323 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17324 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17325 [(set (match_dup 2) (match_dup 1))
17326 (set (match_dup 0) (match_dup 2))]
17330 [(set (match_operand:DI 0 "push_operand" "")
17331 (match_operand:DI 1 "memory_operand" ""))
17332 (match_scratch:DI 2 "r")]
17333 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17334 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17335 [(set (match_dup 2) (match_dup 1))
17336 (set (match_dup 0) (match_dup 2))]
17339 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17342 [(set (match_operand:SF 0 "push_operand" "")
17343 (match_operand:SF 1 "memory_operand" ""))
17344 (match_scratch:SF 2 "r")]
17345 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17346 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17347 [(set (match_dup 2) (match_dup 1))
17348 (set (match_dup 0) (match_dup 2))]
17352 [(set (match_operand:HI 0 "push_operand" "")
17353 (match_operand:HI 1 "memory_operand" ""))
17354 (match_scratch:HI 2 "r")]
17355 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17356 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17357 [(set (match_dup 2) (match_dup 1))
17358 (set (match_dup 0) (match_dup 2))]
17362 [(set (match_operand:QI 0 "push_operand" "")
17363 (match_operand:QI 1 "memory_operand" ""))
17364 (match_scratch:QI 2 "q")]
17365 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17366 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17367 [(set (match_dup 2) (match_dup 1))
17368 (set (match_dup 0) (match_dup 2))]
17371 ;; Don't move an immediate directly to memory when the instruction
17374 [(match_scratch:SI 1 "r")
17375 (set (match_operand:SI 0 "memory_operand" "")
17377 "optimize_insn_for_speed_p ()
17378 && ! TARGET_USE_MOV0
17379 && TARGET_SPLIT_LONG_MOVES
17380 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17381 && peep2_regno_dead_p (0, FLAGS_REG)"
17382 [(parallel [(set (match_dup 1) (const_int 0))
17383 (clobber (reg:CC FLAGS_REG))])
17384 (set (match_dup 0) (match_dup 1))]
17388 [(match_scratch:HI 1 "r")
17389 (set (match_operand:HI 0 "memory_operand" "")
17391 "optimize_insn_for_speed_p ()
17392 && ! TARGET_USE_MOV0
17393 && TARGET_SPLIT_LONG_MOVES
17394 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17395 && peep2_regno_dead_p (0, FLAGS_REG)"
17396 [(parallel [(set (match_dup 2) (const_int 0))
17397 (clobber (reg:CC FLAGS_REG))])
17398 (set (match_dup 0) (match_dup 1))]
17399 "operands[2] = gen_lowpart (SImode, operands[1]);")
17402 [(match_scratch:QI 1 "q")
17403 (set (match_operand:QI 0 "memory_operand" "")
17405 "optimize_insn_for_speed_p ()
17406 && ! TARGET_USE_MOV0
17407 && TARGET_SPLIT_LONG_MOVES
17408 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17409 && peep2_regno_dead_p (0, FLAGS_REG)"
17410 [(parallel [(set (match_dup 2) (const_int 0))
17411 (clobber (reg:CC FLAGS_REG))])
17412 (set (match_dup 0) (match_dup 1))]
17413 "operands[2] = gen_lowpart (SImode, operands[1]);")
17416 [(match_scratch:SI 2 "r")
17417 (set (match_operand:SI 0 "memory_operand" "")
17418 (match_operand:SI 1 "immediate_operand" ""))]
17419 "optimize_insn_for_speed_p ()
17420 && TARGET_SPLIT_LONG_MOVES
17421 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17422 [(set (match_dup 2) (match_dup 1))
17423 (set (match_dup 0) (match_dup 2))]
17427 [(match_scratch:HI 2 "r")
17428 (set (match_operand:HI 0 "memory_operand" "")
17429 (match_operand:HI 1 "immediate_operand" ""))]
17430 "optimize_insn_for_speed_p ()
17431 && TARGET_SPLIT_LONG_MOVES
17432 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17433 [(set (match_dup 2) (match_dup 1))
17434 (set (match_dup 0) (match_dup 2))]
17438 [(match_scratch:QI 2 "q")
17439 (set (match_operand:QI 0 "memory_operand" "")
17440 (match_operand:QI 1 "immediate_operand" ""))]
17441 "optimize_insn_for_speed_p ()
17442 && TARGET_SPLIT_LONG_MOVES
17443 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17444 [(set (match_dup 2) (match_dup 1))
17445 (set (match_dup 0) (match_dup 2))]
17448 ;; Don't compare memory with zero, load and use a test instead.
17450 [(set (match_operand 0 "flags_reg_operand" "")
17451 (match_operator 1 "compare_operator"
17452 [(match_operand:SI 2 "memory_operand" "")
17454 (match_scratch:SI 3 "r")]
17455 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17456 [(set (match_dup 3) (match_dup 2))
17457 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17460 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17461 ;; Don't split NOTs with a displacement operand, because resulting XOR
17462 ;; will not be pairable anyway.
17464 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17465 ;; represented using a modRM byte. The XOR replacement is long decoded,
17466 ;; so this split helps here as well.
17468 ;; Note: Can't do this as a regular split because we can't get proper
17469 ;; lifetime information then.
17472 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17473 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17474 "optimize_insn_for_speed_p ()
17475 && ((TARGET_NOT_UNPAIRABLE
17476 && (!MEM_P (operands[0])
17477 || !memory_displacement_operand (operands[0], SImode)))
17478 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
17479 && peep2_regno_dead_p (0, FLAGS_REG)"
17480 [(parallel [(set (match_dup 0)
17481 (xor:SI (match_dup 1) (const_int -1)))
17482 (clobber (reg:CC FLAGS_REG))])]
17486 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17487 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17488 "optimize_insn_for_speed_p ()
17489 && ((TARGET_NOT_UNPAIRABLE
17490 && (!MEM_P (operands[0])
17491 || !memory_displacement_operand (operands[0], HImode)))
17492 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
17493 && peep2_regno_dead_p (0, FLAGS_REG)"
17494 [(parallel [(set (match_dup 0)
17495 (xor:HI (match_dup 1) (const_int -1)))
17496 (clobber (reg:CC FLAGS_REG))])]
17500 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17501 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17502 "optimize_insn_for_speed_p ()
17503 && ((TARGET_NOT_UNPAIRABLE
17504 && (!MEM_P (operands[0])
17505 || !memory_displacement_operand (operands[0], QImode)))
17506 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
17507 && peep2_regno_dead_p (0, FLAGS_REG)"
17508 [(parallel [(set (match_dup 0)
17509 (xor:QI (match_dup 1) (const_int -1)))
17510 (clobber (reg:CC FLAGS_REG))])]
17513 ;; Non pairable "test imm, reg" instructions can be translated to
17514 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17515 ;; byte opcode instead of two, have a short form for byte operands),
17516 ;; so do it for other CPUs as well. Given that the value was dead,
17517 ;; this should not create any new dependencies. Pass on the sub-word
17518 ;; versions if we're concerned about partial register stalls.
17521 [(set (match_operand 0 "flags_reg_operand" "")
17522 (match_operator 1 "compare_operator"
17523 [(and:SI (match_operand:SI 2 "register_operand" "")
17524 (match_operand:SI 3 "immediate_operand" ""))
17526 "ix86_match_ccmode (insn, CCNOmode)
17527 && (true_regnum (operands[2]) != AX_REG
17528 || satisfies_constraint_K (operands[3]))
17529 && peep2_reg_dead_p (1, operands[2])"
17531 [(set (match_dup 0)
17532 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17535 (and:SI (match_dup 2) (match_dup 3)))])]
17538 ;; We don't need to handle HImode case, because it will be promoted to SImode
17539 ;; on ! TARGET_PARTIAL_REG_STALL
17542 [(set (match_operand 0 "flags_reg_operand" "")
17543 (match_operator 1 "compare_operator"
17544 [(and:QI (match_operand:QI 2 "register_operand" "")
17545 (match_operand:QI 3 "immediate_operand" ""))
17547 "! TARGET_PARTIAL_REG_STALL
17548 && ix86_match_ccmode (insn, CCNOmode)
17549 && true_regnum (operands[2]) != AX_REG
17550 && peep2_reg_dead_p (1, operands[2])"
17552 [(set (match_dup 0)
17553 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17556 (and:QI (match_dup 2) (match_dup 3)))])]
17560 [(set (match_operand 0 "flags_reg_operand" "")
17561 (match_operator 1 "compare_operator"
17564 (match_operand 2 "ext_register_operand" "")
17567 (match_operand 3 "const_int_operand" ""))
17569 "! TARGET_PARTIAL_REG_STALL
17570 && ix86_match_ccmode (insn, CCNOmode)
17571 && true_regnum (operands[2]) != AX_REG
17572 && peep2_reg_dead_p (1, operands[2])"
17573 [(parallel [(set (match_dup 0)
17582 (set (zero_extract:SI (match_dup 2)
17593 ;; Don't do logical operations with memory inputs.
17595 [(match_scratch:SI 2 "r")
17596 (parallel [(set (match_operand:SI 0 "register_operand" "")
17597 (match_operator:SI 3 "arith_or_logical_operator"
17599 (match_operand:SI 1 "memory_operand" "")]))
17600 (clobber (reg:CC FLAGS_REG))])]
17601 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17602 [(set (match_dup 2) (match_dup 1))
17603 (parallel [(set (match_dup 0)
17604 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17605 (clobber (reg:CC FLAGS_REG))])]
17609 [(match_scratch:SI 2 "r")
17610 (parallel [(set (match_operand:SI 0 "register_operand" "")
17611 (match_operator:SI 3 "arith_or_logical_operator"
17612 [(match_operand:SI 1 "memory_operand" "")
17614 (clobber (reg:CC FLAGS_REG))])]
17615 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17616 [(set (match_dup 2) (match_dup 1))
17617 (parallel [(set (match_dup 0)
17618 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17619 (clobber (reg:CC FLAGS_REG))])]
17622 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17623 ;; refers to the destination of the load!
17626 [(set (match_operand:SI 0 "register_operand" "")
17627 (match_operand:SI 1 "register_operand" ""))
17628 (parallel [(set (match_dup 0)
17629 (match_operator:SI 3 "commutative_operator"
17631 (match_operand:SI 2 "memory_operand" "")]))
17632 (clobber (reg:CC FLAGS_REG))])]
17633 "REGNO (operands[0]) != REGNO (operands[1])
17634 && GENERAL_REGNO_P (REGNO (operands[0]))
17635 && GENERAL_REGNO_P (REGNO (operands[1]))"
17636 [(set (match_dup 0) (match_dup 4))
17637 (parallel [(set (match_dup 0)
17638 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17639 (clobber (reg:CC FLAGS_REG))])]
17640 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17643 [(set (match_operand 0 "register_operand" "")
17644 (match_operand 1 "register_operand" ""))
17646 (match_operator 3 "commutative_operator"
17648 (match_operand 2 "memory_operand" "")]))]
17649 "REGNO (operands[0]) != REGNO (operands[1])
17650 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17651 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17652 [(set (match_dup 0) (match_dup 2))
17654 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17657 ; Don't do logical operations with memory outputs
17659 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17660 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17661 ; the same decoder scheduling characteristics as the original.
17664 [(match_scratch:SI 2 "r")
17665 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17666 (match_operator:SI 3 "arith_or_logical_operator"
17668 (match_operand:SI 1 "nonmemory_operand" "")]))
17669 (clobber (reg:CC FLAGS_REG))])]
17670 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17671 /* Do not split stack checking probes. */
17672 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17673 [(set (match_dup 2) (match_dup 0))
17674 (parallel [(set (match_dup 2)
17675 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17676 (clobber (reg:CC FLAGS_REG))])
17677 (set (match_dup 0) (match_dup 2))]
17681 [(match_scratch:SI 2 "r")
17682 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17683 (match_operator:SI 3 "arith_or_logical_operator"
17684 [(match_operand:SI 1 "nonmemory_operand" "")
17686 (clobber (reg:CC FLAGS_REG))])]
17687 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17688 /* Do not split stack checking probes. */
17689 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17690 [(set (match_dup 2) (match_dup 0))
17691 (parallel [(set (match_dup 2)
17692 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17693 (clobber (reg:CC FLAGS_REG))])
17694 (set (match_dup 0) (match_dup 2))]
17697 ;; Attempt to always use XOR for zeroing registers.
17699 [(set (match_operand 0 "register_operand" "")
17700 (match_operand 1 "const0_operand" ""))]
17701 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17702 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17703 && GENERAL_REG_P (operands[0])
17704 && peep2_regno_dead_p (0, FLAGS_REG)"
17705 [(parallel [(set (match_dup 0) (const_int 0))
17706 (clobber (reg:CC FLAGS_REG))])]
17708 operands[0] = gen_lowpart (word_mode, operands[0]);
17712 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17714 "(GET_MODE (operands[0]) == QImode
17715 || GET_MODE (operands[0]) == HImode)
17716 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17717 && peep2_regno_dead_p (0, FLAGS_REG)"
17718 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17719 (clobber (reg:CC FLAGS_REG))])])
17721 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17723 [(set (match_operand 0 "register_operand" "")
17725 "(GET_MODE (operands[0]) == HImode
17726 || GET_MODE (operands[0]) == SImode
17727 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17728 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17729 && peep2_regno_dead_p (0, FLAGS_REG)"
17730 [(parallel [(set (match_dup 0) (const_int -1))
17731 (clobber (reg:CC FLAGS_REG))])]
17732 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17735 ;; Attempt to convert simple leas to adds. These can be created by
17738 [(set (match_operand:SI 0 "register_operand" "")
17739 (plus:SI (match_dup 0)
17740 (match_operand:SI 1 "nonmemory_operand" "")))]
17741 "peep2_regno_dead_p (0, FLAGS_REG)"
17742 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17743 (clobber (reg:CC FLAGS_REG))])]
17747 [(set (match_operand:SI 0 "register_operand" "")
17748 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17749 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17750 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17751 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17752 (clobber (reg:CC FLAGS_REG))])]
17753 "operands[2] = gen_lowpart (SImode, operands[2]);")
17756 [(set (match_operand:DI 0 "register_operand" "")
17757 (plus:DI (match_dup 0)
17758 (match_operand:DI 1 "x86_64_general_operand" "")))]
17759 "peep2_regno_dead_p (0, FLAGS_REG)"
17760 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17761 (clobber (reg:CC FLAGS_REG))])]
17765 [(set (match_operand:SI 0 "register_operand" "")
17766 (mult:SI (match_dup 0)
17767 (match_operand:SI 1 "const_int_operand" "")))]
17768 "exact_log2 (INTVAL (operands[1])) >= 0
17769 && peep2_regno_dead_p (0, FLAGS_REG)"
17770 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17771 (clobber (reg:CC FLAGS_REG))])]
17772 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17775 [(set (match_operand:DI 0 "register_operand" "")
17776 (mult:DI (match_dup 0)
17777 (match_operand:DI 1 "const_int_operand" "")))]
17778 "exact_log2 (INTVAL (operands[1])) >= 0
17779 && peep2_regno_dead_p (0, FLAGS_REG)"
17780 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17781 (clobber (reg:CC FLAGS_REG))])]
17782 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17785 [(set (match_operand:SI 0 "register_operand" "")
17786 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17787 (match_operand:DI 2 "const_int_operand" "")) 0))]
17788 "exact_log2 (INTVAL (operands[2])) >= 0
17789 && REGNO (operands[0]) == REGNO (operands[1])
17790 && peep2_regno_dead_p (0, FLAGS_REG)"
17791 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17792 (clobber (reg:CC FLAGS_REG))])]
17793 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17795 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17796 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17797 ;; many CPUs it is also faster, since special hardware to avoid esp
17798 ;; dependencies is present.
17800 ;; While some of these conversions may be done using splitters, we use peepholes
17801 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17803 ;; Convert prologue esp subtractions to push.
17804 ;; We need register to push. In order to keep verify_flow_info happy we have
17806 ;; - use scratch and clobber it in order to avoid dependencies
17807 ;; - use already live register
17808 ;; We can't use the second way right now, since there is no reliable way how to
17809 ;; verify that given register is live. First choice will also most likely in
17810 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17811 ;; call clobbered registers are dead. We may want to use base pointer as an
17812 ;; alternative when no register is available later.
17815 [(match_scratch:SI 0 "r")
17816 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17817 (clobber (reg:CC FLAGS_REG))
17818 (clobber (mem:BLK (scratch)))])]
17819 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17820 [(clobber (match_dup 0))
17821 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17822 (clobber (mem:BLK (scratch)))])])
17825 [(match_scratch:SI 0 "r")
17826 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17827 (clobber (reg:CC FLAGS_REG))
17828 (clobber (mem:BLK (scratch)))])]
17829 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17830 [(clobber (match_dup 0))
17831 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17832 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17833 (clobber (mem:BLK (scratch)))])])
17835 ;; Convert esp subtractions to push.
17837 [(match_scratch:SI 0 "r")
17838 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17839 (clobber (reg:CC FLAGS_REG))])]
17840 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17841 [(clobber (match_dup 0))
17842 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17845 [(match_scratch:SI 0 "r")
17846 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17847 (clobber (reg:CC FLAGS_REG))])]
17848 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17849 [(clobber (match_dup 0))
17850 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17851 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17853 ;; Convert epilogue deallocator to pop.
17855 [(match_scratch:SI 0 "r")
17856 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17857 (clobber (reg:CC FLAGS_REG))
17858 (clobber (mem:BLK (scratch)))])]
17859 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17860 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17861 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17862 (clobber (mem:BLK (scratch)))])]
17865 ;; Two pops case is tricky, since pop causes dependency on destination register.
17866 ;; We use two registers if available.
17868 [(match_scratch:SI 0 "r")
17869 (match_scratch:SI 1 "r")
17870 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17871 (clobber (reg:CC FLAGS_REG))
17872 (clobber (mem:BLK (scratch)))])]
17873 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17874 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17875 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17876 (clobber (mem:BLK (scratch)))])
17877 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17878 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17882 [(match_scratch:SI 0 "r")
17883 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17884 (clobber (reg:CC FLAGS_REG))
17885 (clobber (mem:BLK (scratch)))])]
17886 "optimize_insn_for_size_p ()"
17887 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17888 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17889 (clobber (mem:BLK (scratch)))])
17890 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17891 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17894 ;; Convert esp additions to pop.
17896 [(match_scratch:SI 0 "r")
17897 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17898 (clobber (reg:CC FLAGS_REG))])]
17900 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17901 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17904 ;; Two pops case is tricky, since pop causes dependency on destination register.
17905 ;; We use two registers if available.
17907 [(match_scratch:SI 0 "r")
17908 (match_scratch:SI 1 "r")
17909 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17910 (clobber (reg:CC FLAGS_REG))])]
17912 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17913 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17914 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17915 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17919 [(match_scratch:SI 0 "r")
17920 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17921 (clobber (reg:CC FLAGS_REG))])]
17922 "optimize_insn_for_size_p ()"
17923 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17924 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17925 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17926 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17929 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17930 ;; required and register dies. Similarly for 128 to -128.
17932 [(set (match_operand 0 "flags_reg_operand" "")
17933 (match_operator 1 "compare_operator"
17934 [(match_operand 2 "register_operand" "")
17935 (match_operand 3 "const_int_operand" "")]))]
17936 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17937 && incdec_operand (operands[3], GET_MODE (operands[3])))
17938 || (!TARGET_FUSE_CMP_AND_BRANCH
17939 && INTVAL (operands[3]) == 128))
17940 && ix86_match_ccmode (insn, CCGCmode)
17941 && peep2_reg_dead_p (1, operands[2])"
17942 [(parallel [(set (match_dup 0)
17943 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17944 (clobber (match_dup 2))])]
17948 [(match_scratch:DI 0 "r")
17949 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17950 (clobber (reg:CC FLAGS_REG))
17951 (clobber (mem:BLK (scratch)))])]
17952 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17953 [(clobber (match_dup 0))
17954 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17955 (clobber (mem:BLK (scratch)))])])
17958 [(match_scratch:DI 0 "r")
17959 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17960 (clobber (reg:CC FLAGS_REG))
17961 (clobber (mem:BLK (scratch)))])]
17962 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17963 [(clobber (match_dup 0))
17964 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17965 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17966 (clobber (mem:BLK (scratch)))])])
17968 ;; Convert esp subtractions to push.
17970 [(match_scratch:DI 0 "r")
17971 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17972 (clobber (reg:CC FLAGS_REG))])]
17973 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17974 [(clobber (match_dup 0))
17975 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17978 [(match_scratch:DI 0 "r")
17979 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17980 (clobber (reg:CC FLAGS_REG))])]
17981 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17982 [(clobber (match_dup 0))
17983 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17984 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17986 ;; Convert epilogue deallocator to pop.
17988 [(match_scratch:DI 0 "r")
17989 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17990 (clobber (reg:CC FLAGS_REG))
17991 (clobber (mem:BLK (scratch)))])]
17992 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17993 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17994 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17995 (clobber (mem:BLK (scratch)))])]
17998 ;; Two pops case is tricky, since pop causes dependency on destination register.
17999 ;; We use two registers if available.
18001 [(match_scratch:DI 0 "r")
18002 (match_scratch:DI 1 "r")
18003 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18004 (clobber (reg:CC FLAGS_REG))
18005 (clobber (mem:BLK (scratch)))])]
18006 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
18007 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18008 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18009 (clobber (mem:BLK (scratch)))])
18010 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18011 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18015 [(match_scratch:DI 0 "r")
18016 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18017 (clobber (reg:CC FLAGS_REG))
18018 (clobber (mem:BLK (scratch)))])]
18019 "optimize_insn_for_size_p ()"
18020 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18021 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18022 (clobber (mem:BLK (scratch)))])
18023 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18024 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18027 ;; Convert esp additions to pop.
18029 [(match_scratch:DI 0 "r")
18030 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18031 (clobber (reg:CC FLAGS_REG))])]
18033 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18034 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18037 ;; Two pops case is tricky, since pop causes dependency on destination register.
18038 ;; We use two registers if available.
18040 [(match_scratch:DI 0 "r")
18041 (match_scratch:DI 1 "r")
18042 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18043 (clobber (reg:CC FLAGS_REG))])]
18045 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18046 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18047 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18048 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18052 [(match_scratch:DI 0 "r")
18053 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18054 (clobber (reg:CC FLAGS_REG))])]
18055 "optimize_insn_for_size_p ()"
18056 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18057 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18058 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18059 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18062 ;; Convert imul by three, five and nine into lea
18065 [(set (match_operand:SI 0 "register_operand" "")
18066 (mult:SI (match_operand:SI 1 "register_operand" "")
18067 (match_operand:SI 2 "const_int_operand" "")))
18068 (clobber (reg:CC FLAGS_REG))])]
18069 "INTVAL (operands[2]) == 3
18070 || INTVAL (operands[2]) == 5
18071 || INTVAL (operands[2]) == 9"
18072 [(set (match_dup 0)
18073 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
18075 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18079 [(set (match_operand:SI 0 "register_operand" "")
18080 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18081 (match_operand:SI 2 "const_int_operand" "")))
18082 (clobber (reg:CC FLAGS_REG))])]
18083 "optimize_insn_for_speed_p ()
18084 && (INTVAL (operands[2]) == 3
18085 || INTVAL (operands[2]) == 5
18086 || INTVAL (operands[2]) == 9)"
18087 [(set (match_dup 0) (match_dup 1))
18089 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
18091 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18095 [(set (match_operand:DI 0 "register_operand" "")
18096 (mult:DI (match_operand:DI 1 "register_operand" "")
18097 (match_operand:DI 2 "const_int_operand" "")))
18098 (clobber (reg:CC FLAGS_REG))])]
18100 && (INTVAL (operands[2]) == 3
18101 || INTVAL (operands[2]) == 5
18102 || INTVAL (operands[2]) == 9)"
18103 [(set (match_dup 0)
18104 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
18106 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18110 [(set (match_operand:DI 0 "register_operand" "")
18111 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18112 (match_operand:DI 2 "const_int_operand" "")))
18113 (clobber (reg:CC FLAGS_REG))])]
18115 && optimize_insn_for_speed_p ()
18116 && (INTVAL (operands[2]) == 3
18117 || INTVAL (operands[2]) == 5
18118 || INTVAL (operands[2]) == 9)"
18119 [(set (match_dup 0) (match_dup 1))
18121 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18123 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18125 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18126 ;; imul $32bit_imm, reg, reg is direct decoded.
18128 [(match_scratch:DI 3 "r")
18129 (parallel [(set (match_operand:DI 0 "register_operand" "")
18130 (mult:DI (match_operand:DI 1 "memory_operand" "")
18131 (match_operand:DI 2 "immediate_operand" "")))
18132 (clobber (reg:CC FLAGS_REG))])]
18133 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18134 && !satisfies_constraint_K (operands[2])"
18135 [(set (match_dup 3) (match_dup 1))
18136 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18137 (clobber (reg:CC FLAGS_REG))])]
18141 [(match_scratch:SI 3 "r")
18142 (parallel [(set (match_operand:SI 0 "register_operand" "")
18143 (mult:SI (match_operand:SI 1 "memory_operand" "")
18144 (match_operand:SI 2 "immediate_operand" "")))
18145 (clobber (reg:CC FLAGS_REG))])]
18146 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18147 && !satisfies_constraint_K (operands[2])"
18148 [(set (match_dup 3) (match_dup 1))
18149 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18150 (clobber (reg:CC FLAGS_REG))])]
18154 [(match_scratch:SI 3 "r")
18155 (parallel [(set (match_operand:DI 0 "register_operand" "")
18157 (mult:SI (match_operand:SI 1 "memory_operand" "")
18158 (match_operand:SI 2 "immediate_operand" ""))))
18159 (clobber (reg:CC FLAGS_REG))])]
18160 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18161 && !satisfies_constraint_K (operands[2])"
18162 [(set (match_dup 3) (match_dup 1))
18163 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18164 (clobber (reg:CC FLAGS_REG))])]
18167 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18168 ;; Convert it into imul reg, reg
18169 ;; It would be better to force assembler to encode instruction using long
18170 ;; immediate, but there is apparently no way to do so.
18172 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18173 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18174 (match_operand:DI 2 "const_int_operand" "")))
18175 (clobber (reg:CC FLAGS_REG))])
18176 (match_scratch:DI 3 "r")]
18177 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18178 && satisfies_constraint_K (operands[2])"
18179 [(set (match_dup 3) (match_dup 2))
18180 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18181 (clobber (reg:CC FLAGS_REG))])]
18183 if (!rtx_equal_p (operands[0], operands[1]))
18184 emit_move_insn (operands[0], operands[1]);
18188 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18189 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18190 (match_operand:SI 2 "const_int_operand" "")))
18191 (clobber (reg:CC FLAGS_REG))])
18192 (match_scratch:SI 3 "r")]
18193 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18194 && satisfies_constraint_K (operands[2])"
18195 [(set (match_dup 3) (match_dup 2))
18196 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18197 (clobber (reg:CC FLAGS_REG))])]
18199 if (!rtx_equal_p (operands[0], operands[1]))
18200 emit_move_insn (operands[0], operands[1]);
18204 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18205 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18206 (match_operand:HI 2 "immediate_operand" "")))
18207 (clobber (reg:CC FLAGS_REG))])
18208 (match_scratch:HI 3 "r")]
18209 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
18210 [(set (match_dup 3) (match_dup 2))
18211 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18212 (clobber (reg:CC FLAGS_REG))])]
18214 if (!rtx_equal_p (operands[0], operands[1]))
18215 emit_move_insn (operands[0], operands[1]);
18218 ;; After splitting up read-modify operations, array accesses with memory
18219 ;; operands might end up in form:
18221 ;; movl 4(%esp), %edx
18223 ;; instead of pre-splitting:
18225 ;; addl 4(%esp), %eax
18227 ;; movl 4(%esp), %edx
18228 ;; leal (%edx,%eax,4), %eax
18231 [(parallel [(set (match_operand 0 "register_operand" "")
18232 (ashift (match_operand 1 "register_operand" "")
18233 (match_operand 2 "const_int_operand" "")))
18234 (clobber (reg:CC FLAGS_REG))])
18235 (set (match_operand 3 "register_operand")
18236 (match_operand 4 "x86_64_general_operand" ""))
18237 (parallel [(set (match_operand 5 "register_operand" "")
18238 (plus (match_operand 6 "register_operand" "")
18239 (match_operand 7 "register_operand" "")))
18240 (clobber (reg:CC FLAGS_REG))])]
18241 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
18242 /* Validate MODE for lea. */
18243 && ((!TARGET_PARTIAL_REG_STALL
18244 && (GET_MODE (operands[0]) == QImode
18245 || GET_MODE (operands[0]) == HImode))
18246 || GET_MODE (operands[0]) == SImode
18247 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18248 /* We reorder load and the shift. */
18249 && !rtx_equal_p (operands[1], operands[3])
18250 && !reg_overlap_mentioned_p (operands[0], operands[4])
18251 /* Last PLUS must consist of operand 0 and 3. */
18252 && !rtx_equal_p (operands[0], operands[3])
18253 && (rtx_equal_p (operands[3], operands[6])
18254 || rtx_equal_p (operands[3], operands[7]))
18255 && (rtx_equal_p (operands[0], operands[6])
18256 || rtx_equal_p (operands[0], operands[7]))
18257 /* The intermediate operand 0 must die or be same as output. */
18258 && (rtx_equal_p (operands[0], operands[5])
18259 || peep2_reg_dead_p (3, operands[0]))"
18260 [(set (match_dup 3) (match_dup 4))
18261 (set (match_dup 0) (match_dup 1))]
18263 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
18264 int scale = 1 << INTVAL (operands[2]);
18265 rtx index = gen_lowpart (Pmode, operands[1]);
18266 rtx base = gen_lowpart (Pmode, operands[3]);
18267 rtx dest = gen_lowpart (mode, operands[5]);
18269 operands[1] = gen_rtx_PLUS (Pmode, base,
18270 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
18272 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18273 operands[0] = dest;
18276 ;; Call-value patterns last so that the wildcard operand does not
18277 ;; disrupt insn-recog's switch tables.
18279 (define_insn "*call_value_pop_0"
18280 [(set (match_operand 0 "" "")
18281 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18282 (match_operand:SI 2 "" "")))
18283 (set (reg:SI SP_REG)
18284 (plus:SI (reg:SI SP_REG)
18285 (match_operand:SI 3 "immediate_operand" "")))]
18288 if (SIBLING_CALL_P (insn))
18291 return "call\t%P1";
18293 [(set_attr "type" "callv")])
18295 (define_insn "*call_value_pop_1"
18296 [(set (match_operand 0 "" "")
18297 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18298 (match_operand:SI 2 "" "")))
18299 (set (reg:SI SP_REG)
18300 (plus:SI (reg:SI SP_REG)
18301 (match_operand:SI 3 "immediate_operand" "i")))]
18302 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18304 if (constant_call_address_operand (operands[1], Pmode))
18305 return "call\t%P1";
18306 return "call\t%A1";
18308 [(set_attr "type" "callv")])
18310 (define_insn "*sibcall_value_pop_1"
18311 [(set (match_operand 0 "" "")
18312 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18313 (match_operand:SI 2 "" "")))
18314 (set (reg:SI SP_REG)
18315 (plus:SI (reg:SI SP_REG)
18316 (match_operand:SI 3 "immediate_operand" "i,i")))]
18317 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18321 [(set_attr "type" "callv")])
18323 (define_insn "*call_value_0"
18324 [(set (match_operand 0 "" "")
18325 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18326 (match_operand:SI 2 "" "")))]
18329 if (SIBLING_CALL_P (insn))
18332 return "call\t%P1";
18334 [(set_attr "type" "callv")])
18336 (define_insn "*call_value_0_rex64"
18337 [(set (match_operand 0 "" "")
18338 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18339 (match_operand:DI 2 "const_int_operand" "")))]
18342 if (SIBLING_CALL_P (insn))
18345 return "call\t%P1";
18347 [(set_attr "type" "callv")])
18349 (define_insn "*call_value_0_rex64_ms_sysv"
18350 [(set (match_operand 0 "" "")
18351 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18352 (match_operand:DI 2 "const_int_operand" "")))
18353 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18354 (clobber (reg:TI XMM6_REG))
18355 (clobber (reg:TI XMM7_REG))
18356 (clobber (reg:TI XMM8_REG))
18357 (clobber (reg:TI XMM9_REG))
18358 (clobber (reg:TI XMM10_REG))
18359 (clobber (reg:TI XMM11_REG))
18360 (clobber (reg:TI XMM12_REG))
18361 (clobber (reg:TI XMM13_REG))
18362 (clobber (reg:TI XMM14_REG))
18363 (clobber (reg:TI XMM15_REG))
18364 (clobber (reg:DI SI_REG))
18365 (clobber (reg:DI DI_REG))]
18366 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18368 if (SIBLING_CALL_P (insn))
18371 return "call\t%P1";
18373 [(set_attr "type" "callv")])
18375 (define_insn "*call_value_1"
18376 [(set (match_operand 0 "" "")
18377 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18378 (match_operand:SI 2 "" "")))]
18379 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18381 if (constant_call_address_operand (operands[1], Pmode))
18382 return "call\t%P1";
18383 return "call\t%A1";
18385 [(set_attr "type" "callv")])
18387 (define_insn "*sibcall_value_1"
18388 [(set (match_operand 0 "" "")
18389 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18390 (match_operand:SI 2 "" "")))]
18391 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18395 [(set_attr "type" "callv")])
18397 (define_insn "*call_value_1_rex64"
18398 [(set (match_operand 0 "" "")
18399 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18400 (match_operand:DI 2 "" "")))]
18401 "TARGET_64BIT && !SIBLING_CALL_P (insn)
18402 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
18404 if (constant_call_address_operand (operands[1], Pmode))
18405 return "call\t%P1";
18406 return "call\t%A1";
18408 [(set_attr "type" "callv")])
18410 (define_insn "*call_value_1_rex64_ms_sysv"
18411 [(set (match_operand 0 "" "")
18412 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18413 (match_operand:DI 2 "" "")))
18414 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18415 (clobber (reg:TI XMM6_REG))
18416 (clobber (reg:TI XMM7_REG))
18417 (clobber (reg:TI XMM8_REG))
18418 (clobber (reg:TI XMM9_REG))
18419 (clobber (reg:TI XMM10_REG))
18420 (clobber (reg:TI XMM11_REG))
18421 (clobber (reg:TI XMM12_REG))
18422 (clobber (reg:TI XMM13_REG))
18423 (clobber (reg:TI XMM14_REG))
18424 (clobber (reg:TI XMM15_REG))
18425 (clobber (reg:DI SI_REG))
18426 (clobber (reg:DI DI_REG))]
18427 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18429 if (constant_call_address_operand (operands[1], Pmode))
18430 return "call\t%P1";
18431 return "call\t%A1";
18433 [(set_attr "type" "callv")])
18435 (define_insn "*call_value_1_rex64_large"
18436 [(set (match_operand 0 "" "")
18437 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
18438 (match_operand:DI 2 "" "")))]
18439 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18441 [(set_attr "type" "callv")])
18443 (define_insn "*sibcall_value_1_rex64"
18444 [(set (match_operand 0 "" "")
18445 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
18446 (match_operand:DI 2 "" "")))]
18447 "TARGET_64BIT && SIBLING_CALL_P (insn)"
18451 [(set_attr "type" "callv")])
18453 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18454 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18455 ;; caught for use by garbage collectors and the like. Using an insn that
18456 ;; maps to SIGILL makes it more likely the program will rightfully die.
18457 ;; Keeping with tradition, "6" is in honor of #UD.
18458 (define_insn "trap"
18459 [(trap_if (const_int 1) (const_int 6))]
18461 { return ASM_SHORT "0x0b0f"; }
18462 [(set_attr "length" "2")])
18464 (define_expand "sse_prologue_save"
18465 [(parallel [(set (match_operand:BLK 0 "" "")
18466 (unspec:BLK [(reg:DI XMM0_REG)
18473 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18474 (use (match_operand:DI 1 "register_operand" ""))
18475 (use (match_operand:DI 2 "immediate_operand" ""))
18476 (use (label_ref:DI (match_operand 3 "" "")))])]
18480 (define_insn "*sse_prologue_save_insn"
18481 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18482 (match_operand:DI 4 "const_int_operand" "n")))
18483 (unspec:BLK [(reg:DI XMM0_REG)
18490 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18491 (use (match_operand:DI 1 "register_operand" "r"))
18492 (use (match_operand:DI 2 "const_int_operand" "i"))
18493 (use (label_ref:DI (match_operand 3 "" "X")))]
18495 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18496 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
18499 operands[0] = gen_rtx_MEM (Pmode,
18500 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
18501 /* VEX instruction with a REX prefix will #UD. */
18502 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
18503 gcc_unreachable ();
18505 output_asm_insn ("jmp\t%A1", operands);
18506 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
18508 operands[4] = adjust_address (operands[0], DImode, i*16);
18509 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
18510 PUT_MODE (operands[4], TImode);
18511 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
18512 output_asm_insn ("rex", operands);
18513 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
18515 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18516 CODE_LABEL_NUMBER (operands[3]));
18519 [(set_attr "type" "other")
18520 (set_attr "length_immediate" "0")
18521 (set_attr "length_address" "0")
18522 (set (attr "length")
18524 (eq (symbol_ref "TARGET_AVX") (const_int 0))
18525 (const_string "34")
18526 (const_string "42")))
18527 (set_attr "memory" "store")
18528 (set_attr "modrm" "0")
18529 (set_attr "prefix" "maybe_vex")
18530 (set_attr "mode" "DI")])
18532 (define_expand "prefetch"
18533 [(prefetch (match_operand 0 "address_operand" "")
18534 (match_operand:SI 1 "const_int_operand" "")
18535 (match_operand:SI 2 "const_int_operand" ""))]
18536 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
18538 int rw = INTVAL (operands[1]);
18539 int locality = INTVAL (operands[2]);
18541 gcc_assert (rw == 0 || rw == 1);
18542 gcc_assert (locality >= 0 && locality <= 3);
18543 gcc_assert (GET_MODE (operands[0]) == Pmode
18544 || GET_MODE (operands[0]) == VOIDmode);
18546 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18547 supported by SSE counterpart or the SSE prefetch is not available
18548 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18550 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
18551 operands[2] = GEN_INT (3);
18553 operands[1] = const0_rtx;
18556 (define_insn "*prefetch_sse"
18557 [(prefetch (match_operand:SI 0 "address_operand" "p")
18559 (match_operand:SI 1 "const_int_operand" ""))]
18560 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
18562 static const char * const patterns[4] = {
18563 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18566 int locality = INTVAL (operands[1]);
18567 gcc_assert (locality >= 0 && locality <= 3);
18569 return patterns[locality];
18571 [(set_attr "type" "sse")
18572 (set_attr "atom_sse_attr" "prefetch")
18573 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18574 (set_attr "memory" "none")])
18576 (define_insn "*prefetch_sse_rex"
18577 [(prefetch (match_operand:DI 0 "address_operand" "p")
18579 (match_operand:SI 1 "const_int_operand" ""))]
18580 "TARGET_PREFETCH_SSE && TARGET_64BIT"
18582 static const char * const patterns[4] = {
18583 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18586 int locality = INTVAL (operands[1]);
18587 gcc_assert (locality >= 0 && locality <= 3);
18589 return patterns[locality];
18591 [(set_attr "type" "sse")
18592 (set_attr "atom_sse_attr" "prefetch")
18593 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18594 (set_attr "memory" "none")])
18596 (define_insn "*prefetch_3dnow"
18597 [(prefetch (match_operand:SI 0 "address_operand" "p")
18598 (match_operand:SI 1 "const_int_operand" "n")
18600 "TARGET_3DNOW && !TARGET_64BIT"
18602 if (INTVAL (operands[1]) == 0)
18603 return "prefetch\t%a0";
18605 return "prefetchw\t%a0";
18607 [(set_attr "type" "mmx")
18608 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18609 (set_attr "memory" "none")])
18611 (define_insn "*prefetch_3dnow_rex"
18612 [(prefetch (match_operand:DI 0 "address_operand" "p")
18613 (match_operand:SI 1 "const_int_operand" "n")
18615 "TARGET_3DNOW && TARGET_64BIT"
18617 if (INTVAL (operands[1]) == 0)
18618 return "prefetch\t%a0";
18620 return "prefetchw\t%a0";
18622 [(set_attr "type" "mmx")
18623 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18624 (set_attr "memory" "none")])
18626 (define_expand "stack_protect_set"
18627 [(match_operand 0 "memory_operand" "")
18628 (match_operand 1 "memory_operand" "")]
18631 #ifdef TARGET_THREAD_SSP_OFFSET
18633 emit_insn (gen_stack_tls_protect_set_di (operands[0],
18634 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18636 emit_insn (gen_stack_tls_protect_set_si (operands[0],
18637 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18640 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18642 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18647 (define_insn "stack_protect_set_si"
18648 [(set (match_operand:SI 0 "memory_operand" "=m")
18649 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18650 (set (match_scratch:SI 2 "=&r") (const_int 0))
18651 (clobber (reg:CC FLAGS_REG))]
18653 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18654 [(set_attr "type" "multi")])
18656 (define_insn "stack_protect_set_di"
18657 [(set (match_operand:DI 0 "memory_operand" "=m")
18658 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18659 (set (match_scratch:DI 2 "=&r") (const_int 0))
18660 (clobber (reg:CC FLAGS_REG))]
18662 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18663 [(set_attr "type" "multi")])
18665 (define_insn "stack_tls_protect_set_si"
18666 [(set (match_operand:SI 0 "memory_operand" "=m")
18667 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18668 (set (match_scratch:SI 2 "=&r") (const_int 0))
18669 (clobber (reg:CC FLAGS_REG))]
18671 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18672 [(set_attr "type" "multi")])
18674 (define_insn "stack_tls_protect_set_di"
18675 [(set (match_operand:DI 0 "memory_operand" "=m")
18676 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18677 (set (match_scratch:DI 2 "=&r") (const_int 0))
18678 (clobber (reg:CC FLAGS_REG))]
18681 /* The kernel uses a different segment register for performance reasons; a
18682 system call would not have to trash the userspace segment register,
18683 which would be expensive */
18684 if (ix86_cmodel != CM_KERNEL)
18685 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18687 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18689 [(set_attr "type" "multi")])
18691 (define_expand "stack_protect_test"
18692 [(match_operand 0 "memory_operand" "")
18693 (match_operand 1 "memory_operand" "")
18694 (match_operand 2 "" "")]
18697 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18699 #ifdef TARGET_THREAD_SSP_OFFSET
18701 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18702 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18704 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18705 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18708 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18710 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18713 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18714 flags, const0_rtx, operands[2]));
18718 (define_insn "stack_protect_test_si"
18719 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18720 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18721 (match_operand:SI 2 "memory_operand" "m")]
18723 (clobber (match_scratch:SI 3 "=&r"))]
18725 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18726 [(set_attr "type" "multi")])
18728 (define_insn "stack_protect_test_di"
18729 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18730 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18731 (match_operand:DI 2 "memory_operand" "m")]
18733 (clobber (match_scratch:DI 3 "=&r"))]
18735 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18736 [(set_attr "type" "multi")])
18738 (define_insn "stack_tls_protect_test_si"
18739 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18740 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18741 (match_operand:SI 2 "const_int_operand" "i")]
18742 UNSPEC_SP_TLS_TEST))
18743 (clobber (match_scratch:SI 3 "=r"))]
18745 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18746 [(set_attr "type" "multi")])
18748 (define_insn "stack_tls_protect_test_di"
18749 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18750 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18751 (match_operand:DI 2 "const_int_operand" "i")]
18752 UNSPEC_SP_TLS_TEST))
18753 (clobber (match_scratch:DI 3 "=r"))]
18756 /* The kernel uses a different segment register for performance reasons; a
18757 system call would not have to trash the userspace segment register,
18758 which would be expensive */
18759 if (ix86_cmodel != CM_KERNEL)
18760 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18762 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18764 [(set_attr "type" "multi")])
18766 (define_insn "sse4_2_crc32<mode>"
18767 [(set (match_operand:SI 0 "register_operand" "=r")
18769 [(match_operand:SI 1 "register_operand" "0")
18770 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18772 "TARGET_SSE4_2 || TARGET_CRC32"
18773 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18774 [(set_attr "type" "sselog1")
18775 (set_attr "prefix_rep" "1")
18776 (set_attr "prefix_extra" "1")
18777 (set (attr "prefix_data16")
18778 (if_then_else (match_operand:HI 2 "" "")
18780 (const_string "*")))
18781 (set (attr "prefix_rex")
18782 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18784 (const_string "*")))
18785 (set_attr "mode" "SI")])
18787 (define_insn "sse4_2_crc32di"
18788 [(set (match_operand:DI 0 "register_operand" "=r")
18790 [(match_operand:DI 1 "register_operand" "0")
18791 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18793 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18794 "crc32{q}\t{%2, %0|%0, %2}"
18795 [(set_attr "type" "sselog1")
18796 (set_attr "prefix_rep" "1")
18797 (set_attr "prefix_extra" "1")
18798 (set_attr "mode" "DI")])
18800 (define_expand "rdpmc"
18801 [(match_operand:DI 0 "register_operand" "")
18802 (match_operand:SI 1 "register_operand" "")]
18805 rtx reg = gen_reg_rtx (DImode);
18808 /* Force operand 1 into ECX. */
18809 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18810 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18811 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18816 rtvec vec = rtvec_alloc (2);
18817 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18818 rtx upper = gen_reg_rtx (DImode);
18819 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18820 gen_rtvec (1, const0_rtx),
18822 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18823 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18825 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18826 NULL, 1, OPTAB_DIRECT);
18827 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18831 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18832 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18836 (define_insn "*rdpmc"
18837 [(set (match_operand:DI 0 "register_operand" "=A")
18838 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18842 [(set_attr "type" "other")
18843 (set_attr "length" "2")])
18845 (define_insn "*rdpmc_rex64"
18846 [(set (match_operand:DI 0 "register_operand" "=a")
18847 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18849 (set (match_operand:DI 1 "register_operand" "=d")
18850 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18853 [(set_attr "type" "other")
18854 (set_attr "length" "2")])
18856 (define_expand "rdtsc"
18857 [(set (match_operand:DI 0 "register_operand" "")
18858 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18863 rtvec vec = rtvec_alloc (2);
18864 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18865 rtx upper = gen_reg_rtx (DImode);
18866 rtx lower = gen_reg_rtx (DImode);
18867 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18868 gen_rtvec (1, const0_rtx),
18870 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18871 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18873 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18874 NULL, 1, OPTAB_DIRECT);
18875 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18877 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18882 (define_insn "*rdtsc"
18883 [(set (match_operand:DI 0 "register_operand" "=A")
18884 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18887 [(set_attr "type" "other")
18888 (set_attr "length" "2")])
18890 (define_insn "*rdtsc_rex64"
18891 [(set (match_operand:DI 0 "register_operand" "=a")
18892 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18893 (set (match_operand:DI 1 "register_operand" "=d")
18894 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18897 [(set_attr "type" "other")
18898 (set_attr "length" "2")])
18900 (define_expand "rdtscp"
18901 [(match_operand:DI 0 "register_operand" "")
18902 (match_operand:SI 1 "memory_operand" "")]
18905 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18906 gen_rtvec (1, const0_rtx),
18908 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18909 gen_rtvec (1, const0_rtx),
18911 rtx reg = gen_reg_rtx (DImode);
18912 rtx tmp = gen_reg_rtx (SImode);
18916 rtvec vec = rtvec_alloc (3);
18917 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18918 rtx upper = gen_reg_rtx (DImode);
18919 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18920 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18921 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18923 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18924 NULL, 1, OPTAB_DIRECT);
18925 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18930 rtvec vec = rtvec_alloc (2);
18931 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18932 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18933 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18936 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18937 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18941 (define_insn "*rdtscp"
18942 [(set (match_operand:DI 0 "register_operand" "=A")
18943 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18944 (set (match_operand:SI 1 "register_operand" "=c")
18945 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18948 [(set_attr "type" "other")
18949 (set_attr "length" "3")])
18951 (define_insn "*rdtscp_rex64"
18952 [(set (match_operand:DI 0 "register_operand" "=a")
18953 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18954 (set (match_operand:DI 1 "register_operand" "=d")
18955 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18956 (set (match_operand:SI 2 "register_operand" "=c")
18957 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18960 [(set_attr "type" "other")
18961 (set_attr "length" "3")])
18963 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18965 ;; LWP instructions
18967 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18969 (define_expand "lwp_llwpcb"
18970 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18971 UNSPECV_LLWP_INTRINSIC)]
18975 (define_insn "*lwp_llwpcb<mode>1"
18976 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18977 UNSPECV_LLWP_INTRINSIC)]
18980 [(set_attr "type" "lwp")
18981 (set_attr "mode" "<MODE>")
18982 (set_attr "length" "5")])
18984 (define_expand "lwp_slwpcb"
18985 [(set (match_operand 0 "register_operand" "=r")
18986 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18990 emit_insn (gen_lwp_slwpcbdi (operands[0]));
18992 emit_insn (gen_lwp_slwpcbsi (operands[0]));
18996 (define_insn "lwp_slwpcb<mode>"
18997 [(set (match_operand:P 0 "register_operand" "=r")
18998 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19001 [(set_attr "type" "lwp")
19002 (set_attr "mode" "<MODE>")
19003 (set_attr "length" "5")])
19005 (define_expand "lwp_lwpval<mode>3"
19006 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
19007 (match_operand:SI 2 "nonimmediate_operand" "rm")
19008 (match_operand:SI 3 "const_int_operand" "i")]
19009 UNSPECV_LWPVAL_INTRINSIC)]
19011 "/* Avoid unused variable warning. */
19014 (define_insn "*lwp_lwpval<mode>3_1"
19015 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19016 (match_operand:SI 1 "nonimmediate_operand" "rm")
19017 (match_operand:SI 2 "const_int_operand" "i")]
19018 UNSPECV_LWPVAL_INTRINSIC)]
19020 "lwpval\t{%2, %1, %0|%0, %1, %2}"
19021 [(set_attr "type" "lwp")
19022 (set_attr "mode" "<MODE>")
19023 (set (attr "length")
19024 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19026 (define_expand "lwp_lwpins<mode>3"
19027 [(set (reg:CCC FLAGS_REG)
19028 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
19029 (match_operand:SI 2 "nonimmediate_operand" "rm")
19030 (match_operand:SI 3 "const_int_operand" "i")]
19031 UNSPECV_LWPINS_INTRINSIC))
19032 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
19033 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19037 (define_insn "*lwp_lwpins<mode>3_1"
19038 [(set (reg:CCC FLAGS_REG)
19039 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19040 (match_operand:SI 1 "nonimmediate_operand" "rm")
19041 (match_operand:SI 2 "const_int_operand" "i")]
19042 UNSPECV_LWPINS_INTRINSIC))]
19044 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19045 [(set_attr "type" "lwp")
19046 (set_attr "mode" "<MODE>")
19047 (set (attr "length")
19048 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19052 (include "sync.md")