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)
88 (UNSPEC_SSE_PROLOGUE_SAVE_LOW 19)
93 (UNSPEC_TLS_LD_BASE 22)
96 ; Other random patterns
101 (UNSPEC_ADD_CARRY 34)
104 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
105 (UNSPEC_TRUNC_NOOP 39)
107 ; For SSE/MMX support:
108 (UNSPEC_FIX_NOTRUNC 40)
125 (UNSPEC_MS_TO_SYSV_CALL 48)
127 ; Generic math support
129 (UNSPEC_IEEE_MIN 51) ; not commutative
130 (UNSPEC_IEEE_MAX 52) ; not commutative
145 (UNSPEC_FRNDINT_FLOOR 70)
146 (UNSPEC_FRNDINT_CEIL 71)
147 (UNSPEC_FRNDINT_TRUNC 72)
148 (UNSPEC_FRNDINT_MASK_PM 73)
149 (UNSPEC_FIST_FLOOR 74)
150 (UNSPEC_FIST_CEIL 75)
152 ; x87 Double output FP
153 (UNSPEC_SINCOS_COS 80)
154 (UNSPEC_SINCOS_SIN 81)
155 (UNSPEC_XTRACT_FRACT 84)
156 (UNSPEC_XTRACT_EXP 85)
157 (UNSPEC_FSCALE_FRACT 86)
158 (UNSPEC_FSCALE_EXP 87)
170 (UNSPEC_SP_TLS_SET 102)
171 (UNSPEC_SP_TLS_TEST 103)
181 (UNSPEC_INSERTQI 132)
186 (UNSPEC_INSERTPS 135)
188 (UNSPEC_MOVNTDQA 137)
190 (UNSPEC_PHMINPOSUW 139)
196 (UNSPEC_PCMPESTR 144)
197 (UNSPEC_PCMPISTR 145)
200 (UNSPEC_FMA4_INTRINSIC 150)
201 (UNSPEC_FMA4_FMADDSUB 151)
202 (UNSPEC_FMA4_FMSUBADD 152)
203 (UNSPEC_XOP_UNSIGNED_CMP 151)
204 (UNSPEC_XOP_TRUEFALSE 152)
205 (UNSPEC_XOP_PERMUTE 153)
210 (UNSPEC_AESENCLAST 160)
212 (UNSPEC_AESDECLAST 162)
214 (UNSPEC_AESKEYGENASSIST 164)
222 (UNSPEC_VPERMIL2 168)
223 (UNSPEC_VPERMIL2F128 169)
224 (UNSPEC_MASKLOAD 170)
225 (UNSPEC_MASKSTORE 171)
231 [(UNSPECV_BLOCKAGE 0)
232 (UNSPECV_STACK_PROBE 1)
244 (UNSPECV_PROLOGUE_USE 14)
246 (UNSPECV_VZEROALL 16)
247 (UNSPECV_VZEROUPPER 17)
251 (UNSPECV_VSWAPMOV 21)
252 (UNSPECV_LLWP_INTRINSIC 22)
253 (UNSPECV_SLWP_INTRINSIC 23)
254 (UNSPECV_LWPVAL_INTRINSIC 24)
255 (UNSPECV_LWPINS_INTRINSIC 25)
258 ;; Constants to represent pcomtrue/pcomfalse variants
268 ;; Constants used in the XOP pperm instruction
270 [(PPERM_SRC 0x00) /* copy source */
271 (PPERM_INVERT 0x20) /* invert source */
272 (PPERM_REVERSE 0x40) /* bit reverse source */
273 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
274 (PPERM_ZERO 0x80) /* all 0's */
275 (PPERM_ONES 0xa0) /* all 1's */
276 (PPERM_SIGN 0xc0) /* propagate sign bit */
277 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
278 (PPERM_SRC1 0x00) /* use first source byte */
279 (PPERM_SRC2 0x10) /* use second source byte */
282 ;; Registers by name.
335 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
338 ;; In C guard expressions, put expressions which may be compile-time
339 ;; constants first. This allows for better optimization. For
340 ;; example, write "TARGET_64BIT && reload_completed", not
341 ;; "reload_completed && TARGET_64BIT".
345 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
347 (const (symbol_ref "ix86_schedule")))
349 ;; A basic instruction type. Refinements due to arguments to be
350 ;; provided in other attributes.
353 alu,alu1,negnot,imov,imovx,lea,
354 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
355 icmp,test,ibr,setcc,icmov,
356 push,pop,call,callv,leave,
358 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
359 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
360 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
361 ssemuladd,sse4arg,lwp,
362 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
363 (const_string "other"))
365 ;; Main data type used by the insn
367 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
368 (const_string "unknown"))
370 ;; The CPU unit operations uses.
371 (define_attr "unit" "integer,i387,sse,mmx,unknown"
372 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
373 (const_string "i387")
374 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
375 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
376 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
378 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
380 (eq_attr "type" "other")
381 (const_string "unknown")]
382 (const_string "integer")))
384 ;; The (bounding maximum) length of an instruction immediate.
385 (define_attr "length_immediate" ""
386 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
389 (eq_attr "unit" "i387,sse,mmx")
391 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
393 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
394 (eq_attr "type" "imov,test")
395 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
396 (eq_attr "type" "call")
397 (if_then_else (match_operand 0 "constant_call_address_operand" "")
400 (eq_attr "type" "callv")
401 (if_then_else (match_operand 1 "constant_call_address_operand" "")
404 ;; We don't know the size before shorten_branches. Expect
405 ;; the instruction to fit for better scheduling.
406 (eq_attr "type" "ibr")
409 (symbol_ref "/* Update immediate_length and other attributes! */
410 gcc_unreachable (),1")))
412 ;; The (bounding maximum) length of an instruction address.
413 (define_attr "length_address" ""
414 (cond [(eq_attr "type" "str,other,multi,fxch")
416 (and (eq_attr "type" "call")
417 (match_operand 0 "constant_call_address_operand" ""))
419 (and (eq_attr "type" "callv")
420 (match_operand 1 "constant_call_address_operand" ""))
423 (symbol_ref "ix86_attr_length_address_default (insn)")))
425 ;; Set when length prefix is used.
426 (define_attr "prefix_data16" ""
427 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
429 (eq_attr "mode" "HI")
431 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
436 ;; Set when string REP prefix is used.
437 (define_attr "prefix_rep" ""
438 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
440 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
445 ;; Set when 0f opcode prefix is used.
446 (define_attr "prefix_0f" ""
448 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
449 (eq_attr "unit" "sse,mmx"))
453 ;; Set when REX opcode prefix is used.
454 (define_attr "prefix_rex" ""
455 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
457 (and (eq_attr "mode" "DI")
458 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
459 (eq_attr "unit" "!mmx")))
461 (and (eq_attr "mode" "QI")
462 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
465 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
468 (and (eq_attr "type" "imovx")
469 (match_operand:QI 1 "ext_QIreg_operand" ""))
474 ;; There are also additional prefixes in 3DNOW, SSSE3.
475 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
476 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
477 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
478 (define_attr "prefix_extra" ""
479 (cond [(eq_attr "type" "ssemuladd,sse4arg")
481 (eq_attr "type" "sseiadd1,ssecvt1")
486 ;; Prefix used: original, VEX or maybe VEX.
487 (define_attr "prefix" "orig,vex,maybe_vex"
488 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
490 (const_string "orig")))
492 ;; VEX W bit is used.
493 (define_attr "prefix_vex_w" "" (const_int 0))
495 ;; The length of VEX prefix
496 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
497 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
498 ;; still prefix_0f 1, with prefix_extra 1.
499 (define_attr "length_vex" ""
500 (if_then_else (and (eq_attr "prefix_0f" "1")
501 (eq_attr "prefix_extra" "0"))
502 (if_then_else (eq_attr "prefix_vex_w" "1")
503 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
504 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
505 (if_then_else (eq_attr "prefix_vex_w" "1")
506 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
507 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
509 ;; Set when modrm byte is used.
510 (define_attr "modrm" ""
511 (cond [(eq_attr "type" "str,leave")
513 (eq_attr "unit" "i387")
515 (and (eq_attr "type" "incdec")
516 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
517 (ior (match_operand:SI 1 "register_operand" "")
518 (match_operand:HI 1 "register_operand" ""))))
520 (and (eq_attr "type" "push")
521 (not (match_operand 1 "memory_operand" "")))
523 (and (eq_attr "type" "pop")
524 (not (match_operand 0 "memory_operand" "")))
526 (and (eq_attr "type" "imov")
527 (and (not (eq_attr "mode" "DI"))
528 (ior (and (match_operand 0 "register_operand" "")
529 (match_operand 1 "immediate_operand" ""))
530 (ior (and (match_operand 0 "ax_reg_operand" "")
531 (match_operand 1 "memory_displacement_only_operand" ""))
532 (and (match_operand 0 "memory_displacement_only_operand" "")
533 (match_operand 1 "ax_reg_operand" ""))))))
535 (and (eq_attr "type" "call")
536 (match_operand 0 "constant_call_address_operand" ""))
538 (and (eq_attr "type" "callv")
539 (match_operand 1 "constant_call_address_operand" ""))
541 (and (eq_attr "type" "alu,alu1,icmp,test")
542 (match_operand 0 "ax_reg_operand" ""))
543 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
547 ;; The (bounding maximum) length of an instruction in bytes.
548 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
549 ;; Later we may want to split them and compute proper length as for
551 (define_attr "length" ""
552 (cond [(eq_attr "type" "other,multi,fistp,frndint")
554 (eq_attr "type" "fcmp")
556 (eq_attr "unit" "i387")
558 (plus (attr "prefix_data16")
559 (attr "length_address")))
560 (ior (eq_attr "prefix" "vex")
561 (and (eq_attr "prefix" "maybe_vex")
562 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
563 (plus (attr "length_vex")
564 (plus (attr "length_immediate")
566 (attr "length_address"))))]
567 (plus (plus (attr "modrm")
568 (plus (attr "prefix_0f")
569 (plus (attr "prefix_rex")
570 (plus (attr "prefix_extra")
572 (plus (attr "prefix_rep")
573 (plus (attr "prefix_data16")
574 (plus (attr "length_immediate")
575 (attr "length_address")))))))
577 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
578 ;; `store' if there is a simple memory reference therein, or `unknown'
579 ;; if the instruction is complex.
581 (define_attr "memory" "none,load,store,both,unknown"
582 (cond [(eq_attr "type" "other,multi,str,lwp")
583 (const_string "unknown")
584 (eq_attr "type" "lea,fcmov,fpspc")
585 (const_string "none")
586 (eq_attr "type" "fistp,leave")
587 (const_string "both")
588 (eq_attr "type" "frndint")
589 (const_string "load")
590 (eq_attr "type" "push")
591 (if_then_else (match_operand 1 "memory_operand" "")
592 (const_string "both")
593 (const_string "store"))
594 (eq_attr "type" "pop")
595 (if_then_else (match_operand 0 "memory_operand" "")
596 (const_string "both")
597 (const_string "load"))
598 (eq_attr "type" "setcc")
599 (if_then_else (match_operand 0 "memory_operand" "")
600 (const_string "store")
601 (const_string "none"))
602 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
603 (if_then_else (ior (match_operand 0 "memory_operand" "")
604 (match_operand 1 "memory_operand" ""))
605 (const_string "load")
606 (const_string "none"))
607 (eq_attr "type" "ibr")
608 (if_then_else (match_operand 0 "memory_operand" "")
609 (const_string "load")
610 (const_string "none"))
611 (eq_attr "type" "call")
612 (if_then_else (match_operand 0 "constant_call_address_operand" "")
613 (const_string "none")
614 (const_string "load"))
615 (eq_attr "type" "callv")
616 (if_then_else (match_operand 1 "constant_call_address_operand" "")
617 (const_string "none")
618 (const_string "load"))
619 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
620 (match_operand 1 "memory_operand" ""))
621 (const_string "both")
622 (and (match_operand 0 "memory_operand" "")
623 (match_operand 1 "memory_operand" ""))
624 (const_string "both")
625 (match_operand 0 "memory_operand" "")
626 (const_string "store")
627 (match_operand 1 "memory_operand" "")
628 (const_string "load")
630 "!alu1,negnot,ishift1,
631 imov,imovx,icmp,test,bitmanip,
633 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
634 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
635 (match_operand 2 "memory_operand" ""))
636 (const_string "load")
637 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
638 (match_operand 3 "memory_operand" ""))
639 (const_string "load")
641 (const_string "none")))
643 ;; Indicates if an instruction has both an immediate and a displacement.
645 (define_attr "imm_disp" "false,true,unknown"
646 (cond [(eq_attr "type" "other,multi")
647 (const_string "unknown")
648 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
649 (and (match_operand 0 "memory_displacement_operand" "")
650 (match_operand 1 "immediate_operand" "")))
651 (const_string "true")
652 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
653 (and (match_operand 0 "memory_displacement_operand" "")
654 (match_operand 2 "immediate_operand" "")))
655 (const_string "true")
657 (const_string "false")))
659 ;; Indicates if an FP operation has an integer source.
661 (define_attr "fp_int_src" "false,true"
662 (const_string "false"))
664 ;; Defines rounding mode of an FP operation.
666 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
667 (const_string "any"))
669 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
670 (define_attr "use_carry" "0,1" (const_string "0"))
672 ;; Define attribute to indicate unaligned ssemov insns
673 (define_attr "movu" "0,1" (const_string "0"))
675 ;; Describe a user's asm statement.
676 (define_asm_attributes
677 [(set_attr "length" "128")
678 (set_attr "type" "multi")])
680 ;; All integer comparison codes.
681 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
683 ;; All floating-point comparison codes.
684 (define_code_iterator fp_cond [unordered ordered
685 uneq unge ungt unle unlt ltgt])
687 (define_code_iterator plusminus [plus minus])
689 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
691 ;; Base name for define_insn
692 (define_code_attr plusminus_insn
693 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
694 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
696 ;; Base name for insn mnemonic.
697 (define_code_attr plusminus_mnemonic
698 [(plus "add") (ss_plus "adds") (us_plus "addus")
699 (minus "sub") (ss_minus "subs") (us_minus "subus")])
700 (define_code_attr plusminus_carry_mnemonic
701 [(plus "adc") (minus "sbb")])
703 ;; Mark commutative operators as such in constraints.
704 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
705 (minus "") (ss_minus "") (us_minus "")])
707 ;; Mapping of signed max and min
708 (define_code_iterator smaxmin [smax smin])
710 ;; Mapping of unsigned max and min
711 (define_code_iterator umaxmin [umax umin])
713 ;; Mapping of signed/unsigned max and min
714 (define_code_iterator maxmin [smax smin umax umin])
716 ;; Base name for integer and FP insn mnemonic
717 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
718 (umax "maxu") (umin "minu")])
719 (define_code_attr maxmin_float [(smax "max") (smin "min")])
721 ;; Mapping of logic operators
722 (define_code_iterator any_logic [and ior xor])
723 (define_code_iterator any_or [ior xor])
725 ;; Base name for insn mnemonic.
726 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
728 ;; Mapping of shift-right operators
729 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
731 ;; Base name for define_insn
732 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
734 ;; Base name for insn mnemonic.
735 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
737 ;; Mapping of rotate operators
738 (define_code_iterator any_rotate [rotate rotatert])
740 ;; Base name for define_insn
741 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
743 ;; Base name for insn mnemonic.
744 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
746 ;; Mapping of abs neg operators
747 (define_code_iterator absneg [abs neg])
749 ;; Base name for x87 insn mnemonic.
750 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
752 ;; Used in signed and unsigned widening multiplications.
753 (define_code_iterator any_extend [sign_extend zero_extend])
755 ;; Various insn prefixes for signed and unsigned operations.
756 (define_code_attr u [(sign_extend "") (zero_extend "u")
757 (div "") (udiv "u")])
758 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
760 ;; Used in signed and unsigned divisions.
761 (define_code_iterator any_div [div udiv])
763 ;; Instruction prefix for signed and unsigned operations.
764 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
765 (div "i") (udiv "")])
767 ;; All single word integer modes.
768 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
770 ;; Single word integer modes without DImode.
771 (define_mode_iterator SWI124 [QI HI SI])
773 ;; Single word integer modes without QImode.
774 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
776 ;; Single word integer modes without QImode and HImode.
777 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
779 ;; All math-dependant single and double word integer modes.
780 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
781 (HI "TARGET_HIMODE_MATH")
782 SI DI (TI "TARGET_64BIT")])
784 ;; Math-dependant single word integer modes.
785 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
786 (HI "TARGET_HIMODE_MATH")
787 SI (DI "TARGET_64BIT")])
789 ;; Math-dependant single word integer modes without DImode.
790 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
791 (HI "TARGET_HIMODE_MATH")
794 ;; Math-dependant single word integer modes without QImode.
795 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
796 SI (DI "TARGET_64BIT")])
798 ;; Double word integer modes.
799 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
800 (TI "TARGET_64BIT")])
802 ;; Double word integer modes as mode attribute.
803 (define_mode_attr DWI [(SI "DI") (DI "TI")])
804 (define_mode_attr dwi [(SI "di") (DI "ti")])
806 ;; Half mode for double word integer modes.
807 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
808 (DI "TARGET_64BIT")])
810 ;; Instruction suffix for integer modes.
811 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
813 ;; Register class for integer modes.
814 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
816 ;; Immediate operand constraint for integer modes.
817 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
819 ;; General operand constraint for word modes.
820 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
822 ;; Immediate operand constraint for double integer modes.
823 (define_mode_attr di [(SI "iF") (DI "e")])
825 ;; Immediate operand constraint for shifts.
826 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
828 ;; General operand predicate for integer modes.
829 (define_mode_attr general_operand
830 [(QI "general_operand")
831 (HI "general_operand")
832 (SI "general_operand")
833 (DI "x86_64_general_operand")
834 (TI "x86_64_general_operand")])
836 ;; General sign/zero extend operand predicate for integer modes.
837 (define_mode_attr general_szext_operand
838 [(QI "general_operand")
839 (HI "general_operand")
840 (SI "general_operand")
841 (DI "x86_64_szext_general_operand")])
843 ;; Operand predicate for shifts.
844 (define_mode_attr shift_operand
845 [(QI "nonimmediate_operand")
846 (HI "nonimmediate_operand")
847 (SI "nonimmediate_operand")
848 (DI "shiftdi_operand")
849 (TI "register_operand")])
851 ;; Operand predicate for shift argument.
852 (define_mode_attr shift_immediate_operand
853 [(QI "const_1_to_31_operand")
854 (HI "const_1_to_31_operand")
855 (SI "const_1_to_31_operand")
856 (DI "const_1_to_63_operand")])
858 ;; Input operand predicate for arithmetic left shifts.
859 (define_mode_attr ashl_input_operand
860 [(QI "nonimmediate_operand")
861 (HI "nonimmediate_operand")
862 (SI "nonimmediate_operand")
863 (DI "ashldi_input_operand")
864 (TI "reg_or_pm1_operand")])
866 ;; SSE and x87 SFmode and DFmode floating point modes
867 (define_mode_iterator MODEF [SF DF])
869 ;; All x87 floating point modes
870 (define_mode_iterator X87MODEF [SF DF XF])
872 ;; All integer modes handled by x87 fisttp operator.
873 (define_mode_iterator X87MODEI [HI SI DI])
875 ;; All integer modes handled by integer x87 operators.
876 (define_mode_iterator X87MODEI12 [HI SI])
878 ;; All integer modes handled by SSE cvtts?2si* operators.
879 (define_mode_iterator SSEMODEI24 [SI DI])
881 ;; SSE asm suffix for floating point modes
882 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
884 ;; SSE vector mode corresponding to a scalar mode
885 (define_mode_attr ssevecmode
886 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
888 ;; Instruction suffix for REX 64bit operators.
889 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
891 ;; This mode iterator allows :P to be used for patterns that operate on
892 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
893 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
895 ;; Scheduling descriptions
897 (include "pentium.md")
900 (include "athlon.md")
905 ;; Operand and operator predicates and constraints
907 (include "predicates.md")
908 (include "constraints.md")
911 ;; Compare and branch/compare and store instructions.
913 (define_expand "cbranch<mode>4"
914 [(set (reg:CC FLAGS_REG)
915 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
916 (match_operand:SDWIM 2 "<general_operand>" "")))
917 (set (pc) (if_then_else
918 (match_operator 0 "comparison_operator"
919 [(reg:CC FLAGS_REG) (const_int 0)])
920 (label_ref (match_operand 3 "" ""))
924 if (MEM_P (operands[1]) && MEM_P (operands[2]))
925 operands[1] = force_reg (<MODE>mode, operands[1]);
926 ix86_compare_op0 = operands[1];
927 ix86_compare_op1 = operands[2];
928 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
932 (define_expand "cstore<mode>4"
933 [(set (reg:CC FLAGS_REG)
934 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
935 (match_operand:SWIM 3 "<general_operand>" "")))
936 (set (match_operand:QI 0 "register_operand" "")
937 (match_operator 1 "comparison_operator"
938 [(reg:CC FLAGS_REG) (const_int 0)]))]
941 if (MEM_P (operands[2]) && MEM_P (operands[3]))
942 operands[2] = force_reg (<MODE>mode, operands[2]);
943 ix86_compare_op0 = operands[2];
944 ix86_compare_op1 = operands[3];
945 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
949 (define_expand "cmp<mode>_1"
950 [(set (reg:CC FLAGS_REG)
951 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
952 (match_operand:SWI48 1 "<general_operand>" "")))]
956 (define_insn "*cmp<mode>_ccno_1"
957 [(set (reg FLAGS_REG)
958 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
959 (match_operand:SWI 1 "const0_operand" "")))]
960 "ix86_match_ccmode (insn, CCNOmode)"
962 test{<imodesuffix>}\t%0, %0
963 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
964 [(set_attr "type" "test,icmp")
965 (set_attr "length_immediate" "0,1")
966 (set_attr "mode" "<MODE>")])
968 (define_insn "*cmp<mode>_1"
969 [(set (reg FLAGS_REG)
970 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
971 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
972 "ix86_match_ccmode (insn, CCmode)"
973 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
974 [(set_attr "type" "icmp")
975 (set_attr "mode" "<MODE>")])
977 (define_insn "*cmp<mode>_minus_1"
978 [(set (reg FLAGS_REG)
980 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
981 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
983 "ix86_match_ccmode (insn, CCGOCmode)"
984 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
985 [(set_attr "type" "icmp")
986 (set_attr "mode" "<MODE>")])
988 (define_insn "*cmpqi_ext_1"
989 [(set (reg FLAGS_REG)
991 (match_operand:QI 0 "general_operand" "Qm")
994 (match_operand 1 "ext_register_operand" "Q")
997 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
998 "cmp{b}\t{%h1, %0|%0, %h1}"
999 [(set_attr "type" "icmp")
1000 (set_attr "mode" "QI")])
1002 (define_insn "*cmpqi_ext_1_rex64"
1003 [(set (reg FLAGS_REG)
1005 (match_operand:QI 0 "register_operand" "Q")
1008 (match_operand 1 "ext_register_operand" "Q")
1010 (const_int 8)) 0)))]
1011 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1012 "cmp{b}\t{%h1, %0|%0, %h1}"
1013 [(set_attr "type" "icmp")
1014 (set_attr "mode" "QI")])
1016 (define_insn "*cmpqi_ext_2"
1017 [(set (reg FLAGS_REG)
1021 (match_operand 0 "ext_register_operand" "Q")
1024 (match_operand:QI 1 "const0_operand" "")))]
1025 "ix86_match_ccmode (insn, CCNOmode)"
1027 [(set_attr "type" "test")
1028 (set_attr "length_immediate" "0")
1029 (set_attr "mode" "QI")])
1031 (define_expand "cmpqi_ext_3"
1032 [(set (reg:CC FLAGS_REG)
1036 (match_operand 0 "ext_register_operand" "")
1039 (match_operand:QI 1 "immediate_operand" "")))]
1043 (define_insn "*cmpqi_ext_3_insn"
1044 [(set (reg FLAGS_REG)
1048 (match_operand 0 "ext_register_operand" "Q")
1051 (match_operand:QI 1 "general_operand" "Qmn")))]
1052 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1053 "cmp{b}\t{%1, %h0|%h0, %1}"
1054 [(set_attr "type" "icmp")
1055 (set_attr "modrm" "1")
1056 (set_attr "mode" "QI")])
1058 (define_insn "*cmpqi_ext_3_insn_rex64"
1059 [(set (reg FLAGS_REG)
1063 (match_operand 0 "ext_register_operand" "Q")
1066 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1067 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1068 "cmp{b}\t{%1, %h0|%h0, %1}"
1069 [(set_attr "type" "icmp")
1070 (set_attr "modrm" "1")
1071 (set_attr "mode" "QI")])
1073 (define_insn "*cmpqi_ext_4"
1074 [(set (reg FLAGS_REG)
1078 (match_operand 0 "ext_register_operand" "Q")
1083 (match_operand 1 "ext_register_operand" "Q")
1085 (const_int 8)) 0)))]
1086 "ix86_match_ccmode (insn, CCmode)"
1087 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1088 [(set_attr "type" "icmp")
1089 (set_attr "mode" "QI")])
1091 ;; These implement float point compares.
1092 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1093 ;; which would allow mix and match FP modes on the compares. Which is what
1094 ;; the old patterns did, but with many more of them.
1096 (define_expand "cbranchxf4"
1097 [(set (reg:CC FLAGS_REG)
1098 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1099 (match_operand:XF 2 "nonmemory_operand" "")))
1100 (set (pc) (if_then_else
1101 (match_operator 0 "ix86_fp_comparison_operator"
1104 (label_ref (match_operand 3 "" ""))
1108 ix86_compare_op0 = operands[1];
1109 ix86_compare_op1 = operands[2];
1110 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1114 (define_expand "cstorexf4"
1115 [(set (reg:CC FLAGS_REG)
1116 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1117 (match_operand:XF 3 "nonmemory_operand" "")))
1118 (set (match_operand:QI 0 "register_operand" "")
1119 (match_operator 1 "ix86_fp_comparison_operator"
1124 ix86_compare_op0 = operands[2];
1125 ix86_compare_op1 = operands[3];
1126 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1130 (define_expand "cbranch<mode>4"
1131 [(set (reg:CC FLAGS_REG)
1132 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1133 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1134 (set (pc) (if_then_else
1135 (match_operator 0 "ix86_fp_comparison_operator"
1138 (label_ref (match_operand 3 "" ""))
1140 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1142 ix86_compare_op0 = operands[1];
1143 ix86_compare_op1 = operands[2];
1144 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1148 (define_expand "cstore<mode>4"
1149 [(set (reg:CC FLAGS_REG)
1150 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1151 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1152 (set (match_operand:QI 0 "register_operand" "")
1153 (match_operator 1 "ix86_fp_comparison_operator"
1156 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1158 ix86_compare_op0 = operands[2];
1159 ix86_compare_op1 = operands[3];
1160 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1164 (define_expand "cbranchcc4"
1165 [(set (pc) (if_then_else
1166 (match_operator 0 "comparison_operator"
1167 [(match_operand 1 "flags_reg_operand" "")
1168 (match_operand 2 "const0_operand" "")])
1169 (label_ref (match_operand 3 "" ""))
1173 ix86_compare_op0 = operands[1];
1174 ix86_compare_op1 = operands[2];
1175 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1179 (define_expand "cstorecc4"
1180 [(set (match_operand:QI 0 "register_operand" "")
1181 (match_operator 1 "comparison_operator"
1182 [(match_operand 2 "flags_reg_operand" "")
1183 (match_operand 3 "const0_operand" "")]))]
1186 ix86_compare_op0 = operands[2];
1187 ix86_compare_op1 = operands[3];
1188 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1193 ;; FP compares, step 1:
1194 ;; Set the FP condition codes.
1196 ;; CCFPmode compare with exceptions
1197 ;; CCFPUmode compare with no exceptions
1199 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1200 ;; used to manage the reg stack popping would not be preserved.
1202 (define_insn "*cmpfp_0"
1203 [(set (match_operand:HI 0 "register_operand" "=a")
1206 (match_operand 1 "register_operand" "f")
1207 (match_operand 2 "const0_operand" ""))]
1209 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1210 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1211 "* return output_fp_compare (insn, operands, 0, 0);"
1212 [(set_attr "type" "multi")
1213 (set_attr "unit" "i387")
1215 (cond [(match_operand:SF 1 "" "")
1217 (match_operand:DF 1 "" "")
1220 (const_string "XF")))])
1222 (define_insn_and_split "*cmpfp_0_cc"
1223 [(set (reg:CCFP FLAGS_REG)
1225 (match_operand 1 "register_operand" "f")
1226 (match_operand 2 "const0_operand" "")))
1227 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1228 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1229 && TARGET_SAHF && !TARGET_CMOVE
1230 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1232 "&& reload_completed"
1235 [(compare:CCFP (match_dup 1)(match_dup 2))]
1237 (set (reg:CC FLAGS_REG)
1238 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1240 [(set_attr "type" "multi")
1241 (set_attr "unit" "i387")
1243 (cond [(match_operand:SF 1 "" "")
1245 (match_operand:DF 1 "" "")
1248 (const_string "XF")))])
1250 (define_insn "*cmpfp_xf"
1251 [(set (match_operand:HI 0 "register_operand" "=a")
1254 (match_operand:XF 1 "register_operand" "f")
1255 (match_operand:XF 2 "register_operand" "f"))]
1258 "* return output_fp_compare (insn, operands, 0, 0);"
1259 [(set_attr "type" "multi")
1260 (set_attr "unit" "i387")
1261 (set_attr "mode" "XF")])
1263 (define_insn_and_split "*cmpfp_xf_cc"
1264 [(set (reg:CCFP FLAGS_REG)
1266 (match_operand:XF 1 "register_operand" "f")
1267 (match_operand:XF 2 "register_operand" "f")))
1268 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1270 && TARGET_SAHF && !TARGET_CMOVE"
1272 "&& reload_completed"
1275 [(compare:CCFP (match_dup 1)(match_dup 2))]
1277 (set (reg:CC FLAGS_REG)
1278 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1280 [(set_attr "type" "multi")
1281 (set_attr "unit" "i387")
1282 (set_attr "mode" "XF")])
1284 (define_insn "*cmpfp_<mode>"
1285 [(set (match_operand:HI 0 "register_operand" "=a")
1288 (match_operand:MODEF 1 "register_operand" "f")
1289 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1292 "* return output_fp_compare (insn, operands, 0, 0);"
1293 [(set_attr "type" "multi")
1294 (set_attr "unit" "i387")
1295 (set_attr "mode" "<MODE>")])
1297 (define_insn_and_split "*cmpfp_<mode>_cc"
1298 [(set (reg:CCFP FLAGS_REG)
1300 (match_operand:MODEF 1 "register_operand" "f")
1301 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1302 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1304 && TARGET_SAHF && !TARGET_CMOVE"
1306 "&& reload_completed"
1309 [(compare:CCFP (match_dup 1)(match_dup 2))]
1311 (set (reg:CC FLAGS_REG)
1312 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1314 [(set_attr "type" "multi")
1315 (set_attr "unit" "i387")
1316 (set_attr "mode" "<MODE>")])
1318 (define_insn "*cmpfp_u"
1319 [(set (match_operand:HI 0 "register_operand" "=a")
1322 (match_operand 1 "register_operand" "f")
1323 (match_operand 2 "register_operand" "f"))]
1325 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1326 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1327 "* return output_fp_compare (insn, operands, 0, 1);"
1328 [(set_attr "type" "multi")
1329 (set_attr "unit" "i387")
1331 (cond [(match_operand:SF 1 "" "")
1333 (match_operand:DF 1 "" "")
1336 (const_string "XF")))])
1338 (define_insn_and_split "*cmpfp_u_cc"
1339 [(set (reg:CCFPU FLAGS_REG)
1341 (match_operand 1 "register_operand" "f")
1342 (match_operand 2 "register_operand" "f")))
1343 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1344 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1345 && TARGET_SAHF && !TARGET_CMOVE
1346 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1348 "&& reload_completed"
1351 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1353 (set (reg:CC FLAGS_REG)
1354 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1356 [(set_attr "type" "multi")
1357 (set_attr "unit" "i387")
1359 (cond [(match_operand:SF 1 "" "")
1361 (match_operand:DF 1 "" "")
1364 (const_string "XF")))])
1366 (define_insn "*cmpfp_<mode>"
1367 [(set (match_operand:HI 0 "register_operand" "=a")
1370 (match_operand 1 "register_operand" "f")
1371 (match_operator 3 "float_operator"
1372 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1374 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1375 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1376 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1377 "* return output_fp_compare (insn, operands, 0, 0);"
1378 [(set_attr "type" "multi")
1379 (set_attr "unit" "i387")
1380 (set_attr "fp_int_src" "true")
1381 (set_attr "mode" "<MODE>")])
1383 (define_insn_and_split "*cmpfp_<mode>_cc"
1384 [(set (reg:CCFP FLAGS_REG)
1386 (match_operand 1 "register_operand" "f")
1387 (match_operator 3 "float_operator"
1388 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1389 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1390 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1391 && TARGET_SAHF && !TARGET_CMOVE
1392 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1393 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1395 "&& reload_completed"
1400 (match_op_dup 3 [(match_dup 2)]))]
1402 (set (reg:CC FLAGS_REG)
1403 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1405 [(set_attr "type" "multi")
1406 (set_attr "unit" "i387")
1407 (set_attr "fp_int_src" "true")
1408 (set_attr "mode" "<MODE>")])
1410 ;; FP compares, step 2
1411 ;; Move the fpsw to ax.
1413 (define_insn "x86_fnstsw_1"
1414 [(set (match_operand:HI 0 "register_operand" "=a")
1415 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1418 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1419 (set_attr "mode" "SI")
1420 (set_attr "unit" "i387")])
1422 ;; FP compares, step 3
1423 ;; Get ax into flags, general case.
1425 (define_insn "x86_sahf_1"
1426 [(set (reg:CC FLAGS_REG)
1427 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1431 #ifdef HAVE_AS_IX86_SAHF
1434 return ASM_BYTE "0x9e";
1437 [(set_attr "length" "1")
1438 (set_attr "athlon_decode" "vector")
1439 (set_attr "amdfam10_decode" "direct")
1440 (set_attr "mode" "SI")])
1442 ;; Pentium Pro can do steps 1 through 3 in one go.
1443 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1444 (define_insn "*cmpfp_i_mixed"
1445 [(set (reg:CCFP FLAGS_REG)
1446 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1447 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1448 "TARGET_MIX_SSE_I387
1449 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1450 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1451 "* return output_fp_compare (insn, operands, 1, 0);"
1452 [(set_attr "type" "fcmp,ssecomi")
1453 (set_attr "prefix" "orig,maybe_vex")
1455 (if_then_else (match_operand:SF 1 "" "")
1457 (const_string "DF")))
1458 (set (attr "prefix_rep")
1459 (if_then_else (eq_attr "type" "ssecomi")
1461 (const_string "*")))
1462 (set (attr "prefix_data16")
1463 (cond [(eq_attr "type" "fcmp")
1465 (eq_attr "mode" "DF")
1468 (const_string "0")))
1469 (set_attr "athlon_decode" "vector")
1470 (set_attr "amdfam10_decode" "direct")])
1472 (define_insn "*cmpfp_i_sse"
1473 [(set (reg:CCFP FLAGS_REG)
1474 (compare:CCFP (match_operand 0 "register_operand" "x")
1475 (match_operand 1 "nonimmediate_operand" "xm")))]
1477 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1478 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1479 "* return output_fp_compare (insn, operands, 1, 0);"
1480 [(set_attr "type" "ssecomi")
1481 (set_attr "prefix" "maybe_vex")
1483 (if_then_else (match_operand:SF 1 "" "")
1485 (const_string "DF")))
1486 (set_attr "prefix_rep" "0")
1487 (set (attr "prefix_data16")
1488 (if_then_else (eq_attr "mode" "DF")
1490 (const_string "0")))
1491 (set_attr "athlon_decode" "vector")
1492 (set_attr "amdfam10_decode" "direct")])
1494 (define_insn "*cmpfp_i_i387"
1495 [(set (reg:CCFP FLAGS_REG)
1496 (compare:CCFP (match_operand 0 "register_operand" "f")
1497 (match_operand 1 "register_operand" "f")))]
1498 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1500 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1501 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1502 "* return output_fp_compare (insn, operands, 1, 0);"
1503 [(set_attr "type" "fcmp")
1505 (cond [(match_operand:SF 1 "" "")
1507 (match_operand:DF 1 "" "")
1510 (const_string "XF")))
1511 (set_attr "athlon_decode" "vector")
1512 (set_attr "amdfam10_decode" "direct")])
1514 (define_insn "*cmpfp_iu_mixed"
1515 [(set (reg:CCFPU FLAGS_REG)
1516 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1517 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1518 "TARGET_MIX_SSE_I387
1519 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1520 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1521 "* return output_fp_compare (insn, operands, 1, 1);"
1522 [(set_attr "type" "fcmp,ssecomi")
1523 (set_attr "prefix" "orig,maybe_vex")
1525 (if_then_else (match_operand:SF 1 "" "")
1527 (const_string "DF")))
1528 (set (attr "prefix_rep")
1529 (if_then_else (eq_attr "type" "ssecomi")
1531 (const_string "*")))
1532 (set (attr "prefix_data16")
1533 (cond [(eq_attr "type" "fcmp")
1535 (eq_attr "mode" "DF")
1538 (const_string "0")))
1539 (set_attr "athlon_decode" "vector")
1540 (set_attr "amdfam10_decode" "direct")])
1542 (define_insn "*cmpfp_iu_sse"
1543 [(set (reg:CCFPU FLAGS_REG)
1544 (compare:CCFPU (match_operand 0 "register_operand" "x")
1545 (match_operand 1 "nonimmediate_operand" "xm")))]
1547 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1548 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1549 "* return output_fp_compare (insn, operands, 1, 1);"
1550 [(set_attr "type" "ssecomi")
1551 (set_attr "prefix" "maybe_vex")
1553 (if_then_else (match_operand:SF 1 "" "")
1555 (const_string "DF")))
1556 (set_attr "prefix_rep" "0")
1557 (set (attr "prefix_data16")
1558 (if_then_else (eq_attr "mode" "DF")
1560 (const_string "0")))
1561 (set_attr "athlon_decode" "vector")
1562 (set_attr "amdfam10_decode" "direct")])
1564 (define_insn "*cmpfp_iu_387"
1565 [(set (reg:CCFPU FLAGS_REG)
1566 (compare:CCFPU (match_operand 0 "register_operand" "f")
1567 (match_operand 1 "register_operand" "f")))]
1568 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1570 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1571 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1572 "* return output_fp_compare (insn, operands, 1, 1);"
1573 [(set_attr "type" "fcmp")
1575 (cond [(match_operand:SF 1 "" "")
1577 (match_operand:DF 1 "" "")
1580 (const_string "XF")))
1581 (set_attr "athlon_decode" "vector")
1582 (set_attr "amdfam10_decode" "direct")])
1584 ;; Move instructions.
1586 ;; General case of fullword move.
1588 (define_expand "movsi"
1589 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1590 (match_operand:SI 1 "general_operand" ""))]
1592 "ix86_expand_move (SImode, operands); DONE;")
1594 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1597 ;; %%% We don't use a post-inc memory reference because x86 is not a
1598 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1599 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1600 ;; targets without our curiosities, and it is just as easy to represent
1601 ;; this differently.
1603 (define_insn "*pushsi2"
1604 [(set (match_operand:SI 0 "push_operand" "=<")
1605 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1608 [(set_attr "type" "push")
1609 (set_attr "mode" "SI")])
1611 ;; For 64BIT abi we always round up to 8 bytes.
1612 (define_insn "*pushsi2_rex64"
1613 [(set (match_operand:SI 0 "push_operand" "=X")
1614 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1617 [(set_attr "type" "push")
1618 (set_attr "mode" "SI")])
1620 (define_insn "*pushsi2_prologue"
1621 [(set (match_operand:SI 0 "push_operand" "=<")
1622 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1623 (clobber (mem:BLK (scratch)))]
1626 [(set_attr "type" "push")
1627 (set_attr "mode" "SI")])
1629 (define_insn "*popsi1_epilogue"
1630 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1631 (mem:SI (reg:SI SP_REG)))
1632 (set (reg:SI SP_REG)
1633 (plus:SI (reg:SI SP_REG) (const_int 4)))
1634 (clobber (mem:BLK (scratch)))]
1637 [(set_attr "type" "pop")
1638 (set_attr "mode" "SI")])
1640 (define_insn "popsi1"
1641 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1642 (mem:SI (reg:SI SP_REG)))
1643 (set (reg:SI SP_REG)
1644 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1647 [(set_attr "type" "pop")
1648 (set_attr "mode" "SI")])
1650 (define_insn "*movsi_xor"
1651 [(set (match_operand:SI 0 "register_operand" "=r")
1652 (match_operand:SI 1 "const0_operand" ""))
1653 (clobber (reg:CC FLAGS_REG))]
1656 [(set_attr "type" "alu1")
1657 (set_attr "mode" "SI")
1658 (set_attr "length_immediate" "0")])
1660 (define_insn "*movsi_or"
1661 [(set (match_operand:SI 0 "register_operand" "=r")
1662 (match_operand:SI 1 "immediate_operand" "i"))
1663 (clobber (reg:CC FLAGS_REG))]
1665 && operands[1] == constm1_rtx"
1667 operands[1] = constm1_rtx;
1668 return "or{l}\t{%1, %0|%0, %1}";
1670 [(set_attr "type" "alu1")
1671 (set_attr "mode" "SI")
1672 (set_attr "length_immediate" "1")])
1674 (define_insn "*movsi_1"
1675 [(set (match_operand:SI 0 "nonimmediate_operand"
1676 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1677 (match_operand:SI 1 "general_operand"
1678 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1679 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1681 switch (get_attr_type (insn))
1684 if (get_attr_mode (insn) == MODE_TI)
1685 return "%vpxor\t%0, %d0";
1686 return "%vxorps\t%0, %d0";
1689 switch (get_attr_mode (insn))
1692 return "%vmovdqa\t{%1, %0|%0, %1}";
1694 return "%vmovaps\t{%1, %0|%0, %1}";
1696 return "%vmovd\t{%1, %0|%0, %1}";
1698 return "%vmovss\t{%1, %0|%0, %1}";
1704 return "pxor\t%0, %0";
1707 if (get_attr_mode (insn) == MODE_DI)
1708 return "movq\t{%1, %0|%0, %1}";
1709 return "movd\t{%1, %0|%0, %1}";
1712 return "lea{l}\t{%1, %0|%0, %1}";
1715 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1716 return "mov{l}\t{%1, %0|%0, %1}";
1720 (cond [(eq_attr "alternative" "2")
1721 (const_string "mmx")
1722 (eq_attr "alternative" "3,4,5")
1723 (const_string "mmxmov")
1724 (eq_attr "alternative" "6")
1725 (const_string "sselog1")
1726 (eq_attr "alternative" "7,8,9,10,11")
1727 (const_string "ssemov")
1728 (match_operand:DI 1 "pic_32bit_operand" "")
1729 (const_string "lea")
1731 (const_string "imov")))
1732 (set (attr "prefix")
1733 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1734 (const_string "orig")
1735 (const_string "maybe_vex")))
1736 (set (attr "prefix_data16")
1737 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1739 (const_string "*")))
1741 (cond [(eq_attr "alternative" "2,3")
1743 (eq_attr "alternative" "6,7")
1745 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1746 (const_string "V4SF")
1747 (const_string "TI"))
1748 (and (eq_attr "alternative" "8,9,10,11")
1749 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1752 (const_string "SI")))])
1754 ;; Stores and loads of ax to arbitrary constant address.
1755 ;; We fake an second form of instruction to force reload to load address
1756 ;; into register when rax is not available
1757 (define_insn "*movabssi_1_rex64"
1758 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1759 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1760 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1762 movabs{l}\t{%1, %P0|%P0, %1}
1763 mov{l}\t{%1, %a0|%a0, %1}"
1764 [(set_attr "type" "imov")
1765 (set_attr "modrm" "0,*")
1766 (set_attr "length_address" "8,0")
1767 (set_attr "length_immediate" "0,*")
1768 (set_attr "memory" "store")
1769 (set_attr "mode" "SI")])
1771 (define_insn "*movabssi_2_rex64"
1772 [(set (match_operand:SI 0 "register_operand" "=a,r")
1773 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1774 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1776 movabs{l}\t{%P1, %0|%0, %P1}
1777 mov{l}\t{%a1, %0|%0, %a1}"
1778 [(set_attr "type" "imov")
1779 (set_attr "modrm" "0,*")
1780 (set_attr "length_address" "8,0")
1781 (set_attr "length_immediate" "0")
1782 (set_attr "memory" "load")
1783 (set_attr "mode" "SI")])
1785 (define_insn "*swapsi"
1786 [(set (match_operand:SI 0 "register_operand" "+r")
1787 (match_operand:SI 1 "register_operand" "+r"))
1792 [(set_attr "type" "imov")
1793 (set_attr "mode" "SI")
1794 (set_attr "pent_pair" "np")
1795 (set_attr "athlon_decode" "vector")
1796 (set_attr "amdfam10_decode" "double")])
1798 (define_expand "movhi"
1799 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1800 (match_operand:HI 1 "general_operand" ""))]
1802 "ix86_expand_move (HImode, operands); DONE;")
1804 (define_insn "*pushhi2"
1805 [(set (match_operand:HI 0 "push_operand" "=X")
1806 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1809 [(set_attr "type" "push")
1810 (set_attr "mode" "SI")])
1812 ;; For 64BIT abi we always round up to 8 bytes.
1813 (define_insn "*pushhi2_rex64"
1814 [(set (match_operand:HI 0 "push_operand" "=X")
1815 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1818 [(set_attr "type" "push")
1819 (set_attr "mode" "DI")])
1821 (define_insn "*movhi_1"
1822 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1823 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1824 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1826 switch (get_attr_type (insn))
1829 /* movzwl is faster than movw on p2 due to partial word stalls,
1830 though not as fast as an aligned movl. */
1831 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1833 if (get_attr_mode (insn) == MODE_SI)
1834 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1836 return "mov{w}\t{%1, %0|%0, %1}";
1840 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1841 (const_string "imov")
1842 (and (eq_attr "alternative" "0")
1843 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1845 (eq (symbol_ref "TARGET_HIMODE_MATH")
1847 (const_string "imov")
1848 (and (eq_attr "alternative" "1,2")
1849 (match_operand:HI 1 "aligned_operand" ""))
1850 (const_string "imov")
1851 (and (ne (symbol_ref "TARGET_MOVX")
1853 (eq_attr "alternative" "0,2"))
1854 (const_string "imovx")
1856 (const_string "imov")))
1858 (cond [(eq_attr "type" "imovx")
1860 (and (eq_attr "alternative" "1,2")
1861 (match_operand:HI 1 "aligned_operand" ""))
1863 (and (eq_attr "alternative" "0")
1864 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1866 (eq (symbol_ref "TARGET_HIMODE_MATH")
1870 (const_string "HI")))])
1872 ;; Stores and loads of ax to arbitrary constant address.
1873 ;; We fake an second form of instruction to force reload to load address
1874 ;; into register when rax is not available
1875 (define_insn "*movabshi_1_rex64"
1876 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1877 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1878 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1880 movabs{w}\t{%1, %P0|%P0, %1}
1881 mov{w}\t{%1, %a0|%a0, %1}"
1882 [(set_attr "type" "imov")
1883 (set_attr "modrm" "0,*")
1884 (set_attr "length_address" "8,0")
1885 (set_attr "length_immediate" "0,*")
1886 (set_attr "memory" "store")
1887 (set_attr "mode" "HI")])
1889 (define_insn "*movabshi_2_rex64"
1890 [(set (match_operand:HI 0 "register_operand" "=a,r")
1891 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1892 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1894 movabs{w}\t{%P1, %0|%0, %P1}
1895 mov{w}\t{%a1, %0|%0, %a1}"
1896 [(set_attr "type" "imov")
1897 (set_attr "modrm" "0,*")
1898 (set_attr "length_address" "8,0")
1899 (set_attr "length_immediate" "0")
1900 (set_attr "memory" "load")
1901 (set_attr "mode" "HI")])
1903 (define_insn "*swaphi_1"
1904 [(set (match_operand:HI 0 "register_operand" "+r")
1905 (match_operand:HI 1 "register_operand" "+r"))
1908 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1910 [(set_attr "type" "imov")
1911 (set_attr "mode" "SI")
1912 (set_attr "pent_pair" "np")
1913 (set_attr "athlon_decode" "vector")
1914 (set_attr "amdfam10_decode" "double")])
1916 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1917 (define_insn "*swaphi_2"
1918 [(set (match_operand:HI 0 "register_operand" "+r")
1919 (match_operand:HI 1 "register_operand" "+r"))
1922 "TARGET_PARTIAL_REG_STALL"
1924 [(set_attr "type" "imov")
1925 (set_attr "mode" "HI")
1926 (set_attr "pent_pair" "np")
1927 (set_attr "athlon_decode" "vector")])
1929 (define_expand "movstricthi"
1930 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1931 (match_operand:HI 1 "general_operand" ""))]
1934 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1936 /* Don't generate memory->memory moves, go through a register */
1937 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1938 operands[1] = force_reg (HImode, operands[1]);
1941 (define_insn "*movstricthi_1"
1942 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1943 (match_operand:HI 1 "general_operand" "rn,m"))]
1944 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1945 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1946 "mov{w}\t{%1, %0|%0, %1}"
1947 [(set_attr "type" "imov")
1948 (set_attr "mode" "HI")])
1950 (define_insn "*movstricthi_xor"
1951 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1952 (match_operand:HI 1 "const0_operand" ""))
1953 (clobber (reg:CC FLAGS_REG))]
1956 [(set_attr "type" "alu1")
1957 (set_attr "mode" "HI")
1958 (set_attr "length_immediate" "0")])
1960 (define_expand "movqi"
1961 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1962 (match_operand:QI 1 "general_operand" ""))]
1964 "ix86_expand_move (QImode, operands); DONE;")
1966 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1967 ;; "push a byte". But actually we use pushl, which has the effect
1968 ;; of rounding the amount pushed up to a word.
1970 (define_insn "*pushqi2"
1971 [(set (match_operand:QI 0 "push_operand" "=X")
1972 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1975 [(set_attr "type" "push")
1976 (set_attr "mode" "SI")])
1978 ;; For 64BIT abi we always round up to 8 bytes.
1979 (define_insn "*pushqi2_rex64"
1980 [(set (match_operand:QI 0 "push_operand" "=X")
1981 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1984 [(set_attr "type" "push")
1985 (set_attr "mode" "DI")])
1987 ;; Situation is quite tricky about when to choose full sized (SImode) move
1988 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1989 ;; partial register dependency machines (such as AMD Athlon), where QImode
1990 ;; moves issue extra dependency and for partial register stalls machines
1991 ;; that don't use QImode patterns (and QImode move cause stall on the next
1994 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1995 ;; register stall machines with, where we use QImode instructions, since
1996 ;; partial register stall can be caused there. Then we use movzx.
1997 (define_insn "*movqi_1"
1998 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1999 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2000 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2002 switch (get_attr_type (insn))
2005 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2006 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2008 if (get_attr_mode (insn) == MODE_SI)
2009 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2011 return "mov{b}\t{%1, %0|%0, %1}";
2015 (cond [(and (eq_attr "alternative" "5")
2016 (not (match_operand:QI 1 "aligned_operand" "")))
2017 (const_string "imovx")
2018 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2019 (const_string "imov")
2020 (and (eq_attr "alternative" "3")
2021 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2023 (eq (symbol_ref "TARGET_QIMODE_MATH")
2025 (const_string "imov")
2026 (eq_attr "alternative" "3,5")
2027 (const_string "imovx")
2028 (and (ne (symbol_ref "TARGET_MOVX")
2030 (eq_attr "alternative" "2"))
2031 (const_string "imovx")
2033 (const_string "imov")))
2035 (cond [(eq_attr "alternative" "3,4,5")
2037 (eq_attr "alternative" "6")
2039 (eq_attr "type" "imovx")
2041 (and (eq_attr "type" "imov")
2042 (and (eq_attr "alternative" "0,1")
2043 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2045 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2047 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2050 ;; Avoid partial register stalls when not using QImode arithmetic
2051 (and (eq_attr "type" "imov")
2052 (and (eq_attr "alternative" "0,1")
2053 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2055 (eq (symbol_ref "TARGET_QIMODE_MATH")
2059 (const_string "QI")))])
2061 (define_insn "*swapqi_1"
2062 [(set (match_operand:QI 0 "register_operand" "+r")
2063 (match_operand:QI 1 "register_operand" "+r"))
2066 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2068 [(set_attr "type" "imov")
2069 (set_attr "mode" "SI")
2070 (set_attr "pent_pair" "np")
2071 (set_attr "athlon_decode" "vector")
2072 (set_attr "amdfam10_decode" "vector")])
2074 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2075 (define_insn "*swapqi_2"
2076 [(set (match_operand:QI 0 "register_operand" "+q")
2077 (match_operand:QI 1 "register_operand" "+q"))
2080 "TARGET_PARTIAL_REG_STALL"
2082 [(set_attr "type" "imov")
2083 (set_attr "mode" "QI")
2084 (set_attr "pent_pair" "np")
2085 (set_attr "athlon_decode" "vector")])
2087 (define_expand "movstrictqi"
2088 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2089 (match_operand:QI 1 "general_operand" ""))]
2092 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2094 /* Don't generate memory->memory moves, go through a register. */
2095 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2096 operands[1] = force_reg (QImode, operands[1]);
2099 (define_insn "*movstrictqi_1"
2100 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2101 (match_operand:QI 1 "general_operand" "*qn,m"))]
2102 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2103 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2104 "mov{b}\t{%1, %0|%0, %1}"
2105 [(set_attr "type" "imov")
2106 (set_attr "mode" "QI")])
2108 (define_insn "*movstrictqi_xor"
2109 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2110 (match_operand:QI 1 "const0_operand" ""))
2111 (clobber (reg:CC FLAGS_REG))]
2114 [(set_attr "type" "alu1")
2115 (set_attr "mode" "QI")
2116 (set_attr "length_immediate" "0")])
2118 (define_insn "*movsi_extv_1"
2119 [(set (match_operand:SI 0 "register_operand" "=R")
2120 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2124 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2125 [(set_attr "type" "imovx")
2126 (set_attr "mode" "SI")])
2128 (define_insn "*movhi_extv_1"
2129 [(set (match_operand:HI 0 "register_operand" "=R")
2130 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2134 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2135 [(set_attr "type" "imovx")
2136 (set_attr "mode" "SI")])
2138 (define_insn "*movqi_extv_1"
2139 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2140 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2145 switch (get_attr_type (insn))
2148 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2150 return "mov{b}\t{%h1, %0|%0, %h1}";
2154 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2155 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2156 (ne (symbol_ref "TARGET_MOVX")
2158 (const_string "imovx")
2159 (const_string "imov")))
2161 (if_then_else (eq_attr "type" "imovx")
2163 (const_string "QI")))])
2165 (define_insn "*movqi_extv_1_rex64"
2166 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2167 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2172 switch (get_attr_type (insn))
2175 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2177 return "mov{b}\t{%h1, %0|%0, %h1}";
2181 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2182 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2183 (ne (symbol_ref "TARGET_MOVX")
2185 (const_string "imovx")
2186 (const_string "imov")))
2188 (if_then_else (eq_attr "type" "imovx")
2190 (const_string "QI")))])
2192 ;; Stores and loads of ax to arbitrary constant address.
2193 ;; We fake an second form of instruction to force reload to load address
2194 ;; into register when rax is not available
2195 (define_insn "*movabsqi_1_rex64"
2196 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2197 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2198 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2200 movabs{b}\t{%1, %P0|%P0, %1}
2201 mov{b}\t{%1, %a0|%a0, %1}"
2202 [(set_attr "type" "imov")
2203 (set_attr "modrm" "0,*")
2204 (set_attr "length_address" "8,0")
2205 (set_attr "length_immediate" "0,*")
2206 (set_attr "memory" "store")
2207 (set_attr "mode" "QI")])
2209 (define_insn "*movabsqi_2_rex64"
2210 [(set (match_operand:QI 0 "register_operand" "=a,r")
2211 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2212 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2214 movabs{b}\t{%P1, %0|%0, %P1}
2215 mov{b}\t{%a1, %0|%0, %a1}"
2216 [(set_attr "type" "imov")
2217 (set_attr "modrm" "0,*")
2218 (set_attr "length_address" "8,0")
2219 (set_attr "length_immediate" "0")
2220 (set_attr "memory" "load")
2221 (set_attr "mode" "QI")])
2223 (define_insn "*movdi_extzv_1"
2224 [(set (match_operand:DI 0 "register_operand" "=R")
2225 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2229 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2230 [(set_attr "type" "imovx")
2231 (set_attr "mode" "SI")])
2233 (define_insn "*movsi_extzv_1"
2234 [(set (match_operand:SI 0 "register_operand" "=R")
2235 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2239 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2240 [(set_attr "type" "imovx")
2241 (set_attr "mode" "SI")])
2243 (define_insn "*movqi_extzv_2"
2244 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2245 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2250 switch (get_attr_type (insn))
2253 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2255 return "mov{b}\t{%h1, %0|%0, %h1}";
2259 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2260 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2261 (ne (symbol_ref "TARGET_MOVX")
2263 (const_string "imovx")
2264 (const_string "imov")))
2266 (if_then_else (eq_attr "type" "imovx")
2268 (const_string "QI")))])
2270 (define_insn "*movqi_extzv_2_rex64"
2271 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2272 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2277 switch (get_attr_type (insn))
2280 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2282 return "mov{b}\t{%h1, %0|%0, %h1}";
2286 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2287 (ne (symbol_ref "TARGET_MOVX")
2289 (const_string "imovx")
2290 (const_string "imov")))
2292 (if_then_else (eq_attr "type" "imovx")
2294 (const_string "QI")))])
2296 (define_insn "movsi_insv_1"
2297 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2300 (match_operand:SI 1 "general_operand" "Qmn"))]
2302 "mov{b}\t{%b1, %h0|%h0, %b1}"
2303 [(set_attr "type" "imov")
2304 (set_attr "mode" "QI")])
2306 (define_insn "*movsi_insv_1_rex64"
2307 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2310 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2312 "mov{b}\t{%b1, %h0|%h0, %b1}"
2313 [(set_attr "type" "imov")
2314 (set_attr "mode" "QI")])
2316 (define_insn "movdi_insv_1_rex64"
2317 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2320 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2322 "mov{b}\t{%b1, %h0|%h0, %b1}"
2323 [(set_attr "type" "imov")
2324 (set_attr "mode" "QI")])
2326 (define_insn "*movqi_insv_2"
2327 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2330 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2333 "mov{b}\t{%h1, %h0|%h0, %h1}"
2334 [(set_attr "type" "imov")
2335 (set_attr "mode" "QI")])
2337 (define_expand "movdi"
2338 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2339 (match_operand:DI 1 "general_operand" ""))]
2341 "ix86_expand_move (DImode, operands); DONE;")
2343 (define_insn "*pushdi"
2344 [(set (match_operand:DI 0 "push_operand" "=<")
2345 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2349 (define_insn "*pushdi2_rex64"
2350 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2351 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2356 [(set_attr "type" "push,multi")
2357 (set_attr "mode" "DI")])
2359 ;; Convert impossible pushes of immediate to existing instructions.
2360 ;; First try to get scratch register and go through it. In case this
2361 ;; fails, push sign extended lower part first and then overwrite
2362 ;; upper part by 32bit move.
2364 [(match_scratch:DI 2 "r")
2365 (set (match_operand:DI 0 "push_operand" "")
2366 (match_operand:DI 1 "immediate_operand" ""))]
2367 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2368 && !x86_64_immediate_operand (operands[1], DImode)"
2369 [(set (match_dup 2) (match_dup 1))
2370 (set (match_dup 0) (match_dup 2))]
2373 ;; We need to define this as both peepholer and splitter for case
2374 ;; peephole2 pass is not run.
2375 ;; "&& 1" is needed to keep it from matching the previous pattern.
2377 [(set (match_operand:DI 0 "push_operand" "")
2378 (match_operand:DI 1 "immediate_operand" ""))]
2379 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2380 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2381 [(set (match_dup 0) (match_dup 1))
2382 (set (match_dup 2) (match_dup 3))]
2384 split_di (&operands[1], 1, &operands[2], &operands[3]);
2386 operands[1] = gen_lowpart (DImode, operands[2]);
2387 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2392 [(set (match_operand:DI 0 "push_operand" "")
2393 (match_operand:DI 1 "immediate_operand" ""))]
2394 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2395 ? epilogue_completed : reload_completed)
2396 && !symbolic_operand (operands[1], DImode)
2397 && !x86_64_immediate_operand (operands[1], DImode)"
2398 [(set (match_dup 0) (match_dup 1))
2399 (set (match_dup 2) (match_dup 3))]
2401 split_di (&operands[1], 1, &operands[2], &operands[3]);
2403 operands[1] = gen_lowpart (DImode, operands[2]);
2404 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2408 (define_insn "*pushdi2_prologue_rex64"
2409 [(set (match_operand:DI 0 "push_operand" "=<")
2410 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2411 (clobber (mem:BLK (scratch)))]
2414 [(set_attr "type" "push")
2415 (set_attr "mode" "DI")])
2417 (define_insn "*popdi1_epilogue_rex64"
2418 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2419 (mem:DI (reg:DI SP_REG)))
2420 (set (reg:DI SP_REG)
2421 (plus:DI (reg:DI SP_REG) (const_int 8)))
2422 (clobber (mem:BLK (scratch)))]
2425 [(set_attr "type" "pop")
2426 (set_attr "mode" "DI")])
2428 (define_insn "popdi1"
2429 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2430 (mem:DI (reg:DI SP_REG)))
2431 (set (reg:DI SP_REG)
2432 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2435 [(set_attr "type" "pop")
2436 (set_attr "mode" "DI")])
2438 (define_insn "*movdi_xor_rex64"
2439 [(set (match_operand:DI 0 "register_operand" "=r")
2440 (match_operand:DI 1 "const0_operand" ""))
2441 (clobber (reg:CC FLAGS_REG))]
2443 && reload_completed"
2445 [(set_attr "type" "alu1")
2446 (set_attr "mode" "SI")
2447 (set_attr "length_immediate" "0")])
2449 (define_insn "*movdi_or_rex64"
2450 [(set (match_operand:DI 0 "register_operand" "=r")
2451 (match_operand:DI 1 "const_int_operand" "i"))
2452 (clobber (reg:CC FLAGS_REG))]
2455 && operands[1] == constm1_rtx"
2457 operands[1] = constm1_rtx;
2458 return "or{q}\t{%1, %0|%0, %1}";
2460 [(set_attr "type" "alu1")
2461 (set_attr "mode" "DI")
2462 (set_attr "length_immediate" "1")])
2464 (define_insn "*movdi_2"
2465 [(set (match_operand:DI 0 "nonimmediate_operand"
2466 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2467 (match_operand:DI 1 "general_operand"
2468 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2469 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2474 movq\t{%1, %0|%0, %1}
2475 movq\t{%1, %0|%0, %1}
2477 %vmovq\t{%1, %0|%0, %1}
2478 %vmovdqa\t{%1, %0|%0, %1}
2479 %vmovq\t{%1, %0|%0, %1}
2481 movlps\t{%1, %0|%0, %1}
2482 movaps\t{%1, %0|%0, %1}
2483 movlps\t{%1, %0|%0, %1}"
2484 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2485 (set (attr "prefix")
2486 (if_then_else (eq_attr "alternative" "5,6,7,8")
2487 (const_string "vex")
2488 (const_string "orig")))
2489 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2492 [(set (match_operand:DI 0 "push_operand" "")
2493 (match_operand:DI 1 "general_operand" ""))]
2494 "!TARGET_64BIT && reload_completed
2495 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2497 "ix86_split_long_move (operands); DONE;")
2499 ;; %%% This multiword shite has got to go.
2501 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2502 (match_operand:DI 1 "general_operand" ""))]
2503 "!TARGET_64BIT && reload_completed
2504 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2505 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2507 "ix86_split_long_move (operands); DONE;")
2509 (define_insn "*movdi_1_rex64"
2510 [(set (match_operand:DI 0 "nonimmediate_operand"
2511 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2512 (match_operand:DI 1 "general_operand"
2513 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2514 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2516 switch (get_attr_type (insn))
2519 if (SSE_REG_P (operands[0]))
2520 return "movq2dq\t{%1, %0|%0, %1}";
2522 return "movdq2q\t{%1, %0|%0, %1}";
2527 if (get_attr_mode (insn) == MODE_TI)
2528 return "vmovdqa\t{%1, %0|%0, %1}";
2530 return "vmovq\t{%1, %0|%0, %1}";
2533 if (get_attr_mode (insn) == MODE_TI)
2534 return "movdqa\t{%1, %0|%0, %1}";
2538 /* Moves from and into integer register is done using movd
2539 opcode with REX prefix. */
2540 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2541 return "movd\t{%1, %0|%0, %1}";
2542 return "movq\t{%1, %0|%0, %1}";
2545 return "%vpxor\t%0, %d0";
2548 return "pxor\t%0, %0";
2554 return "lea{q}\t{%a1, %0|%0, %a1}";
2557 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2558 if (get_attr_mode (insn) == MODE_SI)
2559 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2560 else if (which_alternative == 2)
2561 return "movabs{q}\t{%1, %0|%0, %1}";
2563 return "mov{q}\t{%1, %0|%0, %1}";
2567 (cond [(eq_attr "alternative" "5")
2568 (const_string "mmx")
2569 (eq_attr "alternative" "6,7,8,9,10")
2570 (const_string "mmxmov")
2571 (eq_attr "alternative" "11")
2572 (const_string "sselog1")
2573 (eq_attr "alternative" "12,13,14,15,16")
2574 (const_string "ssemov")
2575 (eq_attr "alternative" "17,18")
2576 (const_string "ssecvt")
2577 (eq_attr "alternative" "4")
2578 (const_string "multi")
2579 (match_operand:DI 1 "pic_32bit_operand" "")
2580 (const_string "lea")
2582 (const_string "imov")))
2585 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2587 (const_string "*")))
2588 (set (attr "length_immediate")
2590 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2592 (const_string "*")))
2593 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2594 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2595 (set (attr "prefix")
2596 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2597 (const_string "maybe_vex")
2598 (const_string "orig")))
2599 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2601 ;; Stores and loads of ax to arbitrary constant address.
2602 ;; We fake an second form of instruction to force reload to load address
2603 ;; into register when rax is not available
2604 (define_insn "*movabsdi_1_rex64"
2605 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2606 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2607 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2609 movabs{q}\t{%1, %P0|%P0, %1}
2610 mov{q}\t{%1, %a0|%a0, %1}"
2611 [(set_attr "type" "imov")
2612 (set_attr "modrm" "0,*")
2613 (set_attr "length_address" "8,0")
2614 (set_attr "length_immediate" "0,*")
2615 (set_attr "memory" "store")
2616 (set_attr "mode" "DI")])
2618 (define_insn "*movabsdi_2_rex64"
2619 [(set (match_operand:DI 0 "register_operand" "=a,r")
2620 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2621 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2623 movabs{q}\t{%P1, %0|%0, %P1}
2624 mov{q}\t{%a1, %0|%0, %a1}"
2625 [(set_attr "type" "imov")
2626 (set_attr "modrm" "0,*")
2627 (set_attr "length_address" "8,0")
2628 (set_attr "length_immediate" "0")
2629 (set_attr "memory" "load")
2630 (set_attr "mode" "DI")])
2632 ;; Convert impossible stores of immediate to existing instructions.
2633 ;; First try to get scratch register and go through it. In case this
2634 ;; fails, move by 32bit parts.
2636 [(match_scratch:DI 2 "r")
2637 (set (match_operand:DI 0 "memory_operand" "")
2638 (match_operand:DI 1 "immediate_operand" ""))]
2639 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2640 && !x86_64_immediate_operand (operands[1], DImode)"
2641 [(set (match_dup 2) (match_dup 1))
2642 (set (match_dup 0) (match_dup 2))]
2645 ;; We need to define this as both peepholer and splitter for case
2646 ;; peephole2 pass is not run.
2647 ;; "&& 1" is needed to keep it from matching the previous pattern.
2649 [(set (match_operand:DI 0 "memory_operand" "")
2650 (match_operand:DI 1 "immediate_operand" ""))]
2651 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2652 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2653 [(set (match_dup 2) (match_dup 3))
2654 (set (match_dup 4) (match_dup 5))]
2655 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2658 [(set (match_operand:DI 0 "memory_operand" "")
2659 (match_operand:DI 1 "immediate_operand" ""))]
2660 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2661 ? epilogue_completed : reload_completed)
2662 && !symbolic_operand (operands[1], DImode)
2663 && !x86_64_immediate_operand (operands[1], DImode)"
2664 [(set (match_dup 2) (match_dup 3))
2665 (set (match_dup 4) (match_dup 5))]
2666 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2668 (define_insn "*swapdi_rex64"
2669 [(set (match_operand:DI 0 "register_operand" "+r")
2670 (match_operand:DI 1 "register_operand" "+r"))
2675 [(set_attr "type" "imov")
2676 (set_attr "mode" "DI")
2677 (set_attr "pent_pair" "np")
2678 (set_attr "athlon_decode" "vector")
2679 (set_attr "amdfam10_decode" "double")])
2681 (define_expand "movoi"
2682 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2683 (match_operand:OI 1 "general_operand" ""))]
2685 "ix86_expand_move (OImode, operands); DONE;")
2687 (define_insn "*movoi_internal"
2688 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2689 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2691 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2693 switch (which_alternative)
2696 return "vxorps\t%0, %0, %0";
2699 if (misaligned_operand (operands[0], OImode)
2700 || misaligned_operand (operands[1], OImode))
2701 return "vmovdqu\t{%1, %0|%0, %1}";
2703 return "vmovdqa\t{%1, %0|%0, %1}";
2708 [(set_attr "type" "sselog1,ssemov,ssemov")
2709 (set_attr "prefix" "vex")
2710 (set_attr "mode" "OI")])
2712 (define_expand "movti"
2713 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2714 (match_operand:TI 1 "nonimmediate_operand" ""))]
2715 "TARGET_SSE || TARGET_64BIT"
2718 ix86_expand_move (TImode, operands);
2719 else if (push_operand (operands[0], TImode))
2720 ix86_expand_push (TImode, operands[1]);
2722 ix86_expand_vector_move (TImode, operands);
2726 (define_insn "*movti_internal"
2727 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2728 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2729 "TARGET_SSE && !TARGET_64BIT
2730 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2732 switch (which_alternative)
2735 if (get_attr_mode (insn) == MODE_V4SF)
2736 return "%vxorps\t%0, %d0";
2738 return "%vpxor\t%0, %d0";
2741 /* TDmode values are passed as TImode on the stack. Moving them
2742 to stack may result in unaligned memory access. */
2743 if (misaligned_operand (operands[0], TImode)
2744 || misaligned_operand (operands[1], TImode))
2746 if (get_attr_mode (insn) == MODE_V4SF)
2747 return "%vmovups\t{%1, %0|%0, %1}";
2749 return "%vmovdqu\t{%1, %0|%0, %1}";
2753 if (get_attr_mode (insn) == MODE_V4SF)
2754 return "%vmovaps\t{%1, %0|%0, %1}";
2756 return "%vmovdqa\t{%1, %0|%0, %1}";
2762 [(set_attr "type" "sselog1,ssemov,ssemov")
2763 (set_attr "prefix" "maybe_vex")
2765 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2766 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2767 (const_string "V4SF")
2768 (and (eq_attr "alternative" "2")
2769 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2771 (const_string "V4SF")]
2772 (const_string "TI")))])
2774 (define_insn "*movti_rex64"
2775 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2776 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2778 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2780 switch (which_alternative)
2786 if (get_attr_mode (insn) == MODE_V4SF)
2787 return "%vxorps\t%0, %d0";
2789 return "%vpxor\t%0, %d0";
2792 /* TDmode values are passed as TImode on the stack. Moving them
2793 to stack may result in unaligned memory access. */
2794 if (misaligned_operand (operands[0], TImode)
2795 || misaligned_operand (operands[1], TImode))
2797 if (get_attr_mode (insn) == MODE_V4SF)
2798 return "%vmovups\t{%1, %0|%0, %1}";
2800 return "%vmovdqu\t{%1, %0|%0, %1}";
2804 if (get_attr_mode (insn) == MODE_V4SF)
2805 return "%vmovaps\t{%1, %0|%0, %1}";
2807 return "%vmovdqa\t{%1, %0|%0, %1}";
2813 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2814 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2816 (cond [(eq_attr "alternative" "2,3")
2818 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2820 (const_string "V4SF")
2821 (const_string "TI"))
2822 (eq_attr "alternative" "4")
2824 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2826 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2828 (const_string "V4SF")
2829 (const_string "TI"))]
2830 (const_string "DI")))])
2833 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2834 (match_operand:TI 1 "general_operand" ""))]
2835 "reload_completed && !SSE_REG_P (operands[0])
2836 && !SSE_REG_P (operands[1])"
2838 "ix86_split_long_move (operands); DONE;")
2840 ;; This expands to what emit_move_complex would generate if we didn't
2841 ;; have a movti pattern. Having this avoids problems with reload on
2842 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2843 ;; to have around all the time.
2844 (define_expand "movcdi"
2845 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2846 (match_operand:CDI 1 "general_operand" ""))]
2849 if (push_operand (operands[0], CDImode))
2850 emit_move_complex_push (CDImode, operands[0], operands[1]);
2852 emit_move_complex_parts (operands[0], operands[1]);
2856 (define_expand "movsf"
2857 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2858 (match_operand:SF 1 "general_operand" ""))]
2860 "ix86_expand_move (SFmode, operands); DONE;")
2862 (define_insn "*pushsf"
2863 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2864 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2867 /* Anything else should be already split before reg-stack. */
2868 gcc_assert (which_alternative == 1);
2869 return "push{l}\t%1";
2871 [(set_attr "type" "multi,push,multi")
2872 (set_attr "unit" "i387,*,*")
2873 (set_attr "mode" "SF,SI,SF")])
2875 (define_insn "*pushsf_rex64"
2876 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2877 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2880 /* Anything else should be already split before reg-stack. */
2881 gcc_assert (which_alternative == 1);
2882 return "push{q}\t%q1";
2884 [(set_attr "type" "multi,push,multi")
2885 (set_attr "unit" "i387,*,*")
2886 (set_attr "mode" "SF,DI,SF")])
2889 [(set (match_operand:SF 0 "push_operand" "")
2890 (match_operand:SF 1 "memory_operand" ""))]
2892 && MEM_P (operands[1])
2893 && (operands[2] = find_constant_src (insn))"
2897 ;; %%% Kill this when call knows how to work this out.
2899 [(set (match_operand:SF 0 "push_operand" "")
2900 (match_operand:SF 1 "any_fp_register_operand" ""))]
2902 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2903 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2906 [(set (match_operand:SF 0 "push_operand" "")
2907 (match_operand:SF 1 "any_fp_register_operand" ""))]
2909 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2910 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2912 (define_insn "*movsf_1"
2913 [(set (match_operand:SF 0 "nonimmediate_operand"
2914 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2915 (match_operand:SF 1 "general_operand"
2916 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2917 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2918 && (reload_in_progress || reload_completed
2919 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2920 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2921 && standard_80387_constant_p (operands[1]))
2922 || GET_CODE (operands[1]) != CONST_DOUBLE
2923 || memory_operand (operands[0], SFmode))"
2925 switch (which_alternative)
2929 return output_387_reg_move (insn, operands);
2932 return standard_80387_constant_opcode (operands[1]);
2936 return "mov{l}\t{%1, %0|%0, %1}";
2938 if (get_attr_mode (insn) == MODE_TI)
2939 return "%vpxor\t%0, %d0";
2941 return "%vxorps\t%0, %d0";
2943 if (get_attr_mode (insn) == MODE_V4SF)
2944 return "%vmovaps\t{%1, %0|%0, %1}";
2946 return "%vmovss\t{%1, %d0|%d0, %1}";
2949 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2950 : "vmovss\t{%1, %0|%0, %1}";
2952 return "movss\t{%1, %0|%0, %1}";
2954 return "%vmovss\t{%1, %0|%0, %1}";
2956 case 9: case 10: case 14: case 15:
2957 return "movd\t{%1, %0|%0, %1}";
2959 return "%vmovd\t{%1, %0|%0, %1}";
2962 return "movq\t{%1, %0|%0, %1}";
2968 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2969 (set (attr "prefix")
2970 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2971 (const_string "maybe_vex")
2972 (const_string "orig")))
2974 (cond [(eq_attr "alternative" "3,4,9,10")
2976 (eq_attr "alternative" "5")
2978 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2980 (ne (symbol_ref "TARGET_SSE2")
2982 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2985 (const_string "V4SF"))
2986 /* For architectures resolving dependencies on
2987 whole SSE registers use APS move to break dependency
2988 chains, otherwise use short move to avoid extra work.
2990 Do the same for architectures resolving dependencies on
2991 the parts. While in DF mode it is better to always handle
2992 just register parts, the SF mode is different due to lack
2993 of instructions to load just part of the register. It is
2994 better to maintain the whole registers in single format
2995 to avoid problems on using packed logical operations. */
2996 (eq_attr "alternative" "6")
2998 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3000 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3002 (const_string "V4SF")
3003 (const_string "SF"))
3004 (eq_attr "alternative" "11")
3005 (const_string "DI")]
3006 (const_string "SF")))])
3008 (define_insn "*swapsf"
3009 [(set (match_operand:SF 0 "fp_register_operand" "+f")
3010 (match_operand:SF 1 "fp_register_operand" "+f"))
3013 "reload_completed || TARGET_80387"
3015 if (STACK_TOP_P (operands[0]))
3020 [(set_attr "type" "fxch")
3021 (set_attr "mode" "SF")])
3023 (define_expand "movdf"
3024 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3025 (match_operand:DF 1 "general_operand" ""))]
3027 "ix86_expand_move (DFmode, operands); DONE;")
3029 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3030 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3031 ;; On the average, pushdf using integers can be still shorter. Allow this
3032 ;; pattern for optimize_size too.
3034 (define_insn "*pushdf_nointeger"
3035 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3036 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3037 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3039 /* This insn should be already split before reg-stack. */
3042 [(set_attr "type" "multi")
3043 (set_attr "unit" "i387,*,*,*")
3044 (set_attr "mode" "DF,SI,SI,DF")])
3046 (define_insn "*pushdf_integer"
3047 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3048 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3049 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3051 /* This insn should be already split before reg-stack. */
3054 [(set_attr "type" "multi")
3055 (set_attr "unit" "i387,*,*")
3056 (set_attr "mode" "DF,SI,DF")])
3058 ;; %%% Kill this when call knows how to work this out.
3060 [(set (match_operand:DF 0 "push_operand" "")
3061 (match_operand:DF 1 "any_fp_register_operand" ""))]
3063 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3064 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3068 [(set (match_operand:DF 0 "push_operand" "")
3069 (match_operand:DF 1 "general_operand" ""))]
3072 "ix86_split_long_move (operands); DONE;")
3074 ;; Moving is usually shorter when only FP registers are used. This separate
3075 ;; movdf pattern avoids the use of integer registers for FP operations
3076 ;; when optimizing for size.
3078 (define_insn "*movdf_nointeger"
3079 [(set (match_operand:DF 0 "nonimmediate_operand"
3080 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3081 (match_operand:DF 1 "general_operand"
3082 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3083 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3084 && ((optimize_function_for_size_p (cfun)
3085 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3086 && (reload_in_progress || reload_completed
3087 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3088 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3089 && optimize_function_for_size_p (cfun)
3090 && !memory_operand (operands[0], DFmode)
3091 && standard_80387_constant_p (operands[1]))
3092 || GET_CODE (operands[1]) != CONST_DOUBLE
3093 || ((optimize_function_for_size_p (cfun)
3094 || !TARGET_MEMORY_MISMATCH_STALL
3095 || reload_in_progress || reload_completed)
3096 && memory_operand (operands[0], DFmode)))"
3098 switch (which_alternative)
3102 return output_387_reg_move (insn, operands);
3105 return standard_80387_constant_opcode (operands[1]);
3111 switch (get_attr_mode (insn))
3114 return "%vxorps\t%0, %d0";
3116 return "%vxorpd\t%0, %d0";
3118 return "%vpxor\t%0, %d0";
3125 switch (get_attr_mode (insn))
3128 return "%vmovaps\t{%1, %0|%0, %1}";
3130 return "%vmovapd\t{%1, %0|%0, %1}";
3132 return "%vmovdqa\t{%1, %0|%0, %1}";
3134 return "%vmovq\t{%1, %0|%0, %1}";
3138 if (REG_P (operands[0]) && REG_P (operands[1]))
3139 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3141 return "vmovsd\t{%1, %0|%0, %1}";
3144 return "movsd\t{%1, %0|%0, %1}";
3148 if (REG_P (operands[0]))
3149 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3151 return "vmovlpd\t{%1, %0|%0, %1}";
3154 return "movlpd\t{%1, %0|%0, %1}";
3158 if (REG_P (operands[0]))
3159 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3161 return "vmovlps\t{%1, %0|%0, %1}";
3164 return "movlps\t{%1, %0|%0, %1}";
3173 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3174 (set (attr "prefix")
3175 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3176 (const_string "orig")
3177 (const_string "maybe_vex")))
3178 (set (attr "prefix_data16")
3179 (if_then_else (eq_attr "mode" "V1DF")
3181 (const_string "*")))
3183 (cond [(eq_attr "alternative" "0,1,2")
3185 (eq_attr "alternative" "3,4")
3188 /* For SSE1, we have many fewer alternatives. */
3189 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3190 (cond [(eq_attr "alternative" "5,6")
3191 (const_string "V4SF")
3193 (const_string "V2SF"))
3195 /* xorps is one byte shorter. */
3196 (eq_attr "alternative" "5")
3197 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3199 (const_string "V4SF")
3200 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3204 (const_string "V2DF"))
3206 /* For architectures resolving dependencies on
3207 whole SSE registers use APD move to break dependency
3208 chains, otherwise use short move to avoid extra work.
3210 movaps encodes one byte shorter. */
3211 (eq_attr "alternative" "6")
3213 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3215 (const_string "V4SF")
3216 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3218 (const_string "V2DF")
3220 (const_string "DF"))
3221 /* For architectures resolving dependencies on register
3222 parts we may avoid extra work to zero out upper part
3224 (eq_attr "alternative" "7")
3226 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3228 (const_string "V1DF")
3229 (const_string "DF"))
3231 (const_string "DF")))])
3233 (define_insn "*movdf_integer_rex64"
3234 [(set (match_operand:DF 0 "nonimmediate_operand"
3235 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3236 (match_operand:DF 1 "general_operand"
3237 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3238 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3239 && (reload_in_progress || reload_completed
3240 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3241 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3242 && optimize_function_for_size_p (cfun)
3243 && standard_80387_constant_p (operands[1]))
3244 || GET_CODE (operands[1]) != CONST_DOUBLE
3245 || memory_operand (operands[0], DFmode))"
3247 switch (which_alternative)
3251 return output_387_reg_move (insn, operands);
3254 return standard_80387_constant_opcode (operands[1]);
3261 switch (get_attr_mode (insn))
3264 return "%vxorps\t%0, %d0";
3266 return "%vxorpd\t%0, %d0";
3268 return "%vpxor\t%0, %d0";
3275 switch (get_attr_mode (insn))
3278 return "%vmovaps\t{%1, %0|%0, %1}";
3280 return "%vmovapd\t{%1, %0|%0, %1}";
3282 return "%vmovdqa\t{%1, %0|%0, %1}";
3284 return "%vmovq\t{%1, %0|%0, %1}";
3288 if (REG_P (operands[0]) && REG_P (operands[1]))
3289 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3291 return "vmovsd\t{%1, %0|%0, %1}";
3294 return "movsd\t{%1, %0|%0, %1}";
3296 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3298 return "%vmovlps\t{%1, %d0|%d0, %1}";
3305 return "%vmovd\t{%1, %0|%0, %1}";
3311 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3312 (set (attr "prefix")
3313 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3314 (const_string "orig")
3315 (const_string "maybe_vex")))
3316 (set (attr "prefix_data16")
3317 (if_then_else (eq_attr "mode" "V1DF")
3319 (const_string "*")))
3321 (cond [(eq_attr "alternative" "0,1,2")
3323 (eq_attr "alternative" "3,4,9,10")
3326 /* For SSE1, we have many fewer alternatives. */
3327 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3328 (cond [(eq_attr "alternative" "5,6")
3329 (const_string "V4SF")
3331 (const_string "V2SF"))
3333 /* xorps is one byte shorter. */
3334 (eq_attr "alternative" "5")
3335 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3337 (const_string "V4SF")
3338 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3342 (const_string "V2DF"))
3344 /* For architectures resolving dependencies on
3345 whole SSE registers use APD move to break dependency
3346 chains, otherwise use short move to avoid extra work.
3348 movaps encodes one byte shorter. */
3349 (eq_attr "alternative" "6")
3351 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3353 (const_string "V4SF")
3354 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3356 (const_string "V2DF")
3358 (const_string "DF"))
3359 /* For architectures resolving dependencies on register
3360 parts we may avoid extra work to zero out upper part
3362 (eq_attr "alternative" "7")
3364 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3366 (const_string "V1DF")
3367 (const_string "DF"))
3369 (const_string "DF")))])
3371 (define_insn "*movdf_integer"
3372 [(set (match_operand:DF 0 "nonimmediate_operand"
3373 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3374 (match_operand:DF 1 "general_operand"
3375 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3376 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3377 && optimize_function_for_speed_p (cfun)
3378 && TARGET_INTEGER_DFMODE_MOVES
3379 && (reload_in_progress || reload_completed
3380 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3381 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3382 && optimize_function_for_size_p (cfun)
3383 && standard_80387_constant_p (operands[1]))
3384 || GET_CODE (operands[1]) != CONST_DOUBLE
3385 || memory_operand (operands[0], DFmode))"
3387 switch (which_alternative)
3391 return output_387_reg_move (insn, operands);
3394 return standard_80387_constant_opcode (operands[1]);
3401 switch (get_attr_mode (insn))
3404 return "xorps\t%0, %0";
3406 return "xorpd\t%0, %0";
3408 return "pxor\t%0, %0";
3415 switch (get_attr_mode (insn))
3418 return "movaps\t{%1, %0|%0, %1}";
3420 return "movapd\t{%1, %0|%0, %1}";
3422 return "movdqa\t{%1, %0|%0, %1}";
3424 return "movq\t{%1, %0|%0, %1}";
3426 return "movsd\t{%1, %0|%0, %1}";
3428 return "movlpd\t{%1, %0|%0, %1}";
3430 return "movlps\t{%1, %0|%0, %1}";
3439 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3440 (set (attr "prefix_data16")
3441 (if_then_else (eq_attr "mode" "V1DF")
3443 (const_string "*")))
3445 (cond [(eq_attr "alternative" "0,1,2")
3447 (eq_attr "alternative" "3,4")
3450 /* For SSE1, we have many fewer alternatives. */
3451 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3452 (cond [(eq_attr "alternative" "5,6")
3453 (const_string "V4SF")
3455 (const_string "V2SF"))
3457 /* xorps is one byte shorter. */
3458 (eq_attr "alternative" "5")
3459 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3461 (const_string "V4SF")
3462 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3466 (const_string "V2DF"))
3468 /* For architectures resolving dependencies on
3469 whole SSE registers use APD move to break dependency
3470 chains, otherwise use short move to avoid extra work.
3472 movaps encodes one byte shorter. */
3473 (eq_attr "alternative" "6")
3475 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3477 (const_string "V4SF")
3478 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3480 (const_string "V2DF")
3482 (const_string "DF"))
3483 /* For architectures resolving dependencies on register
3484 parts we may avoid extra work to zero out upper part
3486 (eq_attr "alternative" "7")
3488 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3490 (const_string "V1DF")
3491 (const_string "DF"))
3493 (const_string "DF")))])
3496 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3497 (match_operand:DF 1 "general_operand" ""))]
3499 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3500 && ! (ANY_FP_REG_P (operands[0]) ||
3501 (GET_CODE (operands[0]) == SUBREG
3502 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3503 && ! (ANY_FP_REG_P (operands[1]) ||
3504 (GET_CODE (operands[1]) == SUBREG
3505 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3507 "ix86_split_long_move (operands); DONE;")
3509 (define_insn "*swapdf"
3510 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3511 (match_operand:DF 1 "fp_register_operand" "+f"))
3514 "reload_completed || TARGET_80387"
3516 if (STACK_TOP_P (operands[0]))
3521 [(set_attr "type" "fxch")
3522 (set_attr "mode" "DF")])
3524 (define_expand "movxf"
3525 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3526 (match_operand:XF 1 "general_operand" ""))]
3528 "ix86_expand_move (XFmode, operands); DONE;")
3530 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3531 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3532 ;; Pushing using integer instructions is longer except for constants
3533 ;; and direct memory references.
3534 ;; (assuming that any given constant is pushed only once, but this ought to be
3535 ;; handled elsewhere).
3537 (define_insn "*pushxf_nointeger"
3538 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3539 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3540 "optimize_function_for_size_p (cfun)"
3542 /* This insn should be already split before reg-stack. */
3545 [(set_attr "type" "multi")
3546 (set_attr "unit" "i387,*,*")
3547 (set_attr "mode" "XF,SI,SI")])
3549 (define_insn "*pushxf_integer"
3550 [(set (match_operand:XF 0 "push_operand" "=<,<")
3551 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3552 "optimize_function_for_speed_p (cfun)"
3554 /* This insn should be already split before reg-stack. */
3557 [(set_attr "type" "multi")
3558 (set_attr "unit" "i387,*")
3559 (set_attr "mode" "XF,SI")])
3562 [(set (match_operand 0 "push_operand" "")
3563 (match_operand 1 "general_operand" ""))]
3565 && (GET_MODE (operands[0]) == XFmode
3566 || GET_MODE (operands[0]) == DFmode)
3567 && !ANY_FP_REG_P (operands[1])"
3569 "ix86_split_long_move (operands); DONE;")
3572 [(set (match_operand:XF 0 "push_operand" "")
3573 (match_operand:XF 1 "any_fp_register_operand" ""))]
3575 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3576 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3577 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3579 ;; Do not use integer registers when optimizing for size
3580 (define_insn "*movxf_nointeger"
3581 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3582 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3583 "optimize_function_for_size_p (cfun)
3584 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3585 && (reload_in_progress || reload_completed
3586 || standard_80387_constant_p (operands[1])
3587 || GET_CODE (operands[1]) != CONST_DOUBLE
3588 || memory_operand (operands[0], XFmode))"
3590 switch (which_alternative)
3594 return output_387_reg_move (insn, operands);
3597 return standard_80387_constant_opcode (operands[1]);
3605 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3606 (set_attr "mode" "XF,XF,XF,SI,SI")])
3608 (define_insn "*movxf_integer"
3609 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3610 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3611 "optimize_function_for_speed_p (cfun)
3612 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3613 && (reload_in_progress || reload_completed
3614 || GET_CODE (operands[1]) != CONST_DOUBLE
3615 || memory_operand (operands[0], XFmode))"
3617 switch (which_alternative)
3621 return output_387_reg_move (insn, operands);
3624 return standard_80387_constant_opcode (operands[1]);
3633 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3634 (set_attr "mode" "XF,XF,XF,SI,SI")])
3636 (define_expand "movtf"
3637 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3638 (match_operand:TF 1 "nonimmediate_operand" ""))]
3641 ix86_expand_move (TFmode, operands);
3645 (define_insn "*movtf_internal"
3646 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3647 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3649 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3651 switch (which_alternative)
3655 if (get_attr_mode (insn) == MODE_V4SF)
3656 return "%vmovaps\t{%1, %0|%0, %1}";
3658 return "%vmovdqa\t{%1, %0|%0, %1}";
3660 if (get_attr_mode (insn) == MODE_V4SF)
3661 return "%vxorps\t%0, %d0";
3663 return "%vpxor\t%0, %d0";
3671 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3672 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3674 (cond [(eq_attr "alternative" "0,2")
3676 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3678 (const_string "V4SF")
3679 (const_string "TI"))
3680 (eq_attr "alternative" "1")
3682 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3684 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3686 (const_string "V4SF")
3687 (const_string "TI"))]
3688 (const_string "DI")))])
3690 (define_insn "*pushtf_sse"
3691 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3692 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3695 /* This insn should be already split before reg-stack. */
3698 [(set_attr "type" "multi")
3699 (set_attr "unit" "sse,*,*")
3700 (set_attr "mode" "TF,SI,SI")])
3703 [(set (match_operand:TF 0 "push_operand" "")
3704 (match_operand:TF 1 "general_operand" ""))]
3705 "TARGET_SSE2 && reload_completed
3706 && !SSE_REG_P (operands[1])"
3708 "ix86_split_long_move (operands); DONE;")
3711 [(set (match_operand:TF 0 "push_operand" "")
3712 (match_operand:TF 1 "any_fp_register_operand" ""))]
3714 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3715 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3719 [(set (match_operand 0 "nonimmediate_operand" "")
3720 (match_operand 1 "general_operand" ""))]
3722 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3723 && GET_MODE (operands[0]) == XFmode
3724 && ! (ANY_FP_REG_P (operands[0]) ||
3725 (GET_CODE (operands[0]) == SUBREG
3726 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3727 && ! (ANY_FP_REG_P (operands[1]) ||
3728 (GET_CODE (operands[1]) == SUBREG
3729 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3731 "ix86_split_long_move (operands); DONE;")
3734 [(set (match_operand 0 "register_operand" "")
3735 (match_operand 1 "memory_operand" ""))]
3737 && MEM_P (operands[1])
3738 && (GET_MODE (operands[0]) == TFmode
3739 || GET_MODE (operands[0]) == XFmode
3740 || GET_MODE (operands[0]) == SFmode
3741 || GET_MODE (operands[0]) == DFmode)
3742 && (operands[2] = find_constant_src (insn))"
3743 [(set (match_dup 0) (match_dup 2))]
3745 rtx c = operands[2];
3746 rtx r = operands[0];
3748 if (GET_CODE (r) == SUBREG)
3753 if (!standard_sse_constant_p (c))
3756 else if (FP_REG_P (r))
3758 if (!standard_80387_constant_p (c))
3761 else if (MMX_REG_P (r))
3766 [(set (match_operand 0 "register_operand" "")
3767 (float_extend (match_operand 1 "memory_operand" "")))]
3769 && MEM_P (operands[1])
3770 && (GET_MODE (operands[0]) == TFmode
3771 || GET_MODE (operands[0]) == XFmode
3772 || GET_MODE (operands[0]) == SFmode
3773 || GET_MODE (operands[0]) == DFmode)
3774 && (operands[2] = find_constant_src (insn))"
3775 [(set (match_dup 0) (match_dup 2))]
3777 rtx c = operands[2];
3778 rtx r = operands[0];
3780 if (GET_CODE (r) == SUBREG)
3785 if (!standard_sse_constant_p (c))
3788 else if (FP_REG_P (r))
3790 if (!standard_80387_constant_p (c))
3793 else if (MMX_REG_P (r))
3797 (define_insn "swapxf"
3798 [(set (match_operand:XF 0 "register_operand" "+f")
3799 (match_operand:XF 1 "register_operand" "+f"))
3804 if (STACK_TOP_P (operands[0]))
3809 [(set_attr "type" "fxch")
3810 (set_attr "mode" "XF")])
3812 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3814 [(set (match_operand:X87MODEF 0 "register_operand" "")
3815 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3816 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3817 && (standard_80387_constant_p (operands[1]) == 8
3818 || standard_80387_constant_p (operands[1]) == 9)"
3819 [(set (match_dup 0)(match_dup 1))
3821 (neg:X87MODEF (match_dup 0)))]
3825 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3826 if (real_isnegzero (&r))
3827 operands[1] = CONST0_RTX (<MODE>mode);
3829 operands[1] = CONST1_RTX (<MODE>mode);
3833 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3834 (match_operand:TF 1 "general_operand" ""))]
3836 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3838 "ix86_split_long_move (operands); DONE;")
3840 ;; Zero extension instructions
3842 (define_expand "zero_extendhisi2"
3843 [(set (match_operand:SI 0 "register_operand" "")
3844 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3847 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3849 operands[1] = force_reg (HImode, operands[1]);
3850 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3855 (define_insn "zero_extendhisi2_and"
3856 [(set (match_operand:SI 0 "register_operand" "=r")
3857 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3858 (clobber (reg:CC FLAGS_REG))]
3859 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3861 [(set_attr "type" "alu1")
3862 (set_attr "mode" "SI")])
3865 [(set (match_operand:SI 0 "register_operand" "")
3866 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3867 (clobber (reg:CC FLAGS_REG))]
3868 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3869 && optimize_function_for_speed_p (cfun)"
3870 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3871 (clobber (reg:CC FLAGS_REG))])]
3874 (define_insn "*zero_extendhisi2_movzwl"
3875 [(set (match_operand:SI 0 "register_operand" "=r")
3876 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3877 "!TARGET_ZERO_EXTEND_WITH_AND
3878 || optimize_function_for_size_p (cfun)"
3879 "movz{wl|x}\t{%1, %0|%0, %1}"
3880 [(set_attr "type" "imovx")
3881 (set_attr "mode" "SI")])
3883 (define_expand "zero_extendqihi2"
3885 [(set (match_operand:HI 0 "register_operand" "")
3886 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3887 (clobber (reg:CC FLAGS_REG))])]
3891 (define_insn "*zero_extendqihi2_and"
3892 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3893 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3894 (clobber (reg:CC FLAGS_REG))]
3895 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3897 [(set_attr "type" "alu1")
3898 (set_attr "mode" "HI")])
3900 (define_insn "*zero_extendqihi2_movzbw_and"
3901 [(set (match_operand:HI 0 "register_operand" "=r,r")
3902 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3903 (clobber (reg:CC FLAGS_REG))]
3904 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3906 [(set_attr "type" "imovx,alu1")
3907 (set_attr "mode" "HI")])
3909 ; zero extend to SImode here to avoid partial register stalls
3910 (define_insn "*zero_extendqihi2_movzbl"
3911 [(set (match_operand:HI 0 "register_operand" "=r")
3912 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3913 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3914 && reload_completed"
3915 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3916 [(set_attr "type" "imovx")
3917 (set_attr "mode" "SI")])
3919 ;; For the movzbw case strip only the clobber
3921 [(set (match_operand:HI 0 "register_operand" "")
3922 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3923 (clobber (reg:CC FLAGS_REG))]
3925 && (!TARGET_ZERO_EXTEND_WITH_AND
3926 || optimize_function_for_size_p (cfun))
3927 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3928 [(set (match_operand:HI 0 "register_operand" "")
3929 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3931 ;; When source and destination does not overlap, clear destination
3932 ;; first and then do the movb
3934 [(set (match_operand:HI 0 "register_operand" "")
3935 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3936 (clobber (reg:CC FLAGS_REG))]
3938 && ANY_QI_REG_P (operands[0])
3939 && (TARGET_ZERO_EXTEND_WITH_AND
3940 && optimize_function_for_speed_p (cfun))
3941 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3942 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3944 operands[2] = gen_lowpart (QImode, operands[0]);
3945 ix86_expand_clear (operands[0]);
3948 ;; Rest is handled by single and.
3950 [(set (match_operand:HI 0 "register_operand" "")
3951 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3952 (clobber (reg:CC FLAGS_REG))]
3954 && true_regnum (operands[0]) == true_regnum (operands[1])"
3955 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3956 (clobber (reg:CC FLAGS_REG))])]
3959 (define_expand "zero_extendqisi2"
3961 [(set (match_operand:SI 0 "register_operand" "")
3962 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3963 (clobber (reg:CC FLAGS_REG))])]
3967 (define_insn "*zero_extendqisi2_and"
3968 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3969 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3970 (clobber (reg:CC FLAGS_REG))]
3971 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3973 [(set_attr "type" "alu1")
3974 (set_attr "mode" "SI")])
3976 (define_insn "*zero_extendqisi2_movzbl_and"
3977 [(set (match_operand:SI 0 "register_operand" "=r,r")
3978 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3979 (clobber (reg:CC FLAGS_REG))]
3980 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3982 [(set_attr "type" "imovx,alu1")
3983 (set_attr "mode" "SI")])
3985 (define_insn "*zero_extendqisi2_movzbl"
3986 [(set (match_operand:SI 0 "register_operand" "=r")
3987 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3988 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3989 && reload_completed"
3990 "movz{bl|x}\t{%1, %0|%0, %1}"
3991 [(set_attr "type" "imovx")
3992 (set_attr "mode" "SI")])
3994 ;; For the movzbl case strip only the clobber
3996 [(set (match_operand:SI 0 "register_operand" "")
3997 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3998 (clobber (reg:CC FLAGS_REG))]
4000 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4001 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4003 (zero_extend:SI (match_dup 1)))])
4005 ;; When source and destination does not overlap, clear destination
4006 ;; first and then do the movb
4008 [(set (match_operand:SI 0 "register_operand" "")
4009 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4010 (clobber (reg:CC FLAGS_REG))]
4012 && ANY_QI_REG_P (operands[0])
4013 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4014 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4015 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4016 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
4018 operands[2] = gen_lowpart (QImode, operands[0]);
4019 ix86_expand_clear (operands[0]);
4022 ;; Rest is handled by single and.
4024 [(set (match_operand:SI 0 "register_operand" "")
4025 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4026 (clobber (reg:CC FLAGS_REG))]
4028 && true_regnum (operands[0]) == true_regnum (operands[1])"
4029 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4030 (clobber (reg:CC FLAGS_REG))])]
4033 ;; %%% Kill me once multi-word ops are sane.
4034 (define_expand "zero_extendsidi2"
4035 [(set (match_operand:DI 0 "register_operand" "")
4036 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4041 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4046 (define_insn "zero_extendsidi2_32"
4047 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4049 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
4050 (clobber (reg:CC FLAGS_REG))]
4056 movd\t{%1, %0|%0, %1}
4057 movd\t{%1, %0|%0, %1}
4058 %vmovd\t{%1, %0|%0, %1}
4059 %vmovd\t{%1, %0|%0, %1}"
4060 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4061 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4062 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4064 (define_insn "zero_extendsidi2_rex64"
4065 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4067 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4070 mov\t{%k1, %k0|%k0, %k1}
4072 movd\t{%1, %0|%0, %1}
4073 movd\t{%1, %0|%0, %1}
4074 %vmovd\t{%1, %0|%0, %1}
4075 %vmovd\t{%1, %0|%0, %1}"
4076 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4077 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4078 (set_attr "prefix_0f" "0,*,*,*,*,*")
4079 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4082 [(set (match_operand:DI 0 "memory_operand" "")
4083 (zero_extend:DI (match_dup 0)))]
4085 [(set (match_dup 4) (const_int 0))]
4086 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4089 [(set (match_operand:DI 0 "register_operand" "")
4090 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4091 (clobber (reg:CC FLAGS_REG))]
4092 "!TARGET_64BIT && reload_completed
4093 && true_regnum (operands[0]) == true_regnum (operands[1])"
4094 [(set (match_dup 4) (const_int 0))]
4095 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4098 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4099 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4100 (clobber (reg:CC FLAGS_REG))]
4101 "!TARGET_64BIT && reload_completed
4102 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4103 [(set (match_dup 3) (match_dup 1))
4104 (set (match_dup 4) (const_int 0))]
4105 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4107 (define_insn "zero_extendhidi2"
4108 [(set (match_operand:DI 0 "register_operand" "=r")
4109 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4111 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4112 [(set_attr "type" "imovx")
4113 (set_attr "mode" "SI")])
4115 (define_insn "zero_extendqidi2"
4116 [(set (match_operand:DI 0 "register_operand" "=r")
4117 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4119 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4120 [(set_attr "type" "imovx")
4121 (set_attr "mode" "SI")])
4123 ;; Sign extension instructions
4125 (define_expand "extendsidi2"
4126 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4127 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4128 (clobber (reg:CC FLAGS_REG))
4129 (clobber (match_scratch:SI 2 ""))])]
4134 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4139 (define_insn "*extendsidi2_1"
4140 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4141 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4142 (clobber (reg:CC FLAGS_REG))
4143 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4147 (define_insn "extendsidi2_rex64"
4148 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4149 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4153 movs{lq|x}\t{%1, %0|%0, %1}"
4154 [(set_attr "type" "imovx")
4155 (set_attr "mode" "DI")
4156 (set_attr "prefix_0f" "0")
4157 (set_attr "modrm" "0,1")])
4159 (define_insn "extendhidi2"
4160 [(set (match_operand:DI 0 "register_operand" "=r")
4161 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4163 "movs{wq|x}\t{%1, %0|%0, %1}"
4164 [(set_attr "type" "imovx")
4165 (set_attr "mode" "DI")])
4167 (define_insn "extendqidi2"
4168 [(set (match_operand:DI 0 "register_operand" "=r")
4169 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4171 "movs{bq|x}\t{%1, %0|%0, %1}"
4172 [(set_attr "type" "imovx")
4173 (set_attr "mode" "DI")])
4175 ;; Extend to memory case when source register does die.
4177 [(set (match_operand:DI 0 "memory_operand" "")
4178 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4179 (clobber (reg:CC FLAGS_REG))
4180 (clobber (match_operand:SI 2 "register_operand" ""))]
4182 && dead_or_set_p (insn, operands[1])
4183 && !reg_mentioned_p (operands[1], operands[0]))"
4184 [(set (match_dup 3) (match_dup 1))
4185 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4186 (clobber (reg:CC FLAGS_REG))])
4187 (set (match_dup 4) (match_dup 1))]
4188 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4190 ;; Extend to memory case when source register does not die.
4192 [(set (match_operand:DI 0 "memory_operand" "")
4193 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4194 (clobber (reg:CC FLAGS_REG))
4195 (clobber (match_operand:SI 2 "register_operand" ""))]
4199 split_di (&operands[0], 1, &operands[3], &operands[4]);
4201 emit_move_insn (operands[3], operands[1]);
4203 /* Generate a cltd if possible and doing so it profitable. */
4204 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4205 && true_regnum (operands[1]) == AX_REG
4206 && true_regnum (operands[2]) == DX_REG)
4208 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4212 emit_move_insn (operands[2], operands[1]);
4213 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4215 emit_move_insn (operands[4], operands[2]);
4219 ;; Extend to register case. Optimize case where source and destination
4220 ;; registers match and cases where we can use cltd.
4222 [(set (match_operand:DI 0 "register_operand" "")
4223 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4224 (clobber (reg:CC FLAGS_REG))
4225 (clobber (match_scratch:SI 2 ""))]
4229 split_di (&operands[0], 1, &operands[3], &operands[4]);
4231 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4232 emit_move_insn (operands[3], operands[1]);
4234 /* Generate a cltd if possible and doing so it profitable. */
4235 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4236 && true_regnum (operands[3]) == AX_REG
4237 && true_regnum (operands[4]) == DX_REG)
4239 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4243 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4244 emit_move_insn (operands[4], operands[1]);
4246 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4250 (define_insn "extendhisi2"
4251 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4252 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4255 switch (get_attr_prefix_0f (insn))
4258 return "{cwtl|cwde}";
4260 return "movs{wl|x}\t{%1, %0|%0, %1}";
4263 [(set_attr "type" "imovx")
4264 (set_attr "mode" "SI")
4265 (set (attr "prefix_0f")
4266 ;; movsx is short decodable while cwtl is vector decoded.
4267 (if_then_else (and (eq_attr "cpu" "!k6")
4268 (eq_attr "alternative" "0"))
4270 (const_string "1")))
4272 (if_then_else (eq_attr "prefix_0f" "0")
4274 (const_string "1")))])
4276 (define_insn "*extendhisi2_zext"
4277 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4279 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4282 switch (get_attr_prefix_0f (insn))
4285 return "{cwtl|cwde}";
4287 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4290 [(set_attr "type" "imovx")
4291 (set_attr "mode" "SI")
4292 (set (attr "prefix_0f")
4293 ;; movsx is short decodable while cwtl is vector decoded.
4294 (if_then_else (and (eq_attr "cpu" "!k6")
4295 (eq_attr "alternative" "0"))
4297 (const_string "1")))
4299 (if_then_else (eq_attr "prefix_0f" "0")
4301 (const_string "1")))])
4303 (define_insn "extendqihi2"
4304 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4305 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4308 switch (get_attr_prefix_0f (insn))
4311 return "{cbtw|cbw}";
4313 return "movs{bw|x}\t{%1, %0|%0, %1}";
4316 [(set_attr "type" "imovx")
4317 (set_attr "mode" "HI")
4318 (set (attr "prefix_0f")
4319 ;; movsx is short decodable while cwtl is vector decoded.
4320 (if_then_else (and (eq_attr "cpu" "!k6")
4321 (eq_attr "alternative" "0"))
4323 (const_string "1")))
4325 (if_then_else (eq_attr "prefix_0f" "0")
4327 (const_string "1")))])
4329 (define_insn "extendqisi2"
4330 [(set (match_operand:SI 0 "register_operand" "=r")
4331 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4333 "movs{bl|x}\t{%1, %0|%0, %1}"
4334 [(set_attr "type" "imovx")
4335 (set_attr "mode" "SI")])
4337 (define_insn "*extendqisi2_zext"
4338 [(set (match_operand:DI 0 "register_operand" "=r")
4340 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4342 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4343 [(set_attr "type" "imovx")
4344 (set_attr "mode" "SI")])
4346 ;; Conversions between float and double.
4348 ;; These are all no-ops in the model used for the 80387. So just
4351 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4352 (define_insn "*dummy_extendsfdf2"
4353 [(set (match_operand:DF 0 "push_operand" "=<")
4354 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4359 [(set (match_operand:DF 0 "push_operand" "")
4360 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4362 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4363 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4365 (define_insn "*dummy_extendsfxf2"
4366 [(set (match_operand:XF 0 "push_operand" "=<")
4367 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4372 [(set (match_operand:XF 0 "push_operand" "")
4373 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4375 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4376 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4377 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4380 [(set (match_operand:XF 0 "push_operand" "")
4381 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4383 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4384 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4385 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4387 (define_expand "extendsfdf2"
4388 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4389 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4390 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4392 /* ??? Needed for compress_float_constant since all fp constants
4393 are LEGITIMATE_CONSTANT_P. */
4394 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4396 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4397 && standard_80387_constant_p (operands[1]) > 0)
4399 operands[1] = simplify_const_unary_operation
4400 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4401 emit_move_insn_1 (operands[0], operands[1]);
4404 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4408 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4410 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4412 We do the conversion post reload to avoid producing of 128bit spills
4413 that might lead to ICE on 32bit target. The sequence unlikely combine
4416 [(set (match_operand:DF 0 "register_operand" "")
4418 (match_operand:SF 1 "nonimmediate_operand" "")))]
4419 "TARGET_USE_VECTOR_FP_CONVERTS
4420 && optimize_insn_for_speed_p ()
4421 && reload_completed && SSE_REG_P (operands[0])"
4426 (parallel [(const_int 0) (const_int 1)]))))]
4428 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4429 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4430 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4431 Try to avoid move when unpacking can be done in source. */
4432 if (REG_P (operands[1]))
4434 /* If it is unsafe to overwrite upper half of source, we need
4435 to move to destination and unpack there. */
4436 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4437 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4438 && true_regnum (operands[0]) != true_regnum (operands[1]))
4440 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4441 emit_move_insn (tmp, operands[1]);
4444 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4445 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4449 emit_insn (gen_vec_setv4sf_0 (operands[3],
4450 CONST0_RTX (V4SFmode), operands[1]));
4453 (define_insn "*extendsfdf2_mixed"
4454 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4456 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4457 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4459 switch (which_alternative)
4463 return output_387_reg_move (insn, operands);
4466 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4472 [(set_attr "type" "fmov,fmov,ssecvt")
4473 (set_attr "prefix" "orig,orig,maybe_vex")
4474 (set_attr "mode" "SF,XF,DF")])
4476 (define_insn "*extendsfdf2_sse"
4477 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4478 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4479 "TARGET_SSE2 && TARGET_SSE_MATH"
4480 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4481 [(set_attr "type" "ssecvt")
4482 (set_attr "prefix" "maybe_vex")
4483 (set_attr "mode" "DF")])
4485 (define_insn "*extendsfdf2_i387"
4486 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4487 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4489 "* return output_387_reg_move (insn, operands);"
4490 [(set_attr "type" "fmov")
4491 (set_attr "mode" "SF,XF")])
4493 (define_expand "extend<mode>xf2"
4494 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4495 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4498 /* ??? Needed for compress_float_constant since all fp constants
4499 are LEGITIMATE_CONSTANT_P. */
4500 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4502 if (standard_80387_constant_p (operands[1]) > 0)
4504 operands[1] = simplify_const_unary_operation
4505 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4506 emit_move_insn_1 (operands[0], operands[1]);
4509 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4513 (define_insn "*extend<mode>xf2_i387"
4514 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4516 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4518 "* return output_387_reg_move (insn, operands);"
4519 [(set_attr "type" "fmov")
4520 (set_attr "mode" "<MODE>,XF")])
4522 ;; %%% This seems bad bad news.
4523 ;; This cannot output into an f-reg because there is no way to be sure
4524 ;; of truncating in that case. Otherwise this is just like a simple move
4525 ;; insn. So we pretend we can output to a reg in order to get better
4526 ;; register preferencing, but we really use a stack slot.
4528 ;; Conversion from DFmode to SFmode.
4530 (define_expand "truncdfsf2"
4531 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4533 (match_operand:DF 1 "nonimmediate_operand" "")))]
4534 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4536 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4538 else if (flag_unsafe_math_optimizations)
4542 enum ix86_stack_slot slot = (virtuals_instantiated
4545 rtx temp = assign_386_stack_local (SFmode, slot);
4546 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4551 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4553 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4555 We do the conversion post reload to avoid producing of 128bit spills
4556 that might lead to ICE on 32bit target. The sequence unlikely combine
4559 [(set (match_operand:SF 0 "register_operand" "")
4561 (match_operand:DF 1 "nonimmediate_operand" "")))]
4562 "TARGET_USE_VECTOR_FP_CONVERTS
4563 && optimize_insn_for_speed_p ()
4564 && reload_completed && SSE_REG_P (operands[0])"
4567 (float_truncate:V2SF
4571 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4572 operands[3] = CONST0_RTX (V2SFmode);
4573 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4574 /* Use movsd for loading from memory, unpcklpd for registers.
4575 Try to avoid move when unpacking can be done in source, or SSE3
4576 movddup is available. */
4577 if (REG_P (operands[1]))
4580 && true_regnum (operands[0]) != true_regnum (operands[1])
4581 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4582 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4584 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4585 emit_move_insn (tmp, operands[1]);
4588 else if (!TARGET_SSE3)
4589 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4590 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4593 emit_insn (gen_sse2_loadlpd (operands[4],
4594 CONST0_RTX (V2DFmode), operands[1]));
4597 (define_expand "truncdfsf2_with_temp"
4598 [(parallel [(set (match_operand:SF 0 "" "")
4599 (float_truncate:SF (match_operand:DF 1 "" "")))
4600 (clobber (match_operand:SF 2 "" ""))])]
4603 (define_insn "*truncdfsf_fast_mixed"
4604 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4606 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4607 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4609 switch (which_alternative)
4612 return output_387_reg_move (insn, operands);
4614 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4619 [(set_attr "type" "fmov,ssecvt")
4620 (set_attr "prefix" "orig,maybe_vex")
4621 (set_attr "mode" "SF")])
4623 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4624 ;; because nothing we do here is unsafe.
4625 (define_insn "*truncdfsf_fast_sse"
4626 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4628 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4629 "TARGET_SSE2 && TARGET_SSE_MATH"
4630 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4631 [(set_attr "type" "ssecvt")
4632 (set_attr "prefix" "maybe_vex")
4633 (set_attr "mode" "SF")])
4635 (define_insn "*truncdfsf_fast_i387"
4636 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4638 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4639 "TARGET_80387 && flag_unsafe_math_optimizations"
4640 "* return output_387_reg_move (insn, operands);"
4641 [(set_attr "type" "fmov")
4642 (set_attr "mode" "SF")])
4644 (define_insn "*truncdfsf_mixed"
4645 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4647 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4648 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4649 "TARGET_MIX_SSE_I387"
4651 switch (which_alternative)
4654 return output_387_reg_move (insn, operands);
4656 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4662 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4663 (set_attr "unit" "*,*,i387,i387,i387")
4664 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4665 (set_attr "mode" "SF")])
4667 (define_insn "*truncdfsf_i387"
4668 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4670 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4671 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4674 switch (which_alternative)
4677 return output_387_reg_move (insn, operands);
4683 [(set_attr "type" "fmov,multi,multi,multi")
4684 (set_attr "unit" "*,i387,i387,i387")
4685 (set_attr "mode" "SF")])
4687 (define_insn "*truncdfsf2_i387_1"
4688 [(set (match_operand:SF 0 "memory_operand" "=m")
4690 (match_operand:DF 1 "register_operand" "f")))]
4692 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4693 && !TARGET_MIX_SSE_I387"
4694 "* return output_387_reg_move (insn, operands);"
4695 [(set_attr "type" "fmov")
4696 (set_attr "mode" "SF")])
4699 [(set (match_operand:SF 0 "register_operand" "")
4701 (match_operand:DF 1 "fp_register_operand" "")))
4702 (clobber (match_operand 2 "" ""))]
4704 [(set (match_dup 2) (match_dup 1))
4705 (set (match_dup 0) (match_dup 2))]
4707 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4710 ;; Conversion from XFmode to {SF,DF}mode
4712 (define_expand "truncxf<mode>2"
4713 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4714 (float_truncate:MODEF
4715 (match_operand:XF 1 "register_operand" "")))
4716 (clobber (match_dup 2))])]
4719 if (flag_unsafe_math_optimizations)
4721 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4722 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4723 if (reg != operands[0])
4724 emit_move_insn (operands[0], reg);
4729 enum ix86_stack_slot slot = (virtuals_instantiated
4732 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4736 (define_insn "*truncxfsf2_mixed"
4737 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4739 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4740 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4743 gcc_assert (!which_alternative);
4744 return output_387_reg_move (insn, operands);
4746 [(set_attr "type" "fmov,multi,multi,multi")
4747 (set_attr "unit" "*,i387,i387,i387")
4748 (set_attr "mode" "SF")])
4750 (define_insn "*truncxfdf2_mixed"
4751 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4753 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4754 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4757 gcc_assert (!which_alternative);
4758 return output_387_reg_move (insn, operands);
4760 [(set_attr "type" "fmov,multi,multi,multi")
4761 (set_attr "unit" "*,i387,i387,i387")
4762 (set_attr "mode" "DF")])
4764 (define_insn "truncxf<mode>2_i387_noop"
4765 [(set (match_operand:MODEF 0 "register_operand" "=f")
4766 (float_truncate:MODEF
4767 (match_operand:XF 1 "register_operand" "f")))]
4768 "TARGET_80387 && flag_unsafe_math_optimizations"
4769 "* return output_387_reg_move (insn, operands);"
4770 [(set_attr "type" "fmov")
4771 (set_attr "mode" "<MODE>")])
4773 (define_insn "*truncxf<mode>2_i387"
4774 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4775 (float_truncate:MODEF
4776 (match_operand:XF 1 "register_operand" "f")))]
4778 "* return output_387_reg_move (insn, operands);"
4779 [(set_attr "type" "fmov")
4780 (set_attr "mode" "<MODE>")])
4783 [(set (match_operand:MODEF 0 "register_operand" "")
4784 (float_truncate:MODEF
4785 (match_operand:XF 1 "register_operand" "")))
4786 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4787 "TARGET_80387 && reload_completed"
4788 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4789 (set (match_dup 0) (match_dup 2))]
4793 [(set (match_operand:MODEF 0 "memory_operand" "")
4794 (float_truncate:MODEF
4795 (match_operand:XF 1 "register_operand" "")))
4796 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4798 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4801 ;; Signed conversion to DImode.
4803 (define_expand "fix_truncxfdi2"
4804 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4805 (fix:DI (match_operand:XF 1 "register_operand" "")))
4806 (clobber (reg:CC FLAGS_REG))])]
4811 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4816 (define_expand "fix_trunc<mode>di2"
4817 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4818 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4819 (clobber (reg:CC FLAGS_REG))])]
4820 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4823 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4825 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4828 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4830 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4831 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4832 if (out != operands[0])
4833 emit_move_insn (operands[0], out);
4838 ;; Signed conversion to SImode.
4840 (define_expand "fix_truncxfsi2"
4841 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4842 (fix:SI (match_operand:XF 1 "register_operand" "")))
4843 (clobber (reg:CC FLAGS_REG))])]
4848 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4853 (define_expand "fix_trunc<mode>si2"
4854 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4855 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4856 (clobber (reg:CC FLAGS_REG))])]
4857 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4860 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4862 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4865 if (SSE_FLOAT_MODE_P (<MODE>mode))
4867 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4868 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4869 if (out != operands[0])
4870 emit_move_insn (operands[0], out);
4875 ;; Signed conversion to HImode.
4877 (define_expand "fix_trunc<mode>hi2"
4878 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4879 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4880 (clobber (reg:CC FLAGS_REG))])]
4882 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4886 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4891 ;; Unsigned conversion to SImode.
4893 (define_expand "fixuns_trunc<mode>si2"
4895 [(set (match_operand:SI 0 "register_operand" "")
4897 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4899 (clobber (match_scratch:<ssevecmode> 3 ""))
4900 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4901 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4903 enum machine_mode mode = <MODE>mode;
4904 enum machine_mode vecmode = <ssevecmode>mode;
4905 REAL_VALUE_TYPE TWO31r;
4908 if (optimize_insn_for_size_p ())
4911 real_ldexp (&TWO31r, &dconst1, 31);
4912 two31 = const_double_from_real_value (TWO31r, mode);
4913 two31 = ix86_build_const_vector (mode, true, two31);
4914 operands[2] = force_reg (vecmode, two31);
4917 (define_insn_and_split "*fixuns_trunc<mode>_1"
4918 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4920 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4921 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4922 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4923 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4924 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4925 && optimize_function_for_speed_p (cfun)"
4927 "&& reload_completed"
4930 ix86_split_convert_uns_si_sse (operands);
4934 ;; Unsigned conversion to HImode.
4935 ;; Without these patterns, we'll try the unsigned SI conversion which
4936 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4938 (define_expand "fixuns_trunc<mode>hi2"
4940 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4941 (set (match_operand:HI 0 "nonimmediate_operand" "")
4942 (subreg:HI (match_dup 2) 0))]
4943 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4944 "operands[2] = gen_reg_rtx (SImode);")
4946 ;; When SSE is available, it is always faster to use it!
4947 (define_insn "fix_trunc<mode>di_sse"
4948 [(set (match_operand:DI 0 "register_operand" "=r,r")
4949 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4950 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4951 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4952 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4953 [(set_attr "type" "sseicvt")
4954 (set_attr "prefix" "maybe_vex")
4955 (set_attr "prefix_rex" "1")
4956 (set_attr "mode" "<MODE>")
4957 (set_attr "athlon_decode" "double,vector")
4958 (set_attr "amdfam10_decode" "double,double")])
4960 (define_insn "fix_trunc<mode>si_sse"
4961 [(set (match_operand:SI 0 "register_operand" "=r,r")
4962 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4963 "SSE_FLOAT_MODE_P (<MODE>mode)
4964 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4965 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4966 [(set_attr "type" "sseicvt")
4967 (set_attr "prefix" "maybe_vex")
4968 (set_attr "mode" "<MODE>")
4969 (set_attr "athlon_decode" "double,vector")
4970 (set_attr "amdfam10_decode" "double,double")])
4972 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4974 [(set (match_operand:MODEF 0 "register_operand" "")
4975 (match_operand:MODEF 1 "memory_operand" ""))
4976 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4977 (fix:SSEMODEI24 (match_dup 0)))]
4978 "TARGET_SHORTEN_X87_SSE
4979 && peep2_reg_dead_p (2, operands[0])"
4980 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4983 ;; Avoid vector decoded forms of the instruction.
4985 [(match_scratch:DF 2 "Y2")
4986 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4987 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4988 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4989 [(set (match_dup 2) (match_dup 1))
4990 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4994 [(match_scratch:SF 2 "x")
4995 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4996 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4997 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4998 [(set (match_dup 2) (match_dup 1))
4999 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5002 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5003 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5004 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5005 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5007 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5008 && (TARGET_64BIT || <MODE>mode != DImode))
5010 && can_create_pseudo_p ()"
5015 if (memory_operand (operands[0], VOIDmode))
5016 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5019 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5020 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5026 [(set_attr "type" "fisttp")
5027 (set_attr "mode" "<MODE>")])
5029 (define_insn "fix_trunc<mode>_i387_fisttp"
5030 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5031 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5032 (clobber (match_scratch:XF 2 "=&1f"))]
5033 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5035 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5036 && (TARGET_64BIT || <MODE>mode != DImode))
5037 && TARGET_SSE_MATH)"
5038 "* return output_fix_trunc (insn, operands, 1);"
5039 [(set_attr "type" "fisttp")
5040 (set_attr "mode" "<MODE>")])
5042 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5043 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5044 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5045 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5046 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5047 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5049 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5050 && (TARGET_64BIT || <MODE>mode != DImode))
5051 && TARGET_SSE_MATH)"
5053 [(set_attr "type" "fisttp")
5054 (set_attr "mode" "<MODE>")])
5057 [(set (match_operand:X87MODEI 0 "register_operand" "")
5058 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5059 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5060 (clobber (match_scratch 3 ""))]
5062 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5063 (clobber (match_dup 3))])
5064 (set (match_dup 0) (match_dup 2))]
5068 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5069 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5070 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5071 (clobber (match_scratch 3 ""))]
5073 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5074 (clobber (match_dup 3))])]
5077 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5078 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5079 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5080 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5081 ;; function in i386.c.
5082 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5083 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5084 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5085 (clobber (reg:CC FLAGS_REG))]
5086 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5088 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5089 && (TARGET_64BIT || <MODE>mode != DImode))
5090 && can_create_pseudo_p ()"
5095 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5097 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5098 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5099 if (memory_operand (operands[0], VOIDmode))
5100 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5101 operands[2], operands[3]));
5104 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5105 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5106 operands[2], operands[3],
5111 [(set_attr "type" "fistp")
5112 (set_attr "i387_cw" "trunc")
5113 (set_attr "mode" "<MODE>")])
5115 (define_insn "fix_truncdi_i387"
5116 [(set (match_operand:DI 0 "memory_operand" "=m")
5117 (fix:DI (match_operand 1 "register_operand" "f")))
5118 (use (match_operand:HI 2 "memory_operand" "m"))
5119 (use (match_operand:HI 3 "memory_operand" "m"))
5120 (clobber (match_scratch:XF 4 "=&1f"))]
5121 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5123 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5124 "* return output_fix_trunc (insn, operands, 0);"
5125 [(set_attr "type" "fistp")
5126 (set_attr "i387_cw" "trunc")
5127 (set_attr "mode" "DI")])
5129 (define_insn "fix_truncdi_i387_with_temp"
5130 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5131 (fix:DI (match_operand 1 "register_operand" "f,f")))
5132 (use (match_operand:HI 2 "memory_operand" "m,m"))
5133 (use (match_operand:HI 3 "memory_operand" "m,m"))
5134 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5135 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5136 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5138 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5140 [(set_attr "type" "fistp")
5141 (set_attr "i387_cw" "trunc")
5142 (set_attr "mode" "DI")])
5145 [(set (match_operand:DI 0 "register_operand" "")
5146 (fix:DI (match_operand 1 "register_operand" "")))
5147 (use (match_operand:HI 2 "memory_operand" ""))
5148 (use (match_operand:HI 3 "memory_operand" ""))
5149 (clobber (match_operand:DI 4 "memory_operand" ""))
5150 (clobber (match_scratch 5 ""))]
5152 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5155 (clobber (match_dup 5))])
5156 (set (match_dup 0) (match_dup 4))]
5160 [(set (match_operand:DI 0 "memory_operand" "")
5161 (fix:DI (match_operand 1 "register_operand" "")))
5162 (use (match_operand:HI 2 "memory_operand" ""))
5163 (use (match_operand:HI 3 "memory_operand" ""))
5164 (clobber (match_operand:DI 4 "memory_operand" ""))
5165 (clobber (match_scratch 5 ""))]
5167 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5170 (clobber (match_dup 5))])]
5173 (define_insn "fix_trunc<mode>_i387"
5174 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5175 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5176 (use (match_operand:HI 2 "memory_operand" "m"))
5177 (use (match_operand:HI 3 "memory_operand" "m"))]
5178 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5180 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5181 "* return output_fix_trunc (insn, operands, 0);"
5182 [(set_attr "type" "fistp")
5183 (set_attr "i387_cw" "trunc")
5184 (set_attr "mode" "<MODE>")])
5186 (define_insn "fix_trunc<mode>_i387_with_temp"
5187 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5188 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5189 (use (match_operand:HI 2 "memory_operand" "m,m"))
5190 (use (match_operand:HI 3 "memory_operand" "m,m"))
5191 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5192 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5194 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5196 [(set_attr "type" "fistp")
5197 (set_attr "i387_cw" "trunc")
5198 (set_attr "mode" "<MODE>")])
5201 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5202 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5203 (use (match_operand:HI 2 "memory_operand" ""))
5204 (use (match_operand:HI 3 "memory_operand" ""))
5205 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5207 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5209 (use (match_dup 3))])
5210 (set (match_dup 0) (match_dup 4))]
5214 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5215 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5216 (use (match_operand:HI 2 "memory_operand" ""))
5217 (use (match_operand:HI 3 "memory_operand" ""))
5218 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5220 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5222 (use (match_dup 3))])]
5225 (define_insn "x86_fnstcw_1"
5226 [(set (match_operand:HI 0 "memory_operand" "=m")
5227 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5230 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5231 (set_attr "mode" "HI")
5232 (set_attr "unit" "i387")])
5234 (define_insn "x86_fldcw_1"
5235 [(set (reg:HI FPCR_REG)
5236 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5239 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5240 (set_attr "mode" "HI")
5241 (set_attr "unit" "i387")
5242 (set_attr "athlon_decode" "vector")
5243 (set_attr "amdfam10_decode" "vector")])
5245 ;; Conversion between fixed point and floating point.
5247 ;; Even though we only accept memory inputs, the backend _really_
5248 ;; wants to be able to do this between registers.
5250 (define_expand "floathi<mode>2"
5251 [(set (match_operand:X87MODEF 0 "register_operand" "")
5252 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5254 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5255 || TARGET_MIX_SSE_I387)"
5258 ;; Pre-reload splitter to add memory clobber to the pattern.
5259 (define_insn_and_split "*floathi<mode>2_1"
5260 [(set (match_operand:X87MODEF 0 "register_operand" "")
5261 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5263 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5264 || TARGET_MIX_SSE_I387)
5265 && can_create_pseudo_p ()"
5268 [(parallel [(set (match_dup 0)
5269 (float:X87MODEF (match_dup 1)))
5270 (clobber (match_dup 2))])]
5271 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5273 (define_insn "*floathi<mode>2_i387_with_temp"
5274 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5275 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5276 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5278 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5279 || TARGET_MIX_SSE_I387)"
5281 [(set_attr "type" "fmov,multi")
5282 (set_attr "mode" "<MODE>")
5283 (set_attr "unit" "*,i387")
5284 (set_attr "fp_int_src" "true")])
5286 (define_insn "*floathi<mode>2_i387"
5287 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5288 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5290 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5291 || TARGET_MIX_SSE_I387)"
5293 [(set_attr "type" "fmov")
5294 (set_attr "mode" "<MODE>")
5295 (set_attr "fp_int_src" "true")])
5298 [(set (match_operand:X87MODEF 0 "register_operand" "")
5299 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5300 (clobber (match_operand:HI 2 "memory_operand" ""))]
5302 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5303 || TARGET_MIX_SSE_I387)
5304 && reload_completed"
5305 [(set (match_dup 2) (match_dup 1))
5306 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5310 [(set (match_operand:X87MODEF 0 "register_operand" "")
5311 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5312 (clobber (match_operand:HI 2 "memory_operand" ""))]
5314 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5315 || TARGET_MIX_SSE_I387)
5316 && reload_completed"
5317 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5320 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5321 [(set (match_operand:X87MODEF 0 "register_operand" "")
5323 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5325 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5326 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5328 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5329 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5330 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5332 rtx reg = gen_reg_rtx (XFmode);
5335 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5337 if (<X87MODEF:MODE>mode == SFmode)
5338 insn = gen_truncxfsf2 (operands[0], reg);
5339 else if (<X87MODEF:MODE>mode == DFmode)
5340 insn = gen_truncxfdf2 (operands[0], reg);
5349 ;; Pre-reload splitter to add memory clobber to the pattern.
5350 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5351 [(set (match_operand:X87MODEF 0 "register_operand" "")
5352 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5354 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5355 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5356 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5357 || TARGET_MIX_SSE_I387))
5358 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5359 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5360 && ((<SSEMODEI24:MODE>mode == SImode
5361 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5362 && optimize_function_for_speed_p (cfun)
5363 && flag_trapping_math)
5364 || !(TARGET_INTER_UNIT_CONVERSIONS
5365 || optimize_function_for_size_p (cfun)))))
5366 && can_create_pseudo_p ()"
5369 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5370 (clobber (match_dup 2))])]
5372 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5374 /* Avoid store forwarding (partial memory) stall penalty
5375 by passing DImode value through XMM registers. */
5376 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5377 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5378 && optimize_function_for_speed_p (cfun))
5380 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5387 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5388 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5390 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5391 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5392 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5393 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5395 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5396 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5397 (set_attr "unit" "*,i387,*,*,*")
5398 (set_attr "athlon_decode" "*,*,double,direct,double")
5399 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5400 (set_attr "fp_int_src" "true")])
5402 (define_insn "*floatsi<mode>2_vector_mixed"
5403 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5404 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5405 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5406 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5410 [(set_attr "type" "fmov,sseicvt")
5411 (set_attr "mode" "<MODE>,<ssevecmode>")
5412 (set_attr "unit" "i387,*")
5413 (set_attr "athlon_decode" "*,direct")
5414 (set_attr "amdfam10_decode" "*,double")
5415 (set_attr "fp_int_src" "true")])
5417 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5418 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5420 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5421 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5422 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5423 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5425 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5426 (set_attr "mode" "<MODEF:MODE>")
5427 (set_attr "unit" "*,i387,*,*")
5428 (set_attr "athlon_decode" "*,*,double,direct")
5429 (set_attr "amdfam10_decode" "*,*,vector,double")
5430 (set_attr "fp_int_src" "true")])
5433 [(set (match_operand:MODEF 0 "register_operand" "")
5434 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5435 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5436 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5437 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5438 && TARGET_INTER_UNIT_CONVERSIONS
5440 && (SSE_REG_P (operands[0])
5441 || (GET_CODE (operands[0]) == SUBREG
5442 && SSE_REG_P (operands[0])))"
5443 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5447 [(set (match_operand:MODEF 0 "register_operand" "")
5448 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5449 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5450 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5451 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5452 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5454 && (SSE_REG_P (operands[0])
5455 || (GET_CODE (operands[0]) == SUBREG
5456 && SSE_REG_P (operands[0])))"
5457 [(set (match_dup 2) (match_dup 1))
5458 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5461 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5462 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5464 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5465 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5466 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5467 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5470 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5471 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5472 [(set_attr "type" "fmov,sseicvt,sseicvt")
5473 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5474 (set_attr "mode" "<MODEF:MODE>")
5475 (set (attr "prefix_rex")
5477 (and (eq_attr "prefix" "maybe_vex")
5478 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5480 (const_string "*")))
5481 (set_attr "unit" "i387,*,*")
5482 (set_attr "athlon_decode" "*,double,direct")
5483 (set_attr "amdfam10_decode" "*,vector,double")
5484 (set_attr "fp_int_src" "true")])
5486 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5487 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5489 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5490 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5491 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5492 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5495 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5496 [(set_attr "type" "fmov,sseicvt")
5497 (set_attr "prefix" "orig,maybe_vex")
5498 (set_attr "mode" "<MODEF:MODE>")
5499 (set (attr "prefix_rex")
5501 (and (eq_attr "prefix" "maybe_vex")
5502 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5504 (const_string "*")))
5505 (set_attr "athlon_decode" "*,direct")
5506 (set_attr "amdfam10_decode" "*,double")
5507 (set_attr "fp_int_src" "true")])
5509 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5510 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5512 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5513 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5514 "TARGET_SSE2 && TARGET_SSE_MATH
5515 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5517 [(set_attr "type" "sseicvt")
5518 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5519 (set_attr "athlon_decode" "double,direct,double")
5520 (set_attr "amdfam10_decode" "vector,double,double")
5521 (set_attr "fp_int_src" "true")])
5523 (define_insn "*floatsi<mode>2_vector_sse"
5524 [(set (match_operand:MODEF 0 "register_operand" "=x")
5525 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5526 "TARGET_SSE2 && TARGET_SSE_MATH
5527 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5529 [(set_attr "type" "sseicvt")
5530 (set_attr "mode" "<MODE>")
5531 (set_attr "athlon_decode" "direct")
5532 (set_attr "amdfam10_decode" "double")
5533 (set_attr "fp_int_src" "true")])
5536 [(set (match_operand:MODEF 0 "register_operand" "")
5537 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5538 (clobber (match_operand:SI 2 "memory_operand" ""))]
5539 "TARGET_SSE2 && TARGET_SSE_MATH
5540 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5542 && (SSE_REG_P (operands[0])
5543 || (GET_CODE (operands[0]) == SUBREG
5544 && SSE_REG_P (operands[0])))"
5547 rtx op1 = operands[1];
5549 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5551 if (GET_CODE (op1) == SUBREG)
5552 op1 = SUBREG_REG (op1);
5554 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5556 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5557 emit_insn (gen_sse2_loadld (operands[4],
5558 CONST0_RTX (V4SImode), operands[1]));
5560 /* We can ignore possible trapping value in the
5561 high part of SSE register for non-trapping math. */
5562 else if (SSE_REG_P (op1) && !flag_trapping_math)
5563 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5566 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5567 emit_move_insn (operands[2], operands[1]);
5568 emit_insn (gen_sse2_loadld (operands[4],
5569 CONST0_RTX (V4SImode), operands[2]));
5572 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5577 [(set (match_operand:MODEF 0 "register_operand" "")
5578 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5579 (clobber (match_operand:SI 2 "memory_operand" ""))]
5580 "TARGET_SSE2 && TARGET_SSE_MATH
5581 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5583 && (SSE_REG_P (operands[0])
5584 || (GET_CODE (operands[0]) == SUBREG
5585 && SSE_REG_P (operands[0])))"
5588 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5590 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5592 emit_insn (gen_sse2_loadld (operands[4],
5593 CONST0_RTX (V4SImode), operands[1]));
5595 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5600 [(set (match_operand:MODEF 0 "register_operand" "")
5601 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5602 "TARGET_SSE2 && TARGET_SSE_MATH
5603 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5605 && (SSE_REG_P (operands[0])
5606 || (GET_CODE (operands[0]) == SUBREG
5607 && SSE_REG_P (operands[0])))"
5610 rtx op1 = operands[1];
5612 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5614 if (GET_CODE (op1) == SUBREG)
5615 op1 = SUBREG_REG (op1);
5617 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5619 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5620 emit_insn (gen_sse2_loadld (operands[4],
5621 CONST0_RTX (V4SImode), operands[1]));
5623 /* We can ignore possible trapping value in the
5624 high part of SSE register for non-trapping math. */
5625 else if (SSE_REG_P (op1) && !flag_trapping_math)
5626 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5630 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5635 [(set (match_operand:MODEF 0 "register_operand" "")
5636 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5637 "TARGET_SSE2 && TARGET_SSE_MATH
5638 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5640 && (SSE_REG_P (operands[0])
5641 || (GET_CODE (operands[0]) == SUBREG
5642 && SSE_REG_P (operands[0])))"
5645 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5647 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5649 emit_insn (gen_sse2_loadld (operands[4],
5650 CONST0_RTX (V4SImode), operands[1]));
5652 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5656 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5657 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5659 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5660 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5661 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5662 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5664 [(set_attr "type" "sseicvt")
5665 (set_attr "mode" "<MODEF:MODE>")
5666 (set_attr "athlon_decode" "double,direct")
5667 (set_attr "amdfam10_decode" "vector,double")
5668 (set_attr "fp_int_src" "true")])
5670 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5671 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5673 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5674 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5675 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5676 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5677 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5678 [(set_attr "type" "sseicvt")
5679 (set_attr "prefix" "maybe_vex")
5680 (set_attr "mode" "<MODEF:MODE>")
5681 (set (attr "prefix_rex")
5683 (and (eq_attr "prefix" "maybe_vex")
5684 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5686 (const_string "*")))
5687 (set_attr "athlon_decode" "double,direct")
5688 (set_attr "amdfam10_decode" "vector,double")
5689 (set_attr "fp_int_src" "true")])
5692 [(set (match_operand:MODEF 0 "register_operand" "")
5693 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5694 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5695 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5696 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5697 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5699 && (SSE_REG_P (operands[0])
5700 || (GET_CODE (operands[0]) == SUBREG
5701 && SSE_REG_P (operands[0])))"
5702 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5705 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5706 [(set (match_operand:MODEF 0 "register_operand" "=x")
5708 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5709 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5710 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5711 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5712 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5713 [(set_attr "type" "sseicvt")
5714 (set_attr "prefix" "maybe_vex")
5715 (set_attr "mode" "<MODEF:MODE>")
5716 (set (attr "prefix_rex")
5718 (and (eq_attr "prefix" "maybe_vex")
5719 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5721 (const_string "*")))
5722 (set_attr "athlon_decode" "direct")
5723 (set_attr "amdfam10_decode" "double")
5724 (set_attr "fp_int_src" "true")])
5727 [(set (match_operand:MODEF 0 "register_operand" "")
5728 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5729 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5730 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5731 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5732 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5734 && (SSE_REG_P (operands[0])
5735 || (GET_CODE (operands[0]) == SUBREG
5736 && SSE_REG_P (operands[0])))"
5737 [(set (match_dup 2) (match_dup 1))
5738 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5742 [(set (match_operand:MODEF 0 "register_operand" "")
5743 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5744 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5745 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5746 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5748 && (SSE_REG_P (operands[0])
5749 || (GET_CODE (operands[0]) == SUBREG
5750 && SSE_REG_P (operands[0])))"
5751 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5754 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5755 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5757 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5758 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5760 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5764 [(set_attr "type" "fmov,multi")
5765 (set_attr "mode" "<X87MODEF:MODE>")
5766 (set_attr "unit" "*,i387")
5767 (set_attr "fp_int_src" "true")])
5769 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5770 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5772 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5774 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5776 [(set_attr "type" "fmov")
5777 (set_attr "mode" "<X87MODEF:MODE>")
5778 (set_attr "fp_int_src" "true")])
5781 [(set (match_operand:X87MODEF 0 "register_operand" "")
5782 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5783 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5785 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5787 && FP_REG_P (operands[0])"
5788 [(set (match_dup 2) (match_dup 1))
5789 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5793 [(set (match_operand:X87MODEF 0 "register_operand" "")
5794 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5795 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5797 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5799 && FP_REG_P (operands[0])"
5800 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5803 ;; Avoid store forwarding (partial memory) stall penalty
5804 ;; by passing DImode value through XMM registers. */
5806 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5807 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5809 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5810 (clobber (match_scratch:V4SI 3 "=X,x"))
5811 (clobber (match_scratch:V4SI 4 "=X,x"))
5812 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5813 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5814 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5815 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5817 [(set_attr "type" "multi")
5818 (set_attr "mode" "<X87MODEF:MODE>")
5819 (set_attr "unit" "i387")
5820 (set_attr "fp_int_src" "true")])
5823 [(set (match_operand:X87MODEF 0 "register_operand" "")
5824 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5825 (clobber (match_scratch:V4SI 3 ""))
5826 (clobber (match_scratch:V4SI 4 ""))
5827 (clobber (match_operand:DI 2 "memory_operand" ""))]
5828 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5829 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5830 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5832 && FP_REG_P (operands[0])"
5833 [(set (match_dup 2) (match_dup 3))
5834 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5836 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5837 Assemble the 64-bit DImode value in an xmm register. */
5838 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5839 gen_rtx_SUBREG (SImode, operands[1], 0)));
5840 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5841 gen_rtx_SUBREG (SImode, operands[1], 4)));
5842 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5845 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5849 [(set (match_operand:X87MODEF 0 "register_operand" "")
5850 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5851 (clobber (match_scratch:V4SI 3 ""))
5852 (clobber (match_scratch:V4SI 4 ""))
5853 (clobber (match_operand:DI 2 "memory_operand" ""))]
5854 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5855 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5856 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5858 && FP_REG_P (operands[0])"
5859 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5862 ;; Avoid store forwarding (partial memory) stall penalty by extending
5863 ;; SImode value to DImode through XMM register instead of pushing two
5864 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5865 ;; targets benefit from this optimization. Also note that fild
5866 ;; loads from memory only.
5868 (define_insn "*floatunssi<mode>2_1"
5869 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5870 (unsigned_float:X87MODEF
5871 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5872 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5873 (clobber (match_scratch:SI 3 "=X,x"))]
5875 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5878 [(set_attr "type" "multi")
5879 (set_attr "mode" "<MODE>")])
5882 [(set (match_operand:X87MODEF 0 "register_operand" "")
5883 (unsigned_float:X87MODEF
5884 (match_operand:SI 1 "register_operand" "")))
5885 (clobber (match_operand:DI 2 "memory_operand" ""))
5886 (clobber (match_scratch:SI 3 ""))]
5888 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5890 && reload_completed"
5891 [(set (match_dup 2) (match_dup 1))
5893 (float:X87MODEF (match_dup 2)))]
5894 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5897 [(set (match_operand:X87MODEF 0 "register_operand" "")
5898 (unsigned_float:X87MODEF
5899 (match_operand:SI 1 "memory_operand" "")))
5900 (clobber (match_operand:DI 2 "memory_operand" ""))
5901 (clobber (match_scratch:SI 3 ""))]
5903 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5905 && reload_completed"
5906 [(set (match_dup 2) (match_dup 3))
5908 (float:X87MODEF (match_dup 2)))]
5910 emit_move_insn (operands[3], operands[1]);
5911 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5914 (define_expand "floatunssi<mode>2"
5916 [(set (match_operand:X87MODEF 0 "register_operand" "")
5917 (unsigned_float:X87MODEF
5918 (match_operand:SI 1 "nonimmediate_operand" "")))
5919 (clobber (match_dup 2))
5920 (clobber (match_scratch:SI 3 ""))])]
5922 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5924 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5926 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5928 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5933 enum ix86_stack_slot slot = (virtuals_instantiated
5936 operands[2] = assign_386_stack_local (DImode, slot);
5940 (define_expand "floatunsdisf2"
5941 [(use (match_operand:SF 0 "register_operand" ""))
5942 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5943 "TARGET_64BIT && TARGET_SSE_MATH"
5944 "x86_emit_floatuns (operands); DONE;")
5946 (define_expand "floatunsdidf2"
5947 [(use (match_operand:DF 0 "register_operand" ""))
5948 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5949 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5950 && TARGET_SSE2 && TARGET_SSE_MATH"
5953 x86_emit_floatuns (operands);
5955 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5961 (define_expand "add<mode>3"
5962 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5963 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5964 (match_operand:SDWIM 2 "<general_operand>" "")))]
5966 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5968 (define_insn_and_split "*add<dwi>3_doubleword"
5969 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5971 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5972 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5973 (clobber (reg:CC FLAGS_REG))]
5974 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5977 [(parallel [(set (reg:CC FLAGS_REG)
5978 (unspec:CC [(match_dup 1) (match_dup 2)]
5981 (plus:DWIH (match_dup 1) (match_dup 2)))])
5982 (parallel [(set (match_dup 3)
5986 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5988 (clobber (reg:CC FLAGS_REG))])]
5989 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5991 (define_insn "*add<mode>3_cc"
5992 [(set (reg:CC FLAGS_REG)
5994 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5995 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5997 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5998 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5999 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6000 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6001 [(set_attr "type" "alu")
6002 (set_attr "mode" "<MODE>")])
6004 (define_insn "addqi3_cc"
6005 [(set (reg:CC FLAGS_REG)
6007 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6008 (match_operand:QI 2 "general_operand" "qn,qm")]
6010 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6011 (plus:QI (match_dup 1) (match_dup 2)))]
6012 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6013 "add{b}\t{%2, %0|%0, %2}"
6014 [(set_attr "type" "alu")
6015 (set_attr "mode" "QI")])
6017 (define_insn "*lea_1"
6018 [(set (match_operand:DWIH 0 "register_operand" "=r")
6019 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
6021 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
6022 [(set_attr "type" "lea")
6023 (set_attr "mode" "<MODE>")])
6025 (define_insn "*lea_2"
6026 [(set (match_operand:SI 0 "register_operand" "=r")
6027 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6029 "lea{l}\t{%a1, %0|%0, %a1}"
6030 [(set_attr "type" "lea")
6031 (set_attr "mode" "SI")])
6033 (define_insn "*lea_2_zext"
6034 [(set (match_operand:DI 0 "register_operand" "=r")
6036 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6038 "lea{l}\t{%a1, %k0|%k0, %a1}"
6039 [(set_attr "type" "lea")
6040 (set_attr "mode" "SI")])
6042 (define_insn "*add<mode>_1"
6043 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6045 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6046 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6047 (clobber (reg:CC FLAGS_REG))]
6048 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6050 switch (get_attr_type (insn))
6053 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6054 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6057 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6058 if (operands[2] == const1_rtx)
6059 return "inc{<imodesuffix>}\t%0";
6062 gcc_assert (operands[2] == constm1_rtx);
6063 return "dec{<imodesuffix>}\t%0";
6067 /* Use add as much as possible to replace lea for AGU optimization. */
6068 if (which_alternative == 2 && TARGET_OPT_AGU)
6069 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6071 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6072 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6073 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6075 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6079 (cond [(and (eq_attr "alternative" "2")
6080 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6081 (const_string "lea")
6082 (eq_attr "alternative" "3")
6083 (const_string "lea")
6084 ; Current assemblers are broken and do not allow @GOTOFF in
6085 ; ought but a memory context.
6086 (match_operand:SWI48 2 "pic_symbolic_operand" "")
6087 (const_string "lea")
6088 (match_operand:SWI48 2 "incdec_operand" "")
6089 (const_string "incdec")
6091 (const_string "alu")))
6092 (set (attr "length_immediate")
6094 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6096 (const_string "*")))
6097 (set_attr "mode" "<MODE>")])
6099 ;; It may seem that nonimmediate operand is proper one for operand 1.
6100 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6101 ;; we take care in ix86_binary_operator_ok to not allow two memory
6102 ;; operands so proper swapping will be done in reload. This allow
6103 ;; patterns constructed from addsi_1 to match.
6105 (define_insn "*addsi_1_zext"
6106 [(set (match_operand:DI 0 "register_operand" "=r,r")
6108 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6109 (match_operand:SI 2 "general_operand" "g,li"))))
6110 (clobber (reg:CC FLAGS_REG))]
6111 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6113 switch (get_attr_type (insn))
6116 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6117 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6120 if (operands[2] == const1_rtx)
6121 return "inc{l}\t%k0";
6124 gcc_assert (operands[2] == constm1_rtx);
6125 return "dec{l}\t%k0";
6129 if (x86_maybe_negate_const_int (&operands[2], SImode))
6130 return "sub{l}\t{%2, %k0|%k0, %2}";
6132 return "add{l}\t{%2, %k0|%k0, %2}";
6136 (cond [(eq_attr "alternative" "1")
6137 (const_string "lea")
6138 ; Current assemblers are broken and do not allow @GOTOFF in
6139 ; ought but a memory context.
6140 (match_operand:SI 2 "pic_symbolic_operand" "")
6141 (const_string "lea")
6142 (match_operand:SI 2 "incdec_operand" "")
6143 (const_string "incdec")
6145 (const_string "alu")))
6146 (set (attr "length_immediate")
6148 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6150 (const_string "*")))
6151 (set_attr "mode" "SI")])
6153 (define_insn "*addhi_1"
6154 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6155 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6156 (match_operand:HI 2 "general_operand" "rn,rm")))
6157 (clobber (reg:CC FLAGS_REG))]
6158 "TARGET_PARTIAL_REG_STALL
6159 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6161 switch (get_attr_type (insn))
6164 if (operands[2] == const1_rtx)
6165 return "inc{w}\t%0";
6168 gcc_assert (operands[2] == constm1_rtx);
6169 return "dec{w}\t%0";
6173 if (x86_maybe_negate_const_int (&operands[2], HImode))
6174 return "sub{w}\t{%2, %0|%0, %2}";
6176 return "add{w}\t{%2, %0|%0, %2}";
6180 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6181 (const_string "incdec")
6182 (const_string "alu")))
6183 (set (attr "length_immediate")
6185 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6187 (const_string "*")))
6188 (set_attr "mode" "HI")])
6190 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6191 ;; type optimizations enabled by define-splits. This is not important
6192 ;; for PII, and in fact harmful because of partial register stalls.
6194 (define_insn "*addhi_1_lea"
6195 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6196 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6197 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6198 (clobber (reg:CC FLAGS_REG))]
6199 "!TARGET_PARTIAL_REG_STALL
6200 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6202 switch (get_attr_type (insn))
6207 if (operands[2] == const1_rtx)
6208 return "inc{w}\t%0";
6211 gcc_assert (operands[2] == constm1_rtx);
6212 return "dec{w}\t%0";
6216 if (x86_maybe_negate_const_int (&operands[2], HImode))
6217 return "sub{w}\t{%2, %0|%0, %2}";
6219 return "add{w}\t{%2, %0|%0, %2}";
6223 (if_then_else (eq_attr "alternative" "2")
6224 (const_string "lea")
6225 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6226 (const_string "incdec")
6227 (const_string "alu"))))
6228 (set (attr "length_immediate")
6230 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6232 (const_string "*")))
6233 (set_attr "mode" "HI,HI,SI")])
6235 (define_insn "*addqi_1"
6236 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6237 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6238 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6239 (clobber (reg:CC FLAGS_REG))]
6240 "TARGET_PARTIAL_REG_STALL
6241 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6243 int widen = (which_alternative == 2);
6244 switch (get_attr_type (insn))
6247 if (operands[2] == const1_rtx)
6248 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6251 gcc_assert (operands[2] == constm1_rtx);
6252 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6256 if (x86_maybe_negate_const_int (&operands[2], QImode))
6259 return "sub{l}\t{%2, %k0|%k0, %2}";
6261 return "sub{b}\t{%2, %0|%0, %2}";
6264 return "add{l}\t{%k2, %k0|%k0, %k2}";
6266 return "add{b}\t{%2, %0|%0, %2}";
6270 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6271 (const_string "incdec")
6272 (const_string "alu")))
6273 (set (attr "length_immediate")
6275 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6277 (const_string "*")))
6278 (set_attr "mode" "QI,QI,SI")])
6280 ;; %%% Potential partial reg stall on alternative 2. What to do?
6281 (define_insn "*addqi_1_lea"
6282 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6283 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6284 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6285 (clobber (reg:CC FLAGS_REG))]
6286 "!TARGET_PARTIAL_REG_STALL
6287 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6289 int widen = (which_alternative == 2);
6290 switch (get_attr_type (insn))
6295 if (operands[2] == const1_rtx)
6296 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6299 gcc_assert (operands[2] == constm1_rtx);
6300 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6304 if (x86_maybe_negate_const_int (&operands[2], QImode))
6307 return "sub{l}\t{%2, %k0|%k0, %2}";
6309 return "sub{b}\t{%2, %0|%0, %2}";
6312 return "add{l}\t{%k2, %k0|%k0, %k2}";
6314 return "add{b}\t{%2, %0|%0, %2}";
6318 (if_then_else (eq_attr "alternative" "3")
6319 (const_string "lea")
6320 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6321 (const_string "incdec")
6322 (const_string "alu"))))
6323 (set (attr "length_immediate")
6325 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6327 (const_string "*")))
6328 (set_attr "mode" "QI,QI,SI,SI")])
6330 (define_insn "*addqi_1_slp"
6331 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6332 (plus:QI (match_dup 0)
6333 (match_operand:QI 1 "general_operand" "qn,qnm")))
6334 (clobber (reg:CC FLAGS_REG))]
6335 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6336 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6338 switch (get_attr_type (insn))
6341 if (operands[1] == const1_rtx)
6342 return "inc{b}\t%0";
6345 gcc_assert (operands[1] == constm1_rtx);
6346 return "dec{b}\t%0";
6350 if (x86_maybe_negate_const_int (&operands[1], QImode))
6351 return "sub{b}\t{%1, %0|%0, %1}";
6353 return "add{b}\t{%1, %0|%0, %1}";
6357 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6358 (const_string "incdec")
6359 (const_string "alu1")))
6360 (set (attr "memory")
6361 (if_then_else (match_operand 1 "memory_operand" "")
6362 (const_string "load")
6363 (const_string "none")))
6364 (set_attr "mode" "QI")])
6366 (define_insn "*add<mode>_2"
6367 [(set (reg FLAGS_REG)
6370 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6371 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6373 (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6374 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6375 "ix86_match_ccmode (insn, CCGOCmode)
6376 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6377 /* Current assemblers are broken and do not allow @GOTOFF in
6378 ought but a memory context. */
6379 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6381 switch (get_attr_type (insn))
6384 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6385 if (operands[2] == const1_rtx)
6386 return "inc{<imodesuffix>}\t%0";
6389 gcc_assert (operands[2] == constm1_rtx);
6390 return "dec{<imodesuffix>}\t%0";
6394 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6395 /* ???? In DImode, we ought to handle there the 32bit case too
6396 - do we need new constraint? */
6397 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6398 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6400 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6404 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6405 (const_string "incdec")
6406 (const_string "alu")))
6407 (set (attr "length_immediate")
6409 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6411 (const_string "*")))
6412 (set_attr "mode" "<MODE>")])
6414 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6415 (define_insn "*addsi_2_zext"
6416 [(set (reg FLAGS_REG)
6418 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6419 (match_operand:SI 2 "general_operand" "g"))
6421 (set (match_operand:DI 0 "register_operand" "=r")
6422 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6423 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6424 && ix86_binary_operator_ok (PLUS, SImode, operands)
6425 /* Current assemblers are broken and do not allow @GOTOFF in
6426 ought but a memory context. */
6427 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6429 switch (get_attr_type (insn))
6432 if (operands[2] == const1_rtx)
6433 return "inc{l}\t%k0";
6436 gcc_assert (operands[2] == constm1_rtx);
6437 return "dec{l}\t%k0";
6441 if (x86_maybe_negate_const_int (&operands[2], SImode))
6442 return "sub{l}\t{%2, %k0|%k0, %2}";
6444 return "add{l}\t{%2, %k0|%k0, %2}";
6448 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6449 (const_string "incdec")
6450 (const_string "alu")))
6451 (set (attr "length_immediate")
6453 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6455 (const_string "*")))
6456 (set_attr "mode" "SI")])
6458 (define_insn "*addhi_2"
6459 [(set (reg FLAGS_REG)
6461 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6462 (match_operand:HI 2 "general_operand" "rmn,rn"))
6464 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6465 (plus:HI (match_dup 1) (match_dup 2)))]
6466 "ix86_match_ccmode (insn, CCGOCmode)
6467 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6469 switch (get_attr_type (insn))
6472 if (operands[2] == const1_rtx)
6473 return "inc{w}\t%0";
6476 gcc_assert (operands[2] == constm1_rtx);
6477 return "dec{w}\t%0";
6481 if (x86_maybe_negate_const_int (&operands[2], HImode))
6482 return "sub{w}\t{%2, %0|%0, %2}";
6484 return "add{w}\t{%2, %0|%0, %2}";
6488 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6489 (const_string "incdec")
6490 (const_string "alu")))
6491 (set (attr "length_immediate")
6493 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6495 (const_string "*")))
6496 (set_attr "mode" "HI")])
6498 (define_insn "*addqi_2"
6499 [(set (reg FLAGS_REG)
6501 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6502 (match_operand:QI 2 "general_operand" "qmn,qn"))
6504 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6505 (plus:QI (match_dup 1) (match_dup 2)))]
6506 "ix86_match_ccmode (insn, CCGOCmode)
6507 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6509 switch (get_attr_type (insn))
6512 if (operands[2] == const1_rtx)
6513 return "inc{b}\t%0";
6516 gcc_assert (operands[2] == constm1_rtx
6517 || (CONST_INT_P (operands[2])
6518 && INTVAL (operands[2]) == 255));
6519 return "dec{b}\t%0";
6523 if (x86_maybe_negate_const_int (&operands[2], QImode))
6524 return "sub{b}\t{%2, %0|%0, %2}";
6526 return "add{b}\t{%2, %0|%0, %2}";
6530 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6531 (const_string "incdec")
6532 (const_string "alu")))
6533 (set_attr "mode" "QI")])
6535 (define_insn "*add<mode>_3"
6536 [(set (reg FLAGS_REG)
6538 (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6539 (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6540 (clobber (match_scratch:SWI48 0 "=r"))]
6541 "ix86_match_ccmode (insn, CCZmode)
6542 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6543 /* Current assemblers are broken and do not allow @GOTOFF in
6544 ought but a memory context. */
6545 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6547 switch (get_attr_type (insn))
6550 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6551 if (operands[2] == const1_rtx)
6552 return "inc{<imodesuffix>}\t%0";
6555 gcc_assert (operands[2] == constm1_rtx);
6556 return "dec{<imodesuffix>}\t%0";
6560 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6561 /* ???? In DImode, we ought to handle there the 32bit case too
6562 - do we need new constraint? */
6563 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6564 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6566 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6570 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6571 (const_string "incdec")
6572 (const_string "alu")))
6573 (set (attr "length_immediate")
6575 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6577 (const_string "*")))
6578 (set_attr "mode" "<MODE>")])
6580 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6581 (define_insn "*addsi_3_zext"
6582 [(set (reg FLAGS_REG)
6584 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6585 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6586 (set (match_operand:DI 0 "register_operand" "=r")
6587 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6588 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6589 && ix86_binary_operator_ok (PLUS, SImode, operands)
6590 /* Current assemblers are broken and do not allow @GOTOFF in
6591 ought but a memory context. */
6592 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6594 switch (get_attr_type (insn))
6597 if (operands[2] == const1_rtx)
6598 return "inc{l}\t%k0";
6601 gcc_assert (operands[2] == constm1_rtx);
6602 return "dec{l}\t%k0";
6606 if (x86_maybe_negate_const_int (&operands[2], SImode))
6607 return "sub{l}\t{%2, %k0|%k0, %2}";
6609 return "add{l}\t{%2, %k0|%k0, %2}";
6613 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6614 (const_string "incdec")
6615 (const_string "alu")))
6616 (set (attr "length_immediate")
6618 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6620 (const_string "*")))
6621 (set_attr "mode" "SI")])
6623 (define_insn "*addhi_3"
6624 [(set (reg FLAGS_REG)
6626 (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6627 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6628 (clobber (match_scratch:HI 0 "=r"))]
6629 "ix86_match_ccmode (insn, CCZmode)
6630 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6632 switch (get_attr_type (insn))
6635 if (operands[2] == const1_rtx)
6636 return "inc{w}\t%0";
6639 gcc_assert (operands[2] == constm1_rtx);
6640 return "dec{w}\t%0";
6644 if (x86_maybe_negate_const_int (&operands[2], HImode))
6645 return "sub{w}\t{%2, %0|%0, %2}";
6647 return "add{w}\t{%2, %0|%0, %2}";
6651 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6652 (const_string "incdec")
6653 (const_string "alu")))
6654 (set (attr "length_immediate")
6656 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6658 (const_string "*")))
6659 (set_attr "mode" "HI")])
6661 (define_insn "*addqi_3"
6662 [(set (reg FLAGS_REG)
6664 (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6665 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6666 (clobber (match_scratch:QI 0 "=q"))]
6667 "ix86_match_ccmode (insn, CCZmode)
6668 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6670 switch (get_attr_type (insn))
6673 if (operands[2] == const1_rtx)
6674 return "inc{b}\t%0";
6677 gcc_assert (operands[2] == constm1_rtx
6678 || (CONST_INT_P (operands[2])
6679 && INTVAL (operands[2]) == 255));
6680 return "dec{b}\t%0";
6684 if (x86_maybe_negate_const_int (&operands[2], QImode))
6685 return "sub{b}\t{%2, %0|%0, %2}";
6687 return "add{b}\t{%2, %0|%0, %2}";
6691 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6692 (const_string "incdec")
6693 (const_string "alu")))
6694 (set_attr "mode" "QI")])
6696 ; For comparisons against 1, -1 and 128, we may generate better code
6697 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6698 ; is matched then. We can't accept general immediate, because for
6699 ; case of overflows, the result is messed up.
6700 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6701 ; only for comparisons not depending on it.
6703 (define_insn "*adddi_4"
6704 [(set (reg FLAGS_REG)
6706 (match_operand:DI 1 "nonimmediate_operand" "0")
6707 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6708 (clobber (match_scratch:DI 0 "=rm"))]
6710 && ix86_match_ccmode (insn, CCGCmode)"
6712 switch (get_attr_type (insn))
6715 if (operands[2] == constm1_rtx)
6716 return "inc{q}\t%0";
6719 gcc_assert (operands[2] == const1_rtx);
6720 return "dec{q}\t%0";
6724 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6725 if (x86_maybe_negate_const_int (&operands[2], DImode))
6726 return "add{q}\t{%2, %0|%0, %2}";
6728 return "sub{q}\t{%2, %0|%0, %2}";
6732 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6733 (const_string "incdec")
6734 (const_string "alu")))
6735 (set (attr "length_immediate")
6737 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6739 (const_string "*")))
6740 (set_attr "mode" "DI")])
6742 ; For comparisons against 1, -1 and 128, we may generate better code
6743 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6744 ; is matched then. We can't accept general immediate, because for
6745 ; case of overflows, the result is messed up.
6746 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6747 ; only for comparisons not depending on it.
6749 (define_insn "*addsi_4"
6750 [(set (reg FLAGS_REG)
6752 (match_operand:SI 1 "nonimmediate_operand" "0")
6753 (match_operand:SI 2 "const_int_operand" "n")))
6754 (clobber (match_scratch:SI 0 "=rm"))]
6755 "ix86_match_ccmode (insn, CCGCmode)"
6757 switch (get_attr_type (insn))
6760 if (operands[2] == constm1_rtx)
6761 return "inc{l}\t%0";
6764 gcc_assert (operands[2] == const1_rtx);
6765 return "dec{l}\t%0";
6769 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6770 if (x86_maybe_negate_const_int (&operands[2], SImode))
6771 return "add{l}\t{%2, %0|%0, %2}";
6773 return "sub{l}\t{%2, %0|%0, %2}";
6777 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6778 (const_string "incdec")
6779 (const_string "alu")))
6780 (set (attr "length_immediate")
6782 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6784 (const_string "*")))
6785 (set_attr "mode" "SI")])
6787 ; See comments above addsi_4 for details.
6789 (define_insn "*addhi_4"
6790 [(set (reg FLAGS_REG)
6792 (match_operand:HI 1 "nonimmediate_operand" "0")
6793 (match_operand:HI 2 "const_int_operand" "n")))
6794 (clobber (match_scratch:HI 0 "=rm"))]
6795 "ix86_match_ccmode (insn, CCGCmode)"
6797 switch (get_attr_type (insn))
6800 if (operands[2] == constm1_rtx)
6801 return "inc{w}\t%0";
6804 gcc_assert (operands[2] == const1_rtx);
6805 return "dec{w}\t%0";
6809 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6810 if (x86_maybe_negate_const_int (&operands[2], HImode))
6811 return "add{w}\t{%2, %0|%0, %2}";
6813 return "sub{w}\t{%2, %0|%0, %2}";
6817 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6818 (const_string "incdec")
6819 (const_string "alu")))
6820 (set (attr "length_immediate")
6822 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6824 (const_string "*")))
6825 (set_attr "mode" "HI")])
6827 ; See comments above addsi_4 for details.
6829 (define_insn "*addqi_4"
6830 [(set (reg FLAGS_REG)
6832 (match_operand:QI 1 "nonimmediate_operand" "0")
6833 (match_operand:QI 2 "const_int_operand" "n")))
6834 (clobber (match_scratch:QI 0 "=qm"))]
6835 "ix86_match_ccmode (insn, CCGCmode)"
6837 switch (get_attr_type (insn))
6840 if (operands[2] == constm1_rtx
6841 || (CONST_INT_P (operands[2])
6842 && INTVAL (operands[2]) == 255))
6843 return "inc{b}\t%0";
6846 gcc_assert (operands[2] == const1_rtx);
6847 return "dec{b}\t%0";
6851 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6852 if (x86_maybe_negate_const_int (&operands[2], QImode))
6853 return "add{b}\t{%2, %0|%0, %2}";
6855 return "sub{b}\t{%2, %0|%0, %2}";
6859 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6860 (const_string "incdec")
6861 (const_string "alu")))
6862 (set_attr "mode" "QI")])
6864 (define_insn "*add<mode>_5"
6865 [(set (reg FLAGS_REG)
6868 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6869 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6871 (clobber (match_scratch:SWI48 0 "=r"))]
6872 "ix86_match_ccmode (insn, CCGOCmode)
6873 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6874 /* Current assemblers are broken and do not allow @GOTOFF in
6875 ought but a memory context. */
6876 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6878 switch (get_attr_type (insn))
6881 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6882 if (operands[2] == const1_rtx)
6883 return "inc{<imodesuffix>}\t%0";
6886 gcc_assert (operands[2] == constm1_rtx);
6887 return "dec{<imodesuffix>}\t%0";
6891 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6892 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6893 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6895 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6899 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6900 (const_string "incdec")
6901 (const_string "alu")))
6902 (set (attr "length_immediate")
6904 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6906 (const_string "*")))
6907 (set_attr "mode" "<MODE>")])
6909 (define_insn "*addhi_5"
6910 [(set (reg FLAGS_REG)
6912 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6913 (match_operand:HI 2 "general_operand" "rmn"))
6915 (clobber (match_scratch:HI 0 "=r"))]
6916 "ix86_match_ccmode (insn, CCGOCmode)
6917 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6919 switch (get_attr_type (insn))
6922 if (operands[2] == const1_rtx)
6923 return "inc{w}\t%0";
6926 gcc_assert (operands[2] == constm1_rtx);
6927 return "dec{w}\t%0";
6931 if (x86_maybe_negate_const_int (&operands[2], HImode))
6932 return "sub{w}\t{%2, %0|%0, %2}";
6934 return "add{w}\t{%2, %0|%0, %2}";
6938 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6939 (const_string "incdec")
6940 (const_string "alu")))
6941 (set (attr "length_immediate")
6943 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6945 (const_string "*")))
6946 (set_attr "mode" "HI")])
6948 (define_insn "*addqi_5"
6949 [(set (reg FLAGS_REG)
6951 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6952 (match_operand:QI 2 "general_operand" "qmn"))
6954 (clobber (match_scratch:QI 0 "=q"))]
6955 "ix86_match_ccmode (insn, CCGOCmode)
6956 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6958 switch (get_attr_type (insn))
6961 if (operands[2] == const1_rtx)
6962 return "inc{b}\t%0";
6965 gcc_assert (operands[2] == constm1_rtx
6966 || (CONST_INT_P (operands[2])
6967 && INTVAL (operands[2]) == 255));
6968 return "dec{b}\t%0";
6972 if (x86_maybe_negate_const_int (&operands[2], QImode))
6973 return "sub{b}\t{%2, %0|%0, %2}";
6975 return "add{b}\t{%2, %0|%0, %2}";
6979 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6980 (const_string "incdec")
6981 (const_string "alu")))
6982 (set_attr "mode" "QI")])
6984 (define_insn "*addqi_ext_1_rex64"
6985 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6990 (match_operand 1 "ext_register_operand" "0")
6993 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6994 (clobber (reg:CC FLAGS_REG))]
6997 switch (get_attr_type (insn))
7000 if (operands[2] == const1_rtx)
7001 return "inc{b}\t%h0";
7004 gcc_assert (operands[2] == constm1_rtx
7005 || (CONST_INT_P (operands[2])
7006 && INTVAL (operands[2]) == 255));
7007 return "dec{b}\t%h0";
7011 return "add{b}\t{%2, %h0|%h0, %2}";
7015 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7016 (const_string "incdec")
7017 (const_string "alu")))
7018 (set_attr "modrm" "1")
7019 (set_attr "mode" "QI")])
7021 (define_insn "addqi_ext_1"
7022 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7027 (match_operand 1 "ext_register_operand" "0")
7030 (match_operand:QI 2 "general_operand" "Qmn")))
7031 (clobber (reg:CC FLAGS_REG))]
7034 switch (get_attr_type (insn))
7037 if (operands[2] == const1_rtx)
7038 return "inc{b}\t%h0";
7041 gcc_assert (operands[2] == constm1_rtx
7042 || (CONST_INT_P (operands[2])
7043 && INTVAL (operands[2]) == 255));
7044 return "dec{b}\t%h0";
7048 return "add{b}\t{%2, %h0|%h0, %2}";
7052 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7053 (const_string "incdec")
7054 (const_string "alu")))
7055 (set_attr "modrm" "1")
7056 (set_attr "mode" "QI")])
7058 (define_insn "*addqi_ext_2"
7059 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7064 (match_operand 1 "ext_register_operand" "%0")
7068 (match_operand 2 "ext_register_operand" "Q")
7071 (clobber (reg:CC FLAGS_REG))]
7073 "add{b}\t{%h2, %h0|%h0, %h2}"
7074 [(set_attr "type" "alu")
7075 (set_attr "mode" "QI")])
7077 ;; The lea patterns for non-Pmodes needs to be matched by
7078 ;; several insns converted to real lea by splitters.
7080 (define_insn_and_split "*lea_general_1"
7081 [(set (match_operand 0 "register_operand" "=r")
7082 (plus (plus (match_operand 1 "index_register_operand" "l")
7083 (match_operand 2 "register_operand" "r"))
7084 (match_operand 3 "immediate_operand" "i")))]
7085 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7086 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7087 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7088 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7089 && GET_MODE (operands[0]) == GET_MODE (operands[2])
7090 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7091 || GET_MODE (operands[3]) == VOIDmode)"
7093 "&& reload_completed"
7097 operands[0] = gen_lowpart (SImode, operands[0]);
7098 operands[1] = gen_lowpart (Pmode, operands[1]);
7099 operands[2] = gen_lowpart (Pmode, operands[2]);
7100 operands[3] = gen_lowpart (Pmode, operands[3]);
7101 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7103 if (Pmode != SImode)
7104 pat = gen_rtx_SUBREG (SImode, pat, 0);
7105 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7108 [(set_attr "type" "lea")
7109 (set_attr "mode" "SI")])
7111 (define_insn_and_split "*lea_general_1_zext"
7112 [(set (match_operand:DI 0 "register_operand" "=r")
7115 (match_operand:SI 1 "index_register_operand" "l")
7116 (match_operand:SI 2 "register_operand" "r"))
7117 (match_operand:SI 3 "immediate_operand" "i"))))]
7120 "&& reload_completed"
7122 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7124 (match_dup 3)) 0)))]
7126 operands[1] = gen_lowpart (Pmode, operands[1]);
7127 operands[2] = gen_lowpart (Pmode, operands[2]);
7128 operands[3] = gen_lowpart (Pmode, operands[3]);
7130 [(set_attr "type" "lea")
7131 (set_attr "mode" "SI")])
7133 (define_insn_and_split "*lea_general_2"
7134 [(set (match_operand 0 "register_operand" "=r")
7135 (plus (mult (match_operand 1 "index_register_operand" "l")
7136 (match_operand 2 "const248_operand" "i"))
7137 (match_operand 3 "nonmemory_operand" "ri")))]
7138 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7139 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7140 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7141 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7142 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7143 || GET_MODE (operands[3]) == VOIDmode)"
7145 "&& reload_completed"
7149 operands[0] = gen_lowpart (SImode, operands[0]);
7150 operands[1] = gen_lowpart (Pmode, operands[1]);
7151 operands[3] = gen_lowpart (Pmode, operands[3]);
7152 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7154 if (Pmode != SImode)
7155 pat = gen_rtx_SUBREG (SImode, pat, 0);
7156 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7159 [(set_attr "type" "lea")
7160 (set_attr "mode" "SI")])
7162 (define_insn_and_split "*lea_general_2_zext"
7163 [(set (match_operand:DI 0 "register_operand" "=r")
7166 (match_operand:SI 1 "index_register_operand" "l")
7167 (match_operand:SI 2 "const248_operand" "n"))
7168 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7171 "&& reload_completed"
7173 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7175 (match_dup 3)) 0)))]
7177 operands[1] = gen_lowpart (Pmode, operands[1]);
7178 operands[3] = gen_lowpart (Pmode, operands[3]);
7180 [(set_attr "type" "lea")
7181 (set_attr "mode" "SI")])
7183 (define_insn_and_split "*lea_general_3"
7184 [(set (match_operand 0 "register_operand" "=r")
7185 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7186 (match_operand 2 "const248_operand" "i"))
7187 (match_operand 3 "register_operand" "r"))
7188 (match_operand 4 "immediate_operand" "i")))]
7189 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7190 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7191 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7192 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7193 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7195 "&& reload_completed"
7199 operands[0] = gen_lowpart (SImode, operands[0]);
7200 operands[1] = gen_lowpart (Pmode, operands[1]);
7201 operands[3] = gen_lowpart (Pmode, operands[3]);
7202 operands[4] = gen_lowpart (Pmode, operands[4]);
7203 pat = gen_rtx_PLUS (Pmode,
7204 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7208 if (Pmode != SImode)
7209 pat = gen_rtx_SUBREG (SImode, pat, 0);
7210 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7213 [(set_attr "type" "lea")
7214 (set_attr "mode" "SI")])
7216 (define_insn_and_split "*lea_general_3_zext"
7217 [(set (match_operand:DI 0 "register_operand" "=r")
7221 (match_operand:SI 1 "index_register_operand" "l")
7222 (match_operand:SI 2 "const248_operand" "n"))
7223 (match_operand:SI 3 "register_operand" "r"))
7224 (match_operand:SI 4 "immediate_operand" "i"))))]
7227 "&& reload_completed"
7229 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7232 (match_dup 4)) 0)))]
7234 operands[1] = gen_lowpart (Pmode, operands[1]);
7235 operands[3] = gen_lowpart (Pmode, operands[3]);
7236 operands[4] = gen_lowpart (Pmode, operands[4]);
7238 [(set_attr "type" "lea")
7239 (set_attr "mode" "SI")])
7241 ;; Convert lea to the lea pattern to avoid flags dependency.
7243 [(set (match_operand:DI 0 "register_operand" "")
7244 (plus:DI (match_operand:DI 1 "register_operand" "")
7245 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7246 (clobber (reg:CC FLAGS_REG))]
7247 "TARGET_64BIT && reload_completed
7248 && ix86_lea_for_add_ok (PLUS, insn, operands)"
7250 (plus:DI (match_dup 1)
7254 ;; Convert lea to the lea pattern to avoid flags dependency.
7256 [(set (match_operand 0 "register_operand" "")
7257 (plus (match_operand 1 "register_operand" "")
7258 (match_operand 2 "nonmemory_operand" "")))
7259 (clobber (reg:CC FLAGS_REG))]
7260 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
7264 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7265 may confuse gen_lowpart. */
7266 if (GET_MODE (operands[0]) != Pmode)
7268 operands[1] = gen_lowpart (Pmode, operands[1]);
7269 operands[2] = gen_lowpart (Pmode, operands[2]);
7271 operands[0] = gen_lowpart (SImode, operands[0]);
7272 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7273 if (Pmode != SImode)
7274 pat = gen_rtx_SUBREG (SImode, pat, 0);
7275 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7279 ;; Convert lea to the lea pattern to avoid flags dependency.
7281 [(set (match_operand:DI 0 "register_operand" "")
7283 (plus:SI (match_operand:SI 1 "register_operand" "")
7284 (match_operand:SI 2 "nonmemory_operand" ""))))
7285 (clobber (reg:CC FLAGS_REG))]
7286 "TARGET_64BIT && reload_completed
7287 && true_regnum (operands[0]) != true_regnum (operands[1])"
7289 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7291 operands[1] = gen_lowpart (Pmode, operands[1]);
7292 operands[2] = gen_lowpart (Pmode, operands[2]);
7295 ;; Subtract instructions
7297 (define_expand "sub<mode>3"
7298 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7299 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7300 (match_operand:SDWIM 2 "<general_operand>" "")))]
7302 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7304 (define_insn_and_split "*sub<dwi>3_doubleword"
7305 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7307 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7308 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7309 (clobber (reg:CC FLAGS_REG))]
7310 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7313 [(parallel [(set (reg:CC FLAGS_REG)
7314 (compare:CC (match_dup 1) (match_dup 2)))
7316 (minus:DWIH (match_dup 1) (match_dup 2)))])
7317 (parallel [(set (match_dup 3)
7321 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7323 (clobber (reg:CC FLAGS_REG))])]
7324 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7326 (define_insn "*sub<mode>_1"
7327 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7329 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7330 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7331 (clobber (reg:CC FLAGS_REG))]
7332 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7333 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7334 [(set_attr "type" "alu")
7335 (set_attr "mode" "<MODE>")])
7337 (define_insn "*subsi_1_zext"
7338 [(set (match_operand:DI 0 "register_operand" "=r")
7340 (minus:SI (match_operand:SI 1 "register_operand" "0")
7341 (match_operand:SI 2 "general_operand" "g"))))
7342 (clobber (reg:CC FLAGS_REG))]
7343 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7344 "sub{l}\t{%2, %k0|%k0, %2}"
7345 [(set_attr "type" "alu")
7346 (set_attr "mode" "SI")])
7348 (define_insn "*subqi_1_slp"
7349 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7350 (minus:QI (match_dup 0)
7351 (match_operand:QI 1 "general_operand" "qn,qm")))
7352 (clobber (reg:CC FLAGS_REG))]
7353 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7354 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7355 "sub{b}\t{%1, %0|%0, %1}"
7356 [(set_attr "type" "alu1")
7357 (set_attr "mode" "QI")])
7359 (define_insn "*sub<mode>_2"
7360 [(set (reg FLAGS_REG)
7363 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7364 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7366 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7367 (minus:SWI (match_dup 1) (match_dup 2)))]
7368 "ix86_match_ccmode (insn, CCGOCmode)
7369 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7370 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7371 [(set_attr "type" "alu")
7372 (set_attr "mode" "<MODE>")])
7374 (define_insn "*subsi_2_zext"
7375 [(set (reg FLAGS_REG)
7377 (minus:SI (match_operand:SI 1 "register_operand" "0")
7378 (match_operand:SI 2 "general_operand" "g"))
7380 (set (match_operand:DI 0 "register_operand" "=r")
7382 (minus:SI (match_dup 1)
7384 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7385 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7386 "sub{l}\t{%2, %k0|%k0, %2}"
7387 [(set_attr "type" "alu")
7388 (set_attr "mode" "SI")])
7390 (define_insn "*sub<mode>_3"
7391 [(set (reg FLAGS_REG)
7392 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7393 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7394 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7395 (minus:SWI (match_dup 1) (match_dup 2)))]
7396 "ix86_match_ccmode (insn, CCmode)
7397 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7398 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7399 [(set_attr "type" "alu")
7400 (set_attr "mode" "<MODE>")])
7402 (define_insn "*subsi_3_zext"
7403 [(set (reg FLAGS_REG)
7404 (compare (match_operand:SI 1 "register_operand" "0")
7405 (match_operand:SI 2 "general_operand" "g")))
7406 (set (match_operand:DI 0 "register_operand" "=r")
7408 (minus:SI (match_dup 1)
7410 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7411 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7412 "sub{l}\t{%2, %1|%1, %2}"
7413 [(set_attr "type" "alu")
7414 (set_attr "mode" "SI")])
7416 ;; Add with carry and subtract with borrow
7418 (define_expand "<plusminus_insn><mode>3_carry"
7420 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7422 (match_operand:SWI 1 "nonimmediate_operand" "")
7423 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7424 [(match_operand 3 "flags_reg_operand" "")
7426 (match_operand:SWI 2 "<general_operand>" ""))))
7427 (clobber (reg:CC FLAGS_REG))])]
7428 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7431 (define_insn "*<plusminus_insn><mode>3_carry"
7432 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7434 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7436 (match_operator 3 "ix86_carry_flag_operator"
7437 [(reg FLAGS_REG) (const_int 0)])
7438 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7439 (clobber (reg:CC FLAGS_REG))]
7440 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7441 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7442 [(set_attr "type" "alu")
7443 (set_attr "use_carry" "1")
7444 (set_attr "pent_pair" "pu")
7445 (set_attr "mode" "<MODE>")])
7447 (define_insn "*addsi3_carry_zext"
7448 [(set (match_operand:DI 0 "register_operand" "=r")
7450 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7451 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7452 [(reg FLAGS_REG) (const_int 0)])
7453 (match_operand:SI 2 "general_operand" "g")))))
7454 (clobber (reg:CC FLAGS_REG))]
7455 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7456 "adc{l}\t{%2, %k0|%k0, %2}"
7457 [(set_attr "type" "alu")
7458 (set_attr "use_carry" "1")
7459 (set_attr "pent_pair" "pu")
7460 (set_attr "mode" "SI")])
7462 (define_insn "*subsi3_carry_zext"
7463 [(set (match_operand:DI 0 "register_operand" "=r")
7465 (minus:SI (match_operand:SI 1 "register_operand" "0")
7466 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7467 [(reg FLAGS_REG) (const_int 0)])
7468 (match_operand:SI 2 "general_operand" "g")))))
7469 (clobber (reg:CC FLAGS_REG))]
7470 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7471 "sbb{l}\t{%2, %k0|%k0, %2}"
7472 [(set_attr "type" "alu")
7473 (set_attr "pent_pair" "pu")
7474 (set_attr "mode" "SI")])
7476 ;; Overflow setting add and subtract instructions
7478 (define_insn "*add<mode>3_cconly_overflow"
7479 [(set (reg:CCC FLAGS_REG)
7482 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7483 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7485 (clobber (match_scratch:SWI 0 "=<r>"))]
7486 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7487 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7488 [(set_attr "type" "alu")
7489 (set_attr "mode" "<MODE>")])
7491 (define_insn "*sub<mode>3_cconly_overflow"
7492 [(set (reg:CCC FLAGS_REG)
7495 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7496 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7499 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7500 [(set_attr "type" "icmp")
7501 (set_attr "mode" "<MODE>")])
7503 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7504 [(set (reg:CCC FLAGS_REG)
7507 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7508 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7510 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7511 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7512 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7513 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7514 [(set_attr "type" "alu")
7515 (set_attr "mode" "<MODE>")])
7517 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7518 [(set (reg:CCC FLAGS_REG)
7521 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7522 (match_operand:SI 2 "general_operand" "g"))
7524 (set (match_operand:DI 0 "register_operand" "=r")
7525 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7526 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7527 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7528 [(set_attr "type" "alu")
7529 (set_attr "mode" "SI")])
7531 ;; The patterns that match these are at the end of this file.
7533 (define_expand "<plusminus_insn>xf3"
7534 [(set (match_operand:XF 0 "register_operand" "")
7536 (match_operand:XF 1 "register_operand" "")
7537 (match_operand:XF 2 "register_operand" "")))]
7541 (define_expand "<plusminus_insn><mode>3"
7542 [(set (match_operand:MODEF 0 "register_operand" "")
7544 (match_operand:MODEF 1 "register_operand" "")
7545 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7546 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7547 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7550 ;; Multiply instructions
7552 (define_expand "mul<mode>3"
7553 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7555 (match_operand:SWIM248 1 "register_operand" "")
7556 (match_operand:SWIM248 2 "<general_operand>" "")))
7557 (clobber (reg:CC FLAGS_REG))])]
7561 (define_expand "mulqi3"
7562 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7564 (match_operand:QI 1 "register_operand" "")
7565 (match_operand:QI 2 "nonimmediate_operand" "")))
7566 (clobber (reg:CC FLAGS_REG))])]
7567 "TARGET_QIMODE_MATH"
7571 ;; IMUL reg32/64, reg32/64, imm8 Direct
7572 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7573 ;; IMUL reg32/64, reg32/64, imm32 Direct
7574 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7575 ;; IMUL reg32/64, reg32/64 Direct
7576 ;; IMUL reg32/64, mem32/64 Direct
7578 (define_insn "*mul<mode>3_1"
7579 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7581 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7582 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7583 (clobber (reg:CC FLAGS_REG))]
7584 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7586 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7587 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7588 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7589 [(set_attr "type" "imul")
7590 (set_attr "prefix_0f" "0,0,1")
7591 (set (attr "athlon_decode")
7592 (cond [(eq_attr "cpu" "athlon")
7593 (const_string "vector")
7594 (eq_attr "alternative" "1")
7595 (const_string "vector")
7596 (and (eq_attr "alternative" "2")
7597 (match_operand 1 "memory_operand" ""))
7598 (const_string "vector")]
7599 (const_string "direct")))
7600 (set (attr "amdfam10_decode")
7601 (cond [(and (eq_attr "alternative" "0,1")
7602 (match_operand 1 "memory_operand" ""))
7603 (const_string "vector")]
7604 (const_string "direct")))
7605 (set_attr "mode" "<MODE>")])
7607 (define_insn "*mulsi3_1_zext"
7608 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7610 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7611 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7612 (clobber (reg:CC FLAGS_REG))]
7614 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7616 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7617 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7618 imul{l}\t{%2, %k0|%k0, %2}"
7619 [(set_attr "type" "imul")
7620 (set_attr "prefix_0f" "0,0,1")
7621 (set (attr "athlon_decode")
7622 (cond [(eq_attr "cpu" "athlon")
7623 (const_string "vector")
7624 (eq_attr "alternative" "1")
7625 (const_string "vector")
7626 (and (eq_attr "alternative" "2")
7627 (match_operand 1 "memory_operand" ""))
7628 (const_string "vector")]
7629 (const_string "direct")))
7630 (set (attr "amdfam10_decode")
7631 (cond [(and (eq_attr "alternative" "0,1")
7632 (match_operand 1 "memory_operand" ""))
7633 (const_string "vector")]
7634 (const_string "direct")))
7635 (set_attr "mode" "SI")])
7638 ;; IMUL reg16, reg16, imm8 VectorPath
7639 ;; IMUL reg16, mem16, imm8 VectorPath
7640 ;; IMUL reg16, reg16, imm16 VectorPath
7641 ;; IMUL reg16, mem16, imm16 VectorPath
7642 ;; IMUL reg16, reg16 Direct
7643 ;; IMUL reg16, mem16 Direct
7645 (define_insn "*mulhi3_1"
7646 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7647 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7648 (match_operand:HI 2 "general_operand" "K,n,mr")))
7649 (clobber (reg:CC FLAGS_REG))]
7651 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7653 imul{w}\t{%2, %1, %0|%0, %1, %2}
7654 imul{w}\t{%2, %1, %0|%0, %1, %2}
7655 imul{w}\t{%2, %0|%0, %2}"
7656 [(set_attr "type" "imul")
7657 (set_attr "prefix_0f" "0,0,1")
7658 (set (attr "athlon_decode")
7659 (cond [(eq_attr "cpu" "athlon")
7660 (const_string "vector")
7661 (eq_attr "alternative" "1,2")
7662 (const_string "vector")]
7663 (const_string "direct")))
7664 (set (attr "amdfam10_decode")
7665 (cond [(eq_attr "alternative" "0,1")
7666 (const_string "vector")]
7667 (const_string "direct")))
7668 (set_attr "mode" "HI")])
7674 (define_insn "*mulqi3_1"
7675 [(set (match_operand:QI 0 "register_operand" "=a")
7676 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7677 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7678 (clobber (reg:CC FLAGS_REG))]
7680 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7682 [(set_attr "type" "imul")
7683 (set_attr "length_immediate" "0")
7684 (set (attr "athlon_decode")
7685 (if_then_else (eq_attr "cpu" "athlon")
7686 (const_string "vector")
7687 (const_string "direct")))
7688 (set_attr "amdfam10_decode" "direct")
7689 (set_attr "mode" "QI")])
7691 (define_expand "<u>mul<mode><dwi>3"
7692 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7695 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7697 (match_operand:DWIH 2 "register_operand" ""))))
7698 (clobber (reg:CC FLAGS_REG))])]
7702 (define_expand "<u>mulqihi3"
7703 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7706 (match_operand:QI 1 "nonimmediate_operand" ""))
7708 (match_operand:QI 2 "register_operand" ""))))
7709 (clobber (reg:CC FLAGS_REG))])]
7710 "TARGET_QIMODE_MATH"
7713 (define_insn "*<u>mul<mode><dwi>3_1"
7714 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7717 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7719 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7720 (clobber (reg:CC FLAGS_REG))]
7721 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7722 "<sgnprefix>mul{<imodesuffix>}\t%2"
7723 [(set_attr "type" "imul")
7724 (set_attr "length_immediate" "0")
7725 (set (attr "athlon_decode")
7726 (if_then_else (eq_attr "cpu" "athlon")
7727 (const_string "vector")
7728 (const_string "double")))
7729 (set_attr "amdfam10_decode" "double")
7730 (set_attr "mode" "<MODE>")])
7732 (define_insn "*<u>mulqihi3_1"
7733 [(set (match_operand:HI 0 "register_operand" "=a")
7736 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7738 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7739 (clobber (reg:CC FLAGS_REG))]
7741 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7742 "<sgnprefix>mul{b}\t%2"
7743 [(set_attr "type" "imul")
7744 (set_attr "length_immediate" "0")
7745 (set (attr "athlon_decode")
7746 (if_then_else (eq_attr "cpu" "athlon")
7747 (const_string "vector")
7748 (const_string "direct")))
7749 (set_attr "amdfam10_decode" "direct")
7750 (set_attr "mode" "QI")])
7752 (define_expand "<s>mul<mode>3_highpart"
7753 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7758 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7760 (match_operand:SWI48 2 "register_operand" "")))
7762 (clobber (match_scratch:SWI48 3 ""))
7763 (clobber (reg:CC FLAGS_REG))])]
7765 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7767 (define_insn "*<s>muldi3_highpart_1"
7768 [(set (match_operand:DI 0 "register_operand" "=d")
7773 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7775 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7777 (clobber (match_scratch:DI 3 "=1"))
7778 (clobber (reg:CC FLAGS_REG))]
7780 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7781 "<sgnprefix>mul{q}\t%2"
7782 [(set_attr "type" "imul")
7783 (set_attr "length_immediate" "0")
7784 (set (attr "athlon_decode")
7785 (if_then_else (eq_attr "cpu" "athlon")
7786 (const_string "vector")
7787 (const_string "double")))
7788 (set_attr "amdfam10_decode" "double")
7789 (set_attr "mode" "DI")])
7791 (define_insn "*<s>mulsi3_highpart_1"
7792 [(set (match_operand:SI 0 "register_operand" "=d")
7797 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7799 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7801 (clobber (match_scratch:SI 3 "=1"))
7802 (clobber (reg:CC FLAGS_REG))]
7803 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7804 "<sgnprefix>mul{l}\t%2"
7805 [(set_attr "type" "imul")
7806 (set_attr "length_immediate" "0")
7807 (set (attr "athlon_decode")
7808 (if_then_else (eq_attr "cpu" "athlon")
7809 (const_string "vector")
7810 (const_string "double")))
7811 (set_attr "amdfam10_decode" "double")
7812 (set_attr "mode" "SI")])
7814 (define_insn "*<s>mulsi3_highpart_zext"
7815 [(set (match_operand:DI 0 "register_operand" "=d")
7816 (zero_extend:DI (truncate:SI
7818 (mult:DI (any_extend:DI
7819 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7821 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7823 (clobber (match_scratch:SI 3 "=1"))
7824 (clobber (reg:CC FLAGS_REG))]
7826 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7827 "<sgnprefix>mul{l}\t%2"
7828 [(set_attr "type" "imul")
7829 (set_attr "length_immediate" "0")
7830 (set (attr "athlon_decode")
7831 (if_then_else (eq_attr "cpu" "athlon")
7832 (const_string "vector")
7833 (const_string "double")))
7834 (set_attr "amdfam10_decode" "double")
7835 (set_attr "mode" "SI")])
7837 ;; The patterns that match these are at the end of this file.
7839 (define_expand "mulxf3"
7840 [(set (match_operand:XF 0 "register_operand" "")
7841 (mult:XF (match_operand:XF 1 "register_operand" "")
7842 (match_operand:XF 2 "register_operand" "")))]
7846 (define_expand "mul<mode>3"
7847 [(set (match_operand:MODEF 0 "register_operand" "")
7848 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7849 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7850 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7851 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7854 ;; Divide instructions
7856 (define_insn "<u>divqi3"
7857 [(set (match_operand:QI 0 "register_operand" "=a")
7859 (match_operand:HI 1 "register_operand" "0")
7860 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7861 (clobber (reg:CC FLAGS_REG))]
7862 "TARGET_QIMODE_MATH"
7863 "<sgnprefix>div{b}\t%2"
7864 [(set_attr "type" "idiv")
7865 (set_attr "mode" "QI")])
7867 ;; The patterns that match these are at the end of this file.
7869 (define_expand "divxf3"
7870 [(set (match_operand:XF 0 "register_operand" "")
7871 (div:XF (match_operand:XF 1 "register_operand" "")
7872 (match_operand:XF 2 "register_operand" "")))]
7876 (define_expand "divdf3"
7877 [(set (match_operand:DF 0 "register_operand" "")
7878 (div:DF (match_operand:DF 1 "register_operand" "")
7879 (match_operand:DF 2 "nonimmediate_operand" "")))]
7880 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7881 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7884 (define_expand "divsf3"
7885 [(set (match_operand:SF 0 "register_operand" "")
7886 (div:SF (match_operand:SF 1 "register_operand" "")
7887 (match_operand:SF 2 "nonimmediate_operand" "")))]
7888 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7891 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7892 && flag_finite_math_only && !flag_trapping_math
7893 && flag_unsafe_math_optimizations)
7895 ix86_emit_swdivsf (operands[0], operands[1],
7896 operands[2], SFmode);
7901 ;; Divmod instructions.
7903 (define_expand "divmod<mode>4"
7904 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7906 (match_operand:SWIM248 1 "register_operand" "")
7907 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7908 (set (match_operand:SWIM248 3 "register_operand" "")
7909 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7910 (clobber (reg:CC FLAGS_REG))])]
7914 (define_insn_and_split "*divmod<mode>4"
7915 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7916 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7917 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7918 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7919 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7920 (clobber (reg:CC FLAGS_REG))]
7924 [(parallel [(set (match_dup 1)
7925 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7926 (clobber (reg:CC FLAGS_REG))])
7927 (parallel [(set (match_dup 0)
7928 (div:SWIM248 (match_dup 2) (match_dup 3)))
7930 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7932 (clobber (reg:CC FLAGS_REG))])]
7934 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7936 if (<MODE>mode != HImode
7937 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7938 operands[4] = operands[2];
7941 /* Avoid use of cltd in favor of a mov+shift. */
7942 emit_move_insn (operands[1], operands[2]);
7943 operands[4] = operands[1];
7946 [(set_attr "type" "multi")
7947 (set_attr "mode" "<MODE>")])
7949 (define_insn "*divmod<mode>4_noext"
7950 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7951 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7952 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7953 (set (match_operand:SWIM248 1 "register_operand" "=d")
7954 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7955 (use (match_operand:SWIM248 4 "register_operand" "1"))
7956 (clobber (reg:CC FLAGS_REG))]
7958 "idiv{<imodesuffix>}\t%3"
7959 [(set_attr "type" "idiv")
7960 (set_attr "mode" "<MODE>")])
7962 (define_expand "udivmod<mode>4"
7963 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7965 (match_operand:SWIM248 1 "register_operand" "")
7966 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7967 (set (match_operand:SWIM248 3 "register_operand" "")
7968 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7969 (clobber (reg:CC FLAGS_REG))])]
7973 (define_insn_and_split "*udivmod<mode>4"
7974 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7975 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7976 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7977 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7978 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7979 (clobber (reg:CC FLAGS_REG))]
7983 [(set (match_dup 1) (const_int 0))
7984 (parallel [(set (match_dup 0)
7985 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7987 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7989 (clobber (reg:CC FLAGS_REG))])]
7991 [(set_attr "type" "multi")
7992 (set_attr "mode" "<MODE>")])
7994 (define_insn "*udivmod<mode>4_noext"
7995 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7996 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7997 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7998 (set (match_operand:SWIM248 1 "register_operand" "=d")
7999 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8000 (use (match_operand:SWIM248 4 "register_operand" "1"))
8001 (clobber (reg:CC FLAGS_REG))]
8003 "div{<imodesuffix>}\t%3"
8004 [(set_attr "type" "idiv")
8005 (set_attr "mode" "<MODE>")])
8007 ;; We cannot use div/idiv for double division, because it causes
8008 ;; "division by zero" on the overflow and that's not what we expect
8009 ;; from truncate. Because true (non truncating) double division is
8010 ;; never generated, we can't create this insn anyway.
8013 ; [(set (match_operand:SI 0 "register_operand" "=a")
8015 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8017 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8018 ; (set (match_operand:SI 3 "register_operand" "=d")
8020 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8021 ; (clobber (reg:CC FLAGS_REG))]
8023 ; "div{l}\t{%2, %0|%0, %2}"
8024 ; [(set_attr "type" "idiv")])
8026 ;;- Logical AND instructions
8028 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8029 ;; Note that this excludes ah.
8031 (define_expand "testsi_ccno_1"
8032 [(set (reg:CCNO FLAGS_REG)
8034 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8035 (match_operand:SI 1 "nonmemory_operand" ""))
8040 (define_expand "testqi_ccz_1"
8041 [(set (reg:CCZ FLAGS_REG)
8042 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8043 (match_operand:QI 1 "nonmemory_operand" ""))
8048 (define_insn "*testdi_1"
8049 [(set (reg FLAGS_REG)
8052 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8053 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8055 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8056 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8058 test{l}\t{%k1, %k0|%k0, %k1}
8059 test{l}\t{%k1, %k0|%k0, %k1}
8060 test{q}\t{%1, %0|%0, %1}
8061 test{q}\t{%1, %0|%0, %1}
8062 test{q}\t{%1, %0|%0, %1}"
8063 [(set_attr "type" "test")
8064 (set_attr "modrm" "0,1,0,1,1")
8065 (set_attr "mode" "SI,SI,DI,DI,DI")])
8067 (define_insn "*testqi_1_maybe_si"
8068 [(set (reg FLAGS_REG)
8071 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8072 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8074 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8075 && ix86_match_ccmode (insn,
8076 CONST_INT_P (operands[1])
8077 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8079 if (which_alternative == 3)
8081 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8082 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8083 return "test{l}\t{%1, %k0|%k0, %1}";
8085 return "test{b}\t{%1, %0|%0, %1}";
8087 [(set_attr "type" "test")
8088 (set_attr "modrm" "0,1,1,1")
8089 (set_attr "mode" "QI,QI,QI,SI")
8090 (set_attr "pent_pair" "uv,np,uv,np")])
8092 (define_insn "*test<mode>_1"
8093 [(set (reg FLAGS_REG)
8096 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8097 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8099 "ix86_match_ccmode (insn, CCNOmode)
8100 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8101 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8102 [(set_attr "type" "test")
8103 (set_attr "modrm" "0,1,1")
8104 (set_attr "mode" "<MODE>")
8105 (set_attr "pent_pair" "uv,np,uv")])
8107 (define_expand "testqi_ext_ccno_0"
8108 [(set (reg:CCNO FLAGS_REG)
8112 (match_operand 0 "ext_register_operand" "")
8115 (match_operand 1 "const_int_operand" ""))
8120 (define_insn "*testqi_ext_0"
8121 [(set (reg FLAGS_REG)
8125 (match_operand 0 "ext_register_operand" "Q")
8128 (match_operand 1 "const_int_operand" "n"))
8130 "ix86_match_ccmode (insn, CCNOmode)"
8131 "test{b}\t{%1, %h0|%h0, %1}"
8132 [(set_attr "type" "test")
8133 (set_attr "mode" "QI")
8134 (set_attr "length_immediate" "1")
8135 (set_attr "modrm" "1")
8136 (set_attr "pent_pair" "np")])
8138 (define_insn "*testqi_ext_1_rex64"
8139 [(set (reg FLAGS_REG)
8143 (match_operand 0 "ext_register_operand" "Q")
8147 (match_operand:QI 1 "register_operand" "Q")))
8149 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8150 "test{b}\t{%1, %h0|%h0, %1}"
8151 [(set_attr "type" "test")
8152 (set_attr "mode" "QI")])
8154 (define_insn "*testqi_ext_1"
8155 [(set (reg FLAGS_REG)
8159 (match_operand 0 "ext_register_operand" "Q")
8163 (match_operand:QI 1 "general_operand" "Qm")))
8165 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8166 "test{b}\t{%1, %h0|%h0, %1}"
8167 [(set_attr "type" "test")
8168 (set_attr "mode" "QI")])
8170 (define_insn "*testqi_ext_2"
8171 [(set (reg FLAGS_REG)
8175 (match_operand 0 "ext_register_operand" "Q")
8179 (match_operand 1 "ext_register_operand" "Q")
8183 "ix86_match_ccmode (insn, CCNOmode)"
8184 "test{b}\t{%h1, %h0|%h0, %h1}"
8185 [(set_attr "type" "test")
8186 (set_attr "mode" "QI")])
8188 (define_insn "*testqi_ext_3_rex64"
8189 [(set (reg FLAGS_REG)
8190 (compare (zero_extract:DI
8191 (match_operand 0 "nonimmediate_operand" "rm")
8192 (match_operand:DI 1 "const_int_operand" "")
8193 (match_operand:DI 2 "const_int_operand" ""))
8196 && ix86_match_ccmode (insn, CCNOmode)
8197 && INTVAL (operands[1]) > 0
8198 && INTVAL (operands[2]) >= 0
8199 /* Ensure that resulting mask is zero or sign extended operand. */
8200 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8201 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8202 && INTVAL (operands[1]) > 32))
8203 && (GET_MODE (operands[0]) == SImode
8204 || GET_MODE (operands[0]) == DImode
8205 || GET_MODE (operands[0]) == HImode
8206 || GET_MODE (operands[0]) == QImode)"
8209 ;; Combine likes to form bit extractions for some tests. Humor it.
8210 (define_insn "*testqi_ext_3"
8211 [(set (reg FLAGS_REG)
8212 (compare (zero_extract:SI
8213 (match_operand 0 "nonimmediate_operand" "rm")
8214 (match_operand:SI 1 "const_int_operand" "")
8215 (match_operand:SI 2 "const_int_operand" ""))
8217 "ix86_match_ccmode (insn, CCNOmode)
8218 && INTVAL (operands[1]) > 0
8219 && INTVAL (operands[2]) >= 0
8220 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8221 && (GET_MODE (operands[0]) == SImode
8222 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8223 || GET_MODE (operands[0]) == HImode
8224 || GET_MODE (operands[0]) == QImode)"
8228 [(set (match_operand 0 "flags_reg_operand" "")
8229 (match_operator 1 "compare_operator"
8231 (match_operand 2 "nonimmediate_operand" "")
8232 (match_operand 3 "const_int_operand" "")
8233 (match_operand 4 "const_int_operand" ""))
8235 "ix86_match_ccmode (insn, CCNOmode)"
8236 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8238 rtx val = operands[2];
8239 HOST_WIDE_INT len = INTVAL (operands[3]);
8240 HOST_WIDE_INT pos = INTVAL (operands[4]);
8242 enum machine_mode mode, submode;
8244 mode = GET_MODE (val);
8247 /* ??? Combine likes to put non-volatile mem extractions in QImode
8248 no matter the size of the test. So find a mode that works. */
8249 if (! MEM_VOLATILE_P (val))
8251 mode = smallest_mode_for_size (pos + len, MODE_INT);
8252 val = adjust_address (val, mode, 0);
8255 else if (GET_CODE (val) == SUBREG
8256 && (submode = GET_MODE (SUBREG_REG (val)),
8257 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8258 && pos + len <= GET_MODE_BITSIZE (submode)
8259 && GET_MODE_CLASS (submode) == MODE_INT)
8261 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8263 val = SUBREG_REG (val);
8265 else if (mode == HImode && pos + len <= 8)
8267 /* Small HImode tests can be converted to QImode. */
8269 val = gen_lowpart (QImode, val);
8272 if (len == HOST_BITS_PER_WIDE_INT)
8275 mask = ((HOST_WIDE_INT)1 << len) - 1;
8278 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8281 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8282 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8283 ;; this is relatively important trick.
8284 ;; Do the conversion only post-reload to avoid limiting of the register class
8287 [(set (match_operand 0 "flags_reg_operand" "")
8288 (match_operator 1 "compare_operator"
8289 [(and (match_operand 2 "register_operand" "")
8290 (match_operand 3 "const_int_operand" ""))
8293 && QI_REG_P (operands[2])
8294 && GET_MODE (operands[2]) != QImode
8295 && ((ix86_match_ccmode (insn, CCZmode)
8296 && !(INTVAL (operands[3]) & ~(255 << 8)))
8297 || (ix86_match_ccmode (insn, CCNOmode)
8298 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8301 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8304 "operands[2] = gen_lowpart (SImode, operands[2]);
8305 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8308 [(set (match_operand 0 "flags_reg_operand" "")
8309 (match_operator 1 "compare_operator"
8310 [(and (match_operand 2 "nonimmediate_operand" "")
8311 (match_operand 3 "const_int_operand" ""))
8314 && GET_MODE (operands[2]) != QImode
8315 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8316 && ((ix86_match_ccmode (insn, CCZmode)
8317 && !(INTVAL (operands[3]) & ~255))
8318 || (ix86_match_ccmode (insn, CCNOmode)
8319 && !(INTVAL (operands[3]) & ~127)))"
8321 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8323 "operands[2] = gen_lowpart (QImode, operands[2]);
8324 operands[3] = gen_lowpart (QImode, operands[3]);")
8326 ;; %%% This used to optimize known byte-wide and operations to memory,
8327 ;; and sometimes to QImode registers. If this is considered useful,
8328 ;; it should be done with splitters.
8330 (define_expand "and<mode>3"
8331 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8332 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8333 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8335 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8337 (define_insn "*anddi_1"
8338 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8340 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8341 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8342 (clobber (reg:CC FLAGS_REG))]
8343 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8345 switch (get_attr_type (insn))
8349 enum machine_mode mode;
8351 gcc_assert (CONST_INT_P (operands[2]));
8352 if (INTVAL (operands[2]) == 0xff)
8356 gcc_assert (INTVAL (operands[2]) == 0xffff);
8360 operands[1] = gen_lowpart (mode, operands[1]);
8362 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8364 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8368 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8369 if (get_attr_mode (insn) == MODE_SI)
8370 return "and{l}\t{%k2, %k0|%k0, %k2}";
8372 return "and{q}\t{%2, %0|%0, %2}";
8375 [(set_attr "type" "alu,alu,alu,imovx")
8376 (set_attr "length_immediate" "*,*,*,0")
8377 (set (attr "prefix_rex")
8379 (and (eq_attr "type" "imovx")
8380 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8381 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8383 (const_string "*")))
8384 (set_attr "mode" "SI,DI,DI,SI")])
8386 (define_insn "*andsi_1"
8387 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8388 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8389 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8390 (clobber (reg:CC FLAGS_REG))]
8391 "ix86_binary_operator_ok (AND, SImode, operands)"
8393 switch (get_attr_type (insn))
8397 enum machine_mode mode;
8399 gcc_assert (CONST_INT_P (operands[2]));
8400 if (INTVAL (operands[2]) == 0xff)
8404 gcc_assert (INTVAL (operands[2]) == 0xffff);
8408 operands[1] = gen_lowpart (mode, operands[1]);
8410 return "movz{bl|x}\t{%1, %0|%0, %1}";
8412 return "movz{wl|x}\t{%1, %0|%0, %1}";
8416 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8417 return "and{l}\t{%2, %0|%0, %2}";
8420 [(set_attr "type" "alu,alu,imovx")
8421 (set (attr "prefix_rex")
8423 (and (eq_attr "type" "imovx")
8424 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8425 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8427 (const_string "*")))
8428 (set_attr "length_immediate" "*,*,0")
8429 (set_attr "mode" "SI")])
8431 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8432 (define_insn "*andsi_1_zext"
8433 [(set (match_operand:DI 0 "register_operand" "=r")
8435 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8436 (match_operand:SI 2 "general_operand" "g"))))
8437 (clobber (reg:CC FLAGS_REG))]
8438 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8439 "and{l}\t{%2, %k0|%k0, %2}"
8440 [(set_attr "type" "alu")
8441 (set_attr "mode" "SI")])
8443 (define_insn "*andhi_1"
8444 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8445 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8446 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8447 (clobber (reg:CC FLAGS_REG))]
8448 "ix86_binary_operator_ok (AND, HImode, operands)"
8450 switch (get_attr_type (insn))
8453 gcc_assert (CONST_INT_P (operands[2]));
8454 gcc_assert (INTVAL (operands[2]) == 0xff);
8455 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8458 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8460 return "and{w}\t{%2, %0|%0, %2}";
8463 [(set_attr "type" "alu,alu,imovx")
8464 (set_attr "length_immediate" "*,*,0")
8465 (set (attr "prefix_rex")
8467 (and (eq_attr "type" "imovx")
8468 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8470 (const_string "*")))
8471 (set_attr "mode" "HI,HI,SI")])
8473 ;; %%% Potential partial reg stall on alternative 2. What to do?
8474 (define_insn "*andqi_1"
8475 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8476 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8477 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8478 (clobber (reg:CC FLAGS_REG))]
8479 "ix86_binary_operator_ok (AND, QImode, operands)"
8481 and{b}\t{%2, %0|%0, %2}
8482 and{b}\t{%2, %0|%0, %2}
8483 and{l}\t{%k2, %k0|%k0, %k2}"
8484 [(set_attr "type" "alu")
8485 (set_attr "mode" "QI,QI,SI")])
8487 (define_insn "*andqi_1_slp"
8488 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8489 (and:QI (match_dup 0)
8490 (match_operand:QI 1 "general_operand" "qn,qmn")))
8491 (clobber (reg:CC FLAGS_REG))]
8492 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8493 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8494 "and{b}\t{%1, %0|%0, %1}"
8495 [(set_attr "type" "alu1")
8496 (set_attr "mode" "QI")])
8499 [(set (match_operand 0 "register_operand" "")
8501 (const_int -65536)))
8502 (clobber (reg:CC FLAGS_REG))]
8503 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8504 || optimize_function_for_size_p (cfun)"
8505 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8506 "operands[1] = gen_lowpart (HImode, operands[0]);")
8509 [(set (match_operand 0 "ext_register_operand" "")
8512 (clobber (reg:CC FLAGS_REG))]
8513 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8514 && reload_completed"
8515 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8516 "operands[1] = gen_lowpart (QImode, operands[0]);")
8519 [(set (match_operand 0 "ext_register_operand" "")
8521 (const_int -65281)))
8522 (clobber (reg:CC FLAGS_REG))]
8523 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8524 && reload_completed"
8525 [(parallel [(set (zero_extract:SI (match_dup 0)
8529 (zero_extract:SI (match_dup 0)
8532 (zero_extract:SI (match_dup 0)
8535 (clobber (reg:CC FLAGS_REG))])]
8536 "operands[0] = gen_lowpart (SImode, operands[0]);")
8538 (define_insn "*anddi_2"
8539 [(set (reg FLAGS_REG)
8542 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8543 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8545 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8546 (and:DI (match_dup 1) (match_dup 2)))]
8547 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8548 && ix86_binary_operator_ok (AND, DImode, operands)"
8550 and{l}\t{%k2, %k0|%k0, %k2}
8551 and{q}\t{%2, %0|%0, %2}
8552 and{q}\t{%2, %0|%0, %2}"
8553 [(set_attr "type" "alu")
8554 (set_attr "mode" "SI,DI,DI")])
8556 (define_insn "*andqi_2_maybe_si"
8557 [(set (reg FLAGS_REG)
8559 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8560 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8562 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8563 (and:QI (match_dup 1) (match_dup 2)))]
8564 "ix86_binary_operator_ok (AND, QImode, operands)
8565 && ix86_match_ccmode (insn,
8566 CONST_INT_P (operands[2])
8567 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8569 if (which_alternative == 2)
8571 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8572 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8573 return "and{l}\t{%2, %k0|%k0, %2}";
8575 return "and{b}\t{%2, %0|%0, %2}";
8577 [(set_attr "type" "alu")
8578 (set_attr "mode" "QI,QI,SI")])
8580 (define_insn "*and<mode>_2"
8581 [(set (reg FLAGS_REG)
8582 (compare (and:SWI124
8583 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8584 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8586 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8587 (and:SWI124 (match_dup 1) (match_dup 2)))]
8588 "ix86_match_ccmode (insn, CCNOmode)
8589 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8590 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8591 [(set_attr "type" "alu")
8592 (set_attr "mode" "<MODE>")])
8594 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8595 (define_insn "*andsi_2_zext"
8596 [(set (reg FLAGS_REG)
8598 (match_operand:SI 1 "nonimmediate_operand" "%0")
8599 (match_operand:SI 2 "general_operand" "g"))
8601 (set (match_operand:DI 0 "register_operand" "=r")
8602 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8603 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8604 && ix86_binary_operator_ok (AND, SImode, operands)"
8605 "and{l}\t{%2, %k0|%k0, %2}"
8606 [(set_attr "type" "alu")
8607 (set_attr "mode" "SI")])
8609 (define_insn "*andqi_2_slp"
8610 [(set (reg FLAGS_REG)
8612 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8613 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8615 (set (strict_low_part (match_dup 0))
8616 (and:QI (match_dup 0) (match_dup 1)))]
8617 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8618 && ix86_match_ccmode (insn, CCNOmode)
8619 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8620 "and{b}\t{%1, %0|%0, %1}"
8621 [(set_attr "type" "alu1")
8622 (set_attr "mode" "QI")])
8624 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8625 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8626 ;; for a QImode operand, which of course failed.
8627 (define_insn "andqi_ext_0"
8628 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8633 (match_operand 1 "ext_register_operand" "0")
8636 (match_operand 2 "const_int_operand" "n")))
8637 (clobber (reg:CC FLAGS_REG))]
8639 "and{b}\t{%2, %h0|%h0, %2}"
8640 [(set_attr "type" "alu")
8641 (set_attr "length_immediate" "1")
8642 (set_attr "modrm" "1")
8643 (set_attr "mode" "QI")])
8645 ;; Generated by peephole translating test to and. This shows up
8646 ;; often in fp comparisons.
8647 (define_insn "*andqi_ext_0_cc"
8648 [(set (reg FLAGS_REG)
8652 (match_operand 1 "ext_register_operand" "0")
8655 (match_operand 2 "const_int_operand" "n"))
8657 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8666 "ix86_match_ccmode (insn, CCNOmode)"
8667 "and{b}\t{%2, %h0|%h0, %2}"
8668 [(set_attr "type" "alu")
8669 (set_attr "length_immediate" "1")
8670 (set_attr "modrm" "1")
8671 (set_attr "mode" "QI")])
8673 (define_insn "*andqi_ext_1_rex64"
8674 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8679 (match_operand 1 "ext_register_operand" "0")
8683 (match_operand 2 "ext_register_operand" "Q"))))
8684 (clobber (reg:CC FLAGS_REG))]
8686 "and{b}\t{%2, %h0|%h0, %2}"
8687 [(set_attr "type" "alu")
8688 (set_attr "length_immediate" "0")
8689 (set_attr "mode" "QI")])
8691 (define_insn "*andqi_ext_1"
8692 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8697 (match_operand 1 "ext_register_operand" "0")
8701 (match_operand:QI 2 "general_operand" "Qm"))))
8702 (clobber (reg:CC FLAGS_REG))]
8704 "and{b}\t{%2, %h0|%h0, %2}"
8705 [(set_attr "type" "alu")
8706 (set_attr "length_immediate" "0")
8707 (set_attr "mode" "QI")])
8709 (define_insn "*andqi_ext_2"
8710 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8715 (match_operand 1 "ext_register_operand" "%0")
8719 (match_operand 2 "ext_register_operand" "Q")
8722 (clobber (reg:CC FLAGS_REG))]
8724 "and{b}\t{%h2, %h0|%h0, %h2}"
8725 [(set_attr "type" "alu")
8726 (set_attr "length_immediate" "0")
8727 (set_attr "mode" "QI")])
8729 ;; Convert wide AND instructions with immediate operand to shorter QImode
8730 ;; equivalents when possible.
8731 ;; Don't do the splitting with memory operands, since it introduces risk
8732 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8733 ;; for size, but that can (should?) be handled by generic code instead.
8735 [(set (match_operand 0 "register_operand" "")
8736 (and (match_operand 1 "register_operand" "")
8737 (match_operand 2 "const_int_operand" "")))
8738 (clobber (reg:CC FLAGS_REG))]
8740 && QI_REG_P (operands[0])
8741 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8742 && !(~INTVAL (operands[2]) & ~(255 << 8))
8743 && GET_MODE (operands[0]) != QImode"
8744 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8745 (and:SI (zero_extract:SI (match_dup 1)
8746 (const_int 8) (const_int 8))
8748 (clobber (reg:CC FLAGS_REG))])]
8749 "operands[0] = gen_lowpart (SImode, operands[0]);
8750 operands[1] = gen_lowpart (SImode, operands[1]);
8751 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8753 ;; Since AND can be encoded with sign extended immediate, this is only
8754 ;; profitable when 7th bit is not set.
8756 [(set (match_operand 0 "register_operand" "")
8757 (and (match_operand 1 "general_operand" "")
8758 (match_operand 2 "const_int_operand" "")))
8759 (clobber (reg:CC FLAGS_REG))]
8761 && ANY_QI_REG_P (operands[0])
8762 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8763 && !(~INTVAL (operands[2]) & ~255)
8764 && !(INTVAL (operands[2]) & 128)
8765 && GET_MODE (operands[0]) != QImode"
8766 [(parallel [(set (strict_low_part (match_dup 0))
8767 (and:QI (match_dup 1)
8769 (clobber (reg:CC FLAGS_REG))])]
8770 "operands[0] = gen_lowpart (QImode, operands[0]);
8771 operands[1] = gen_lowpart (QImode, operands[1]);
8772 operands[2] = gen_lowpart (QImode, operands[2]);")
8774 ;; Logical inclusive and exclusive OR instructions
8776 ;; %%% This used to optimize known byte-wide and operations to memory.
8777 ;; If this is considered useful, it should be done with splitters.
8779 (define_expand "<code><mode>3"
8780 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8781 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8782 (match_operand:SWIM 2 "<general_operand>" "")))]
8784 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8786 (define_insn "*<code><mode>_1"
8787 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8789 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8790 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8791 (clobber (reg:CC FLAGS_REG))]
8792 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8793 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8794 [(set_attr "type" "alu")
8795 (set_attr "mode" "<MODE>")])
8797 ;; %%% Potential partial reg stall on alternative 2. What to do?
8798 (define_insn "*<code>qi_1"
8799 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8800 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8801 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8802 (clobber (reg:CC FLAGS_REG))]
8803 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8805 <logic>{b}\t{%2, %0|%0, %2}
8806 <logic>{b}\t{%2, %0|%0, %2}
8807 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8808 [(set_attr "type" "alu")
8809 (set_attr "mode" "QI,QI,SI")])
8811 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8812 (define_insn "*<code>si_1_zext"
8813 [(set (match_operand:DI 0 "register_operand" "=r")
8815 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8816 (match_operand:SI 2 "general_operand" "g"))))
8817 (clobber (reg:CC FLAGS_REG))]
8818 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8819 "<logic>{l}\t{%2, %k0|%k0, %2}"
8820 [(set_attr "type" "alu")
8821 (set_attr "mode" "SI")])
8823 (define_insn "*<code>si_1_zext_imm"
8824 [(set (match_operand:DI 0 "register_operand" "=r")
8826 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8827 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8828 (clobber (reg:CC FLAGS_REG))]
8829 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8830 "<logic>{l}\t{%2, %k0|%k0, %2}"
8831 [(set_attr "type" "alu")
8832 (set_attr "mode" "SI")])
8834 (define_insn "*<code>qi_1_slp"
8835 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8836 (any_or:QI (match_dup 0)
8837 (match_operand:QI 1 "general_operand" "qmn,qn")))
8838 (clobber (reg:CC FLAGS_REG))]
8839 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8840 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8841 "<logic>{b}\t{%1, %0|%0, %1}"
8842 [(set_attr "type" "alu1")
8843 (set_attr "mode" "QI")])
8845 (define_insn "*<code><mode>_2"
8846 [(set (reg FLAGS_REG)
8847 (compare (any_or:SWI
8848 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8849 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8851 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8852 (any_or:SWI (match_dup 1) (match_dup 2)))]
8853 "ix86_match_ccmode (insn, CCNOmode)
8854 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8855 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8856 [(set_attr "type" "alu")
8857 (set_attr "mode" "<MODE>")])
8859 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8860 ;; ??? Special case for immediate operand is missing - it is tricky.
8861 (define_insn "*<code>si_2_zext"
8862 [(set (reg FLAGS_REG)
8863 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8864 (match_operand:SI 2 "general_operand" "g"))
8866 (set (match_operand:DI 0 "register_operand" "=r")
8867 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8868 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8869 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8870 "<logic>{l}\t{%2, %k0|%k0, %2}"
8871 [(set_attr "type" "alu")
8872 (set_attr "mode" "SI")])
8874 (define_insn "*<code>si_2_zext_imm"
8875 [(set (reg FLAGS_REG)
8877 (match_operand:SI 1 "nonimmediate_operand" "%0")
8878 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8880 (set (match_operand:DI 0 "register_operand" "=r")
8881 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8882 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8883 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8884 "<logic>{l}\t{%2, %k0|%k0, %2}"
8885 [(set_attr "type" "alu")
8886 (set_attr "mode" "SI")])
8888 (define_insn "*<code>qi_2_slp"
8889 [(set (reg FLAGS_REG)
8890 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8891 (match_operand:QI 1 "general_operand" "qmn,qn"))
8893 (set (strict_low_part (match_dup 0))
8894 (any_or:QI (match_dup 0) (match_dup 1)))]
8895 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8896 && ix86_match_ccmode (insn, CCNOmode)
8897 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8898 "<logic>{b}\t{%1, %0|%0, %1}"
8899 [(set_attr "type" "alu1")
8900 (set_attr "mode" "QI")])
8902 (define_insn "*<code><mode>_3"
8903 [(set (reg FLAGS_REG)
8904 (compare (any_or:SWI
8905 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8906 (match_operand:SWI 2 "<general_operand>" "<g>"))
8908 (clobber (match_scratch:SWI 0 "=<r>"))]
8909 "ix86_match_ccmode (insn, CCNOmode)
8910 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8911 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8912 [(set_attr "type" "alu")
8913 (set_attr "mode" "<MODE>")])
8915 (define_insn "*<code>qi_ext_0"
8916 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8921 (match_operand 1 "ext_register_operand" "0")
8924 (match_operand 2 "const_int_operand" "n")))
8925 (clobber (reg:CC FLAGS_REG))]
8926 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8927 "<logic>{b}\t{%2, %h0|%h0, %2}"
8928 [(set_attr "type" "alu")
8929 (set_attr "length_immediate" "1")
8930 (set_attr "modrm" "1")
8931 (set_attr "mode" "QI")])
8933 (define_insn "*<code>qi_ext_1_rex64"
8934 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8939 (match_operand 1 "ext_register_operand" "0")
8943 (match_operand 2 "ext_register_operand" "Q"))))
8944 (clobber (reg:CC FLAGS_REG))]
8946 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8947 "<logic>{b}\t{%2, %h0|%h0, %2}"
8948 [(set_attr "type" "alu")
8949 (set_attr "length_immediate" "0")
8950 (set_attr "mode" "QI")])
8952 (define_insn "*<code>qi_ext_1"
8953 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8958 (match_operand 1 "ext_register_operand" "0")
8962 (match_operand:QI 2 "general_operand" "Qm"))))
8963 (clobber (reg:CC FLAGS_REG))]
8965 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8966 "<logic>{b}\t{%2, %h0|%h0, %2}"
8967 [(set_attr "type" "alu")
8968 (set_attr "length_immediate" "0")
8969 (set_attr "mode" "QI")])
8971 (define_insn "*<code>qi_ext_2"
8972 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8976 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8979 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8982 (clobber (reg:CC FLAGS_REG))]
8983 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8984 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8985 [(set_attr "type" "alu")
8986 (set_attr "length_immediate" "0")
8987 (set_attr "mode" "QI")])
8990 [(set (match_operand 0 "register_operand" "")
8991 (any_or (match_operand 1 "register_operand" "")
8992 (match_operand 2 "const_int_operand" "")))
8993 (clobber (reg:CC FLAGS_REG))]
8995 && QI_REG_P (operands[0])
8996 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8997 && !(INTVAL (operands[2]) & ~(255 << 8))
8998 && GET_MODE (operands[0]) != QImode"
8999 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9000 (any_or:SI (zero_extract:SI (match_dup 1)
9001 (const_int 8) (const_int 8))
9003 (clobber (reg:CC FLAGS_REG))])]
9004 "operands[0] = gen_lowpart (SImode, operands[0]);
9005 operands[1] = gen_lowpart (SImode, operands[1]);
9006 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9008 ;; Since OR can be encoded with sign extended immediate, this is only
9009 ;; profitable when 7th bit is set.
9011 [(set (match_operand 0 "register_operand" "")
9012 (any_or (match_operand 1 "general_operand" "")
9013 (match_operand 2 "const_int_operand" "")))
9014 (clobber (reg:CC FLAGS_REG))]
9016 && ANY_QI_REG_P (operands[0])
9017 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9018 && !(INTVAL (operands[2]) & ~255)
9019 && (INTVAL (operands[2]) & 128)
9020 && GET_MODE (operands[0]) != QImode"
9021 [(parallel [(set (strict_low_part (match_dup 0))
9022 (any_or:QI (match_dup 1)
9024 (clobber (reg:CC FLAGS_REG))])]
9025 "operands[0] = gen_lowpart (QImode, operands[0]);
9026 operands[1] = gen_lowpart (QImode, operands[1]);
9027 operands[2] = gen_lowpart (QImode, operands[2]);")
9029 (define_expand "xorqi_cc_ext_1"
9031 (set (reg:CCNO FLAGS_REG)
9035 (match_operand 1 "ext_register_operand" "")
9038 (match_operand:QI 2 "general_operand" ""))
9040 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9052 (define_insn "*xorqi_cc_ext_1_rex64"
9053 [(set (reg FLAGS_REG)
9057 (match_operand 1 "ext_register_operand" "0")
9060 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9062 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9071 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9072 "xor{b}\t{%2, %h0|%h0, %2}"
9073 [(set_attr "type" "alu")
9074 (set_attr "modrm" "1")
9075 (set_attr "mode" "QI")])
9077 (define_insn "*xorqi_cc_ext_1"
9078 [(set (reg FLAGS_REG)
9082 (match_operand 1 "ext_register_operand" "0")
9085 (match_operand:QI 2 "general_operand" "qmn"))
9087 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9096 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9097 "xor{b}\t{%2, %h0|%h0, %2}"
9098 [(set_attr "type" "alu")
9099 (set_attr "modrm" "1")
9100 (set_attr "mode" "QI")])
9102 ;; Negation instructions
9104 (define_expand "neg<mode>2"
9105 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9106 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9108 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9110 (define_insn_and_split "*neg<dwi>2_doubleword"
9111 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9112 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9113 (clobber (reg:CC FLAGS_REG))]
9114 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9118 [(set (reg:CCZ FLAGS_REG)
9119 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9120 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9123 (plus:DWIH (match_dup 3)
9124 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9126 (clobber (reg:CC FLAGS_REG))])
9129 (neg:DWIH (match_dup 2)))
9130 (clobber (reg:CC FLAGS_REG))])]
9131 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9133 (define_insn "*neg<mode>2_1"
9134 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9135 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9136 (clobber (reg:CC FLAGS_REG))]
9137 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9138 "neg{<imodesuffix>}\t%0"
9139 [(set_attr "type" "negnot")
9140 (set_attr "mode" "<MODE>")])
9142 ;; Combine is quite creative about this pattern.
9143 (define_insn "*negsi2_1_zext"
9144 [(set (match_operand:DI 0 "register_operand" "=r")
9146 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9149 (clobber (reg:CC FLAGS_REG))]
9150 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9152 [(set_attr "type" "negnot")
9153 (set_attr "mode" "SI")])
9155 ;; The problem with neg is that it does not perform (compare x 0),
9156 ;; it really performs (compare 0 x), which leaves us with the zero
9157 ;; flag being the only useful item.
9159 (define_insn "*neg<mode>2_cmpz"
9160 [(set (reg:CCZ FLAGS_REG)
9162 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9164 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9165 (neg:SWI (match_dup 1)))]
9166 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9167 "neg{<imodesuffix>}\t%0"
9168 [(set_attr "type" "negnot")
9169 (set_attr "mode" "<MODE>")])
9171 (define_insn "*negsi2_cmpz_zext"
9172 [(set (reg:CCZ FLAGS_REG)
9176 (match_operand:DI 1 "register_operand" "0")
9180 (set (match_operand:DI 0 "register_operand" "=r")
9181 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9184 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9186 [(set_attr "type" "negnot")
9187 (set_attr "mode" "SI")])
9189 ;; Changing of sign for FP values is doable using integer unit too.
9191 (define_expand "<code><mode>2"
9192 [(set (match_operand:X87MODEF 0 "register_operand" "")
9193 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9194 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9195 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9197 (define_insn "*absneg<mode>2_mixed"
9198 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9199 (match_operator:MODEF 3 "absneg_operator"
9200 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9201 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9202 (clobber (reg:CC FLAGS_REG))]
9203 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9206 (define_insn "*absneg<mode>2_sse"
9207 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9208 (match_operator:MODEF 3 "absneg_operator"
9209 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9210 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9211 (clobber (reg:CC FLAGS_REG))]
9212 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9215 (define_insn "*absneg<mode>2_i387"
9216 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9217 (match_operator:X87MODEF 3 "absneg_operator"
9218 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9219 (use (match_operand 2 "" ""))
9220 (clobber (reg:CC FLAGS_REG))]
9221 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9224 (define_expand "<code>tf2"
9225 [(set (match_operand:TF 0 "register_operand" "")
9226 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9228 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9230 (define_insn "*absnegtf2_sse"
9231 [(set (match_operand:TF 0 "register_operand" "=x,x")
9232 (match_operator:TF 3 "absneg_operator"
9233 [(match_operand:TF 1 "register_operand" "0,x")]))
9234 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9235 (clobber (reg:CC FLAGS_REG))]
9239 ;; Splitters for fp abs and neg.
9242 [(set (match_operand 0 "fp_register_operand" "")
9243 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9244 (use (match_operand 2 "" ""))
9245 (clobber (reg:CC FLAGS_REG))]
9247 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9250 [(set (match_operand 0 "register_operand" "")
9251 (match_operator 3 "absneg_operator"
9252 [(match_operand 1 "register_operand" "")]))
9253 (use (match_operand 2 "nonimmediate_operand" ""))
9254 (clobber (reg:CC FLAGS_REG))]
9255 "reload_completed && SSE_REG_P (operands[0])"
9256 [(set (match_dup 0) (match_dup 3))]
9258 enum machine_mode mode = GET_MODE (operands[0]);
9259 enum machine_mode vmode = GET_MODE (operands[2]);
9262 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9263 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9264 if (operands_match_p (operands[0], operands[2]))
9267 operands[1] = operands[2];
9270 if (GET_CODE (operands[3]) == ABS)
9271 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9273 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9278 [(set (match_operand:SF 0 "register_operand" "")
9279 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9280 (use (match_operand:V4SF 2 "" ""))
9281 (clobber (reg:CC FLAGS_REG))]
9283 [(parallel [(set (match_dup 0) (match_dup 1))
9284 (clobber (reg:CC FLAGS_REG))])]
9287 operands[0] = gen_lowpart (SImode, operands[0]);
9288 if (GET_CODE (operands[1]) == ABS)
9290 tmp = gen_int_mode (0x7fffffff, SImode);
9291 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9295 tmp = gen_int_mode (0x80000000, SImode);
9296 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9302 [(set (match_operand:DF 0 "register_operand" "")
9303 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9304 (use (match_operand 2 "" ""))
9305 (clobber (reg:CC FLAGS_REG))]
9307 [(parallel [(set (match_dup 0) (match_dup 1))
9308 (clobber (reg:CC FLAGS_REG))])]
9313 tmp = gen_lowpart (DImode, operands[0]);
9314 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9317 if (GET_CODE (operands[1]) == ABS)
9320 tmp = gen_rtx_NOT (DImode, tmp);
9324 operands[0] = gen_highpart (SImode, operands[0]);
9325 if (GET_CODE (operands[1]) == ABS)
9327 tmp = gen_int_mode (0x7fffffff, SImode);
9328 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9332 tmp = gen_int_mode (0x80000000, SImode);
9333 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9340 [(set (match_operand:XF 0 "register_operand" "")
9341 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9342 (use (match_operand 2 "" ""))
9343 (clobber (reg:CC FLAGS_REG))]
9345 [(parallel [(set (match_dup 0) (match_dup 1))
9346 (clobber (reg:CC FLAGS_REG))])]
9349 operands[0] = gen_rtx_REG (SImode,
9350 true_regnum (operands[0])
9351 + (TARGET_64BIT ? 1 : 2));
9352 if (GET_CODE (operands[1]) == ABS)
9354 tmp = GEN_INT (0x7fff);
9355 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9359 tmp = GEN_INT (0x8000);
9360 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9365 ;; Conditionalize these after reload. If they match before reload, we
9366 ;; lose the clobber and ability to use integer instructions.
9368 (define_insn "*<code><mode>2_1"
9369 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9370 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9372 && (reload_completed
9373 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9374 "f<absneg_mnemonic>"
9375 [(set_attr "type" "fsgn")
9376 (set_attr "mode" "<MODE>")])
9378 (define_insn "*<code>extendsfdf2"
9379 [(set (match_operand:DF 0 "register_operand" "=f")
9380 (absneg:DF (float_extend:DF
9381 (match_operand:SF 1 "register_operand" "0"))))]
9382 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9383 "f<absneg_mnemonic>"
9384 [(set_attr "type" "fsgn")
9385 (set_attr "mode" "DF")])
9387 (define_insn "*<code>extendsfxf2"
9388 [(set (match_operand:XF 0 "register_operand" "=f")
9389 (absneg:XF (float_extend:XF
9390 (match_operand:SF 1 "register_operand" "0"))))]
9392 "f<absneg_mnemonic>"
9393 [(set_attr "type" "fsgn")
9394 (set_attr "mode" "XF")])
9396 (define_insn "*<code>extenddfxf2"
9397 [(set (match_operand:XF 0 "register_operand" "=f")
9398 (absneg:XF (float_extend:XF
9399 (match_operand:DF 1 "register_operand" "0"))))]
9401 "f<absneg_mnemonic>"
9402 [(set_attr "type" "fsgn")
9403 (set_attr "mode" "XF")])
9405 ;; Copysign instructions
9407 (define_mode_iterator CSGNMODE [SF DF TF])
9408 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9410 (define_expand "copysign<mode>3"
9411 [(match_operand:CSGNMODE 0 "register_operand" "")
9412 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9413 (match_operand:CSGNMODE 2 "register_operand" "")]
9414 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9415 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9417 ix86_expand_copysign (operands);
9421 (define_insn_and_split "copysign<mode>3_const"
9422 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9424 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9425 (match_operand:CSGNMODE 2 "register_operand" "0")
9426 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9428 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9429 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9431 "&& reload_completed"
9434 ix86_split_copysign_const (operands);
9438 (define_insn "copysign<mode>3_var"
9439 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9441 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9442 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9443 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9444 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9446 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9447 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9448 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9452 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9454 [(match_operand:CSGNMODE 2 "register_operand" "")
9455 (match_operand:CSGNMODE 3 "register_operand" "")
9456 (match_operand:<CSGNVMODE> 4 "" "")
9457 (match_operand:<CSGNVMODE> 5 "" "")]
9459 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9460 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9461 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9462 && reload_completed"
9465 ix86_split_copysign_var (operands);
9469 ;; One complement instructions
9471 (define_expand "one_cmpl<mode>2"
9472 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9473 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9475 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9477 (define_insn "*one_cmpl<mode>2_1"
9478 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9479 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9480 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9481 "not{<imodesuffix>}\t%0"
9482 [(set_attr "type" "negnot")
9483 (set_attr "mode" "<MODE>")])
9485 ;; %%% Potential partial reg stall on alternative 1. What to do?
9486 (define_insn "*one_cmplqi2_1"
9487 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9488 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9489 "ix86_unary_operator_ok (NOT, QImode, operands)"
9493 [(set_attr "type" "negnot")
9494 (set_attr "mode" "QI,SI")])
9496 ;; ??? Currently never generated - xor is used instead.
9497 (define_insn "*one_cmplsi2_1_zext"
9498 [(set (match_operand:DI 0 "register_operand" "=r")
9500 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9501 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9503 [(set_attr "type" "negnot")
9504 (set_attr "mode" "SI")])
9506 (define_insn "*one_cmpl<mode>2_2"
9507 [(set (reg FLAGS_REG)
9508 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9510 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9511 (not:SWI (match_dup 1)))]
9512 "ix86_match_ccmode (insn, CCNOmode)
9513 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9515 [(set_attr "type" "alu1")
9516 (set_attr "mode" "<MODE>")])
9519 [(set (match_operand 0 "flags_reg_operand" "")
9520 (match_operator 2 "compare_operator"
9521 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9523 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9524 (not:SWI (match_dup 3)))]
9525 "ix86_match_ccmode (insn, CCNOmode)"
9526 [(parallel [(set (match_dup 0)
9527 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9530 (xor:SWI (match_dup 3) (const_int -1)))])]
9533 ;; ??? Currently never generated - xor is used instead.
9534 (define_insn "*one_cmplsi2_2_zext"
9535 [(set (reg FLAGS_REG)
9536 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9538 (set (match_operand:DI 0 "register_operand" "=r")
9539 (zero_extend:DI (not:SI (match_dup 1))))]
9540 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9541 && ix86_unary_operator_ok (NOT, SImode, operands)"
9543 [(set_attr "type" "alu1")
9544 (set_attr "mode" "SI")])
9547 [(set (match_operand 0 "flags_reg_operand" "")
9548 (match_operator 2 "compare_operator"
9549 [(not:SI (match_operand:SI 3 "register_operand" ""))
9551 (set (match_operand:DI 1 "register_operand" "")
9552 (zero_extend:DI (not:SI (match_dup 3))))]
9553 "ix86_match_ccmode (insn, CCNOmode)"
9554 [(parallel [(set (match_dup 0)
9555 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9558 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9561 ;; Shift instructions
9563 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9564 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9565 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9566 ;; from the assembler input.
9568 ;; This instruction shifts the target reg/mem as usual, but instead of
9569 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9570 ;; is a left shift double, bits are taken from the high order bits of
9571 ;; reg, else if the insn is a shift right double, bits are taken from the
9572 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9573 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9575 ;; Since sh[lr]d does not change the `reg' operand, that is done
9576 ;; separately, making all shifts emit pairs of shift double and normal
9577 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9578 ;; support a 63 bit shift, each shift where the count is in a reg expands
9579 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9581 ;; If the shift count is a constant, we need never emit more than one
9582 ;; shift pair, instead using moves and sign extension for counts greater
9585 (define_expand "ashl<mode>3"
9586 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9587 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9588 (match_operand:QI 2 "nonmemory_operand" "")))]
9590 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9592 (define_insn "*ashl<mode>3_doubleword"
9593 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9594 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9595 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9596 (clobber (reg:CC FLAGS_REG))]
9599 [(set_attr "type" "multi")])
9602 [(set (match_operand:DWI 0 "register_operand" "")
9603 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9604 (match_operand:QI 2 "nonmemory_operand" "")))
9605 (clobber (reg:CC FLAGS_REG))]
9606 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9608 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9610 ;; By default we don't ask for a scratch register, because when DWImode
9611 ;; values are manipulated, registers are already at a premium. But if
9612 ;; we have one handy, we won't turn it away.
9615 [(match_scratch:DWIH 3 "r")
9616 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9618 (match_operand:<DWI> 1 "nonmemory_operand" "")
9619 (match_operand:QI 2 "nonmemory_operand" "")))
9620 (clobber (reg:CC FLAGS_REG))])
9624 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9626 (define_insn "x86_64_shld"
9627 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9628 (ior:DI (ashift:DI (match_dup 0)
9629 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9630 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9631 (minus:QI (const_int 64) (match_dup 2)))))
9632 (clobber (reg:CC FLAGS_REG))]
9634 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9635 [(set_attr "type" "ishift")
9636 (set_attr "prefix_0f" "1")
9637 (set_attr "mode" "DI")
9638 (set_attr "athlon_decode" "vector")
9639 (set_attr "amdfam10_decode" "vector")])
9641 (define_insn "x86_shld"
9642 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9643 (ior:SI (ashift:SI (match_dup 0)
9644 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9645 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9646 (minus:QI (const_int 32) (match_dup 2)))))
9647 (clobber (reg:CC FLAGS_REG))]
9649 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9650 [(set_attr "type" "ishift")
9651 (set_attr "prefix_0f" "1")
9652 (set_attr "mode" "SI")
9653 (set_attr "pent_pair" "np")
9654 (set_attr "athlon_decode" "vector")
9655 (set_attr "amdfam10_decode" "vector")])
9657 (define_expand "x86_shift<mode>_adj_1"
9658 [(set (reg:CCZ FLAGS_REG)
9659 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9662 (set (match_operand:SWI48 0 "register_operand" "")
9663 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9664 (match_operand:SWI48 1 "register_operand" "")
9667 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9668 (match_operand:SWI48 3 "register_operand" "r")
9671 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9673 (define_expand "x86_shift<mode>_adj_2"
9674 [(use (match_operand:SWI48 0 "register_operand" ""))
9675 (use (match_operand:SWI48 1 "register_operand" ""))
9676 (use (match_operand:QI 2 "register_operand" ""))]
9679 rtx label = gen_label_rtx ();
9682 emit_insn (gen_testqi_ccz_1 (operands[2],
9683 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9685 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9686 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9687 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9688 gen_rtx_LABEL_REF (VOIDmode, label),
9690 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9691 JUMP_LABEL (tmp) = label;
9693 emit_move_insn (operands[0], operands[1]);
9694 ix86_expand_clear (operands[1]);
9697 LABEL_NUSES (label) = 1;
9702 (define_insn "*ashl<mode>3_1"
9703 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9704 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9705 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9706 (clobber (reg:CC FLAGS_REG))]
9707 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9709 switch (get_attr_type (insn))
9715 gcc_assert (operands[2] == const1_rtx);
9716 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9717 return "add{<imodesuffix>}\t%0, %0";
9720 if (operands[2] == const1_rtx
9721 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9722 return "sal{<imodesuffix>}\t%0";
9724 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9728 (cond [(eq_attr "alternative" "1")
9729 (const_string "lea")
9730 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9732 (match_operand 0 "register_operand" ""))
9733 (match_operand 2 "const1_operand" ""))
9734 (const_string "alu")
9736 (const_string "ishift")))
9737 (set (attr "length_immediate")
9739 (ior (eq_attr "type" "alu")
9740 (and (eq_attr "type" "ishift")
9741 (and (match_operand 2 "const1_operand" "")
9742 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9745 (const_string "*")))
9746 (set_attr "mode" "<MODE>")])
9748 (define_insn "*ashlsi3_1_zext"
9749 [(set (match_operand:DI 0 "register_operand" "=r,r")
9751 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9752 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9753 (clobber (reg:CC FLAGS_REG))]
9754 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9756 switch (get_attr_type (insn))
9762 gcc_assert (operands[2] == const1_rtx);
9763 return "add{l}\t%k0, %k0";
9766 if (operands[2] == const1_rtx
9767 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9768 return "sal{l}\t%k0";
9770 return "sal{l}\t{%2, %k0|%k0, %2}";
9774 (cond [(eq_attr "alternative" "1")
9775 (const_string "lea")
9776 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9778 (match_operand 2 "const1_operand" ""))
9779 (const_string "alu")
9781 (const_string "ishift")))
9782 (set (attr "length_immediate")
9784 (ior (eq_attr "type" "alu")
9785 (and (eq_attr "type" "ishift")
9786 (and (match_operand 2 "const1_operand" "")
9787 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9790 (const_string "*")))
9791 (set_attr "mode" "SI")])
9793 (define_insn "*ashlhi3_1"
9794 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9795 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9796 (match_operand:QI 2 "nonmemory_operand" "cI")))
9797 (clobber (reg:CC FLAGS_REG))]
9798 "TARGET_PARTIAL_REG_STALL
9799 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9801 switch (get_attr_type (insn))
9804 gcc_assert (operands[2] == const1_rtx);
9805 return "add{w}\t%0, %0";
9808 if (operands[2] == const1_rtx
9809 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9810 return "sal{w}\t%0";
9812 return "sal{w}\t{%2, %0|%0, %2}";
9816 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9818 (match_operand 0 "register_operand" ""))
9819 (match_operand 2 "const1_operand" ""))
9820 (const_string "alu")
9822 (const_string "ishift")))
9823 (set (attr "length_immediate")
9825 (ior (eq_attr "type" "alu")
9826 (and (eq_attr "type" "ishift")
9827 (and (match_operand 2 "const1_operand" "")
9828 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9831 (const_string "*")))
9832 (set_attr "mode" "HI")])
9834 (define_insn "*ashlhi3_1_lea"
9835 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9836 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9837 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9838 (clobber (reg:CC FLAGS_REG))]
9839 "!TARGET_PARTIAL_REG_STALL
9840 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9842 switch (get_attr_type (insn))
9848 gcc_assert (operands[2] == const1_rtx);
9849 return "add{w}\t%0, %0";
9852 if (operands[2] == const1_rtx
9853 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9854 return "sal{w}\t%0";
9856 return "sal{w}\t{%2, %0|%0, %2}";
9860 (cond [(eq_attr "alternative" "1")
9861 (const_string "lea")
9862 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9864 (match_operand 0 "register_operand" ""))
9865 (match_operand 2 "const1_operand" ""))
9866 (const_string "alu")
9868 (const_string "ishift")))
9869 (set (attr "length_immediate")
9871 (ior (eq_attr "type" "alu")
9872 (and (eq_attr "type" "ishift")
9873 (and (match_operand 2 "const1_operand" "")
9874 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9877 (const_string "*")))
9878 (set_attr "mode" "HI,SI")])
9880 (define_insn "*ashlqi3_1"
9881 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9882 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9883 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9884 (clobber (reg:CC FLAGS_REG))]
9885 "TARGET_PARTIAL_REG_STALL
9886 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9888 switch (get_attr_type (insn))
9891 gcc_assert (operands[2] == const1_rtx);
9892 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9893 return "add{l}\t%k0, %k0";
9895 return "add{b}\t%0, %0";
9898 if (operands[2] == const1_rtx
9899 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9901 if (get_attr_mode (insn) == MODE_SI)
9902 return "sal{l}\t%k0";
9904 return "sal{b}\t%0";
9908 if (get_attr_mode (insn) == MODE_SI)
9909 return "sal{l}\t{%2, %k0|%k0, %2}";
9911 return "sal{b}\t{%2, %0|%0, %2}";
9916 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9918 (match_operand 0 "register_operand" ""))
9919 (match_operand 2 "const1_operand" ""))
9920 (const_string "alu")
9922 (const_string "ishift")))
9923 (set (attr "length_immediate")
9925 (ior (eq_attr "type" "alu")
9926 (and (eq_attr "type" "ishift")
9927 (and (match_operand 2 "const1_operand" "")
9928 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9931 (const_string "*")))
9932 (set_attr "mode" "QI,SI")])
9934 ;; %%% Potential partial reg stall on alternative 2. What to do?
9935 (define_insn "*ashlqi3_1_lea"
9936 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9937 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9938 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9939 (clobber (reg:CC FLAGS_REG))]
9940 "!TARGET_PARTIAL_REG_STALL
9941 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9943 switch (get_attr_type (insn))
9949 gcc_assert (operands[2] == const1_rtx);
9950 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9951 return "add{l}\t%k0, %k0";
9953 return "add{b}\t%0, %0";
9956 if (operands[2] == const1_rtx
9957 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9959 if (get_attr_mode (insn) == MODE_SI)
9960 return "sal{l}\t%k0";
9962 return "sal{b}\t%0";
9966 if (get_attr_mode (insn) == MODE_SI)
9967 return "sal{l}\t{%2, %k0|%k0, %2}";
9969 return "sal{b}\t{%2, %0|%0, %2}";
9974 (cond [(eq_attr "alternative" "2")
9975 (const_string "lea")
9976 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9978 (match_operand 0 "register_operand" ""))
9979 (match_operand 2 "const1_operand" ""))
9980 (const_string "alu")
9982 (const_string "ishift")))
9983 (set (attr "length_immediate")
9985 (ior (eq_attr "type" "alu")
9986 (and (eq_attr "type" "ishift")
9987 (and (match_operand 2 "const1_operand" "")
9988 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9991 (const_string "*")))
9992 (set_attr "mode" "QI,SI,SI")])
9994 (define_insn "*ashlqi3_1_slp"
9995 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9996 (ashift:QI (match_dup 0)
9997 (match_operand:QI 1 "nonmemory_operand" "cI")))
9998 (clobber (reg:CC FLAGS_REG))]
9999 "(optimize_function_for_size_p (cfun)
10000 || !TARGET_PARTIAL_FLAG_REG_STALL
10001 || (operands[1] == const1_rtx
10003 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10005 switch (get_attr_type (insn))
10008 gcc_assert (operands[1] == const1_rtx);
10009 return "add{b}\t%0, %0";
10012 if (operands[1] == const1_rtx
10013 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10014 return "sal{b}\t%0";
10016 return "sal{b}\t{%1, %0|%0, %1}";
10019 [(set (attr "type")
10020 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10022 (match_operand 0 "register_operand" ""))
10023 (match_operand 1 "const1_operand" ""))
10024 (const_string "alu")
10026 (const_string "ishift1")))
10027 (set (attr "length_immediate")
10029 (ior (eq_attr "type" "alu")
10030 (and (eq_attr "type" "ishift1")
10031 (and (match_operand 1 "const1_operand" "")
10032 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10035 (const_string "*")))
10036 (set_attr "mode" "QI")])
10038 ;; Convert lea to the lea pattern to avoid flags dependency.
10040 [(set (match_operand:DI 0 "register_operand" "")
10041 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10042 (match_operand:QI 2 "const_int_operand" "")))
10043 (clobber (reg:CC FLAGS_REG))]
10044 "TARGET_64BIT && reload_completed
10045 && true_regnum (operands[0]) != true_regnum (operands[1])"
10046 [(set (match_dup 0)
10047 (mult:DI (match_dup 1)
10049 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10051 ;; Convert lea to the lea pattern to avoid flags dependency.
10053 [(set (match_operand 0 "register_operand" "")
10054 (ashift (match_operand 1 "index_register_operand" "")
10055 (match_operand:QI 2 "const_int_operand" "")))
10056 (clobber (reg:CC FLAGS_REG))]
10058 && true_regnum (operands[0]) != true_regnum (operands[1])
10059 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10063 enum machine_mode mode = GET_MODE (operands[0]);
10065 if (GET_MODE_SIZE (mode) < 4)
10066 operands[0] = gen_lowpart (SImode, operands[0]);
10068 operands[1] = gen_lowpart (Pmode, operands[1]);
10069 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10071 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10072 if (Pmode != SImode)
10073 pat = gen_rtx_SUBREG (SImode, pat, 0);
10074 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10078 ;; Rare case of shifting RSP is handled by generating move and shift
10080 [(set (match_operand 0 "register_operand" "")
10081 (ashift (match_operand 1 "register_operand" "")
10082 (match_operand:QI 2 "const_int_operand" "")))
10083 (clobber (reg:CC FLAGS_REG))]
10085 && true_regnum (operands[0]) != true_regnum (operands[1])"
10089 emit_move_insn (operands[0], operands[1]);
10090 pat = gen_rtx_SET (VOIDmode, operands[0],
10091 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10092 operands[0], operands[2]));
10093 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10094 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10098 ;; Convert lea to the lea pattern to avoid flags dependency.
10100 [(set (match_operand:DI 0 "register_operand" "")
10102 (ashift:SI (match_operand:SI 1 "register_operand" "")
10103 (match_operand:QI 2 "const_int_operand" ""))))
10104 (clobber (reg:CC FLAGS_REG))]
10105 "TARGET_64BIT && reload_completed
10106 && true_regnum (operands[0]) != true_regnum (operands[1])"
10107 [(set (match_dup 0)
10108 (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10110 operands[1] = gen_lowpart (Pmode, operands[1]);
10111 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10114 ;; This pattern can't accept a variable shift count, since shifts by
10115 ;; zero don't affect the flags. We assume that shifts by constant
10116 ;; zero are optimized away.
10117 (define_insn "*ashl<mode>3_cmp"
10118 [(set (reg FLAGS_REG)
10120 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10121 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10123 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10124 (ashift:SWI (match_dup 1) (match_dup 2)))]
10125 "(optimize_function_for_size_p (cfun)
10126 || !TARGET_PARTIAL_FLAG_REG_STALL
10127 || (operands[2] == const1_rtx
10129 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10130 && ix86_match_ccmode (insn, CCGOCmode)
10131 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10133 switch (get_attr_type (insn))
10136 gcc_assert (operands[2] == const1_rtx);
10137 return "add{<imodesuffix>}\t%0, %0";
10140 if (operands[2] == const1_rtx
10141 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10142 return "sal{<imodesuffix>}\t%0";
10144 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10147 [(set (attr "type")
10148 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10150 (match_operand 0 "register_operand" ""))
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" "<MODE>")])
10166 (define_insn "*ashlsi3_cmp_zext"
10167 [(set (reg FLAGS_REG)
10169 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10170 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10172 (set (match_operand:DI 0 "register_operand" "=r")
10173 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10175 && (optimize_function_for_size_p (cfun)
10176 || !TARGET_PARTIAL_FLAG_REG_STALL
10177 || (operands[2] == const1_rtx
10179 || TARGET_DOUBLE_WITH_ADD)))
10180 && ix86_match_ccmode (insn, CCGOCmode)
10181 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10183 switch (get_attr_type (insn))
10186 gcc_assert (operands[2] == const1_rtx);
10187 return "add{l}\t%k0, %k0";
10190 if (operands[2] == const1_rtx
10191 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10192 return "sal{l}\t%k0";
10194 return "sal{l}\t{%2, %k0|%k0, %2}";
10197 [(set (attr "type")
10198 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10200 (match_operand 2 "const1_operand" ""))
10201 (const_string "alu")
10203 (const_string "ishift")))
10204 (set (attr "length_immediate")
10206 (ior (eq_attr "type" "alu")
10207 (and (eq_attr "type" "ishift")
10208 (and (match_operand 2 "const1_operand" "")
10209 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10212 (const_string "*")))
10213 (set_attr "mode" "SI")])
10215 (define_insn "*ashl<mode>3_cconly"
10216 [(set (reg FLAGS_REG)
10218 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10219 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10221 (clobber (match_scratch:SWI 0 "=<r>"))]
10222 "(optimize_function_for_size_p (cfun)
10223 || !TARGET_PARTIAL_FLAG_REG_STALL
10224 || (operands[2] == const1_rtx
10226 || TARGET_DOUBLE_WITH_ADD)))
10227 && ix86_match_ccmode (insn, CCGOCmode)
10228 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10230 switch (get_attr_type (insn))
10233 gcc_assert (operands[2] == const1_rtx);
10234 return "add{<imodesuffix>}\t%0, %0";
10237 if (operands[2] == const1_rtx
10238 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10239 return "sal{<imodesuffix>}\t%0";
10241 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10244 [(set (attr "type")
10245 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10247 (match_operand 0 "register_operand" ""))
10248 (match_operand 2 "const1_operand" ""))
10249 (const_string "alu")
10251 (const_string "ishift")))
10252 (set (attr "length_immediate")
10254 (ior (eq_attr "type" "alu")
10255 (and (eq_attr "type" "ishift")
10256 (and (match_operand 2 "const1_operand" "")
10257 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10260 (const_string "*")))
10261 (set_attr "mode" "<MODE>")])
10263 ;; See comment above `ashl<mode>3' about how this works.
10265 (define_expand "<shiftrt_insn><mode>3"
10266 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
10267 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
10268 (match_operand:QI 2 "nonmemory_operand" "")))]
10270 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10272 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
10273 [(set (match_operand:DWI 0 "register_operand" "=r")
10274 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10275 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10276 (clobber (reg:CC FLAGS_REG))]
10279 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10281 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10282 [(set_attr "type" "multi")])
10284 ;; By default we don't ask for a scratch register, because when DWImode
10285 ;; values are manipulated, registers are already at a premium. But if
10286 ;; we have one handy, we won't turn it away.
10289 [(match_scratch:DWIH 3 "r")
10290 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
10292 (match_operand:<DWI> 1 "register_operand" "")
10293 (match_operand:QI 2 "nonmemory_operand" "")))
10294 (clobber (reg:CC FLAGS_REG))])
10298 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
10300 (define_insn "x86_64_shrd"
10301 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10302 (ior:DI (ashiftrt:DI (match_dup 0)
10303 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10304 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10305 (minus:QI (const_int 64) (match_dup 2)))))
10306 (clobber (reg:CC FLAGS_REG))]
10308 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10309 [(set_attr "type" "ishift")
10310 (set_attr "prefix_0f" "1")
10311 (set_attr "mode" "DI")
10312 (set_attr "athlon_decode" "vector")
10313 (set_attr "amdfam10_decode" "vector")])
10315 (define_insn "x86_shrd"
10316 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10317 (ior:SI (ashiftrt:SI (match_dup 0)
10318 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10319 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10320 (minus:QI (const_int 32) (match_dup 2)))))
10321 (clobber (reg:CC FLAGS_REG))]
10323 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10324 [(set_attr "type" "ishift")
10325 (set_attr "prefix_0f" "1")
10326 (set_attr "mode" "SI")
10327 (set_attr "pent_pair" "np")
10328 (set_attr "athlon_decode" "vector")
10329 (set_attr "amdfam10_decode" "vector")])
10331 (define_insn "ashrdi3_cvt"
10332 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10333 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10334 (match_operand:QI 2 "const_int_operand" "")))
10335 (clobber (reg:CC FLAGS_REG))]
10336 "TARGET_64BIT && INTVAL (operands[2]) == 63
10337 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10338 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10341 sar{q}\t{%2, %0|%0, %2}"
10342 [(set_attr "type" "imovx,ishift")
10343 (set_attr "prefix_0f" "0,*")
10344 (set_attr "length_immediate" "0,*")
10345 (set_attr "modrm" "0,1")
10346 (set_attr "mode" "DI")])
10348 (define_insn "ashrsi3_cvt"
10349 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10350 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10351 (match_operand:QI 2 "const_int_operand" "")))
10352 (clobber (reg:CC FLAGS_REG))]
10353 "INTVAL (operands[2]) == 31
10354 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10355 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10358 sar{l}\t{%2, %0|%0, %2}"
10359 [(set_attr "type" "imovx,ishift")
10360 (set_attr "prefix_0f" "0,*")
10361 (set_attr "length_immediate" "0,*")
10362 (set_attr "modrm" "0,1")
10363 (set_attr "mode" "SI")])
10365 (define_insn "*ashrsi3_cvt_zext"
10366 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10368 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10369 (match_operand:QI 2 "const_int_operand" ""))))
10370 (clobber (reg:CC FLAGS_REG))]
10371 "TARGET_64BIT && INTVAL (operands[2]) == 31
10372 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10373 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10376 sar{l}\t{%2, %k0|%k0, %2}"
10377 [(set_attr "type" "imovx,ishift")
10378 (set_attr "prefix_0f" "0,*")
10379 (set_attr "length_immediate" "0,*")
10380 (set_attr "modrm" "0,1")
10381 (set_attr "mode" "SI")])
10383 (define_expand "x86_shift<mode>_adj_3"
10384 [(use (match_operand:SWI48 0 "register_operand" ""))
10385 (use (match_operand:SWI48 1 "register_operand" ""))
10386 (use (match_operand:QI 2 "register_operand" ""))]
10389 rtx label = gen_label_rtx ();
10392 emit_insn (gen_testqi_ccz_1 (operands[2],
10393 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10395 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10396 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10397 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10398 gen_rtx_LABEL_REF (VOIDmode, label),
10400 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10401 JUMP_LABEL (tmp) = label;
10403 emit_move_insn (operands[0], operands[1]);
10404 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10405 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10406 emit_label (label);
10407 LABEL_NUSES (label) = 1;
10412 (define_insn "*<shiftrt_insn><mode>3_1"
10413 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10414 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10415 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10416 (clobber (reg:CC FLAGS_REG))]
10417 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10419 if (operands[2] == const1_rtx
10420 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10421 return "<shiftrt>{<imodesuffix>}\t%0";
10423 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10425 [(set_attr "type" "ishift")
10426 (set (attr "length_immediate")
10428 (and (match_operand 2 "const1_operand" "")
10429 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10432 (const_string "*")))
10433 (set_attr "mode" "<MODE>")])
10435 (define_insn "*<shiftrt_insn>si3_1_zext"
10436 [(set (match_operand:DI 0 "register_operand" "=r")
10438 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10439 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10440 (clobber (reg:CC FLAGS_REG))]
10441 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10443 if (operands[2] == const1_rtx
10444 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10445 return "<shiftrt>{l}\t%k0";
10447 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10449 [(set_attr "type" "ishift")
10450 (set (attr "length_immediate")
10452 (and (match_operand 2 "const1_operand" "")
10453 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10456 (const_string "*")))
10457 (set_attr "mode" "SI")])
10459 (define_insn "*<shiftrt_insn>qi3_1_slp"
10460 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10461 (any_shiftrt:QI (match_dup 0)
10462 (match_operand:QI 1 "nonmemory_operand" "cI")))
10463 (clobber (reg:CC FLAGS_REG))]
10464 "(optimize_function_for_size_p (cfun)
10465 || !TARGET_PARTIAL_REG_STALL
10466 || (operands[1] == const1_rtx
10467 && TARGET_SHIFT1))"
10469 if (operands[1] == const1_rtx
10470 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10471 return "<shiftrt>{b}\t%0";
10473 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10475 [(set_attr "type" "ishift1")
10476 (set (attr "length_immediate")
10478 (and (match_operand 1 "const1_operand" "")
10479 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10482 (const_string "*")))
10483 (set_attr "mode" "QI")])
10485 ;; This pattern can't accept a variable shift count, since shifts by
10486 ;; zero don't affect the flags. We assume that shifts by constant
10487 ;; zero are optimized away.
10488 (define_insn "*<shiftrt_insn><mode>3_cmp"
10489 [(set (reg FLAGS_REG)
10492 (match_operand:SWI 1 "nonimmediate_operand" "0")
10493 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10495 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10496 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10497 "(optimize_function_for_size_p (cfun)
10498 || !TARGET_PARTIAL_FLAG_REG_STALL
10499 || (operands[2] == const1_rtx
10501 && ix86_match_ccmode (insn, CCGOCmode)
10502 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10504 if (operands[2] == const1_rtx
10505 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10506 return "<shiftrt>{<imodesuffix>}\t%0";
10508 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10510 [(set_attr "type" "ishift")
10511 (set (attr "length_immediate")
10513 (and (match_operand 2 "const1_operand" "")
10514 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10517 (const_string "*")))
10518 (set_attr "mode" "<MODE>")])
10520 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10521 [(set (reg FLAGS_REG)
10523 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10524 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10526 (set (match_operand:DI 0 "register_operand" "=r")
10527 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10529 && (optimize_function_for_size_p (cfun)
10530 || !TARGET_PARTIAL_FLAG_REG_STALL
10531 || (operands[2] == const1_rtx
10533 && ix86_match_ccmode (insn, CCGOCmode)
10534 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10536 if (operands[2] == const1_rtx
10537 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10538 return "<shiftrt>{l}\t%k0";
10540 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10542 [(set_attr "type" "ishift")
10543 (set (attr "length_immediate")
10545 (and (match_operand 2 "const1_operand" "")
10546 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10549 (const_string "*")))
10550 (set_attr "mode" "SI")])
10552 (define_insn "*<shiftrt_insn><mode>3_cconly"
10553 [(set (reg FLAGS_REG)
10556 (match_operand:SWI 1 "nonimmediate_operand" "0")
10557 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10559 (clobber (match_scratch:SWI 0 "=<r>"))]
10560 "(optimize_function_for_size_p (cfun)
10561 || !TARGET_PARTIAL_FLAG_REG_STALL
10562 || (operands[2] == const1_rtx
10564 && ix86_match_ccmode (insn, CCGOCmode)
10565 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10567 if (operands[2] == const1_rtx
10568 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10569 return "<shiftrt>{<imodesuffix>}\t%0";
10571 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10573 [(set_attr "type" "ishift")
10574 (set (attr "length_immediate")
10576 (and (match_operand 2 "const1_operand" "")
10577 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10580 (const_string "*")))
10581 (set_attr "mode" "<MODE>")])
10583 ;; Rotate instructions
10585 (define_expand "<rotate_insn>ti3"
10586 [(set (match_operand:TI 0 "register_operand" "")
10587 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10588 (match_operand:QI 2 "nonmemory_operand" "")))]
10591 if (const_1_to_63_operand (operands[2], VOIDmode))
10592 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10593 (operands[0], operands[1], operands[2]));
10600 (define_expand "<rotate_insn>di3"
10601 [(set (match_operand:DI 0 "shiftdi_operand" "")
10602 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10603 (match_operand:QI 2 "nonmemory_operand" "")))]
10607 ix86_expand_binary_operator (<CODE>, DImode, operands);
10608 else if (const_1_to_31_operand (operands[2], VOIDmode))
10609 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10610 (operands[0], operands[1], operands[2]));
10617 (define_expand "<rotate_insn><mode>3"
10618 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10619 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10620 (match_operand:QI 2 "nonmemory_operand" "")))]
10622 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10624 ;; Implement rotation using two double-precision
10625 ;; shift instructions and a scratch register.
10627 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10628 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10629 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10630 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10631 (clobber (reg:CC FLAGS_REG))
10632 (clobber (match_scratch:DWIH 3 "=&r"))]
10636 [(set (match_dup 3) (match_dup 4))
10638 [(set (match_dup 4)
10639 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10640 (lshiftrt:DWIH (match_dup 5)
10641 (minus:QI (match_dup 6) (match_dup 2)))))
10642 (clobber (reg:CC FLAGS_REG))])
10644 [(set (match_dup 5)
10645 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10646 (lshiftrt:DWIH (match_dup 3)
10647 (minus:QI (match_dup 6) (match_dup 2)))))
10648 (clobber (reg:CC FLAGS_REG))])]
10650 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10652 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10655 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10656 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10657 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10658 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10659 (clobber (reg:CC FLAGS_REG))
10660 (clobber (match_scratch:DWIH 3 "=&r"))]
10664 [(set (match_dup 3) (match_dup 4))
10666 [(set (match_dup 4)
10667 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10668 (ashift:DWIH (match_dup 5)
10669 (minus:QI (match_dup 6) (match_dup 2)))))
10670 (clobber (reg:CC FLAGS_REG))])
10672 [(set (match_dup 5)
10673 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10674 (ashift:DWIH (match_dup 3)
10675 (minus:QI (match_dup 6) (match_dup 2)))))
10676 (clobber (reg:CC FLAGS_REG))])]
10678 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10680 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10683 (define_insn "*<rotate_insn><mode>3_1"
10684 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10685 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10686 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10687 (clobber (reg:CC FLAGS_REG))]
10688 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10690 if (operands[2] == const1_rtx
10691 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10692 return "<rotate>{<imodesuffix>}\t%0";
10694 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10696 [(set_attr "type" "rotate")
10697 (set (attr "length_immediate")
10699 (and (match_operand 2 "const1_operand" "")
10700 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10703 (const_string "*")))
10704 (set_attr "mode" "<MODE>")])
10706 (define_insn "*<rotate_insn>si3_1_zext"
10707 [(set (match_operand:DI 0 "register_operand" "=r")
10709 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10710 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10711 (clobber (reg:CC FLAGS_REG))]
10712 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10714 if (operands[2] == const1_rtx
10715 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10716 return "<rotate>{l}\t%k0";
10718 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10720 [(set_attr "type" "rotate")
10721 (set (attr "length_immediate")
10723 (and (match_operand 2 "const1_operand" "")
10724 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10727 (const_string "*")))
10728 (set_attr "mode" "SI")])
10730 (define_insn "*<rotate_insn>qi3_1_slp"
10731 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10732 (any_rotate:QI (match_dup 0)
10733 (match_operand:QI 1 "nonmemory_operand" "cI")))
10734 (clobber (reg:CC FLAGS_REG))]
10735 "(optimize_function_for_size_p (cfun)
10736 || !TARGET_PARTIAL_REG_STALL
10737 || (operands[1] == const1_rtx
10738 && TARGET_SHIFT1))"
10740 if (operands[1] == const1_rtx
10741 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10742 return "<rotate>{b}\t%0";
10744 return "<rotate>{b}\t{%1, %0|%0, %1}";
10746 [(set_attr "type" "rotate1")
10747 (set (attr "length_immediate")
10749 (and (match_operand 1 "const1_operand" "")
10750 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10753 (const_string "*")))
10754 (set_attr "mode" "QI")])
10757 [(set (match_operand:HI 0 "register_operand" "")
10758 (any_rotate:HI (match_dup 0) (const_int 8)))
10759 (clobber (reg:CC FLAGS_REG))]
10761 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10762 [(parallel [(set (strict_low_part (match_dup 0))
10763 (bswap:HI (match_dup 0)))
10764 (clobber (reg:CC FLAGS_REG))])]
10767 ;; Bit set / bit test instructions
10769 (define_expand "extv"
10770 [(set (match_operand:SI 0 "register_operand" "")
10771 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10772 (match_operand:SI 2 "const8_operand" "")
10773 (match_operand:SI 3 "const8_operand" "")))]
10776 /* Handle extractions from %ah et al. */
10777 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10780 /* From mips.md: extract_bit_field doesn't verify that our source
10781 matches the predicate, so check it again here. */
10782 if (! ext_register_operand (operands[1], VOIDmode))
10786 (define_expand "extzv"
10787 [(set (match_operand:SI 0 "register_operand" "")
10788 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10789 (match_operand:SI 2 "const8_operand" "")
10790 (match_operand:SI 3 "const8_operand" "")))]
10793 /* Handle extractions from %ah et al. */
10794 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10797 /* From mips.md: extract_bit_field doesn't verify that our source
10798 matches the predicate, so check it again here. */
10799 if (! ext_register_operand (operands[1], VOIDmode))
10803 (define_expand "insv"
10804 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10805 (match_operand 1 "const8_operand" "")
10806 (match_operand 2 "const8_operand" ""))
10807 (match_operand 3 "register_operand" ""))]
10810 /* Handle insertions to %ah et al. */
10811 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10814 /* From mips.md: insert_bit_field doesn't verify that our source
10815 matches the predicate, so check it again here. */
10816 if (! ext_register_operand (operands[0], VOIDmode))
10820 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
10822 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10827 ;; %%% bts, btr, btc, bt.
10828 ;; In general these instructions are *slow* when applied to memory,
10829 ;; since they enforce atomic operation. When applied to registers,
10830 ;; it depends on the cpu implementation. They're never faster than
10831 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10832 ;; no point. But in 64-bit, we can't hold the relevant immediates
10833 ;; within the instruction itself, so operating on bits in the high
10834 ;; 32-bits of a register becomes easier.
10836 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10837 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10838 ;; negdf respectively, so they can never be disabled entirely.
10840 (define_insn "*btsq"
10841 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10843 (match_operand:DI 1 "const_0_to_63_operand" ""))
10845 (clobber (reg:CC FLAGS_REG))]
10846 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10847 "bts{q}\t{%1, %0|%0, %1}"
10848 [(set_attr "type" "alu1")
10849 (set_attr "prefix_0f" "1")
10850 (set_attr "mode" "DI")])
10852 (define_insn "*btrq"
10853 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10855 (match_operand:DI 1 "const_0_to_63_operand" ""))
10857 (clobber (reg:CC FLAGS_REG))]
10858 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10859 "btr{q}\t{%1, %0|%0, %1}"
10860 [(set_attr "type" "alu1")
10861 (set_attr "prefix_0f" "1")
10862 (set_attr "mode" "DI")])
10864 (define_insn "*btcq"
10865 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10867 (match_operand:DI 1 "const_0_to_63_operand" ""))
10868 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10869 (clobber (reg:CC FLAGS_REG))]
10870 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10871 "btc{q}\t{%1, %0|%0, %1}"
10872 [(set_attr "type" "alu1")
10873 (set_attr "prefix_0f" "1")
10874 (set_attr "mode" "DI")])
10876 ;; Allow Nocona to avoid these instructions if a register is available.
10879 [(match_scratch:DI 2 "r")
10880 (parallel [(set (zero_extract:DI
10881 (match_operand:DI 0 "register_operand" "")
10883 (match_operand:DI 1 "const_0_to_63_operand" ""))
10885 (clobber (reg:CC FLAGS_REG))])]
10886 "TARGET_64BIT && !TARGET_USE_BT"
10889 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10892 if (HOST_BITS_PER_WIDE_INT >= 64)
10893 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10894 else if (i < HOST_BITS_PER_WIDE_INT)
10895 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10897 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10899 op1 = immed_double_const (lo, hi, DImode);
10902 emit_move_insn (operands[2], op1);
10906 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10911 [(match_scratch:DI 2 "r")
10912 (parallel [(set (zero_extract:DI
10913 (match_operand:DI 0 "register_operand" "")
10915 (match_operand:DI 1 "const_0_to_63_operand" ""))
10917 (clobber (reg:CC FLAGS_REG))])]
10918 "TARGET_64BIT && !TARGET_USE_BT"
10921 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10924 if (HOST_BITS_PER_WIDE_INT >= 64)
10925 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10926 else if (i < HOST_BITS_PER_WIDE_INT)
10927 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10929 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10931 op1 = immed_double_const (~lo, ~hi, DImode);
10934 emit_move_insn (operands[2], op1);
10938 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10943 [(match_scratch:DI 2 "r")
10944 (parallel [(set (zero_extract:DI
10945 (match_operand:DI 0 "register_operand" "")
10947 (match_operand:DI 1 "const_0_to_63_operand" ""))
10948 (not:DI (zero_extract:DI
10949 (match_dup 0) (const_int 1) (match_dup 1))))
10950 (clobber (reg:CC FLAGS_REG))])]
10951 "TARGET_64BIT && !TARGET_USE_BT"
10954 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10957 if (HOST_BITS_PER_WIDE_INT >= 64)
10958 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10959 else if (i < HOST_BITS_PER_WIDE_INT)
10960 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10962 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10964 op1 = immed_double_const (lo, hi, DImode);
10967 emit_move_insn (operands[2], op1);
10971 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10975 (define_insn "*bt<mode>"
10976 [(set (reg:CCC FLAGS_REG)
10978 (zero_extract:SWI48
10979 (match_operand:SWI48 0 "register_operand" "r")
10981 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10983 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10984 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10985 [(set_attr "type" "alu1")
10986 (set_attr "prefix_0f" "1")
10987 (set_attr "mode" "<MODE>")])
10989 ;; Store-flag instructions.
10991 ;; For all sCOND expanders, also expand the compare or test insn that
10992 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10994 (define_insn_and_split "*setcc_di_1"
10995 [(set (match_operand:DI 0 "register_operand" "=q")
10996 (match_operator:DI 1 "ix86_comparison_operator"
10997 [(reg FLAGS_REG) (const_int 0)]))]
10998 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11000 "&& reload_completed"
11001 [(set (match_dup 2) (match_dup 1))
11002 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11004 PUT_MODE (operands[1], QImode);
11005 operands[2] = gen_lowpart (QImode, operands[0]);
11008 (define_insn_and_split "*setcc_si_1_and"
11009 [(set (match_operand:SI 0 "register_operand" "=q")
11010 (match_operator:SI 1 "ix86_comparison_operator"
11011 [(reg FLAGS_REG) (const_int 0)]))
11012 (clobber (reg:CC FLAGS_REG))]
11013 "!TARGET_PARTIAL_REG_STALL
11014 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11016 "&& reload_completed"
11017 [(set (match_dup 2) (match_dup 1))
11018 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11019 (clobber (reg:CC FLAGS_REG))])]
11021 PUT_MODE (operands[1], QImode);
11022 operands[2] = gen_lowpart (QImode, operands[0]);
11025 (define_insn_and_split "*setcc_si_1_movzbl"
11026 [(set (match_operand:SI 0 "register_operand" "=q")
11027 (match_operator:SI 1 "ix86_comparison_operator"
11028 [(reg FLAGS_REG) (const_int 0)]))]
11029 "!TARGET_PARTIAL_REG_STALL
11030 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11032 "&& reload_completed"
11033 [(set (match_dup 2) (match_dup 1))
11034 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11036 PUT_MODE (operands[1], QImode);
11037 operands[2] = gen_lowpart (QImode, operands[0]);
11040 (define_insn "*setcc_qi"
11041 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11042 (match_operator:QI 1 "ix86_comparison_operator"
11043 [(reg FLAGS_REG) (const_int 0)]))]
11046 [(set_attr "type" "setcc")
11047 (set_attr "mode" "QI")])
11049 (define_insn "*setcc_qi_slp"
11050 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11051 (match_operator:QI 1 "ix86_comparison_operator"
11052 [(reg FLAGS_REG) (const_int 0)]))]
11055 [(set_attr "type" "setcc")
11056 (set_attr "mode" "QI")])
11058 ;; In general it is not safe to assume too much about CCmode registers,
11059 ;; so simplify-rtx stops when it sees a second one. Under certain
11060 ;; conditions this is safe on x86, so help combine not create
11067 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11068 (ne:QI (match_operator 1 "ix86_comparison_operator"
11069 [(reg FLAGS_REG) (const_int 0)])
11072 [(set (match_dup 0) (match_dup 1))]
11074 PUT_MODE (operands[1], QImode);
11078 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11079 (ne:QI (match_operator 1 "ix86_comparison_operator"
11080 [(reg FLAGS_REG) (const_int 0)])
11083 [(set (match_dup 0) (match_dup 1))]
11085 PUT_MODE (operands[1], QImode);
11089 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11090 (eq:QI (match_operator 1 "ix86_comparison_operator"
11091 [(reg FLAGS_REG) (const_int 0)])
11094 [(set (match_dup 0) (match_dup 1))]
11096 rtx new_op1 = copy_rtx (operands[1]);
11097 operands[1] = new_op1;
11098 PUT_MODE (new_op1, QImode);
11099 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11100 GET_MODE (XEXP (new_op1, 0))));
11102 /* Make sure that (a) the CCmode we have for the flags is strong
11103 enough for the reversed compare or (b) we have a valid FP compare. */
11104 if (! ix86_comparison_operator (new_op1, VOIDmode))
11109 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11110 (eq:QI (match_operator 1 "ix86_comparison_operator"
11111 [(reg FLAGS_REG) (const_int 0)])
11114 [(set (match_dup 0) (match_dup 1))]
11116 rtx new_op1 = copy_rtx (operands[1]);
11117 operands[1] = new_op1;
11118 PUT_MODE (new_op1, QImode);
11119 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11120 GET_MODE (XEXP (new_op1, 0))));
11122 /* Make sure that (a) the CCmode we have for the flags is strong
11123 enough for the reversed compare or (b) we have a valid FP compare. */
11124 if (! ix86_comparison_operator (new_op1, VOIDmode))
11128 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11129 ;; subsequent logical operations are used to imitate conditional moves.
11130 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11133 (define_insn "*avx_setcc<mode>"
11134 [(set (match_operand:MODEF 0 "register_operand" "=x")
11135 (match_operator:MODEF 1 "avx_comparison_float_operator"
11136 [(match_operand:MODEF 2 "register_operand" "x")
11137 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11139 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
11140 [(set_attr "type" "ssecmp")
11141 (set_attr "prefix" "vex")
11142 (set_attr "length_immediate" "1")
11143 (set_attr "mode" "<MODE>")])
11145 (define_insn "*sse_setcc<mode>"
11146 [(set (match_operand:MODEF 0 "register_operand" "=x")
11147 (match_operator:MODEF 1 "sse_comparison_operator"
11148 [(match_operand:MODEF 2 "register_operand" "0")
11149 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11150 "SSE_FLOAT_MODE_P (<MODE>mode)"
11151 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
11152 [(set_attr "type" "ssecmp")
11153 (set_attr "length_immediate" "1")
11154 (set_attr "mode" "<MODE>")])
11156 ;; Basic conditional jump instructions.
11157 ;; We ignore the overflow flag for signed branch instructions.
11159 (define_insn "*jcc_1"
11161 (if_then_else (match_operator 1 "ix86_comparison_operator"
11162 [(reg FLAGS_REG) (const_int 0)])
11163 (label_ref (match_operand 0 "" ""))
11167 [(set_attr "type" "ibr")
11168 (set_attr "modrm" "0")
11169 (set (attr "length")
11170 (if_then_else (and (ge (minus (match_dup 0) (pc))
11172 (lt (minus (match_dup 0) (pc))
11177 (define_insn "*jcc_2"
11179 (if_then_else (match_operator 1 "ix86_comparison_operator"
11180 [(reg FLAGS_REG) (const_int 0)])
11182 (label_ref (match_operand 0 "" ""))))]
11185 [(set_attr "type" "ibr")
11186 (set_attr "modrm" "0")
11187 (set (attr "length")
11188 (if_then_else (and (ge (minus (match_dup 0) (pc))
11190 (lt (minus (match_dup 0) (pc))
11195 ;; In general it is not safe to assume too much about CCmode registers,
11196 ;; so simplify-rtx stops when it sees a second one. Under certain
11197 ;; conditions this is safe on x86, so help combine not create
11205 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11206 [(reg FLAGS_REG) (const_int 0)])
11208 (label_ref (match_operand 1 "" ""))
11212 (if_then_else (match_dup 0)
11213 (label_ref (match_dup 1))
11216 PUT_MODE (operands[0], VOIDmode);
11221 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11222 [(reg FLAGS_REG) (const_int 0)])
11224 (label_ref (match_operand 1 "" ""))
11228 (if_then_else (match_dup 0)
11229 (label_ref (match_dup 1))
11232 rtx new_op0 = copy_rtx (operands[0]);
11233 operands[0] = new_op0;
11234 PUT_MODE (new_op0, VOIDmode);
11235 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11236 GET_MODE (XEXP (new_op0, 0))));
11238 /* Make sure that (a) the CCmode we have for the flags is strong
11239 enough for the reversed compare or (b) we have a valid FP compare. */
11240 if (! ix86_comparison_operator (new_op0, VOIDmode))
11244 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11245 ;; pass generates from shift insn with QImode operand. Actually, the mode
11246 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11247 ;; appropriate modulo of the bit offset value.
11249 (define_insn_and_split "*jcc_bt<mode>"
11251 (if_then_else (match_operator 0 "bt_comparison_operator"
11252 [(zero_extract:SWI48
11253 (match_operand:SWI48 1 "register_operand" "r")
11256 (match_operand:QI 2 "register_operand" "r")))
11258 (label_ref (match_operand 3 "" ""))
11260 (clobber (reg:CC FLAGS_REG))]
11261 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11264 [(set (reg:CCC FLAGS_REG)
11266 (zero_extract:SWI48
11272 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11273 (label_ref (match_dup 3))
11276 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11278 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11281 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11282 ;; also for DImode, this is what combine produces.
11283 (define_insn_and_split "*jcc_bt<mode>_mask"
11285 (if_then_else (match_operator 0 "bt_comparison_operator"
11286 [(zero_extract:SWI48
11287 (match_operand:SWI48 1 "register_operand" "r")
11290 (match_operand:SI 2 "register_operand" "r")
11291 (match_operand:SI 3 "const_int_operand" "n")))])
11292 (label_ref (match_operand 4 "" ""))
11294 (clobber (reg:CC FLAGS_REG))]
11295 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11296 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11297 == GET_MODE_BITSIZE (<MODE>mode)-1"
11300 [(set (reg:CCC FLAGS_REG)
11302 (zero_extract:SWI48
11308 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11309 (label_ref (match_dup 4))
11312 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11314 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11317 (define_insn_and_split "*jcc_btsi_1"
11319 (if_then_else (match_operator 0 "bt_comparison_operator"
11322 (match_operand:SI 1 "register_operand" "r")
11323 (match_operand:QI 2 "register_operand" "r"))
11326 (label_ref (match_operand 3 "" ""))
11328 (clobber (reg:CC FLAGS_REG))]
11329 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11332 [(set (reg:CCC FLAGS_REG)
11340 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11341 (label_ref (match_dup 3))
11344 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11346 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11349 ;; avoid useless masking of bit offset operand
11350 (define_insn_and_split "*jcc_btsi_mask_1"
11353 (match_operator 0 "bt_comparison_operator"
11356 (match_operand:SI 1 "register_operand" "r")
11359 (match_operand:SI 2 "register_operand" "r")
11360 (match_operand:SI 3 "const_int_operand" "n")) 0))
11363 (label_ref (match_operand 4 "" ""))
11365 (clobber (reg:CC FLAGS_REG))]
11366 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11367 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11370 [(set (reg:CCC FLAGS_REG)
11378 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11379 (label_ref (match_dup 4))
11381 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11383 ;; Define combination compare-and-branch fp compare instructions to help
11386 (define_insn "*fp_jcc_3_387"
11388 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11389 [(match_operand 1 "register_operand" "f")
11390 (match_operand 2 "nonimmediate_operand" "fm")])
11391 (label_ref (match_operand 3 "" ""))
11393 (clobber (reg:CCFP FPSR_REG))
11394 (clobber (reg:CCFP FLAGS_REG))
11395 (clobber (match_scratch:HI 4 "=a"))]
11397 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11398 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11399 && SELECT_CC_MODE (GET_CODE (operands[0]),
11400 operands[1], operands[2]) == CCFPmode
11404 (define_insn "*fp_jcc_4_387"
11406 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11407 [(match_operand 1 "register_operand" "f")
11408 (match_operand 2 "nonimmediate_operand" "fm")])
11410 (label_ref (match_operand 3 "" ""))))
11411 (clobber (reg:CCFP FPSR_REG))
11412 (clobber (reg:CCFP FLAGS_REG))
11413 (clobber (match_scratch:HI 4 "=a"))]
11415 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11416 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11417 && SELECT_CC_MODE (GET_CODE (operands[0]),
11418 operands[1], operands[2]) == CCFPmode
11422 (define_insn "*fp_jcc_5_387"
11424 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11425 [(match_operand 1 "register_operand" "f")
11426 (match_operand 2 "register_operand" "f")])
11427 (label_ref (match_operand 3 "" ""))
11429 (clobber (reg:CCFP FPSR_REG))
11430 (clobber (reg:CCFP FLAGS_REG))
11431 (clobber (match_scratch:HI 4 "=a"))]
11432 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11433 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11437 (define_insn "*fp_jcc_6_387"
11439 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11440 [(match_operand 1 "register_operand" "f")
11441 (match_operand 2 "register_operand" "f")])
11443 (label_ref (match_operand 3 "" ""))))
11444 (clobber (reg:CCFP FPSR_REG))
11445 (clobber (reg:CCFP FLAGS_REG))
11446 (clobber (match_scratch:HI 4 "=a"))]
11447 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11448 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11452 (define_insn "*fp_jcc_7_387"
11454 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11455 [(match_operand 1 "register_operand" "f")
11456 (match_operand 2 "const0_operand" "")])
11457 (label_ref (match_operand 3 "" ""))
11459 (clobber (reg:CCFP FPSR_REG))
11460 (clobber (reg:CCFP FLAGS_REG))
11461 (clobber (match_scratch:HI 4 "=a"))]
11462 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11463 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11464 && SELECT_CC_MODE (GET_CODE (operands[0]),
11465 operands[1], operands[2]) == CCFPmode
11469 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
11470 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11471 ;; with a precedence over other operators and is always put in the first
11472 ;; place. Swap condition and operands to match ficom instruction.
11474 (define_insn "*fp_jcc_8<mode>_387"
11476 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11477 [(match_operator 1 "float_operator"
11478 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11479 (match_operand 3 "register_operand" "f,f")])
11480 (label_ref (match_operand 4 "" ""))
11482 (clobber (reg:CCFP FPSR_REG))
11483 (clobber (reg:CCFP FLAGS_REG))
11484 (clobber (match_scratch:HI 5 "=a,a"))]
11485 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11486 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11487 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11488 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11494 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11495 [(match_operand 1 "register_operand" "")
11496 (match_operand 2 "nonimmediate_operand" "")])
11497 (match_operand 3 "" "")
11498 (match_operand 4 "" "")))
11499 (clobber (reg:CCFP FPSR_REG))
11500 (clobber (reg:CCFP FLAGS_REG))]
11504 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11505 operands[3], operands[4], NULL_RTX, NULL_RTX);
11511 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11512 [(match_operand 1 "register_operand" "")
11513 (match_operand 2 "general_operand" "")])
11514 (match_operand 3 "" "")
11515 (match_operand 4 "" "")))
11516 (clobber (reg:CCFP FPSR_REG))
11517 (clobber (reg:CCFP FLAGS_REG))
11518 (clobber (match_scratch:HI 5 "=a"))]
11522 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11523 operands[3], operands[4], operands[5], NULL_RTX);
11529 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11530 [(match_operator 1 "float_operator"
11531 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11532 (match_operand 3 "register_operand" "")])
11533 (match_operand 4 "" "")
11534 (match_operand 5 "" "")))
11535 (clobber (reg:CCFP FPSR_REG))
11536 (clobber (reg:CCFP FLAGS_REG))
11537 (clobber (match_scratch:HI 6 "=a"))]
11541 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11543 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11544 operands[3], operands[7],
11545 operands[4], operands[5], operands[6], NULL_RTX);
11549 ;; %%% Kill this when reload knows how to do it.
11552 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11553 [(match_operator 1 "float_operator"
11554 [(match_operand:X87MODEI12 2 "register_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] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11565 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11567 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11568 operands[3], operands[7],
11569 operands[4], operands[5], operands[6], operands[2]);
11573 ;; Unconditional and other jump instructions
11575 (define_insn "jump"
11577 (label_ref (match_operand 0 "" "")))]
11580 [(set_attr "type" "ibr")
11581 (set (attr "length")
11582 (if_then_else (and (ge (minus (match_dup 0) (pc))
11584 (lt (minus (match_dup 0) (pc))
11588 (set_attr "modrm" "0")])
11590 (define_expand "indirect_jump"
11591 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11595 (define_insn "*indirect_jump"
11596 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11599 [(set_attr "type" "ibr")
11600 (set_attr "length_immediate" "0")])
11602 (define_expand "tablejump"
11603 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11604 (use (label_ref (match_operand 1 "" "")))])]
11607 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11608 relative. Convert the relative address to an absolute address. */
11612 enum rtx_code code;
11614 /* We can't use @GOTOFF for text labels on VxWorks;
11615 see gotoff_operand. */
11616 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11620 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11622 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11626 op1 = pic_offset_table_rtx;
11631 op0 = pic_offset_table_rtx;
11635 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11640 (define_insn "*tablejump_1"
11641 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11642 (use (label_ref (match_operand 1 "" "")))]
11645 [(set_attr "type" "ibr")
11646 (set_attr "length_immediate" "0")])
11648 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11651 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11652 (set (match_operand:QI 1 "register_operand" "")
11653 (match_operator:QI 2 "ix86_comparison_operator"
11654 [(reg FLAGS_REG) (const_int 0)]))
11655 (set (match_operand 3 "q_regs_operand" "")
11656 (zero_extend (match_dup 1)))]
11657 "(peep2_reg_dead_p (3, operands[1])
11658 || operands_match_p (operands[1], operands[3]))
11659 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11660 [(set (match_dup 4) (match_dup 0))
11661 (set (strict_low_part (match_dup 5))
11664 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11665 operands[5] = gen_lowpart (QImode, operands[3]);
11666 ix86_expand_clear (operands[3]);
11669 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
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 (parallel [(set (match_operand 3 "q_regs_operand" "")
11677 (zero_extend (match_dup 1)))
11678 (clobber (reg:CC FLAGS_REG))])]
11679 "(peep2_reg_dead_p (3, operands[1])
11680 || operands_match_p (operands[1], operands[3]))
11681 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11682 [(set (match_dup 4) (match_dup 0))
11683 (set (strict_low_part (match_dup 5))
11686 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11687 operands[5] = gen_lowpart (QImode, operands[3]);
11688 ix86_expand_clear (operands[3]);
11691 ;; Call instructions.
11693 ;; The predicates normally associated with named expanders are not properly
11694 ;; checked for calls. This is a bug in the generic code, but it isn't that
11695 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11697 ;; P6 processors will jump to the address after the decrement when %esp
11698 ;; is used as a call operand, so they will execute return address as a code.
11699 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11701 ;; Call subroutine returning no value.
11703 (define_expand "call_pop"
11704 [(parallel [(call (match_operand:QI 0 "" "")
11705 (match_operand:SI 1 "" ""))
11706 (set (reg:SI SP_REG)
11707 (plus:SI (reg:SI SP_REG)
11708 (match_operand:SI 3 "" "")))])]
11711 ix86_expand_call (NULL, operands[0], operands[1],
11712 operands[2], operands[3], 0);
11716 (define_insn "*call_pop_0"
11717 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11718 (match_operand:SI 1 "" ""))
11719 (set (reg:SI SP_REG)
11720 (plus:SI (reg:SI SP_REG)
11721 (match_operand:SI 2 "immediate_operand" "")))]
11724 if (SIBLING_CALL_P (insn))
11727 return "call\t%P0";
11729 [(set_attr "type" "call")])
11731 (define_insn "*call_pop_1"
11732 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11733 (match_operand:SI 1 "" ""))
11734 (set (reg:SI SP_REG)
11735 (plus:SI (reg:SI SP_REG)
11736 (match_operand:SI 2 "immediate_operand" "i")))]
11737 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11739 if (constant_call_address_operand (operands[0], Pmode))
11740 return "call\t%P0";
11741 return "call\t%A0";
11743 [(set_attr "type" "call")])
11745 (define_insn "*sibcall_pop_1"
11746 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11747 (match_operand:SI 1 "" ""))
11748 (set (reg:SI SP_REG)
11749 (plus:SI (reg:SI SP_REG)
11750 (match_operand:SI 2 "immediate_operand" "i,i")))]
11751 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11755 [(set_attr "type" "call")])
11757 (define_expand "call"
11758 [(call (match_operand:QI 0 "" "")
11759 (match_operand 1 "" ""))
11760 (use (match_operand 2 "" ""))]
11763 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11767 (define_expand "sibcall"
11768 [(call (match_operand:QI 0 "" "")
11769 (match_operand 1 "" ""))
11770 (use (match_operand 2 "" ""))]
11773 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11777 (define_insn "*call_0"
11778 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11779 (match_operand 1 "" ""))]
11782 if (SIBLING_CALL_P (insn))
11785 return "call\t%P0";
11787 [(set_attr "type" "call")])
11789 (define_insn "*call_1"
11790 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11791 (match_operand 1 "" ""))]
11792 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11794 if (constant_call_address_operand (operands[0], Pmode))
11795 return "call\t%P0";
11796 return "call\t%A0";
11798 [(set_attr "type" "call")])
11800 (define_insn "*sibcall_1"
11801 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11802 (match_operand 1 "" ""))]
11803 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11807 [(set_attr "type" "call")])
11809 (define_insn "*call_1_rex64"
11810 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11811 (match_operand 1 "" ""))]
11812 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11813 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
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 "*call_1_rex64_ms_sysv"
11822 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11823 (match_operand 1 "" ""))
11824 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11825 (clobber (reg:TI XMM6_REG))
11826 (clobber (reg:TI XMM7_REG))
11827 (clobber (reg:TI XMM8_REG))
11828 (clobber (reg:TI XMM9_REG))
11829 (clobber (reg:TI XMM10_REG))
11830 (clobber (reg:TI XMM11_REG))
11831 (clobber (reg:TI XMM12_REG))
11832 (clobber (reg:TI XMM13_REG))
11833 (clobber (reg:TI XMM14_REG))
11834 (clobber (reg:TI XMM15_REG))
11835 (clobber (reg:DI SI_REG))
11836 (clobber (reg:DI DI_REG))]
11837 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11839 if (constant_call_address_operand (operands[0], Pmode))
11840 return "call\t%P0";
11841 return "call\t%A0";
11843 [(set_attr "type" "call")])
11845 (define_insn "*call_1_rex64_large"
11846 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11847 (match_operand 1 "" ""))]
11848 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11850 [(set_attr "type" "call")])
11852 (define_insn "*sibcall_1_rex64"
11853 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11854 (match_operand 1 "" ""))]
11855 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11859 [(set_attr "type" "call")])
11861 ;; Call subroutine, returning value in operand 0
11862 (define_expand "call_value_pop"
11863 [(parallel [(set (match_operand 0 "" "")
11864 (call (match_operand:QI 1 "" "")
11865 (match_operand:SI 2 "" "")))
11866 (set (reg:SI SP_REG)
11867 (plus:SI (reg:SI SP_REG)
11868 (match_operand:SI 4 "" "")))])]
11871 ix86_expand_call (operands[0], operands[1], operands[2],
11872 operands[3], operands[4], 0);
11876 (define_expand "call_value"
11877 [(set (match_operand 0 "" "")
11878 (call (match_operand:QI 1 "" "")
11879 (match_operand:SI 2 "" "")))
11880 (use (match_operand:SI 3 "" ""))]
11881 ;; Operand 3 is not used on the i386.
11884 ix86_expand_call (operands[0], operands[1], operands[2],
11885 operands[3], NULL, 0);
11889 (define_expand "sibcall_value"
11890 [(set (match_operand 0 "" "")
11891 (call (match_operand:QI 1 "" "")
11892 (match_operand:SI 2 "" "")))
11893 (use (match_operand:SI 3 "" ""))]
11894 ;; Operand 3 is not used on the i386.
11897 ix86_expand_call (operands[0], operands[1], operands[2],
11898 operands[3], NULL, 1);
11902 ;; Call subroutine returning any type.
11904 (define_expand "untyped_call"
11905 [(parallel [(call (match_operand 0 "" "")
11907 (match_operand 1 "" "")
11908 (match_operand 2 "" "")])]
11913 /* In order to give reg-stack an easier job in validating two
11914 coprocessor registers as containing a possible return value,
11915 simply pretend the untyped call returns a complex long double
11918 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11919 and should have the default ABI. */
11921 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11922 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11923 operands[0], const0_rtx,
11924 GEN_INT ((TARGET_64BIT
11925 ? (ix86_abi == SYSV_ABI
11926 ? X86_64_SSE_REGPARM_MAX
11927 : X86_64_MS_SSE_REGPARM_MAX)
11928 : X86_32_SSE_REGPARM_MAX)
11932 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11934 rtx set = XVECEXP (operands[2], 0, i);
11935 emit_move_insn (SET_DEST (set), SET_SRC (set));
11938 /* The optimizer does not know that the call sets the function value
11939 registers we stored in the result block. We avoid problems by
11940 claiming that all hard registers are used and clobbered at this
11942 emit_insn (gen_blockage ());
11947 ;; Prologue and epilogue instructions
11949 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11950 ;; all of memory. This blocks insns from being moved across this point.
11952 (define_insn "blockage"
11953 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11956 [(set_attr "length" "0")])
11958 ;; Do not schedule instructions accessing memory across this point.
11960 (define_expand "memory_blockage"
11961 [(set (match_dup 0)
11962 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11965 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11966 MEM_VOLATILE_P (operands[0]) = 1;
11969 (define_insn "*memory_blockage"
11970 [(set (match_operand:BLK 0 "" "")
11971 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11974 [(set_attr "length" "0")])
11976 ;; As USE insns aren't meaningful after reload, this is used instead
11977 ;; to prevent deleting instructions setting registers for PIC code
11978 (define_insn "prologue_use"
11979 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11982 [(set_attr "length" "0")])
11984 ;; Insn emitted into the body of a function to return from a function.
11985 ;; This is only done if the function's epilogue is known to be simple.
11986 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11988 (define_expand "return"
11990 "ix86_can_use_return_insn_p ()"
11992 if (crtl->args.pops_args)
11994 rtx popc = GEN_INT (crtl->args.pops_args);
11995 emit_jump_insn (gen_return_pop_internal (popc));
12000 (define_insn "return_internal"
12004 [(set_attr "length" "1")
12005 (set_attr "atom_unit" "jeu")
12006 (set_attr "length_immediate" "0")
12007 (set_attr "modrm" "0")])
12009 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12010 ;; instruction Athlon and K8 have.
12012 (define_insn "return_internal_long"
12014 (unspec [(const_int 0)] UNSPEC_REP)]
12017 [(set_attr "length" "2")
12018 (set_attr "atom_unit" "jeu")
12019 (set_attr "length_immediate" "0")
12020 (set_attr "prefix_rep" "1")
12021 (set_attr "modrm" "0")])
12023 (define_insn "return_pop_internal"
12025 (use (match_operand:SI 0 "const_int_operand" ""))]
12028 [(set_attr "length" "3")
12029 (set_attr "atom_unit" "jeu")
12030 (set_attr "length_immediate" "2")
12031 (set_attr "modrm" "0")])
12033 (define_insn "return_indirect_internal"
12035 (use (match_operand:SI 0 "register_operand" "r"))]
12038 [(set_attr "type" "ibr")
12039 (set_attr "length_immediate" "0")])
12045 [(set_attr "length" "1")
12046 (set_attr "length_immediate" "0")
12047 (set_attr "modrm" "0")])
12049 (define_insn "vswapmov"
12050 [(set (match_operand:SI 0 "register_operand" "=r")
12051 (match_operand:SI 1 "register_operand" "r"))
12052 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
12054 "movl.s\t{%1, %0|%0, %1}"
12055 [(set_attr "length" "2")
12056 (set_attr "length_immediate" "0")
12057 (set_attr "modrm" "0")])
12059 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12060 ;; branch prediction penalty for the third jump in a 16-byte
12064 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
12067 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12068 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12070 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12071 The align insn is used to avoid 3 jump instructions in the row to improve
12072 branch prediction and the benefits hardly outweigh the cost of extra 8
12073 nops on the average inserted by full alignment pseudo operation. */
12077 [(set_attr "length" "16")])
12079 (define_expand "prologue"
12082 "ix86_expand_prologue (); DONE;")
12084 (define_insn "set_got"
12085 [(set (match_operand:SI 0 "register_operand" "=r")
12086 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12087 (clobber (reg:CC FLAGS_REG))]
12089 { return output_set_got (operands[0], NULL_RTX); }
12090 [(set_attr "type" "multi")
12091 (set_attr "length" "12")])
12093 (define_insn "set_got_labelled"
12094 [(set (match_operand:SI 0 "register_operand" "=r")
12095 (unspec:SI [(label_ref (match_operand 1 "" ""))]
12097 (clobber (reg:CC FLAGS_REG))]
12099 { return output_set_got (operands[0], operands[1]); }
12100 [(set_attr "type" "multi")
12101 (set_attr "length" "12")])
12103 (define_insn "set_got_rex64"
12104 [(set (match_operand:DI 0 "register_operand" "=r")
12105 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12107 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12108 [(set_attr "type" "lea")
12109 (set_attr "length_address" "4")
12110 (set_attr "mode" "DI")])
12112 (define_insn "set_rip_rex64"
12113 [(set (match_operand:DI 0 "register_operand" "=r")
12114 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
12116 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12117 [(set_attr "type" "lea")
12118 (set_attr "length_address" "4")
12119 (set_attr "mode" "DI")])
12121 (define_insn "set_got_offset_rex64"
12122 [(set (match_operand:DI 0 "register_operand" "=r")
12124 [(label_ref (match_operand 1 "" ""))]
12125 UNSPEC_SET_GOT_OFFSET))]
12127 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12128 [(set_attr "type" "imov")
12129 (set_attr "length_immediate" "0")
12130 (set_attr "length_address" "8")
12131 (set_attr "mode" "DI")])
12133 (define_expand "epilogue"
12136 "ix86_expand_epilogue (1); DONE;")
12138 (define_expand "sibcall_epilogue"
12141 "ix86_expand_epilogue (0); DONE;")
12143 (define_expand "eh_return"
12144 [(use (match_operand 0 "register_operand" ""))]
12147 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12149 /* Tricky bit: we write the address of the handler to which we will
12150 be returning into someone else's stack frame, one word below the
12151 stack address we wish to restore. */
12152 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12153 tmp = plus_constant (tmp, -UNITS_PER_WORD);
12154 tmp = gen_rtx_MEM (Pmode, tmp);
12155 emit_move_insn (tmp, ra);
12157 emit_jump_insn (gen_eh_return_internal ());
12162 (define_insn_and_split "eh_return_internal"
12166 "epilogue_completed"
12168 "ix86_expand_epilogue (2); DONE;")
12170 (define_insn "leave"
12171 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12172 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12173 (clobber (mem:BLK (scratch)))]
12176 [(set_attr "type" "leave")])
12178 (define_insn "leave_rex64"
12179 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12180 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12181 (clobber (mem:BLK (scratch)))]
12184 [(set_attr "type" "leave")])
12186 ;; Bit manipulation instructions.
12188 (define_expand "ffs<mode>2"
12189 [(set (match_dup 2) (const_int -1))
12190 (parallel [(set (reg:CCZ FLAGS_REG)
12192 (match_operand:SWI48 1 "nonimmediate_operand" "")
12194 (set (match_operand:SWI48 0 "register_operand" "")
12195 (ctz:SWI48 (match_dup 1)))])
12196 (set (match_dup 0) (if_then_else:SWI48
12197 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12200 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12201 (clobber (reg:CC FLAGS_REG))])]
12204 if (<MODE>mode == SImode && !TARGET_CMOVE)
12206 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12209 operands[2] = gen_reg_rtx (<MODE>mode);
12212 (define_insn_and_split "ffssi2_no_cmove"
12213 [(set (match_operand:SI 0 "register_operand" "=r")
12214 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12215 (clobber (match_scratch:SI 2 "=&q"))
12216 (clobber (reg:CC FLAGS_REG))]
12219 "&& reload_completed"
12220 [(parallel [(set (reg:CCZ FLAGS_REG)
12221 (compare:CCZ (match_dup 1) (const_int 0)))
12222 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12223 (set (strict_low_part (match_dup 3))
12224 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12225 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12226 (clobber (reg:CC FLAGS_REG))])
12227 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12228 (clobber (reg:CC FLAGS_REG))])
12229 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12230 (clobber (reg:CC FLAGS_REG))])]
12232 operands[3] = gen_lowpart (QImode, operands[2]);
12233 ix86_expand_clear (operands[2]);
12236 (define_insn "*ffs<mode>_1"
12237 [(set (reg:CCZ FLAGS_REG)
12238 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12240 (set (match_operand:SWI48 0 "register_operand" "=r")
12241 (ctz:SWI48 (match_dup 1)))]
12243 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12244 [(set_attr "type" "alu1")
12245 (set_attr "prefix_0f" "1")
12246 (set_attr "mode" "<MODE>")])
12248 (define_insn "ctz<mode>2"
12249 [(set (match_operand:SWI48 0 "register_operand" "=r")
12250 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12251 (clobber (reg:CC FLAGS_REG))]
12253 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12254 [(set_attr "type" "alu1")
12255 (set_attr "prefix_0f" "1")
12256 (set_attr "mode" "<MODE>")])
12258 (define_expand "clz<mode>2"
12260 [(set (match_operand:SWI248 0 "register_operand" "")
12263 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12264 (clobber (reg:CC FLAGS_REG))])
12266 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12267 (clobber (reg:CC FLAGS_REG))])]
12272 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12275 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12278 (define_insn "clz<mode>2_abm"
12279 [(set (match_operand:SWI248 0 "register_operand" "=r")
12280 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12281 (clobber (reg:CC FLAGS_REG))]
12283 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12284 [(set_attr "prefix_rep" "1")
12285 (set_attr "type" "bitmanip")
12286 (set_attr "mode" "<MODE>")])
12288 (define_insn "bsr_rex64"
12289 [(set (match_operand:DI 0 "register_operand" "=r")
12290 (minus:DI (const_int 63)
12291 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12292 (clobber (reg:CC FLAGS_REG))]
12294 "bsr{q}\t{%1, %0|%0, %1}"
12295 [(set_attr "type" "alu1")
12296 (set_attr "prefix_0f" "1")
12297 (set_attr "mode" "DI")])
12300 [(set (match_operand:SI 0 "register_operand" "=r")
12301 (minus:SI (const_int 31)
12302 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12303 (clobber (reg:CC FLAGS_REG))]
12305 "bsr{l}\t{%1, %0|%0, %1}"
12306 [(set_attr "type" "alu1")
12307 (set_attr "prefix_0f" "1")
12308 (set_attr "mode" "SI")])
12310 (define_insn "*bsrhi"
12311 [(set (match_operand:HI 0 "register_operand" "=r")
12312 (minus:HI (const_int 15)
12313 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12314 (clobber (reg:CC FLAGS_REG))]
12316 "bsr{w}\t{%1, %0|%0, %1}"
12317 [(set_attr "type" "alu1")
12318 (set_attr "prefix_0f" "1")
12319 (set_attr "mode" "HI")])
12321 (define_insn "popcount<mode>2"
12322 [(set (match_operand:SWI248 0 "register_operand" "=r")
12324 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12325 (clobber (reg:CC FLAGS_REG))]
12329 return "popcnt\t{%1, %0|%0, %1}";
12331 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12334 [(set_attr "prefix_rep" "1")
12335 (set_attr "type" "bitmanip")
12336 (set_attr "mode" "<MODE>")])
12338 (define_insn "*popcount<mode>2_cmp"
12339 [(set (reg FLAGS_REG)
12342 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12344 (set (match_operand:SWI248 0 "register_operand" "=r")
12345 (popcount:SWI248 (match_dup 1)))]
12346 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12349 return "popcnt\t{%1, %0|%0, %1}";
12351 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12354 [(set_attr "prefix_rep" "1")
12355 (set_attr "type" "bitmanip")
12356 (set_attr "mode" "<MODE>")])
12358 (define_insn "*popcountsi2_cmp_zext"
12359 [(set (reg FLAGS_REG)
12361 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12363 (set (match_operand:DI 0 "register_operand" "=r")
12364 (zero_extend:DI(popcount:SI (match_dup 1))))]
12365 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12368 return "popcnt\t{%1, %0|%0, %1}";
12370 return "popcnt{l}\t{%1, %0|%0, %1}";
12373 [(set_attr "prefix_rep" "1")
12374 (set_attr "type" "bitmanip")
12375 (set_attr "mode" "SI")])
12377 (define_expand "bswap<mode>2"
12378 [(set (match_operand:SWI48 0 "register_operand" "")
12379 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12382 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12384 rtx x = operands[0];
12386 emit_move_insn (x, operands[1]);
12387 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12388 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12389 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12394 (define_insn "*bswap<mode>2_movbe"
12395 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12396 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12398 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12401 movbe\t{%1, %0|%0, %1}
12402 movbe\t{%1, %0|%0, %1}"
12403 [(set_attr "type" "bitmanip,imov,imov")
12404 (set_attr "modrm" "0,1,1")
12405 (set_attr "prefix_0f" "*,1,1")
12406 (set_attr "prefix_extra" "*,1,1")
12407 (set_attr "mode" "<MODE>")])
12409 (define_insn "*bswap<mode>2_1"
12410 [(set (match_operand:SWI48 0 "register_operand" "=r")
12411 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12414 [(set_attr "type" "bitmanip")
12415 (set_attr "modrm" "0")
12416 (set_attr "mode" "<MODE>")])
12418 (define_insn "*bswaphi_lowpart_1"
12419 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12420 (bswap:HI (match_dup 0)))
12421 (clobber (reg:CC FLAGS_REG))]
12422 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12424 xchg{b}\t{%h0, %b0|%b0, %h0}
12425 rol{w}\t{$8, %0|%0, 8}"
12426 [(set_attr "length" "2,4")
12427 (set_attr "mode" "QI,HI")])
12429 (define_insn "bswaphi_lowpart"
12430 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12431 (bswap:HI (match_dup 0)))
12432 (clobber (reg:CC FLAGS_REG))]
12434 "rol{w}\t{$8, %0|%0, 8}"
12435 [(set_attr "length" "4")
12436 (set_attr "mode" "HI")])
12438 (define_expand "paritydi2"
12439 [(set (match_operand:DI 0 "register_operand" "")
12440 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12443 rtx scratch = gen_reg_rtx (QImode);
12446 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12447 NULL_RTX, operands[1]));
12449 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12450 gen_rtx_REG (CCmode, FLAGS_REG),
12452 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12455 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12458 rtx tmp = gen_reg_rtx (SImode);
12460 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12461 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12466 (define_expand "paritysi2"
12467 [(set (match_operand:SI 0 "register_operand" "")
12468 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12471 rtx scratch = gen_reg_rtx (QImode);
12474 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12476 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12477 gen_rtx_REG (CCmode, FLAGS_REG),
12479 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12481 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12485 (define_insn_and_split "paritydi2_cmp"
12486 [(set (reg:CC FLAGS_REG)
12487 (parity:CC (match_operand:DI 3 "register_operand" "0")))
12488 (clobber (match_scratch:DI 0 "=r"))
12489 (clobber (match_scratch:SI 1 "=&r"))
12490 (clobber (match_scratch:HI 2 "=Q"))]
12493 "&& reload_completed"
12495 [(set (match_dup 1)
12496 (xor:SI (match_dup 1) (match_dup 4)))
12497 (clobber (reg:CC FLAGS_REG))])
12499 [(set (reg:CC FLAGS_REG)
12500 (parity:CC (match_dup 1)))
12501 (clobber (match_dup 1))
12502 (clobber (match_dup 2))])]
12504 operands[4] = gen_lowpart (SImode, operands[3]);
12508 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12509 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12512 operands[1] = gen_highpart (SImode, operands[3]);
12515 (define_insn_and_split "paritysi2_cmp"
12516 [(set (reg:CC FLAGS_REG)
12517 (parity:CC (match_operand:SI 2 "register_operand" "0")))
12518 (clobber (match_scratch:SI 0 "=r"))
12519 (clobber (match_scratch:HI 1 "=&Q"))]
12522 "&& reload_completed"
12524 [(set (match_dup 1)
12525 (xor:HI (match_dup 1) (match_dup 3)))
12526 (clobber (reg:CC FLAGS_REG))])
12528 [(set (reg:CC FLAGS_REG)
12529 (parity:CC (match_dup 1)))
12530 (clobber (match_dup 1))])]
12532 operands[3] = gen_lowpart (HImode, operands[2]);
12534 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12535 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12538 (define_insn "*parityhi2_cmp"
12539 [(set (reg:CC FLAGS_REG)
12540 (parity:CC (match_operand:HI 1 "register_operand" "0")))
12541 (clobber (match_scratch:HI 0 "=Q"))]
12543 "xor{b}\t{%h0, %b0|%b0, %h0}"
12544 [(set_attr "length" "2")
12545 (set_attr "mode" "HI")])
12547 (define_insn "*parityqi2_cmp"
12548 [(set (reg:CC FLAGS_REG)
12549 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
12552 [(set_attr "length" "2")
12553 (set_attr "mode" "QI")])
12555 ;; Thread-local storage patterns for ELF.
12557 ;; Note that these code sequences must appear exactly as shown
12558 ;; in order to allow linker relaxation.
12560 (define_insn "*tls_global_dynamic_32_gnu"
12561 [(set (match_operand:SI 0 "register_operand" "=a")
12562 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12563 (match_operand:SI 2 "tls_symbolic_operand" "")
12564 (match_operand:SI 3 "call_insn_operand" "")]
12566 (clobber (match_scratch:SI 4 "=d"))
12567 (clobber (match_scratch:SI 5 "=c"))
12568 (clobber (reg:CC FLAGS_REG))]
12569 "!TARGET_64BIT && TARGET_GNU_TLS"
12570 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12571 [(set_attr "type" "multi")
12572 (set_attr "length" "12")])
12574 (define_expand "tls_global_dynamic_32"
12575 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12578 (match_operand:SI 1 "tls_symbolic_operand" "")
12581 (clobber (match_scratch:SI 4 ""))
12582 (clobber (match_scratch:SI 5 ""))
12583 (clobber (reg:CC FLAGS_REG))])]
12587 operands[2] = pic_offset_table_rtx;
12590 operands[2] = gen_reg_rtx (Pmode);
12591 emit_insn (gen_set_got (operands[2]));
12593 if (TARGET_GNU2_TLS)
12595 emit_insn (gen_tls_dynamic_gnu2_32
12596 (operands[0], operands[1], operands[2]));
12599 operands[3] = ix86_tls_get_addr ();
12602 (define_insn "*tls_global_dynamic_64"
12603 [(set (match_operand:DI 0 "register_operand" "=a")
12604 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12605 (match_operand:DI 3 "" "")))
12606 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12609 { 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"; }
12610 [(set_attr "type" "multi")
12611 (set_attr "length" "16")])
12613 (define_expand "tls_global_dynamic_64"
12614 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12615 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12616 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12620 if (TARGET_GNU2_TLS)
12622 emit_insn (gen_tls_dynamic_gnu2_64
12623 (operands[0], operands[1]));
12626 operands[2] = ix86_tls_get_addr ();
12629 (define_insn "*tls_local_dynamic_base_32_gnu"
12630 [(set (match_operand:SI 0 "register_operand" "=a")
12631 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12632 (match_operand:SI 2 "call_insn_operand" "")]
12633 UNSPEC_TLS_LD_BASE))
12634 (clobber (match_scratch:SI 3 "=d"))
12635 (clobber (match_scratch:SI 4 "=c"))
12636 (clobber (reg:CC FLAGS_REG))]
12637 "!TARGET_64BIT && TARGET_GNU_TLS"
12638 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12639 [(set_attr "type" "multi")
12640 (set_attr "length" "11")])
12642 (define_expand "tls_local_dynamic_base_32"
12643 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12644 (unspec:SI [(match_dup 1) (match_dup 2)]
12645 UNSPEC_TLS_LD_BASE))
12646 (clobber (match_scratch:SI 3 ""))
12647 (clobber (match_scratch:SI 4 ""))
12648 (clobber (reg:CC FLAGS_REG))])]
12652 operands[1] = pic_offset_table_rtx;
12655 operands[1] = gen_reg_rtx (Pmode);
12656 emit_insn (gen_set_got (operands[1]));
12658 if (TARGET_GNU2_TLS)
12660 emit_insn (gen_tls_dynamic_gnu2_32
12661 (operands[0], ix86_tls_module_base (), operands[1]));
12664 operands[2] = ix86_tls_get_addr ();
12667 (define_insn "*tls_local_dynamic_base_64"
12668 [(set (match_operand:DI 0 "register_operand" "=a")
12669 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12670 (match_operand:DI 2 "" "")))
12671 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12673 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12674 [(set_attr "type" "multi")
12675 (set_attr "length" "12")])
12677 (define_expand "tls_local_dynamic_base_64"
12678 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12679 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12680 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12683 if (TARGET_GNU2_TLS)
12685 emit_insn (gen_tls_dynamic_gnu2_64
12686 (operands[0], ix86_tls_module_base ()));
12689 operands[1] = ix86_tls_get_addr ();
12692 ;; Local dynamic of a single variable is a lose. Show combine how
12693 ;; to convert that back to global dynamic.
12695 (define_insn_and_split "*tls_local_dynamic_32_once"
12696 [(set (match_operand:SI 0 "register_operand" "=a")
12697 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12698 (match_operand:SI 2 "call_insn_operand" "")]
12699 UNSPEC_TLS_LD_BASE)
12700 (const:SI (unspec:SI
12701 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12703 (clobber (match_scratch:SI 4 "=d"))
12704 (clobber (match_scratch:SI 5 "=c"))
12705 (clobber (reg:CC FLAGS_REG))]
12709 [(parallel [(set (match_dup 0)
12710 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12712 (clobber (match_dup 4))
12713 (clobber (match_dup 5))
12714 (clobber (reg:CC FLAGS_REG))])]
12717 ;; Load and add the thread base pointer from %gs:0.
12719 (define_insn "*load_tp_si"
12720 [(set (match_operand:SI 0 "register_operand" "=r")
12721 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12723 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12724 [(set_attr "type" "imov")
12725 (set_attr "modrm" "0")
12726 (set_attr "length" "7")
12727 (set_attr "memory" "load")
12728 (set_attr "imm_disp" "false")])
12730 (define_insn "*add_tp_si"
12731 [(set (match_operand:SI 0 "register_operand" "=r")
12732 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12733 (match_operand:SI 1 "register_operand" "0")))
12734 (clobber (reg:CC FLAGS_REG))]
12736 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12737 [(set_attr "type" "alu")
12738 (set_attr "modrm" "0")
12739 (set_attr "length" "7")
12740 (set_attr "memory" "load")
12741 (set_attr "imm_disp" "false")])
12743 (define_insn "*load_tp_di"
12744 [(set (match_operand:DI 0 "register_operand" "=r")
12745 (unspec:DI [(const_int 0)] UNSPEC_TP))]
12747 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12748 [(set_attr "type" "imov")
12749 (set_attr "modrm" "0")
12750 (set_attr "length" "7")
12751 (set_attr "memory" "load")
12752 (set_attr "imm_disp" "false")])
12754 (define_insn "*add_tp_di"
12755 [(set (match_operand:DI 0 "register_operand" "=r")
12756 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12757 (match_operand:DI 1 "register_operand" "0")))
12758 (clobber (reg:CC FLAGS_REG))]
12760 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12761 [(set_attr "type" "alu")
12762 (set_attr "modrm" "0")
12763 (set_attr "length" "7")
12764 (set_attr "memory" "load")
12765 (set_attr "imm_disp" "false")])
12767 ;; GNU2 TLS patterns can be split.
12769 (define_expand "tls_dynamic_gnu2_32"
12770 [(set (match_dup 3)
12771 (plus:SI (match_operand:SI 2 "register_operand" "")
12773 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12776 [(set (match_operand:SI 0 "register_operand" "")
12777 (unspec:SI [(match_dup 1) (match_dup 3)
12778 (match_dup 2) (reg:SI SP_REG)]
12780 (clobber (reg:CC FLAGS_REG))])]
12781 "!TARGET_64BIT && TARGET_GNU2_TLS"
12783 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12784 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12787 (define_insn "*tls_dynamic_lea_32"
12788 [(set (match_operand:SI 0 "register_operand" "=r")
12789 (plus:SI (match_operand:SI 1 "register_operand" "b")
12791 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12792 UNSPEC_TLSDESC))))]
12793 "!TARGET_64BIT && TARGET_GNU2_TLS"
12794 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12795 [(set_attr "type" "lea")
12796 (set_attr "mode" "SI")
12797 (set_attr "length" "6")
12798 (set_attr "length_address" "4")])
12800 (define_insn "*tls_dynamic_call_32"
12801 [(set (match_operand:SI 0 "register_operand" "=a")
12802 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12803 (match_operand:SI 2 "register_operand" "0")
12804 ;; we have to make sure %ebx still points to the GOT
12805 (match_operand:SI 3 "register_operand" "b")
12808 (clobber (reg:CC FLAGS_REG))]
12809 "!TARGET_64BIT && TARGET_GNU2_TLS"
12810 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12811 [(set_attr "type" "call")
12812 (set_attr "length" "2")
12813 (set_attr "length_address" "0")])
12815 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12816 [(set (match_operand:SI 0 "register_operand" "=&a")
12818 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12819 (match_operand:SI 4 "" "")
12820 (match_operand:SI 2 "register_operand" "b")
12823 (const:SI (unspec:SI
12824 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12826 (clobber (reg:CC FLAGS_REG))]
12827 "!TARGET_64BIT && TARGET_GNU2_TLS"
12830 [(set (match_dup 0) (match_dup 5))]
12832 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12833 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12836 (define_expand "tls_dynamic_gnu2_64"
12837 [(set (match_dup 2)
12838 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12841 [(set (match_operand:DI 0 "register_operand" "")
12842 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12844 (clobber (reg:CC FLAGS_REG))])]
12845 "TARGET_64BIT && TARGET_GNU2_TLS"
12847 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12848 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12851 (define_insn "*tls_dynamic_lea_64"
12852 [(set (match_operand:DI 0 "register_operand" "=r")
12853 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12855 "TARGET_64BIT && TARGET_GNU2_TLS"
12856 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12857 [(set_attr "type" "lea")
12858 (set_attr "mode" "DI")
12859 (set_attr "length" "7")
12860 (set_attr "length_address" "4")])
12862 (define_insn "*tls_dynamic_call_64"
12863 [(set (match_operand:DI 0 "register_operand" "=a")
12864 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12865 (match_operand:DI 2 "register_operand" "0")
12868 (clobber (reg:CC FLAGS_REG))]
12869 "TARGET_64BIT && TARGET_GNU2_TLS"
12870 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12871 [(set_attr "type" "call")
12872 (set_attr "length" "2")
12873 (set_attr "length_address" "0")])
12875 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12876 [(set (match_operand:DI 0 "register_operand" "=&a")
12878 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12879 (match_operand:DI 3 "" "")
12882 (const:DI (unspec:DI
12883 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12885 (clobber (reg:CC FLAGS_REG))]
12886 "TARGET_64BIT && TARGET_GNU2_TLS"
12889 [(set (match_dup 0) (match_dup 4))]
12891 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12892 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12897 ;; These patterns match the binary 387 instructions for addM3, subM3,
12898 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12899 ;; SFmode. The first is the normal insn, the second the same insn but
12900 ;; with one operand a conversion, and the third the same insn but with
12901 ;; the other operand a conversion. The conversion may be SFmode or
12902 ;; SImode if the target mode DFmode, but only SImode if the target mode
12905 ;; Gcc is slightly more smart about handling normal two address instructions
12906 ;; so use special patterns for add and mull.
12908 (define_insn "*fop_<mode>_comm_mixed_avx"
12909 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12910 (match_operator:MODEF 3 "binary_fp_operator"
12911 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12912 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12913 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12914 && COMMUTATIVE_ARITH_P (operands[3])
12915 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12916 "* return output_387_binary_op (insn, operands);"
12917 [(set (attr "type")
12918 (if_then_else (eq_attr "alternative" "1")
12919 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12920 (const_string "ssemul")
12921 (const_string "sseadd"))
12922 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12923 (const_string "fmul")
12924 (const_string "fop"))))
12925 (set_attr "prefix" "orig,maybe_vex")
12926 (set_attr "mode" "<MODE>")])
12928 (define_insn "*fop_<mode>_comm_mixed"
12929 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12930 (match_operator:MODEF 3 "binary_fp_operator"
12931 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12932 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12933 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12934 && COMMUTATIVE_ARITH_P (operands[3])
12935 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12936 "* return output_387_binary_op (insn, operands);"
12937 [(set (attr "type")
12938 (if_then_else (eq_attr "alternative" "1")
12939 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12940 (const_string "ssemul")
12941 (const_string "sseadd"))
12942 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12943 (const_string "fmul")
12944 (const_string "fop"))))
12945 (set_attr "mode" "<MODE>")])
12947 (define_insn "*fop_<mode>_comm_avx"
12948 [(set (match_operand:MODEF 0 "register_operand" "=x")
12949 (match_operator:MODEF 3 "binary_fp_operator"
12950 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12951 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12952 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12953 && COMMUTATIVE_ARITH_P (operands[3])
12954 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12955 "* return output_387_binary_op (insn, operands);"
12956 [(set (attr "type")
12957 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12958 (const_string "ssemul")
12959 (const_string "sseadd")))
12960 (set_attr "prefix" "vex")
12961 (set_attr "mode" "<MODE>")])
12963 (define_insn "*fop_<mode>_comm_sse"
12964 [(set (match_operand:MODEF 0 "register_operand" "=x")
12965 (match_operator:MODEF 3 "binary_fp_operator"
12966 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12967 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12968 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12969 && COMMUTATIVE_ARITH_P (operands[3])
12970 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12971 "* return output_387_binary_op (insn, operands);"
12972 [(set (attr "type")
12973 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12974 (const_string "ssemul")
12975 (const_string "sseadd")))
12976 (set_attr "mode" "<MODE>")])
12978 (define_insn "*fop_<mode>_comm_i387"
12979 [(set (match_operand:MODEF 0 "register_operand" "=f")
12980 (match_operator:MODEF 3 "binary_fp_operator"
12981 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12982 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12983 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12984 && COMMUTATIVE_ARITH_P (operands[3])
12985 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12986 "* return output_387_binary_op (insn, operands);"
12987 [(set (attr "type")
12988 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12989 (const_string "fmul")
12990 (const_string "fop")))
12991 (set_attr "mode" "<MODE>")])
12993 (define_insn "*fop_<mode>_1_mixed_avx"
12994 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12995 (match_operator:MODEF 3 "binary_fp_operator"
12996 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12997 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12998 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12999 && !COMMUTATIVE_ARITH_P (operands[3])
13000 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13001 "* return output_387_binary_op (insn, operands);"
13002 [(set (attr "type")
13003 (cond [(and (eq_attr "alternative" "2")
13004 (match_operand:MODEF 3 "mult_operator" ""))
13005 (const_string "ssemul")
13006 (and (eq_attr "alternative" "2")
13007 (match_operand:MODEF 3 "div_operator" ""))
13008 (const_string "ssediv")
13009 (eq_attr "alternative" "2")
13010 (const_string "sseadd")
13011 (match_operand:MODEF 3 "mult_operator" "")
13012 (const_string "fmul")
13013 (match_operand:MODEF 3 "div_operator" "")
13014 (const_string "fdiv")
13016 (const_string "fop")))
13017 (set_attr "prefix" "orig,orig,maybe_vex")
13018 (set_attr "mode" "<MODE>")])
13020 (define_insn "*fop_<mode>_1_mixed"
13021 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13022 (match_operator:MODEF 3 "binary_fp_operator"
13023 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
13024 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13025 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13026 && !COMMUTATIVE_ARITH_P (operands[3])
13027 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13028 "* return output_387_binary_op (insn, operands);"
13029 [(set (attr "type")
13030 (cond [(and (eq_attr "alternative" "2")
13031 (match_operand:MODEF 3 "mult_operator" ""))
13032 (const_string "ssemul")
13033 (and (eq_attr "alternative" "2")
13034 (match_operand:MODEF 3 "div_operator" ""))
13035 (const_string "ssediv")
13036 (eq_attr "alternative" "2")
13037 (const_string "sseadd")
13038 (match_operand:MODEF 3 "mult_operator" "")
13039 (const_string "fmul")
13040 (match_operand:MODEF 3 "div_operator" "")
13041 (const_string "fdiv")
13043 (const_string "fop")))
13044 (set_attr "mode" "<MODE>")])
13046 (define_insn "*rcpsf2_sse"
13047 [(set (match_operand:SF 0 "register_operand" "=x")
13048 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13051 "%vrcpss\t{%1, %d0|%d0, %1}"
13052 [(set_attr "type" "sse")
13053 (set_attr "atom_sse_attr" "rcp")
13054 (set_attr "prefix" "maybe_vex")
13055 (set_attr "mode" "SF")])
13057 (define_insn "*fop_<mode>_1_avx"
13058 [(set (match_operand:MODEF 0 "register_operand" "=x")
13059 (match_operator:MODEF 3 "binary_fp_operator"
13060 [(match_operand:MODEF 1 "register_operand" "x")
13061 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13062 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13063 && !COMMUTATIVE_ARITH_P (operands[3])"
13064 "* return output_387_binary_op (insn, operands);"
13065 [(set (attr "type")
13066 (cond [(match_operand:MODEF 3 "mult_operator" "")
13067 (const_string "ssemul")
13068 (match_operand:MODEF 3 "div_operator" "")
13069 (const_string "ssediv")
13071 (const_string "sseadd")))
13072 (set_attr "prefix" "vex")
13073 (set_attr "mode" "<MODE>")])
13075 (define_insn "*fop_<mode>_1_sse"
13076 [(set (match_operand:MODEF 0 "register_operand" "=x")
13077 (match_operator:MODEF 3 "binary_fp_operator"
13078 [(match_operand:MODEF 1 "register_operand" "0")
13079 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13080 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13081 && !COMMUTATIVE_ARITH_P (operands[3])"
13082 "* return output_387_binary_op (insn, operands);"
13083 [(set (attr "type")
13084 (cond [(match_operand:MODEF 3 "mult_operator" "")
13085 (const_string "ssemul")
13086 (match_operand:MODEF 3 "div_operator" "")
13087 (const_string "ssediv")
13089 (const_string "sseadd")))
13090 (set_attr "mode" "<MODE>")])
13092 ;; This pattern is not fully shadowed by the pattern above.
13093 (define_insn "*fop_<mode>_1_i387"
13094 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13095 (match_operator:MODEF 3 "binary_fp_operator"
13096 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13097 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13098 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13099 && !(SSE_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 (cond [(match_operand:MODEF 3 "mult_operator" "")
13105 (const_string "fmul")
13106 (match_operand:MODEF 3 "div_operator" "")
13107 (const_string "fdiv")
13109 (const_string "fop")))
13110 (set_attr "mode" "<MODE>")])
13112 ;; ??? Add SSE splitters for these!
13113 (define_insn "*fop_<MODEF:mode>_2_i387"
13114 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13115 (match_operator:MODEF 3 "binary_fp_operator"
13117 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13118 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13119 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13120 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13121 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13122 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13123 [(set (attr "type")
13124 (cond [(match_operand:MODEF 3 "mult_operator" "")
13125 (const_string "fmul")
13126 (match_operand:MODEF 3 "div_operator" "")
13127 (const_string "fdiv")
13129 (const_string "fop")))
13130 (set_attr "fp_int_src" "true")
13131 (set_attr "mode" "<X87MODEI12:MODE>")])
13133 (define_insn "*fop_<MODEF:mode>_3_i387"
13134 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13135 (match_operator:MODEF 3 "binary_fp_operator"
13136 [(match_operand:MODEF 1 "register_operand" "0,0")
13138 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13139 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13140 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13141 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13142 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13143 [(set (attr "type")
13144 (cond [(match_operand:MODEF 3 "mult_operator" "")
13145 (const_string "fmul")
13146 (match_operand:MODEF 3 "div_operator" "")
13147 (const_string "fdiv")
13149 (const_string "fop")))
13150 (set_attr "fp_int_src" "true")
13151 (set_attr "mode" "<MODE>")])
13153 (define_insn "*fop_df_4_i387"
13154 [(set (match_operand:DF 0 "register_operand" "=f,f")
13155 (match_operator:DF 3 "binary_fp_operator"
13157 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13158 (match_operand:DF 2 "register_operand" "0,f")]))]
13159 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13160 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13161 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13162 "* return output_387_binary_op (insn, operands);"
13163 [(set (attr "type")
13164 (cond [(match_operand:DF 3 "mult_operator" "")
13165 (const_string "fmul")
13166 (match_operand:DF 3 "div_operator" "")
13167 (const_string "fdiv")
13169 (const_string "fop")))
13170 (set_attr "mode" "SF")])
13172 (define_insn "*fop_df_5_i387"
13173 [(set (match_operand:DF 0 "register_operand" "=f,f")
13174 (match_operator:DF 3 "binary_fp_operator"
13175 [(match_operand:DF 1 "register_operand" "0,f")
13177 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13178 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13179 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13180 "* return output_387_binary_op (insn, operands);"
13181 [(set (attr "type")
13182 (cond [(match_operand:DF 3 "mult_operator" "")
13183 (const_string "fmul")
13184 (match_operand:DF 3 "div_operator" "")
13185 (const_string "fdiv")
13187 (const_string "fop")))
13188 (set_attr "mode" "SF")])
13190 (define_insn "*fop_df_6_i387"
13191 [(set (match_operand:DF 0 "register_operand" "=f,f")
13192 (match_operator:DF 3 "binary_fp_operator"
13194 (match_operand:SF 1 "register_operand" "0,f"))
13196 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13197 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13198 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13199 "* return output_387_binary_op (insn, operands);"
13200 [(set (attr "type")
13201 (cond [(match_operand:DF 3 "mult_operator" "")
13202 (const_string "fmul")
13203 (match_operand:DF 3 "div_operator" "")
13204 (const_string "fdiv")
13206 (const_string "fop")))
13207 (set_attr "mode" "SF")])
13209 (define_insn "*fop_xf_comm_i387"
13210 [(set (match_operand:XF 0 "register_operand" "=f")
13211 (match_operator:XF 3 "binary_fp_operator"
13212 [(match_operand:XF 1 "register_operand" "%0")
13213 (match_operand:XF 2 "register_operand" "f")]))]
13215 && COMMUTATIVE_ARITH_P (operands[3])"
13216 "* return output_387_binary_op (insn, operands);"
13217 [(set (attr "type")
13218 (if_then_else (match_operand:XF 3 "mult_operator" "")
13219 (const_string "fmul")
13220 (const_string "fop")))
13221 (set_attr "mode" "XF")])
13223 (define_insn "*fop_xf_1_i387"
13224 [(set (match_operand:XF 0 "register_operand" "=f,f")
13225 (match_operator:XF 3 "binary_fp_operator"
13226 [(match_operand:XF 1 "register_operand" "0,f")
13227 (match_operand:XF 2 "register_operand" "f,0")]))]
13229 && !COMMUTATIVE_ARITH_P (operands[3])"
13230 "* return output_387_binary_op (insn, operands);"
13231 [(set (attr "type")
13232 (cond [(match_operand:XF 3 "mult_operator" "")
13233 (const_string "fmul")
13234 (match_operand:XF 3 "div_operator" "")
13235 (const_string "fdiv")
13237 (const_string "fop")))
13238 (set_attr "mode" "XF")])
13240 (define_insn "*fop_xf_2_i387"
13241 [(set (match_operand:XF 0 "register_operand" "=f,f")
13242 (match_operator:XF 3 "binary_fp_operator"
13244 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13245 (match_operand:XF 2 "register_operand" "0,0")]))]
13246 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13247 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13248 [(set (attr "type")
13249 (cond [(match_operand:XF 3 "mult_operator" "")
13250 (const_string "fmul")
13251 (match_operand:XF 3 "div_operator" "")
13252 (const_string "fdiv")
13254 (const_string "fop")))
13255 (set_attr "fp_int_src" "true")
13256 (set_attr "mode" "<MODE>")])
13258 (define_insn "*fop_xf_3_i387"
13259 [(set (match_operand:XF 0 "register_operand" "=f,f")
13260 (match_operator:XF 3 "binary_fp_operator"
13261 [(match_operand:XF 1 "register_operand" "0,0")
13263 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13264 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13265 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13266 [(set (attr "type")
13267 (cond [(match_operand:XF 3 "mult_operator" "")
13268 (const_string "fmul")
13269 (match_operand:XF 3 "div_operator" "")
13270 (const_string "fdiv")
13272 (const_string "fop")))
13273 (set_attr "fp_int_src" "true")
13274 (set_attr "mode" "<MODE>")])
13276 (define_insn "*fop_xf_4_i387"
13277 [(set (match_operand:XF 0 "register_operand" "=f,f")
13278 (match_operator:XF 3 "binary_fp_operator"
13280 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13281 (match_operand:XF 2 "register_operand" "0,f")]))]
13283 "* return output_387_binary_op (insn, operands);"
13284 [(set (attr "type")
13285 (cond [(match_operand:XF 3 "mult_operator" "")
13286 (const_string "fmul")
13287 (match_operand:XF 3 "div_operator" "")
13288 (const_string "fdiv")
13290 (const_string "fop")))
13291 (set_attr "mode" "<MODE>")])
13293 (define_insn "*fop_xf_5_i387"
13294 [(set (match_operand:XF 0 "register_operand" "=f,f")
13295 (match_operator:XF 3 "binary_fp_operator"
13296 [(match_operand:XF 1 "register_operand" "0,f")
13298 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13300 "* return output_387_binary_op (insn, operands);"
13301 [(set (attr "type")
13302 (cond [(match_operand:XF 3 "mult_operator" "")
13303 (const_string "fmul")
13304 (match_operand:XF 3 "div_operator" "")
13305 (const_string "fdiv")
13307 (const_string "fop")))
13308 (set_attr "mode" "<MODE>")])
13310 (define_insn "*fop_xf_6_i387"
13311 [(set (match_operand:XF 0 "register_operand" "=f,f")
13312 (match_operator:XF 3 "binary_fp_operator"
13314 (match_operand:MODEF 1 "register_operand" "0,f"))
13316 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13318 "* return output_387_binary_op (insn, operands);"
13319 [(set (attr "type")
13320 (cond [(match_operand:XF 3 "mult_operator" "")
13321 (const_string "fmul")
13322 (match_operand:XF 3 "div_operator" "")
13323 (const_string "fdiv")
13325 (const_string "fop")))
13326 (set_attr "mode" "<MODE>")])
13329 [(set (match_operand 0 "register_operand" "")
13330 (match_operator 3 "binary_fp_operator"
13331 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13332 (match_operand 2 "register_operand" "")]))]
13334 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13335 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13338 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13339 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13340 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13341 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13342 GET_MODE (operands[3]),
13345 ix86_free_from_memory (GET_MODE (operands[1]));
13350 [(set (match_operand 0 "register_operand" "")
13351 (match_operator 3 "binary_fp_operator"
13352 [(match_operand 1 "register_operand" "")
13353 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13355 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13356 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13359 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13360 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13361 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13362 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13363 GET_MODE (operands[3]),
13366 ix86_free_from_memory (GET_MODE (operands[2]));
13370 ;; FPU special functions.
13372 ;; This pattern implements a no-op XFmode truncation for
13373 ;; all fancy i386 XFmode math functions.
13375 (define_insn "truncxf<mode>2_i387_noop_unspec"
13376 [(set (match_operand:MODEF 0 "register_operand" "=f")
13377 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13378 UNSPEC_TRUNC_NOOP))]
13379 "TARGET_USE_FANCY_MATH_387"
13380 "* return output_387_reg_move (insn, operands);"
13381 [(set_attr "type" "fmov")
13382 (set_attr "mode" "<MODE>")])
13384 (define_insn "sqrtxf2"
13385 [(set (match_operand:XF 0 "register_operand" "=f")
13386 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13387 "TARGET_USE_FANCY_MATH_387"
13389 [(set_attr "type" "fpspc")
13390 (set_attr "mode" "XF")
13391 (set_attr "athlon_decode" "direct")
13392 (set_attr "amdfam10_decode" "direct")])
13394 (define_insn "sqrt_extend<mode>xf2_i387"
13395 [(set (match_operand:XF 0 "register_operand" "=f")
13398 (match_operand:MODEF 1 "register_operand" "0"))))]
13399 "TARGET_USE_FANCY_MATH_387"
13401 [(set_attr "type" "fpspc")
13402 (set_attr "mode" "XF")
13403 (set_attr "athlon_decode" "direct")
13404 (set_attr "amdfam10_decode" "direct")])
13406 (define_insn "*rsqrtsf2_sse"
13407 [(set (match_operand:SF 0 "register_operand" "=x")
13408 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13411 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13412 [(set_attr "type" "sse")
13413 (set_attr "atom_sse_attr" "rcp")
13414 (set_attr "prefix" "maybe_vex")
13415 (set_attr "mode" "SF")])
13417 (define_expand "rsqrtsf2"
13418 [(set (match_operand:SF 0 "register_operand" "")
13419 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13423 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13427 (define_insn "*sqrt<mode>2_sse"
13428 [(set (match_operand:MODEF 0 "register_operand" "=x")
13430 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13431 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13432 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13433 [(set_attr "type" "sse")
13434 (set_attr "atom_sse_attr" "sqrt")
13435 (set_attr "prefix" "maybe_vex")
13436 (set_attr "mode" "<MODE>")
13437 (set_attr "athlon_decode" "*")
13438 (set_attr "amdfam10_decode" "*")])
13440 (define_expand "sqrt<mode>2"
13441 [(set (match_operand:MODEF 0 "register_operand" "")
13443 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13444 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13445 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13447 if (<MODE>mode == SFmode
13448 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13449 && flag_finite_math_only && !flag_trapping_math
13450 && flag_unsafe_math_optimizations)
13452 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13456 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13458 rtx op0 = gen_reg_rtx (XFmode);
13459 rtx op1 = force_reg (<MODE>mode, operands[1]);
13461 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13462 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13467 (define_insn "fpremxf4_i387"
13468 [(set (match_operand:XF 0 "register_operand" "=f")
13469 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13470 (match_operand:XF 3 "register_operand" "1")]
13472 (set (match_operand:XF 1 "register_operand" "=u")
13473 (unspec:XF [(match_dup 2) (match_dup 3)]
13475 (set (reg:CCFP FPSR_REG)
13476 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13478 "TARGET_USE_FANCY_MATH_387"
13480 [(set_attr "type" "fpspc")
13481 (set_attr "mode" "XF")])
13483 (define_expand "fmodxf3"
13484 [(use (match_operand:XF 0 "register_operand" ""))
13485 (use (match_operand:XF 1 "general_operand" ""))
13486 (use (match_operand:XF 2 "general_operand" ""))]
13487 "TARGET_USE_FANCY_MATH_387"
13489 rtx label = gen_label_rtx ();
13491 rtx op1 = gen_reg_rtx (XFmode);
13492 rtx op2 = gen_reg_rtx (XFmode);
13494 emit_move_insn (op2, operands[2]);
13495 emit_move_insn (op1, operands[1]);
13497 emit_label (label);
13498 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13499 ix86_emit_fp_unordered_jump (label);
13500 LABEL_NUSES (label) = 1;
13502 emit_move_insn (operands[0], op1);
13506 (define_expand "fmod<mode>3"
13507 [(use (match_operand:MODEF 0 "register_operand" ""))
13508 (use (match_operand:MODEF 1 "general_operand" ""))
13509 (use (match_operand:MODEF 2 "general_operand" ""))]
13510 "TARGET_USE_FANCY_MATH_387"
13512 rtx label = gen_label_rtx ();
13514 rtx op1 = gen_reg_rtx (XFmode);
13515 rtx op2 = gen_reg_rtx (XFmode);
13517 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13518 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13520 emit_label (label);
13521 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13522 ix86_emit_fp_unordered_jump (label);
13523 LABEL_NUSES (label) = 1;
13525 /* Truncate the result properly for strict SSE math. */
13526 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13527 && !TARGET_MIX_SSE_I387)
13528 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13530 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13535 (define_insn "fprem1xf4_i387"
13536 [(set (match_operand:XF 0 "register_operand" "=f")
13537 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13538 (match_operand:XF 3 "register_operand" "1")]
13540 (set (match_operand:XF 1 "register_operand" "=u")
13541 (unspec:XF [(match_dup 2) (match_dup 3)]
13543 (set (reg:CCFP FPSR_REG)
13544 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13546 "TARGET_USE_FANCY_MATH_387"
13548 [(set_attr "type" "fpspc")
13549 (set_attr "mode" "XF")])
13551 (define_expand "remainderxf3"
13552 [(use (match_operand:XF 0 "register_operand" ""))
13553 (use (match_operand:XF 1 "general_operand" ""))
13554 (use (match_operand:XF 2 "general_operand" ""))]
13555 "TARGET_USE_FANCY_MATH_387"
13557 rtx label = gen_label_rtx ();
13559 rtx op1 = gen_reg_rtx (XFmode);
13560 rtx op2 = gen_reg_rtx (XFmode);
13562 emit_move_insn (op2, operands[2]);
13563 emit_move_insn (op1, operands[1]);
13565 emit_label (label);
13566 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13567 ix86_emit_fp_unordered_jump (label);
13568 LABEL_NUSES (label) = 1;
13570 emit_move_insn (operands[0], op1);
13574 (define_expand "remainder<mode>3"
13575 [(use (match_operand:MODEF 0 "register_operand" ""))
13576 (use (match_operand:MODEF 1 "general_operand" ""))
13577 (use (match_operand:MODEF 2 "general_operand" ""))]
13578 "TARGET_USE_FANCY_MATH_387"
13580 rtx label = gen_label_rtx ();
13582 rtx op1 = gen_reg_rtx (XFmode);
13583 rtx op2 = gen_reg_rtx (XFmode);
13585 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13586 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13588 emit_label (label);
13590 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13591 ix86_emit_fp_unordered_jump (label);
13592 LABEL_NUSES (label) = 1;
13594 /* Truncate the result properly for strict SSE math. */
13595 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13596 && !TARGET_MIX_SSE_I387)
13597 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13599 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13604 (define_insn "*sinxf2_i387"
13605 [(set (match_operand:XF 0 "register_operand" "=f")
13606 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13607 "TARGET_USE_FANCY_MATH_387
13608 && flag_unsafe_math_optimizations"
13610 [(set_attr "type" "fpspc")
13611 (set_attr "mode" "XF")])
13613 (define_insn "*sin_extend<mode>xf2_i387"
13614 [(set (match_operand:XF 0 "register_operand" "=f")
13615 (unspec:XF [(float_extend:XF
13616 (match_operand:MODEF 1 "register_operand" "0"))]
13618 "TARGET_USE_FANCY_MATH_387
13619 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13620 || TARGET_MIX_SSE_I387)
13621 && flag_unsafe_math_optimizations"
13623 [(set_attr "type" "fpspc")
13624 (set_attr "mode" "XF")])
13626 (define_insn "*cosxf2_i387"
13627 [(set (match_operand:XF 0 "register_operand" "=f")
13628 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13629 "TARGET_USE_FANCY_MATH_387
13630 && flag_unsafe_math_optimizations"
13632 [(set_attr "type" "fpspc")
13633 (set_attr "mode" "XF")])
13635 (define_insn "*cos_extend<mode>xf2_i387"
13636 [(set (match_operand:XF 0 "register_operand" "=f")
13637 (unspec:XF [(float_extend:XF
13638 (match_operand:MODEF 1 "register_operand" "0"))]
13640 "TARGET_USE_FANCY_MATH_387
13641 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13642 || TARGET_MIX_SSE_I387)
13643 && flag_unsafe_math_optimizations"
13645 [(set_attr "type" "fpspc")
13646 (set_attr "mode" "XF")])
13648 ;; When sincos pattern is defined, sin and cos builtin functions will be
13649 ;; expanded to sincos pattern with one of its outputs left unused.
13650 ;; CSE pass will figure out if two sincos patterns can be combined,
13651 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13652 ;; depending on the unused output.
13654 (define_insn "sincosxf3"
13655 [(set (match_operand:XF 0 "register_operand" "=f")
13656 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13657 UNSPEC_SINCOS_COS))
13658 (set (match_operand:XF 1 "register_operand" "=u")
13659 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13660 "TARGET_USE_FANCY_MATH_387
13661 && flag_unsafe_math_optimizations"
13663 [(set_attr "type" "fpspc")
13664 (set_attr "mode" "XF")])
13667 [(set (match_operand:XF 0 "register_operand" "")
13668 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13669 UNSPEC_SINCOS_COS))
13670 (set (match_operand:XF 1 "register_operand" "")
13671 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13672 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13673 && !(reload_completed || reload_in_progress)"
13674 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13678 [(set (match_operand:XF 0 "register_operand" "")
13679 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13680 UNSPEC_SINCOS_COS))
13681 (set (match_operand:XF 1 "register_operand" "")
13682 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13683 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13684 && !(reload_completed || reload_in_progress)"
13685 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13688 (define_insn "sincos_extend<mode>xf3_i387"
13689 [(set (match_operand:XF 0 "register_operand" "=f")
13690 (unspec:XF [(float_extend:XF
13691 (match_operand:MODEF 2 "register_operand" "0"))]
13692 UNSPEC_SINCOS_COS))
13693 (set (match_operand:XF 1 "register_operand" "=u")
13694 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13695 "TARGET_USE_FANCY_MATH_387
13696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13697 || TARGET_MIX_SSE_I387)
13698 && flag_unsafe_math_optimizations"
13700 [(set_attr "type" "fpspc")
13701 (set_attr "mode" "XF")])
13704 [(set (match_operand:XF 0 "register_operand" "")
13705 (unspec:XF [(float_extend:XF
13706 (match_operand:MODEF 2 "register_operand" ""))]
13707 UNSPEC_SINCOS_COS))
13708 (set (match_operand:XF 1 "register_operand" "")
13709 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13710 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13711 && !(reload_completed || reload_in_progress)"
13712 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13716 [(set (match_operand:XF 0 "register_operand" "")
13717 (unspec:XF [(float_extend:XF
13718 (match_operand:MODEF 2 "register_operand" ""))]
13719 UNSPEC_SINCOS_COS))
13720 (set (match_operand:XF 1 "register_operand" "")
13721 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13722 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13723 && !(reload_completed || reload_in_progress)"
13724 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13727 (define_expand "sincos<mode>3"
13728 [(use (match_operand:MODEF 0 "register_operand" ""))
13729 (use (match_operand:MODEF 1 "register_operand" ""))
13730 (use (match_operand:MODEF 2 "register_operand" ""))]
13731 "TARGET_USE_FANCY_MATH_387
13732 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13733 || TARGET_MIX_SSE_I387)
13734 && flag_unsafe_math_optimizations"
13736 rtx op0 = gen_reg_rtx (XFmode);
13737 rtx op1 = gen_reg_rtx (XFmode);
13739 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13740 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13741 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13745 (define_insn "fptanxf4_i387"
13746 [(set (match_operand:XF 0 "register_operand" "=f")
13747 (match_operand:XF 3 "const_double_operand" "F"))
13748 (set (match_operand:XF 1 "register_operand" "=u")
13749 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13751 "TARGET_USE_FANCY_MATH_387
13752 && flag_unsafe_math_optimizations
13753 && standard_80387_constant_p (operands[3]) == 2"
13755 [(set_attr "type" "fpspc")
13756 (set_attr "mode" "XF")])
13758 (define_insn "fptan_extend<mode>xf4_i387"
13759 [(set (match_operand:MODEF 0 "register_operand" "=f")
13760 (match_operand:MODEF 3 "const_double_operand" "F"))
13761 (set (match_operand:XF 1 "register_operand" "=u")
13762 (unspec:XF [(float_extend:XF
13763 (match_operand:MODEF 2 "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
13769 && standard_80387_constant_p (operands[3]) == 2"
13771 [(set_attr "type" "fpspc")
13772 (set_attr "mode" "XF")])
13774 (define_expand "tanxf2"
13775 [(use (match_operand:XF 0 "register_operand" ""))
13776 (use (match_operand:XF 1 "register_operand" ""))]
13777 "TARGET_USE_FANCY_MATH_387
13778 && flag_unsafe_math_optimizations"
13780 rtx one = gen_reg_rtx (XFmode);
13781 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13783 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13787 (define_expand "tan<mode>2"
13788 [(use (match_operand:MODEF 0 "register_operand" ""))
13789 (use (match_operand:MODEF 1 "register_operand" ""))]
13790 "TARGET_USE_FANCY_MATH_387
13791 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13792 || TARGET_MIX_SSE_I387)
13793 && flag_unsafe_math_optimizations"
13795 rtx op0 = gen_reg_rtx (XFmode);
13797 rtx one = gen_reg_rtx (<MODE>mode);
13798 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13800 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13801 operands[1], op2));
13802 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13806 (define_insn "*fpatanxf3_i387"
13807 [(set (match_operand:XF 0 "register_operand" "=f")
13808 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13809 (match_operand:XF 2 "register_operand" "u")]
13811 (clobber (match_scratch:XF 3 "=2"))]
13812 "TARGET_USE_FANCY_MATH_387
13813 && flag_unsafe_math_optimizations"
13815 [(set_attr "type" "fpspc")
13816 (set_attr "mode" "XF")])
13818 (define_insn "fpatan_extend<mode>xf3_i387"
13819 [(set (match_operand:XF 0 "register_operand" "=f")
13820 (unspec:XF [(float_extend:XF
13821 (match_operand:MODEF 1 "register_operand" "0"))
13823 (match_operand:MODEF 2 "register_operand" "u"))]
13825 (clobber (match_scratch:XF 3 "=2"))]
13826 "TARGET_USE_FANCY_MATH_387
13827 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13828 || TARGET_MIX_SSE_I387)
13829 && flag_unsafe_math_optimizations"
13831 [(set_attr "type" "fpspc")
13832 (set_attr "mode" "XF")])
13834 (define_expand "atan2xf3"
13835 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13836 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13837 (match_operand:XF 1 "register_operand" "")]
13839 (clobber (match_scratch:XF 3 ""))])]
13840 "TARGET_USE_FANCY_MATH_387
13841 && flag_unsafe_math_optimizations"
13844 (define_expand "atan2<mode>3"
13845 [(use (match_operand:MODEF 0 "register_operand" ""))
13846 (use (match_operand:MODEF 1 "register_operand" ""))
13847 (use (match_operand:MODEF 2 "register_operand" ""))]
13848 "TARGET_USE_FANCY_MATH_387
13849 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13850 || TARGET_MIX_SSE_I387)
13851 && flag_unsafe_math_optimizations"
13853 rtx op0 = gen_reg_rtx (XFmode);
13855 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13856 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13860 (define_expand "atanxf2"
13861 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13862 (unspec:XF [(match_dup 2)
13863 (match_operand:XF 1 "register_operand" "")]
13865 (clobber (match_scratch:XF 3 ""))])]
13866 "TARGET_USE_FANCY_MATH_387
13867 && flag_unsafe_math_optimizations"
13869 operands[2] = gen_reg_rtx (XFmode);
13870 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13873 (define_expand "atan<mode>2"
13874 [(use (match_operand:MODEF 0 "register_operand" ""))
13875 (use (match_operand:MODEF 1 "register_operand" ""))]
13876 "TARGET_USE_FANCY_MATH_387
13877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13878 || TARGET_MIX_SSE_I387)
13879 && flag_unsafe_math_optimizations"
13881 rtx op0 = gen_reg_rtx (XFmode);
13883 rtx op2 = gen_reg_rtx (<MODE>mode);
13884 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13886 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13887 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13891 (define_expand "asinxf2"
13892 [(set (match_dup 2)
13893 (mult:XF (match_operand:XF 1 "register_operand" "")
13895 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13896 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13897 (parallel [(set (match_operand:XF 0 "register_operand" "")
13898 (unspec:XF [(match_dup 5) (match_dup 1)]
13900 (clobber (match_scratch:XF 6 ""))])]
13901 "TARGET_USE_FANCY_MATH_387
13902 && flag_unsafe_math_optimizations"
13906 if (optimize_insn_for_size_p ())
13909 for (i = 2; i < 6; i++)
13910 operands[i] = gen_reg_rtx (XFmode);
13912 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13915 (define_expand "asin<mode>2"
13916 [(use (match_operand:MODEF 0 "register_operand" ""))
13917 (use (match_operand:MODEF 1 "general_operand" ""))]
13918 "TARGET_USE_FANCY_MATH_387
13919 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13920 || TARGET_MIX_SSE_I387)
13921 && flag_unsafe_math_optimizations"
13923 rtx op0 = gen_reg_rtx (XFmode);
13924 rtx op1 = gen_reg_rtx (XFmode);
13926 if (optimize_insn_for_size_p ())
13929 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13930 emit_insn (gen_asinxf2 (op0, op1));
13931 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13935 (define_expand "acosxf2"
13936 [(set (match_dup 2)
13937 (mult:XF (match_operand:XF 1 "register_operand" "")
13939 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13940 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13941 (parallel [(set (match_operand:XF 0 "register_operand" "")
13942 (unspec:XF [(match_dup 1) (match_dup 5)]
13944 (clobber (match_scratch:XF 6 ""))])]
13945 "TARGET_USE_FANCY_MATH_387
13946 && flag_unsafe_math_optimizations"
13950 if (optimize_insn_for_size_p ())
13953 for (i = 2; i < 6; i++)
13954 operands[i] = gen_reg_rtx (XFmode);
13956 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13959 (define_expand "acos<mode>2"
13960 [(use (match_operand:MODEF 0 "register_operand" ""))
13961 (use (match_operand:MODEF 1 "general_operand" ""))]
13962 "TARGET_USE_FANCY_MATH_387
13963 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13964 || TARGET_MIX_SSE_I387)
13965 && flag_unsafe_math_optimizations"
13967 rtx op0 = gen_reg_rtx (XFmode);
13968 rtx op1 = gen_reg_rtx (XFmode);
13970 if (optimize_insn_for_size_p ())
13973 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13974 emit_insn (gen_acosxf2 (op0, op1));
13975 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13979 (define_insn "fyl2xxf3_i387"
13980 [(set (match_operand:XF 0 "register_operand" "=f")
13981 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13982 (match_operand:XF 2 "register_operand" "u")]
13984 (clobber (match_scratch:XF 3 "=2"))]
13985 "TARGET_USE_FANCY_MATH_387
13986 && flag_unsafe_math_optimizations"
13988 [(set_attr "type" "fpspc")
13989 (set_attr "mode" "XF")])
13991 (define_insn "fyl2x_extend<mode>xf3_i387"
13992 [(set (match_operand:XF 0 "register_operand" "=f")
13993 (unspec:XF [(float_extend:XF
13994 (match_operand:MODEF 1 "register_operand" "0"))
13995 (match_operand:XF 2 "register_operand" "u")]
13997 (clobber (match_scratch:XF 3 "=2"))]
13998 "TARGET_USE_FANCY_MATH_387
13999 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14000 || TARGET_MIX_SSE_I387)
14001 && flag_unsafe_math_optimizations"
14003 [(set_attr "type" "fpspc")
14004 (set_attr "mode" "XF")])
14006 (define_expand "logxf2"
14007 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14008 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14009 (match_dup 2)] UNSPEC_FYL2X))
14010 (clobber (match_scratch:XF 3 ""))])]
14011 "TARGET_USE_FANCY_MATH_387
14012 && flag_unsafe_math_optimizations"
14014 operands[2] = gen_reg_rtx (XFmode);
14015 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14018 (define_expand "log<mode>2"
14019 [(use (match_operand:MODEF 0 "register_operand" ""))
14020 (use (match_operand:MODEF 1 "register_operand" ""))]
14021 "TARGET_USE_FANCY_MATH_387
14022 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14023 || TARGET_MIX_SSE_I387)
14024 && flag_unsafe_math_optimizations"
14026 rtx op0 = gen_reg_rtx (XFmode);
14028 rtx op2 = gen_reg_rtx (XFmode);
14029 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14031 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14032 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14036 (define_expand "log10xf2"
14037 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14038 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14039 (match_dup 2)] UNSPEC_FYL2X))
14040 (clobber (match_scratch:XF 3 ""))])]
14041 "TARGET_USE_FANCY_MATH_387
14042 && flag_unsafe_math_optimizations"
14044 operands[2] = gen_reg_rtx (XFmode);
14045 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14048 (define_expand "log10<mode>2"
14049 [(use (match_operand:MODEF 0 "register_operand" ""))
14050 (use (match_operand:MODEF 1 "register_operand" ""))]
14051 "TARGET_USE_FANCY_MATH_387
14052 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14053 || TARGET_MIX_SSE_I387)
14054 && flag_unsafe_math_optimizations"
14056 rtx op0 = gen_reg_rtx (XFmode);
14058 rtx op2 = gen_reg_rtx (XFmode);
14059 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14061 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14062 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14066 (define_expand "log2xf2"
14067 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14068 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14069 (match_dup 2)] UNSPEC_FYL2X))
14070 (clobber (match_scratch:XF 3 ""))])]
14071 "TARGET_USE_FANCY_MATH_387
14072 && flag_unsafe_math_optimizations"
14074 operands[2] = gen_reg_rtx (XFmode);
14075 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14078 (define_expand "log2<mode>2"
14079 [(use (match_operand:MODEF 0 "register_operand" ""))
14080 (use (match_operand:MODEF 1 "register_operand" ""))]
14081 "TARGET_USE_FANCY_MATH_387
14082 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14083 || TARGET_MIX_SSE_I387)
14084 && flag_unsafe_math_optimizations"
14086 rtx op0 = gen_reg_rtx (XFmode);
14088 rtx op2 = gen_reg_rtx (XFmode);
14089 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14091 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14092 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14096 (define_insn "fyl2xp1xf3_i387"
14097 [(set (match_operand:XF 0 "register_operand" "=f")
14098 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14099 (match_operand:XF 2 "register_operand" "u")]
14101 (clobber (match_scratch:XF 3 "=2"))]
14102 "TARGET_USE_FANCY_MATH_387
14103 && flag_unsafe_math_optimizations"
14105 [(set_attr "type" "fpspc")
14106 (set_attr "mode" "XF")])
14108 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14109 [(set (match_operand:XF 0 "register_operand" "=f")
14110 (unspec:XF [(float_extend:XF
14111 (match_operand:MODEF 1 "register_operand" "0"))
14112 (match_operand:XF 2 "register_operand" "u")]
14114 (clobber (match_scratch:XF 3 "=2"))]
14115 "TARGET_USE_FANCY_MATH_387
14116 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14117 || TARGET_MIX_SSE_I387)
14118 && flag_unsafe_math_optimizations"
14120 [(set_attr "type" "fpspc")
14121 (set_attr "mode" "XF")])
14123 (define_expand "log1pxf2"
14124 [(use (match_operand:XF 0 "register_operand" ""))
14125 (use (match_operand:XF 1 "register_operand" ""))]
14126 "TARGET_USE_FANCY_MATH_387
14127 && flag_unsafe_math_optimizations"
14129 if (optimize_insn_for_size_p ())
14132 ix86_emit_i387_log1p (operands[0], operands[1]);
14136 (define_expand "log1p<mode>2"
14137 [(use (match_operand:MODEF 0 "register_operand" ""))
14138 (use (match_operand:MODEF 1 "register_operand" ""))]
14139 "TARGET_USE_FANCY_MATH_387
14140 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14141 || TARGET_MIX_SSE_I387)
14142 && flag_unsafe_math_optimizations"
14146 if (optimize_insn_for_size_p ())
14149 op0 = gen_reg_rtx (XFmode);
14151 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14153 ix86_emit_i387_log1p (op0, operands[1]);
14154 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14158 (define_insn "fxtractxf3_i387"
14159 [(set (match_operand:XF 0 "register_operand" "=f")
14160 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14161 UNSPEC_XTRACT_FRACT))
14162 (set (match_operand:XF 1 "register_operand" "=u")
14163 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14164 "TARGET_USE_FANCY_MATH_387
14165 && flag_unsafe_math_optimizations"
14167 [(set_attr "type" "fpspc")
14168 (set_attr "mode" "XF")])
14170 (define_insn "fxtract_extend<mode>xf3_i387"
14171 [(set (match_operand:XF 0 "register_operand" "=f")
14172 (unspec:XF [(float_extend:XF
14173 (match_operand:MODEF 2 "register_operand" "0"))]
14174 UNSPEC_XTRACT_FRACT))
14175 (set (match_operand:XF 1 "register_operand" "=u")
14176 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14177 "TARGET_USE_FANCY_MATH_387
14178 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14179 || TARGET_MIX_SSE_I387)
14180 && flag_unsafe_math_optimizations"
14182 [(set_attr "type" "fpspc")
14183 (set_attr "mode" "XF")])
14185 (define_expand "logbxf2"
14186 [(parallel [(set (match_dup 2)
14187 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14188 UNSPEC_XTRACT_FRACT))
14189 (set (match_operand:XF 0 "register_operand" "")
14190 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14191 "TARGET_USE_FANCY_MATH_387
14192 && flag_unsafe_math_optimizations"
14194 operands[2] = gen_reg_rtx (XFmode);
14197 (define_expand "logb<mode>2"
14198 [(use (match_operand:MODEF 0 "register_operand" ""))
14199 (use (match_operand:MODEF 1 "register_operand" ""))]
14200 "TARGET_USE_FANCY_MATH_387
14201 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14202 || TARGET_MIX_SSE_I387)
14203 && flag_unsafe_math_optimizations"
14205 rtx op0 = gen_reg_rtx (XFmode);
14206 rtx op1 = gen_reg_rtx (XFmode);
14208 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14209 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14213 (define_expand "ilogbxf2"
14214 [(use (match_operand:SI 0 "register_operand" ""))
14215 (use (match_operand:XF 1 "register_operand" ""))]
14216 "TARGET_USE_FANCY_MATH_387
14217 && flag_unsafe_math_optimizations"
14221 if (optimize_insn_for_size_p ())
14224 op0 = gen_reg_rtx (XFmode);
14225 op1 = gen_reg_rtx (XFmode);
14227 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14228 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14232 (define_expand "ilogb<mode>2"
14233 [(use (match_operand:SI 0 "register_operand" ""))
14234 (use (match_operand:MODEF 1 "register_operand" ""))]
14235 "TARGET_USE_FANCY_MATH_387
14236 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14237 || TARGET_MIX_SSE_I387)
14238 && flag_unsafe_math_optimizations"
14242 if (optimize_insn_for_size_p ())
14245 op0 = gen_reg_rtx (XFmode);
14246 op1 = gen_reg_rtx (XFmode);
14248 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14249 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14253 (define_insn "*f2xm1xf2_i387"
14254 [(set (match_operand:XF 0 "register_operand" "=f")
14255 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14257 "TARGET_USE_FANCY_MATH_387
14258 && flag_unsafe_math_optimizations"
14260 [(set_attr "type" "fpspc")
14261 (set_attr "mode" "XF")])
14263 (define_insn "*fscalexf4_i387"
14264 [(set (match_operand:XF 0 "register_operand" "=f")
14265 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14266 (match_operand:XF 3 "register_operand" "1")]
14267 UNSPEC_FSCALE_FRACT))
14268 (set (match_operand:XF 1 "register_operand" "=u")
14269 (unspec:XF [(match_dup 2) (match_dup 3)]
14270 UNSPEC_FSCALE_EXP))]
14271 "TARGET_USE_FANCY_MATH_387
14272 && flag_unsafe_math_optimizations"
14274 [(set_attr "type" "fpspc")
14275 (set_attr "mode" "XF")])
14277 (define_expand "expNcorexf3"
14278 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14279 (match_operand:XF 2 "register_operand" "")))
14280 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14281 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14282 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14283 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14284 (parallel [(set (match_operand:XF 0 "register_operand" "")
14285 (unspec:XF [(match_dup 8) (match_dup 4)]
14286 UNSPEC_FSCALE_FRACT))
14288 (unspec:XF [(match_dup 8) (match_dup 4)]
14289 UNSPEC_FSCALE_EXP))])]
14290 "TARGET_USE_FANCY_MATH_387
14291 && flag_unsafe_math_optimizations"
14295 if (optimize_insn_for_size_p ())
14298 for (i = 3; i < 10; i++)
14299 operands[i] = gen_reg_rtx (XFmode);
14301 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14304 (define_expand "expxf2"
14305 [(use (match_operand:XF 0 "register_operand" ""))
14306 (use (match_operand:XF 1 "register_operand" ""))]
14307 "TARGET_USE_FANCY_MATH_387
14308 && flag_unsafe_math_optimizations"
14312 if (optimize_insn_for_size_p ())
14315 op2 = gen_reg_rtx (XFmode);
14316 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14318 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14322 (define_expand "exp<mode>2"
14323 [(use (match_operand:MODEF 0 "register_operand" ""))
14324 (use (match_operand:MODEF 1 "general_operand" ""))]
14325 "TARGET_USE_FANCY_MATH_387
14326 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14327 || TARGET_MIX_SSE_I387)
14328 && flag_unsafe_math_optimizations"
14332 if (optimize_insn_for_size_p ())
14335 op0 = gen_reg_rtx (XFmode);
14336 op1 = gen_reg_rtx (XFmode);
14338 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14339 emit_insn (gen_expxf2 (op0, op1));
14340 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14344 (define_expand "exp10xf2"
14345 [(use (match_operand:XF 0 "register_operand" ""))
14346 (use (match_operand:XF 1 "register_operand" ""))]
14347 "TARGET_USE_FANCY_MATH_387
14348 && flag_unsafe_math_optimizations"
14352 if (optimize_insn_for_size_p ())
14355 op2 = gen_reg_rtx (XFmode);
14356 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14358 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14362 (define_expand "exp10<mode>2"
14363 [(use (match_operand:MODEF 0 "register_operand" ""))
14364 (use (match_operand:MODEF 1 "general_operand" ""))]
14365 "TARGET_USE_FANCY_MATH_387
14366 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14367 || TARGET_MIX_SSE_I387)
14368 && flag_unsafe_math_optimizations"
14372 if (optimize_insn_for_size_p ())
14375 op0 = gen_reg_rtx (XFmode);
14376 op1 = gen_reg_rtx (XFmode);
14378 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14379 emit_insn (gen_exp10xf2 (op0, op1));
14380 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14384 (define_expand "exp2xf2"
14385 [(use (match_operand:XF 0 "register_operand" ""))
14386 (use (match_operand:XF 1 "register_operand" ""))]
14387 "TARGET_USE_FANCY_MATH_387
14388 && flag_unsafe_math_optimizations"
14392 if (optimize_insn_for_size_p ())
14395 op2 = gen_reg_rtx (XFmode);
14396 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14398 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14402 (define_expand "exp2<mode>2"
14403 [(use (match_operand:MODEF 0 "register_operand" ""))
14404 (use (match_operand:MODEF 1 "general_operand" ""))]
14405 "TARGET_USE_FANCY_MATH_387
14406 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14407 || TARGET_MIX_SSE_I387)
14408 && flag_unsafe_math_optimizations"
14412 if (optimize_insn_for_size_p ())
14415 op0 = gen_reg_rtx (XFmode);
14416 op1 = gen_reg_rtx (XFmode);
14418 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14419 emit_insn (gen_exp2xf2 (op0, op1));
14420 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14424 (define_expand "expm1xf2"
14425 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "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 9) (float_extend:XF (match_dup 13)))
14430 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14431 (parallel [(set (match_dup 7)
14432 (unspec:XF [(match_dup 6) (match_dup 4)]
14433 UNSPEC_FSCALE_FRACT))
14435 (unspec:XF [(match_dup 6) (match_dup 4)]
14436 UNSPEC_FSCALE_EXP))])
14437 (parallel [(set (match_dup 10)
14438 (unspec:XF [(match_dup 9) (match_dup 8)]
14439 UNSPEC_FSCALE_FRACT))
14440 (set (match_dup 11)
14441 (unspec:XF [(match_dup 9) (match_dup 8)]
14442 UNSPEC_FSCALE_EXP))])
14443 (set (match_dup 12) (minus:XF (match_dup 10)
14444 (float_extend:XF (match_dup 13))))
14445 (set (match_operand:XF 0 "register_operand" "")
14446 (plus:XF (match_dup 12) (match_dup 7)))]
14447 "TARGET_USE_FANCY_MATH_387
14448 && flag_unsafe_math_optimizations"
14452 if (optimize_insn_for_size_p ())
14455 for (i = 2; i < 13; i++)
14456 operands[i] = gen_reg_rtx (XFmode);
14459 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14461 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14464 (define_expand "expm1<mode>2"
14465 [(use (match_operand:MODEF 0 "register_operand" ""))
14466 (use (match_operand:MODEF 1 "general_operand" ""))]
14467 "TARGET_USE_FANCY_MATH_387
14468 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14469 || TARGET_MIX_SSE_I387)
14470 && flag_unsafe_math_optimizations"
14474 if (optimize_insn_for_size_p ())
14477 op0 = gen_reg_rtx (XFmode);
14478 op1 = gen_reg_rtx (XFmode);
14480 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14481 emit_insn (gen_expm1xf2 (op0, op1));
14482 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14486 (define_expand "ldexpxf3"
14487 [(set (match_dup 3)
14488 (float:XF (match_operand:SI 2 "register_operand" "")))
14489 (parallel [(set (match_operand:XF 0 " register_operand" "")
14490 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14492 UNSPEC_FSCALE_FRACT))
14494 (unspec:XF [(match_dup 1) (match_dup 3)]
14495 UNSPEC_FSCALE_EXP))])]
14496 "TARGET_USE_FANCY_MATH_387
14497 && flag_unsafe_math_optimizations"
14499 if (optimize_insn_for_size_p ())
14502 operands[3] = gen_reg_rtx (XFmode);
14503 operands[4] = gen_reg_rtx (XFmode);
14506 (define_expand "ldexp<mode>3"
14507 [(use (match_operand:MODEF 0 "register_operand" ""))
14508 (use (match_operand:MODEF 1 "general_operand" ""))
14509 (use (match_operand:SI 2 "register_operand" ""))]
14510 "TARGET_USE_FANCY_MATH_387
14511 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14512 || TARGET_MIX_SSE_I387)
14513 && flag_unsafe_math_optimizations"
14517 if (optimize_insn_for_size_p ())
14520 op0 = gen_reg_rtx (XFmode);
14521 op1 = gen_reg_rtx (XFmode);
14523 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14524 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14525 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14529 (define_expand "scalbxf3"
14530 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14531 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14532 (match_operand:XF 2 "register_operand" "")]
14533 UNSPEC_FSCALE_FRACT))
14535 (unspec:XF [(match_dup 1) (match_dup 2)]
14536 UNSPEC_FSCALE_EXP))])]
14537 "TARGET_USE_FANCY_MATH_387
14538 && flag_unsafe_math_optimizations"
14540 if (optimize_insn_for_size_p ())
14543 operands[3] = gen_reg_rtx (XFmode);
14546 (define_expand "scalb<mode>3"
14547 [(use (match_operand:MODEF 0 "register_operand" ""))
14548 (use (match_operand:MODEF 1 "general_operand" ""))
14549 (use (match_operand:MODEF 2 "general_operand" ""))]
14550 "TARGET_USE_FANCY_MATH_387
14551 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14552 || TARGET_MIX_SSE_I387)
14553 && flag_unsafe_math_optimizations"
14557 if (optimize_insn_for_size_p ())
14560 op0 = gen_reg_rtx (XFmode);
14561 op1 = gen_reg_rtx (XFmode);
14562 op2 = gen_reg_rtx (XFmode);
14564 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14565 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14566 emit_insn (gen_scalbxf3 (op0, op1, op2));
14567 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14571 (define_expand "significandxf2"
14572 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14573 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14574 UNSPEC_XTRACT_FRACT))
14576 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14577 "TARGET_USE_FANCY_MATH_387
14578 && flag_unsafe_math_optimizations"
14580 operands[2] = gen_reg_rtx (XFmode);
14583 (define_expand "significand<mode>2"
14584 [(use (match_operand:MODEF 0 "register_operand" ""))
14585 (use (match_operand:MODEF 1 "register_operand" ""))]
14586 "TARGET_USE_FANCY_MATH_387
14587 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14588 || TARGET_MIX_SSE_I387)
14589 && flag_unsafe_math_optimizations"
14591 rtx op0 = gen_reg_rtx (XFmode);
14592 rtx op1 = gen_reg_rtx (XFmode);
14594 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14595 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14600 (define_insn "sse4_1_round<mode>2"
14601 [(set (match_operand:MODEF 0 "register_operand" "=x")
14602 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14603 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14606 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14607 [(set_attr "type" "ssecvt")
14608 (set_attr "prefix_extra" "1")
14609 (set_attr "prefix" "maybe_vex")
14610 (set_attr "mode" "<MODE>")])
14612 (define_insn "rintxf2"
14613 [(set (match_operand:XF 0 "register_operand" "=f")
14614 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14616 "TARGET_USE_FANCY_MATH_387
14617 && flag_unsafe_math_optimizations"
14619 [(set_attr "type" "fpspc")
14620 (set_attr "mode" "XF")])
14622 (define_expand "rint<mode>2"
14623 [(use (match_operand:MODEF 0 "register_operand" ""))
14624 (use (match_operand:MODEF 1 "register_operand" ""))]
14625 "(TARGET_USE_FANCY_MATH_387
14626 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14627 || TARGET_MIX_SSE_I387)
14628 && flag_unsafe_math_optimizations)
14629 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14630 && !flag_trapping_math)"
14632 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14633 && !flag_trapping_math)
14635 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14638 emit_insn (gen_sse4_1_round<mode>2
14639 (operands[0], operands[1], GEN_INT (0x04)));
14641 ix86_expand_rint (operand0, operand1);
14645 rtx op0 = gen_reg_rtx (XFmode);
14646 rtx op1 = gen_reg_rtx (XFmode);
14648 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14649 emit_insn (gen_rintxf2 (op0, op1));
14651 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14656 (define_expand "round<mode>2"
14657 [(match_operand:MODEF 0 "register_operand" "")
14658 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14659 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14660 && !flag_trapping_math && !flag_rounding_math"
14662 if (optimize_insn_for_size_p ())
14664 if (TARGET_64BIT || (<MODE>mode != DFmode))
14665 ix86_expand_round (operand0, operand1);
14667 ix86_expand_rounddf_32 (operand0, operand1);
14671 (define_insn_and_split "*fistdi2_1"
14672 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14673 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14675 "TARGET_USE_FANCY_MATH_387
14676 && can_create_pseudo_p ()"
14681 if (memory_operand (operands[0], VOIDmode))
14682 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14685 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14686 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14691 [(set_attr "type" "fpspc")
14692 (set_attr "mode" "DI")])
14694 (define_insn "fistdi2"
14695 [(set (match_operand:DI 0 "memory_operand" "=m")
14696 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14698 (clobber (match_scratch:XF 2 "=&1f"))]
14699 "TARGET_USE_FANCY_MATH_387"
14700 "* return output_fix_trunc (insn, operands, 0);"
14701 [(set_attr "type" "fpspc")
14702 (set_attr "mode" "DI")])
14704 (define_insn "fistdi2_with_temp"
14705 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14706 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14708 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14709 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14710 "TARGET_USE_FANCY_MATH_387"
14712 [(set_attr "type" "fpspc")
14713 (set_attr "mode" "DI")])
14716 [(set (match_operand:DI 0 "register_operand" "")
14717 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14719 (clobber (match_operand:DI 2 "memory_operand" ""))
14720 (clobber (match_scratch 3 ""))]
14722 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14723 (clobber (match_dup 3))])
14724 (set (match_dup 0) (match_dup 2))]
14728 [(set (match_operand:DI 0 "memory_operand" "")
14729 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14731 (clobber (match_operand:DI 2 "memory_operand" ""))
14732 (clobber (match_scratch 3 ""))]
14734 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14735 (clobber (match_dup 3))])]
14738 (define_insn_and_split "*fist<mode>2_1"
14739 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14740 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14742 "TARGET_USE_FANCY_MATH_387
14743 && can_create_pseudo_p ()"
14748 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14749 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14753 [(set_attr "type" "fpspc")
14754 (set_attr "mode" "<MODE>")])
14756 (define_insn "fist<mode>2"
14757 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14758 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14760 "TARGET_USE_FANCY_MATH_387"
14761 "* return output_fix_trunc (insn, operands, 0);"
14762 [(set_attr "type" "fpspc")
14763 (set_attr "mode" "<MODE>")])
14765 (define_insn "fist<mode>2_with_temp"
14766 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14767 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14769 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14770 "TARGET_USE_FANCY_MATH_387"
14772 [(set_attr "type" "fpspc")
14773 (set_attr "mode" "<MODE>")])
14776 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14777 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14779 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14781 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14782 (set (match_dup 0) (match_dup 2))]
14786 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14787 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14789 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14791 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14794 (define_expand "lrintxf<mode>2"
14795 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14796 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14798 "TARGET_USE_FANCY_MATH_387"
14801 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14802 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14803 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14804 UNSPEC_FIX_NOTRUNC))]
14805 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14806 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14809 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14810 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14811 (match_operand:MODEF 1 "register_operand" "")]
14812 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14813 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14814 && !flag_trapping_math && !flag_rounding_math"
14816 if (optimize_insn_for_size_p ())
14818 ix86_expand_lround (operand0, operand1);
14822 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14823 (define_insn_and_split "frndintxf2_floor"
14824 [(set (match_operand:XF 0 "register_operand" "")
14825 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14826 UNSPEC_FRNDINT_FLOOR))
14827 (clobber (reg:CC FLAGS_REG))]
14828 "TARGET_USE_FANCY_MATH_387
14829 && flag_unsafe_math_optimizations
14830 && can_create_pseudo_p ()"
14835 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14837 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14838 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14840 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14841 operands[2], operands[3]));
14844 [(set_attr "type" "frndint")
14845 (set_attr "i387_cw" "floor")
14846 (set_attr "mode" "XF")])
14848 (define_insn "frndintxf2_floor_i387"
14849 [(set (match_operand:XF 0 "register_operand" "=f")
14850 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14851 UNSPEC_FRNDINT_FLOOR))
14852 (use (match_operand:HI 2 "memory_operand" "m"))
14853 (use (match_operand:HI 3 "memory_operand" "m"))]
14854 "TARGET_USE_FANCY_MATH_387
14855 && flag_unsafe_math_optimizations"
14856 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14857 [(set_attr "type" "frndint")
14858 (set_attr "i387_cw" "floor")
14859 (set_attr "mode" "XF")])
14861 (define_expand "floorxf2"
14862 [(use (match_operand:XF 0 "register_operand" ""))
14863 (use (match_operand:XF 1 "register_operand" ""))]
14864 "TARGET_USE_FANCY_MATH_387
14865 && flag_unsafe_math_optimizations"
14867 if (optimize_insn_for_size_p ())
14869 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14873 (define_expand "floor<mode>2"
14874 [(use (match_operand:MODEF 0 "register_operand" ""))
14875 (use (match_operand:MODEF 1 "register_operand" ""))]
14876 "(TARGET_USE_FANCY_MATH_387
14877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14878 || TARGET_MIX_SSE_I387)
14879 && flag_unsafe_math_optimizations)
14880 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14881 && !flag_trapping_math)"
14883 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14884 && !flag_trapping_math
14885 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14887 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14890 emit_insn (gen_sse4_1_round<mode>2
14891 (operands[0], operands[1], GEN_INT (0x01)));
14892 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14893 ix86_expand_floorceil (operand0, operand1, true);
14895 ix86_expand_floorceildf_32 (operand0, operand1, true);
14901 if (optimize_insn_for_size_p ())
14904 op0 = gen_reg_rtx (XFmode);
14905 op1 = gen_reg_rtx (XFmode);
14906 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14907 emit_insn (gen_frndintxf2_floor (op0, op1));
14909 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14914 (define_insn_and_split "*fist<mode>2_floor_1"
14915 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14916 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14917 UNSPEC_FIST_FLOOR))
14918 (clobber (reg:CC FLAGS_REG))]
14919 "TARGET_USE_FANCY_MATH_387
14920 && flag_unsafe_math_optimizations
14921 && can_create_pseudo_p ()"
14926 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14928 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14929 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14930 if (memory_operand (operands[0], VOIDmode))
14931 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14932 operands[2], operands[3]));
14935 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14936 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14937 operands[2], operands[3],
14942 [(set_attr "type" "fistp")
14943 (set_attr "i387_cw" "floor")
14944 (set_attr "mode" "<MODE>")])
14946 (define_insn "fistdi2_floor"
14947 [(set (match_operand:DI 0 "memory_operand" "=m")
14948 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14949 UNSPEC_FIST_FLOOR))
14950 (use (match_operand:HI 2 "memory_operand" "m"))
14951 (use (match_operand:HI 3 "memory_operand" "m"))
14952 (clobber (match_scratch:XF 4 "=&1f"))]
14953 "TARGET_USE_FANCY_MATH_387
14954 && flag_unsafe_math_optimizations"
14955 "* return output_fix_trunc (insn, operands, 0);"
14956 [(set_attr "type" "fistp")
14957 (set_attr "i387_cw" "floor")
14958 (set_attr "mode" "DI")])
14960 (define_insn "fistdi2_floor_with_temp"
14961 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14962 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14963 UNSPEC_FIST_FLOOR))
14964 (use (match_operand:HI 2 "memory_operand" "m,m"))
14965 (use (match_operand:HI 3 "memory_operand" "m,m"))
14966 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14967 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14968 "TARGET_USE_FANCY_MATH_387
14969 && flag_unsafe_math_optimizations"
14971 [(set_attr "type" "fistp")
14972 (set_attr "i387_cw" "floor")
14973 (set_attr "mode" "DI")])
14976 [(set (match_operand:DI 0 "register_operand" "")
14977 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14978 UNSPEC_FIST_FLOOR))
14979 (use (match_operand:HI 2 "memory_operand" ""))
14980 (use (match_operand:HI 3 "memory_operand" ""))
14981 (clobber (match_operand:DI 4 "memory_operand" ""))
14982 (clobber (match_scratch 5 ""))]
14984 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14985 (use (match_dup 2))
14986 (use (match_dup 3))
14987 (clobber (match_dup 5))])
14988 (set (match_dup 0) (match_dup 4))]
14992 [(set (match_operand:DI 0 "memory_operand" "")
14993 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14994 UNSPEC_FIST_FLOOR))
14995 (use (match_operand:HI 2 "memory_operand" ""))
14996 (use (match_operand:HI 3 "memory_operand" ""))
14997 (clobber (match_operand:DI 4 "memory_operand" ""))
14998 (clobber (match_scratch 5 ""))]
15000 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15001 (use (match_dup 2))
15002 (use (match_dup 3))
15003 (clobber (match_dup 5))])]
15006 (define_insn "fist<mode>2_floor"
15007 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15008 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15009 UNSPEC_FIST_FLOOR))
15010 (use (match_operand:HI 2 "memory_operand" "m"))
15011 (use (match_operand:HI 3 "memory_operand" "m"))]
15012 "TARGET_USE_FANCY_MATH_387
15013 && flag_unsafe_math_optimizations"
15014 "* return output_fix_trunc (insn, operands, 0);"
15015 [(set_attr "type" "fistp")
15016 (set_attr "i387_cw" "floor")
15017 (set_attr "mode" "<MODE>")])
15019 (define_insn "fist<mode>2_floor_with_temp"
15020 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15021 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15022 UNSPEC_FIST_FLOOR))
15023 (use (match_operand:HI 2 "memory_operand" "m,m"))
15024 (use (match_operand:HI 3 "memory_operand" "m,m"))
15025 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15026 "TARGET_USE_FANCY_MATH_387
15027 && flag_unsafe_math_optimizations"
15029 [(set_attr "type" "fistp")
15030 (set_attr "i387_cw" "floor")
15031 (set_attr "mode" "<MODE>")])
15034 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15035 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15036 UNSPEC_FIST_FLOOR))
15037 (use (match_operand:HI 2 "memory_operand" ""))
15038 (use (match_operand:HI 3 "memory_operand" ""))
15039 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15041 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15042 UNSPEC_FIST_FLOOR))
15043 (use (match_dup 2))
15044 (use (match_dup 3))])
15045 (set (match_dup 0) (match_dup 4))]
15049 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15050 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15051 UNSPEC_FIST_FLOOR))
15052 (use (match_operand:HI 2 "memory_operand" ""))
15053 (use (match_operand:HI 3 "memory_operand" ""))
15054 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15056 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15057 UNSPEC_FIST_FLOOR))
15058 (use (match_dup 2))
15059 (use (match_dup 3))])]
15062 (define_expand "lfloorxf<mode>2"
15063 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15064 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15065 UNSPEC_FIST_FLOOR))
15066 (clobber (reg:CC FLAGS_REG))])]
15067 "TARGET_USE_FANCY_MATH_387
15068 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15069 && flag_unsafe_math_optimizations"
15072 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15073 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15074 (match_operand:MODEF 1 "register_operand" "")]
15075 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15076 && !flag_trapping_math"
15078 if (TARGET_64BIT && optimize_insn_for_size_p ())
15080 ix86_expand_lfloorceil (operand0, operand1, true);
15084 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15085 (define_insn_and_split "frndintxf2_ceil"
15086 [(set (match_operand:XF 0 "register_operand" "")
15087 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15088 UNSPEC_FRNDINT_CEIL))
15089 (clobber (reg:CC FLAGS_REG))]
15090 "TARGET_USE_FANCY_MATH_387
15091 && flag_unsafe_math_optimizations
15092 && can_create_pseudo_p ()"
15097 ix86_optimize_mode_switching[I387_CEIL] = 1;
15099 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15100 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15102 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15103 operands[2], operands[3]));
15106 [(set_attr "type" "frndint")
15107 (set_attr "i387_cw" "ceil")
15108 (set_attr "mode" "XF")])
15110 (define_insn "frndintxf2_ceil_i387"
15111 [(set (match_operand:XF 0 "register_operand" "=f")
15112 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15113 UNSPEC_FRNDINT_CEIL))
15114 (use (match_operand:HI 2 "memory_operand" "m"))
15115 (use (match_operand:HI 3 "memory_operand" "m"))]
15116 "TARGET_USE_FANCY_MATH_387
15117 && flag_unsafe_math_optimizations"
15118 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15119 [(set_attr "type" "frndint")
15120 (set_attr "i387_cw" "ceil")
15121 (set_attr "mode" "XF")])
15123 (define_expand "ceilxf2"
15124 [(use (match_operand:XF 0 "register_operand" ""))
15125 (use (match_operand:XF 1 "register_operand" ""))]
15126 "TARGET_USE_FANCY_MATH_387
15127 && flag_unsafe_math_optimizations"
15129 if (optimize_insn_for_size_p ())
15131 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15135 (define_expand "ceil<mode>2"
15136 [(use (match_operand:MODEF 0 "register_operand" ""))
15137 (use (match_operand:MODEF 1 "register_operand" ""))]
15138 "(TARGET_USE_FANCY_MATH_387
15139 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15140 || TARGET_MIX_SSE_I387)
15141 && flag_unsafe_math_optimizations)
15142 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15143 && !flag_trapping_math)"
15145 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15146 && !flag_trapping_math
15147 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15150 emit_insn (gen_sse4_1_round<mode>2
15151 (operands[0], operands[1], GEN_INT (0x02)));
15152 else if (optimize_insn_for_size_p ())
15154 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15155 ix86_expand_floorceil (operand0, operand1, false);
15157 ix86_expand_floorceildf_32 (operand0, operand1, false);
15163 if (optimize_insn_for_size_p ())
15166 op0 = gen_reg_rtx (XFmode);
15167 op1 = gen_reg_rtx (XFmode);
15168 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15169 emit_insn (gen_frndintxf2_ceil (op0, op1));
15171 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15176 (define_insn_and_split "*fist<mode>2_ceil_1"
15177 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15178 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15180 (clobber (reg:CC FLAGS_REG))]
15181 "TARGET_USE_FANCY_MATH_387
15182 && flag_unsafe_math_optimizations
15183 && can_create_pseudo_p ()"
15188 ix86_optimize_mode_switching[I387_CEIL] = 1;
15190 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15191 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15192 if (memory_operand (operands[0], VOIDmode))
15193 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15194 operands[2], operands[3]));
15197 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15198 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15199 operands[2], operands[3],
15204 [(set_attr "type" "fistp")
15205 (set_attr "i387_cw" "ceil")
15206 (set_attr "mode" "<MODE>")])
15208 (define_insn "fistdi2_ceil"
15209 [(set (match_operand:DI 0 "memory_operand" "=m")
15210 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15212 (use (match_operand:HI 2 "memory_operand" "m"))
15213 (use (match_operand:HI 3 "memory_operand" "m"))
15214 (clobber (match_scratch:XF 4 "=&1f"))]
15215 "TARGET_USE_FANCY_MATH_387
15216 && flag_unsafe_math_optimizations"
15217 "* return output_fix_trunc (insn, operands, 0);"
15218 [(set_attr "type" "fistp")
15219 (set_attr "i387_cw" "ceil")
15220 (set_attr "mode" "DI")])
15222 (define_insn "fistdi2_ceil_with_temp"
15223 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15224 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15226 (use (match_operand:HI 2 "memory_operand" "m,m"))
15227 (use (match_operand:HI 3 "memory_operand" "m,m"))
15228 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15229 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15230 "TARGET_USE_FANCY_MATH_387
15231 && flag_unsafe_math_optimizations"
15233 [(set_attr "type" "fistp")
15234 (set_attr "i387_cw" "ceil")
15235 (set_attr "mode" "DI")])
15238 [(set (match_operand:DI 0 "register_operand" "")
15239 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15241 (use (match_operand:HI 2 "memory_operand" ""))
15242 (use (match_operand:HI 3 "memory_operand" ""))
15243 (clobber (match_operand:DI 4 "memory_operand" ""))
15244 (clobber (match_scratch 5 ""))]
15246 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15247 (use (match_dup 2))
15248 (use (match_dup 3))
15249 (clobber (match_dup 5))])
15250 (set (match_dup 0) (match_dup 4))]
15254 [(set (match_operand:DI 0 "memory_operand" "")
15255 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15257 (use (match_operand:HI 2 "memory_operand" ""))
15258 (use (match_operand:HI 3 "memory_operand" ""))
15259 (clobber (match_operand:DI 4 "memory_operand" ""))
15260 (clobber (match_scratch 5 ""))]
15262 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15263 (use (match_dup 2))
15264 (use (match_dup 3))
15265 (clobber (match_dup 5))])]
15268 (define_insn "fist<mode>2_ceil"
15269 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15270 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15272 (use (match_operand:HI 2 "memory_operand" "m"))
15273 (use (match_operand:HI 3 "memory_operand" "m"))]
15274 "TARGET_USE_FANCY_MATH_387
15275 && flag_unsafe_math_optimizations"
15276 "* return output_fix_trunc (insn, operands, 0);"
15277 [(set_attr "type" "fistp")
15278 (set_attr "i387_cw" "ceil")
15279 (set_attr "mode" "<MODE>")])
15281 (define_insn "fist<mode>2_ceil_with_temp"
15282 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15283 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15285 (use (match_operand:HI 2 "memory_operand" "m,m"))
15286 (use (match_operand:HI 3 "memory_operand" "m,m"))
15287 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15288 "TARGET_USE_FANCY_MATH_387
15289 && flag_unsafe_math_optimizations"
15291 [(set_attr "type" "fistp")
15292 (set_attr "i387_cw" "ceil")
15293 (set_attr "mode" "<MODE>")])
15296 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15297 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15299 (use (match_operand:HI 2 "memory_operand" ""))
15300 (use (match_operand:HI 3 "memory_operand" ""))
15301 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15303 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15305 (use (match_dup 2))
15306 (use (match_dup 3))])
15307 (set (match_dup 0) (match_dup 4))]
15311 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15312 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15314 (use (match_operand:HI 2 "memory_operand" ""))
15315 (use (match_operand:HI 3 "memory_operand" ""))
15316 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15318 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15320 (use (match_dup 2))
15321 (use (match_dup 3))])]
15324 (define_expand "lceilxf<mode>2"
15325 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15326 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15328 (clobber (reg:CC FLAGS_REG))])]
15329 "TARGET_USE_FANCY_MATH_387
15330 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15331 && flag_unsafe_math_optimizations"
15334 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15335 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15336 (match_operand:MODEF 1 "register_operand" "")]
15337 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15338 && !flag_trapping_math"
15340 ix86_expand_lfloorceil (operand0, operand1, false);
15344 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15345 (define_insn_and_split "frndintxf2_trunc"
15346 [(set (match_operand:XF 0 "register_operand" "")
15347 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15348 UNSPEC_FRNDINT_TRUNC))
15349 (clobber (reg:CC FLAGS_REG))]
15350 "TARGET_USE_FANCY_MATH_387
15351 && flag_unsafe_math_optimizations
15352 && can_create_pseudo_p ()"
15357 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15359 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15360 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15362 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15363 operands[2], operands[3]));
15366 [(set_attr "type" "frndint")
15367 (set_attr "i387_cw" "trunc")
15368 (set_attr "mode" "XF")])
15370 (define_insn "frndintxf2_trunc_i387"
15371 [(set (match_operand:XF 0 "register_operand" "=f")
15372 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15373 UNSPEC_FRNDINT_TRUNC))
15374 (use (match_operand:HI 2 "memory_operand" "m"))
15375 (use (match_operand:HI 3 "memory_operand" "m"))]
15376 "TARGET_USE_FANCY_MATH_387
15377 && flag_unsafe_math_optimizations"
15378 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15379 [(set_attr "type" "frndint")
15380 (set_attr "i387_cw" "trunc")
15381 (set_attr "mode" "XF")])
15383 (define_expand "btruncxf2"
15384 [(use (match_operand:XF 0 "register_operand" ""))
15385 (use (match_operand:XF 1 "register_operand" ""))]
15386 "TARGET_USE_FANCY_MATH_387
15387 && flag_unsafe_math_optimizations"
15389 if (optimize_insn_for_size_p ())
15391 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15395 (define_expand "btrunc<mode>2"
15396 [(use (match_operand:MODEF 0 "register_operand" ""))
15397 (use (match_operand:MODEF 1 "register_operand" ""))]
15398 "(TARGET_USE_FANCY_MATH_387
15399 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15400 || TARGET_MIX_SSE_I387)
15401 && flag_unsafe_math_optimizations)
15402 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15403 && !flag_trapping_math)"
15405 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15406 && !flag_trapping_math
15407 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15410 emit_insn (gen_sse4_1_round<mode>2
15411 (operands[0], operands[1], GEN_INT (0x03)));
15412 else if (optimize_insn_for_size_p ())
15414 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15415 ix86_expand_trunc (operand0, operand1);
15417 ix86_expand_truncdf_32 (operand0, operand1);
15423 if (optimize_insn_for_size_p ())
15426 op0 = gen_reg_rtx (XFmode);
15427 op1 = gen_reg_rtx (XFmode);
15428 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15429 emit_insn (gen_frndintxf2_trunc (op0, op1));
15431 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15436 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15437 (define_insn_and_split "frndintxf2_mask_pm"
15438 [(set (match_operand:XF 0 "register_operand" "")
15439 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15440 UNSPEC_FRNDINT_MASK_PM))
15441 (clobber (reg:CC FLAGS_REG))]
15442 "TARGET_USE_FANCY_MATH_387
15443 && flag_unsafe_math_optimizations
15444 && can_create_pseudo_p ()"
15449 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15451 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15452 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15454 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15455 operands[2], operands[3]));
15458 [(set_attr "type" "frndint")
15459 (set_attr "i387_cw" "mask_pm")
15460 (set_attr "mode" "XF")])
15462 (define_insn "frndintxf2_mask_pm_i387"
15463 [(set (match_operand:XF 0 "register_operand" "=f")
15464 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15465 UNSPEC_FRNDINT_MASK_PM))
15466 (use (match_operand:HI 2 "memory_operand" "m"))
15467 (use (match_operand:HI 3 "memory_operand" "m"))]
15468 "TARGET_USE_FANCY_MATH_387
15469 && flag_unsafe_math_optimizations"
15470 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15471 [(set_attr "type" "frndint")
15472 (set_attr "i387_cw" "mask_pm")
15473 (set_attr "mode" "XF")])
15475 (define_expand "nearbyintxf2"
15476 [(use (match_operand:XF 0 "register_operand" ""))
15477 (use (match_operand:XF 1 "register_operand" ""))]
15478 "TARGET_USE_FANCY_MATH_387
15479 && flag_unsafe_math_optimizations"
15481 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15486 (define_expand "nearbyint<mode>2"
15487 [(use (match_operand:MODEF 0 "register_operand" ""))
15488 (use (match_operand:MODEF 1 "register_operand" ""))]
15489 "TARGET_USE_FANCY_MATH_387
15490 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15491 || TARGET_MIX_SSE_I387)
15492 && flag_unsafe_math_optimizations"
15494 rtx op0 = gen_reg_rtx (XFmode);
15495 rtx op1 = gen_reg_rtx (XFmode);
15497 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15498 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15500 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15504 (define_insn "fxam<mode>2_i387"
15505 [(set (match_operand:HI 0 "register_operand" "=a")
15507 [(match_operand:X87MODEF 1 "register_operand" "f")]
15509 "TARGET_USE_FANCY_MATH_387"
15510 "fxam\n\tfnstsw\t%0"
15511 [(set_attr "type" "multi")
15512 (set_attr "length" "4")
15513 (set_attr "unit" "i387")
15514 (set_attr "mode" "<MODE>")])
15516 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15517 [(set (match_operand:HI 0 "register_operand" "")
15519 [(match_operand:MODEF 1 "memory_operand" "")]
15521 "TARGET_USE_FANCY_MATH_387
15522 && can_create_pseudo_p ()"
15525 [(set (match_dup 2)(match_dup 1))
15527 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15529 operands[2] = gen_reg_rtx (<MODE>mode);
15531 MEM_VOLATILE_P (operands[1]) = 1;
15533 [(set_attr "type" "multi")
15534 (set_attr "unit" "i387")
15535 (set_attr "mode" "<MODE>")])
15537 (define_expand "isinfxf2"
15538 [(use (match_operand:SI 0 "register_operand" ""))
15539 (use (match_operand:XF 1 "register_operand" ""))]
15540 "TARGET_USE_FANCY_MATH_387
15541 && TARGET_C99_FUNCTIONS"
15543 rtx mask = GEN_INT (0x45);
15544 rtx val = GEN_INT (0x05);
15548 rtx scratch = gen_reg_rtx (HImode);
15549 rtx res = gen_reg_rtx (QImode);
15551 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15553 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15554 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15555 cond = gen_rtx_fmt_ee (EQ, QImode,
15556 gen_rtx_REG (CCmode, FLAGS_REG),
15558 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15559 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15563 (define_expand "isinf<mode>2"
15564 [(use (match_operand:SI 0 "register_operand" ""))
15565 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15566 "TARGET_USE_FANCY_MATH_387
15567 && TARGET_C99_FUNCTIONS
15568 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15570 rtx mask = GEN_INT (0x45);
15571 rtx val = GEN_INT (0x05);
15575 rtx scratch = gen_reg_rtx (HImode);
15576 rtx res = gen_reg_rtx (QImode);
15578 /* Remove excess precision by forcing value through memory. */
15579 if (memory_operand (operands[1], VOIDmode))
15580 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15583 enum ix86_stack_slot slot = (virtuals_instantiated
15586 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15588 emit_move_insn (temp, operands[1]);
15589 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15592 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15593 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15594 cond = gen_rtx_fmt_ee (EQ, QImode,
15595 gen_rtx_REG (CCmode, FLAGS_REG),
15597 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15598 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15602 (define_expand "signbit<mode>2"
15603 [(use (match_operand:SI 0 "register_operand" ""))
15604 (use (match_operand:X87MODEF 1 "register_operand" ""))]
15605 "TARGET_USE_FANCY_MATH_387
15606 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15608 rtx mask = GEN_INT (0x0200);
15610 rtx scratch = gen_reg_rtx (HImode);
15612 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15613 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15617 ;; Block operation instructions
15620 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15623 [(set_attr "length" "1")
15624 (set_attr "length_immediate" "0")
15625 (set_attr "modrm" "0")])
15627 (define_expand "movmemsi"
15628 [(use (match_operand:BLK 0 "memory_operand" ""))
15629 (use (match_operand:BLK 1 "memory_operand" ""))
15630 (use (match_operand:SI 2 "nonmemory_operand" ""))
15631 (use (match_operand:SI 3 "const_int_operand" ""))
15632 (use (match_operand:SI 4 "const_int_operand" ""))
15633 (use (match_operand:SI 5 "const_int_operand" ""))]
15636 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15637 operands[4], operands[5]))
15643 (define_expand "movmemdi"
15644 [(use (match_operand:BLK 0 "memory_operand" ""))
15645 (use (match_operand:BLK 1 "memory_operand" ""))
15646 (use (match_operand:DI 2 "nonmemory_operand" ""))
15647 (use (match_operand:DI 3 "const_int_operand" ""))
15648 (use (match_operand:SI 4 "const_int_operand" ""))
15649 (use (match_operand:SI 5 "const_int_operand" ""))]
15652 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15653 operands[4], operands[5]))
15659 ;; Most CPUs don't like single string operations
15660 ;; Handle this case here to simplify previous expander.
15662 (define_expand "strmov"
15663 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15664 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15665 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15666 (clobber (reg:CC FLAGS_REG))])
15667 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15668 (clobber (reg:CC FLAGS_REG))])]
15671 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15673 /* If .md ever supports :P for Pmode, these can be directly
15674 in the pattern above. */
15675 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15676 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15678 /* Can't use this if the user has appropriated esi or edi. */
15679 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15680 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15682 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15683 operands[2], operands[3],
15684 operands[5], operands[6]));
15688 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15691 (define_expand "strmov_singleop"
15692 [(parallel [(set (match_operand 1 "memory_operand" "")
15693 (match_operand 3 "memory_operand" ""))
15694 (set (match_operand 0 "register_operand" "")
15695 (match_operand 4 "" ""))
15696 (set (match_operand 2 "register_operand" "")
15697 (match_operand 5 "" ""))])]
15699 "ix86_current_function_needs_cld = 1;")
15701 (define_insn "*strmovdi_rex_1"
15702 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15703 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15704 (set (match_operand:DI 0 "register_operand" "=D")
15705 (plus:DI (match_dup 2)
15707 (set (match_operand:DI 1 "register_operand" "=S")
15708 (plus:DI (match_dup 3)
15712 [(set_attr "type" "str")
15713 (set_attr "mode" "DI")
15714 (set_attr "memory" "both")])
15716 (define_insn "*strmovsi_1"
15717 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15718 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15719 (set (match_operand:SI 0 "register_operand" "=D")
15720 (plus:SI (match_dup 2)
15722 (set (match_operand:SI 1 "register_operand" "=S")
15723 (plus:SI (match_dup 3)
15727 [(set_attr "type" "str")
15728 (set_attr "mode" "SI")
15729 (set_attr "memory" "both")])
15731 (define_insn "*strmovsi_rex_1"
15732 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15733 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15734 (set (match_operand:DI 0 "register_operand" "=D")
15735 (plus:DI (match_dup 2)
15737 (set (match_operand:DI 1 "register_operand" "=S")
15738 (plus:DI (match_dup 3)
15742 [(set_attr "type" "str")
15743 (set_attr "mode" "SI")
15744 (set_attr "memory" "both")])
15746 (define_insn "*strmovhi_1"
15747 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15748 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15749 (set (match_operand:SI 0 "register_operand" "=D")
15750 (plus:SI (match_dup 2)
15752 (set (match_operand:SI 1 "register_operand" "=S")
15753 (plus:SI (match_dup 3)
15757 [(set_attr "type" "str")
15758 (set_attr "memory" "both")
15759 (set_attr "mode" "HI")])
15761 (define_insn "*strmovhi_rex_1"
15762 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15763 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15764 (set (match_operand:DI 0 "register_operand" "=D")
15765 (plus:DI (match_dup 2)
15767 (set (match_operand:DI 1 "register_operand" "=S")
15768 (plus:DI (match_dup 3)
15772 [(set_attr "type" "str")
15773 (set_attr "memory" "both")
15774 (set_attr "mode" "HI")])
15776 (define_insn "*strmovqi_1"
15777 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15778 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15779 (set (match_operand:SI 0 "register_operand" "=D")
15780 (plus:SI (match_dup 2)
15782 (set (match_operand:SI 1 "register_operand" "=S")
15783 (plus:SI (match_dup 3)
15787 [(set_attr "type" "str")
15788 (set_attr "memory" "both")
15789 (set_attr "mode" "QI")])
15791 (define_insn "*strmovqi_rex_1"
15792 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15793 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15794 (set (match_operand:DI 0 "register_operand" "=D")
15795 (plus:DI (match_dup 2)
15797 (set (match_operand:DI 1 "register_operand" "=S")
15798 (plus:DI (match_dup 3)
15802 [(set_attr "type" "str")
15803 (set_attr "memory" "both")
15804 (set_attr "prefix_rex" "0")
15805 (set_attr "mode" "QI")])
15807 (define_expand "rep_mov"
15808 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15809 (set (match_operand 0 "register_operand" "")
15810 (match_operand 5 "" ""))
15811 (set (match_operand 2 "register_operand" "")
15812 (match_operand 6 "" ""))
15813 (set (match_operand 1 "memory_operand" "")
15814 (match_operand 3 "memory_operand" ""))
15815 (use (match_dup 4))])]
15817 "ix86_current_function_needs_cld = 1;")
15819 (define_insn "*rep_movdi_rex64"
15820 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15821 (set (match_operand:DI 0 "register_operand" "=D")
15822 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15824 (match_operand:DI 3 "register_operand" "0")))
15825 (set (match_operand:DI 1 "register_operand" "=S")
15826 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15827 (match_operand:DI 4 "register_operand" "1")))
15828 (set (mem:BLK (match_dup 3))
15829 (mem:BLK (match_dup 4)))
15830 (use (match_dup 5))]
15833 [(set_attr "type" "str")
15834 (set_attr "prefix_rep" "1")
15835 (set_attr "memory" "both")
15836 (set_attr "mode" "DI")])
15838 (define_insn "*rep_movsi"
15839 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15840 (set (match_operand:SI 0 "register_operand" "=D")
15841 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15843 (match_operand:SI 3 "register_operand" "0")))
15844 (set (match_operand:SI 1 "register_operand" "=S")
15845 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15846 (match_operand:SI 4 "register_operand" "1")))
15847 (set (mem:BLK (match_dup 3))
15848 (mem:BLK (match_dup 4)))
15849 (use (match_dup 5))]
15852 [(set_attr "type" "str")
15853 (set_attr "prefix_rep" "1")
15854 (set_attr "memory" "both")
15855 (set_attr "mode" "SI")])
15857 (define_insn "*rep_movsi_rex64"
15858 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15859 (set (match_operand:DI 0 "register_operand" "=D")
15860 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15862 (match_operand:DI 3 "register_operand" "0")))
15863 (set (match_operand:DI 1 "register_operand" "=S")
15864 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15865 (match_operand:DI 4 "register_operand" "1")))
15866 (set (mem:BLK (match_dup 3))
15867 (mem:BLK (match_dup 4)))
15868 (use (match_dup 5))]
15871 [(set_attr "type" "str")
15872 (set_attr "prefix_rep" "1")
15873 (set_attr "memory" "both")
15874 (set_attr "mode" "SI")])
15876 (define_insn "*rep_movqi"
15877 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15878 (set (match_operand:SI 0 "register_operand" "=D")
15879 (plus:SI (match_operand:SI 3 "register_operand" "0")
15880 (match_operand:SI 5 "register_operand" "2")))
15881 (set (match_operand:SI 1 "register_operand" "=S")
15882 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15883 (set (mem:BLK (match_dup 3))
15884 (mem:BLK (match_dup 4)))
15885 (use (match_dup 5))]
15888 [(set_attr "type" "str")
15889 (set_attr "prefix_rep" "1")
15890 (set_attr "memory" "both")
15891 (set_attr "mode" "SI")])
15893 (define_insn "*rep_movqi_rex64"
15894 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15895 (set (match_operand:DI 0 "register_operand" "=D")
15896 (plus:DI (match_operand:DI 3 "register_operand" "0")
15897 (match_operand:DI 5 "register_operand" "2")))
15898 (set (match_operand:DI 1 "register_operand" "=S")
15899 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15900 (set (mem:BLK (match_dup 3))
15901 (mem:BLK (match_dup 4)))
15902 (use (match_dup 5))]
15905 [(set_attr "type" "str")
15906 (set_attr "prefix_rep" "1")
15907 (set_attr "memory" "both")
15908 (set_attr "mode" "SI")])
15910 (define_expand "setmemsi"
15911 [(use (match_operand:BLK 0 "memory_operand" ""))
15912 (use (match_operand:SI 1 "nonmemory_operand" ""))
15913 (use (match_operand 2 "const_int_operand" ""))
15914 (use (match_operand 3 "const_int_operand" ""))
15915 (use (match_operand:SI 4 "const_int_operand" ""))
15916 (use (match_operand:SI 5 "const_int_operand" ""))]
15919 if (ix86_expand_setmem (operands[0], operands[1],
15920 operands[2], operands[3],
15921 operands[4], operands[5]))
15927 (define_expand "setmemdi"
15928 [(use (match_operand:BLK 0 "memory_operand" ""))
15929 (use (match_operand:DI 1 "nonmemory_operand" ""))
15930 (use (match_operand 2 "const_int_operand" ""))
15931 (use (match_operand 3 "const_int_operand" ""))
15932 (use (match_operand 4 "const_int_operand" ""))
15933 (use (match_operand 5 "const_int_operand" ""))]
15936 if (ix86_expand_setmem (operands[0], operands[1],
15937 operands[2], operands[3],
15938 operands[4], operands[5]))
15944 ;; Most CPUs don't like single string operations
15945 ;; Handle this case here to simplify previous expander.
15947 (define_expand "strset"
15948 [(set (match_operand 1 "memory_operand" "")
15949 (match_operand 2 "register_operand" ""))
15950 (parallel [(set (match_operand 0 "register_operand" "")
15952 (clobber (reg:CC FLAGS_REG))])]
15955 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15956 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15958 /* If .md ever supports :P for Pmode, this can be directly
15959 in the pattern above. */
15960 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15961 GEN_INT (GET_MODE_SIZE (GET_MODE
15963 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15965 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15971 (define_expand "strset_singleop"
15972 [(parallel [(set (match_operand 1 "memory_operand" "")
15973 (match_operand 2 "register_operand" ""))
15974 (set (match_operand 0 "register_operand" "")
15975 (match_operand 3 "" ""))])]
15977 "ix86_current_function_needs_cld = 1;")
15979 (define_insn "*strsetdi_rex_1"
15980 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15981 (match_operand:DI 2 "register_operand" "a"))
15982 (set (match_operand:DI 0 "register_operand" "=D")
15983 (plus:DI (match_dup 1)
15987 [(set_attr "type" "str")
15988 (set_attr "memory" "store")
15989 (set_attr "mode" "DI")])
15991 (define_insn "*strsetsi_1"
15992 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15993 (match_operand:SI 2 "register_operand" "a"))
15994 (set (match_operand:SI 0 "register_operand" "=D")
15995 (plus:SI (match_dup 1)
15999 [(set_attr "type" "str")
16000 (set_attr "memory" "store")
16001 (set_attr "mode" "SI")])
16003 (define_insn "*strsetsi_rex_1"
16004 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16005 (match_operand:SI 2 "register_operand" "a"))
16006 (set (match_operand:DI 0 "register_operand" "=D")
16007 (plus:DI (match_dup 1)
16011 [(set_attr "type" "str")
16012 (set_attr "memory" "store")
16013 (set_attr "mode" "SI")])
16015 (define_insn "*strsethi_1"
16016 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16017 (match_operand:HI 2 "register_operand" "a"))
16018 (set (match_operand:SI 0 "register_operand" "=D")
16019 (plus:SI (match_dup 1)
16023 [(set_attr "type" "str")
16024 (set_attr "memory" "store")
16025 (set_attr "mode" "HI")])
16027 (define_insn "*strsethi_rex_1"
16028 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16029 (match_operand:HI 2 "register_operand" "a"))
16030 (set (match_operand:DI 0 "register_operand" "=D")
16031 (plus:DI (match_dup 1)
16035 [(set_attr "type" "str")
16036 (set_attr "memory" "store")
16037 (set_attr "mode" "HI")])
16039 (define_insn "*strsetqi_1"
16040 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16041 (match_operand:QI 2 "register_operand" "a"))
16042 (set (match_operand:SI 0 "register_operand" "=D")
16043 (plus:SI (match_dup 1)
16047 [(set_attr "type" "str")
16048 (set_attr "memory" "store")
16049 (set_attr "mode" "QI")])
16051 (define_insn "*strsetqi_rex_1"
16052 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16053 (match_operand:QI 2 "register_operand" "a"))
16054 (set (match_operand:DI 0 "register_operand" "=D")
16055 (plus:DI (match_dup 1)
16059 [(set_attr "type" "str")
16060 (set_attr "memory" "store")
16061 (set_attr "prefix_rex" "0")
16062 (set_attr "mode" "QI")])
16064 (define_expand "rep_stos"
16065 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16066 (set (match_operand 0 "register_operand" "")
16067 (match_operand 4 "" ""))
16068 (set (match_operand 2 "memory_operand" "") (const_int 0))
16069 (use (match_operand 3 "register_operand" ""))
16070 (use (match_dup 1))])]
16072 "ix86_current_function_needs_cld = 1;")
16074 (define_insn "*rep_stosdi_rex64"
16075 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16076 (set (match_operand:DI 0 "register_operand" "=D")
16077 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16079 (match_operand:DI 3 "register_operand" "0")))
16080 (set (mem:BLK (match_dup 3))
16082 (use (match_operand:DI 2 "register_operand" "a"))
16083 (use (match_dup 4))]
16086 [(set_attr "type" "str")
16087 (set_attr "prefix_rep" "1")
16088 (set_attr "memory" "store")
16089 (set_attr "mode" "DI")])
16091 (define_insn "*rep_stossi"
16092 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16093 (set (match_operand:SI 0 "register_operand" "=D")
16094 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16096 (match_operand:SI 3 "register_operand" "0")))
16097 (set (mem:BLK (match_dup 3))
16099 (use (match_operand:SI 2 "register_operand" "a"))
16100 (use (match_dup 4))]
16103 [(set_attr "type" "str")
16104 (set_attr "prefix_rep" "1")
16105 (set_attr "memory" "store")
16106 (set_attr "mode" "SI")])
16108 (define_insn "*rep_stossi_rex64"
16109 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16110 (set (match_operand:DI 0 "register_operand" "=D")
16111 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16113 (match_operand:DI 3 "register_operand" "0")))
16114 (set (mem:BLK (match_dup 3))
16116 (use (match_operand:SI 2 "register_operand" "a"))
16117 (use (match_dup 4))]
16120 [(set_attr "type" "str")
16121 (set_attr "prefix_rep" "1")
16122 (set_attr "memory" "store")
16123 (set_attr "mode" "SI")])
16125 (define_insn "*rep_stosqi"
16126 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16127 (set (match_operand:SI 0 "register_operand" "=D")
16128 (plus:SI (match_operand:SI 3 "register_operand" "0")
16129 (match_operand:SI 4 "register_operand" "1")))
16130 (set (mem:BLK (match_dup 3))
16132 (use (match_operand:QI 2 "register_operand" "a"))
16133 (use (match_dup 4))]
16136 [(set_attr "type" "str")
16137 (set_attr "prefix_rep" "1")
16138 (set_attr "memory" "store")
16139 (set_attr "mode" "QI")])
16141 (define_insn "*rep_stosqi_rex64"
16142 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16143 (set (match_operand:DI 0 "register_operand" "=D")
16144 (plus:DI (match_operand:DI 3 "register_operand" "0")
16145 (match_operand:DI 4 "register_operand" "1")))
16146 (set (mem:BLK (match_dup 3))
16148 (use (match_operand:QI 2 "register_operand" "a"))
16149 (use (match_dup 4))]
16152 [(set_attr "type" "str")
16153 (set_attr "prefix_rep" "1")
16154 (set_attr "memory" "store")
16155 (set_attr "prefix_rex" "0")
16156 (set_attr "mode" "QI")])
16158 (define_expand "cmpstrnsi"
16159 [(set (match_operand:SI 0 "register_operand" "")
16160 (compare:SI (match_operand:BLK 1 "general_operand" "")
16161 (match_operand:BLK 2 "general_operand" "")))
16162 (use (match_operand 3 "general_operand" ""))
16163 (use (match_operand 4 "immediate_operand" ""))]
16166 rtx addr1, addr2, out, outlow, count, countreg, align;
16168 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16171 /* Can't use this if the user has appropriated esi or edi. */
16172 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
16177 out = gen_reg_rtx (SImode);
16179 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16180 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16181 if (addr1 != XEXP (operands[1], 0))
16182 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16183 if (addr2 != XEXP (operands[2], 0))
16184 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16186 count = operands[3];
16187 countreg = ix86_zero_extend_to_Pmode (count);
16189 /* %%% Iff we are testing strict equality, we can use known alignment
16190 to good advantage. This may be possible with combine, particularly
16191 once cc0 is dead. */
16192 align = operands[4];
16194 if (CONST_INT_P (count))
16196 if (INTVAL (count) == 0)
16198 emit_move_insn (operands[0], const0_rtx);
16201 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16202 operands[1], operands[2]));
16206 rtx (*cmp_insn)(rtx, rtx);
16209 cmp_insn = gen_cmpdi_1;
16211 cmp_insn = gen_cmpsi_1;
16212 emit_insn (cmp_insn (countreg, countreg));
16213 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16214 operands[1], operands[2]));
16217 outlow = gen_lowpart (QImode, out);
16218 emit_insn (gen_cmpintqi (outlow));
16219 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16221 if (operands[0] != out)
16222 emit_move_insn (operands[0], out);
16227 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16229 (define_expand "cmpintqi"
16230 [(set (match_dup 1)
16231 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16233 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16234 (parallel [(set (match_operand:QI 0 "register_operand" "")
16235 (minus:QI (match_dup 1)
16237 (clobber (reg:CC FLAGS_REG))])]
16239 "operands[1] = gen_reg_rtx (QImode);
16240 operands[2] = gen_reg_rtx (QImode);")
16242 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16243 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16245 (define_expand "cmpstrnqi_nz_1"
16246 [(parallel [(set (reg:CC FLAGS_REG)
16247 (compare:CC (match_operand 4 "memory_operand" "")
16248 (match_operand 5 "memory_operand" "")))
16249 (use (match_operand 2 "register_operand" ""))
16250 (use (match_operand:SI 3 "immediate_operand" ""))
16251 (clobber (match_operand 0 "register_operand" ""))
16252 (clobber (match_operand 1 "register_operand" ""))
16253 (clobber (match_dup 2))])]
16255 "ix86_current_function_needs_cld = 1;")
16257 (define_insn "*cmpstrnqi_nz_1"
16258 [(set (reg:CC FLAGS_REG)
16259 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16260 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16261 (use (match_operand:SI 6 "register_operand" "2"))
16262 (use (match_operand:SI 3 "immediate_operand" "i"))
16263 (clobber (match_operand:SI 0 "register_operand" "=S"))
16264 (clobber (match_operand:SI 1 "register_operand" "=D"))
16265 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16268 [(set_attr "type" "str")
16269 (set_attr "mode" "QI")
16270 (set_attr "prefix_rep" "1")])
16272 (define_insn "*cmpstrnqi_nz_rex_1"
16273 [(set (reg:CC FLAGS_REG)
16274 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16275 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16276 (use (match_operand:DI 6 "register_operand" "2"))
16277 (use (match_operand:SI 3 "immediate_operand" "i"))
16278 (clobber (match_operand:DI 0 "register_operand" "=S"))
16279 (clobber (match_operand:DI 1 "register_operand" "=D"))
16280 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16283 [(set_attr "type" "str")
16284 (set_attr "mode" "QI")
16285 (set_attr "prefix_rex" "0")
16286 (set_attr "prefix_rep" "1")])
16288 ;; The same, but the count is not known to not be zero.
16290 (define_expand "cmpstrnqi_1"
16291 [(parallel [(set (reg:CC FLAGS_REG)
16292 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16294 (compare:CC (match_operand 4 "memory_operand" "")
16295 (match_operand 5 "memory_operand" ""))
16297 (use (match_operand:SI 3 "immediate_operand" ""))
16298 (use (reg:CC FLAGS_REG))
16299 (clobber (match_operand 0 "register_operand" ""))
16300 (clobber (match_operand 1 "register_operand" ""))
16301 (clobber (match_dup 2))])]
16303 "ix86_current_function_needs_cld = 1;")
16305 (define_insn "*cmpstrnqi_1"
16306 [(set (reg:CC FLAGS_REG)
16307 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16309 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16310 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16312 (use (match_operand:SI 3 "immediate_operand" "i"))
16313 (use (reg:CC FLAGS_REG))
16314 (clobber (match_operand:SI 0 "register_operand" "=S"))
16315 (clobber (match_operand:SI 1 "register_operand" "=D"))
16316 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16319 [(set_attr "type" "str")
16320 (set_attr "mode" "QI")
16321 (set_attr "prefix_rep" "1")])
16323 (define_insn "*cmpstrnqi_rex_1"
16324 [(set (reg:CC FLAGS_REG)
16325 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16327 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16328 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16330 (use (match_operand:SI 3 "immediate_operand" "i"))
16331 (use (reg:CC FLAGS_REG))
16332 (clobber (match_operand:DI 0 "register_operand" "=S"))
16333 (clobber (match_operand:DI 1 "register_operand" "=D"))
16334 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16337 [(set_attr "type" "str")
16338 (set_attr "mode" "QI")
16339 (set_attr "prefix_rex" "0")
16340 (set_attr "prefix_rep" "1")])
16342 (define_expand "strlensi"
16343 [(set (match_operand:SI 0 "register_operand" "")
16344 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16345 (match_operand:QI 2 "immediate_operand" "")
16346 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16349 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16355 (define_expand "strlendi"
16356 [(set (match_operand:DI 0 "register_operand" "")
16357 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16358 (match_operand:QI 2 "immediate_operand" "")
16359 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16362 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16368 (define_expand "strlenqi_1"
16369 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16370 (clobber (match_operand 1 "register_operand" ""))
16371 (clobber (reg:CC FLAGS_REG))])]
16373 "ix86_current_function_needs_cld = 1;")
16375 (define_insn "*strlenqi_1"
16376 [(set (match_operand:SI 0 "register_operand" "=&c")
16377 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16378 (match_operand:QI 2 "register_operand" "a")
16379 (match_operand:SI 3 "immediate_operand" "i")
16380 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16381 (clobber (match_operand:SI 1 "register_operand" "=D"))
16382 (clobber (reg:CC FLAGS_REG))]
16385 [(set_attr "type" "str")
16386 (set_attr "mode" "QI")
16387 (set_attr "prefix_rep" "1")])
16389 (define_insn "*strlenqi_rex_1"
16390 [(set (match_operand:DI 0 "register_operand" "=&c")
16391 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16392 (match_operand:QI 2 "register_operand" "a")
16393 (match_operand:DI 3 "immediate_operand" "i")
16394 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16395 (clobber (match_operand:DI 1 "register_operand" "=D"))
16396 (clobber (reg:CC FLAGS_REG))]
16399 [(set_attr "type" "str")
16400 (set_attr "mode" "QI")
16401 (set_attr "prefix_rex" "0")
16402 (set_attr "prefix_rep" "1")])
16404 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16405 ;; handled in combine, but it is not currently up to the task.
16406 ;; When used for their truth value, the cmpstrn* expanders generate
16415 ;; The intermediate three instructions are unnecessary.
16417 ;; This one handles cmpstrn*_nz_1...
16420 (set (reg:CC FLAGS_REG)
16421 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16422 (mem:BLK (match_operand 5 "register_operand" ""))))
16423 (use (match_operand 6 "register_operand" ""))
16424 (use (match_operand:SI 3 "immediate_operand" ""))
16425 (clobber (match_operand 0 "register_operand" ""))
16426 (clobber (match_operand 1 "register_operand" ""))
16427 (clobber (match_operand 2 "register_operand" ""))])
16428 (set (match_operand:QI 7 "register_operand" "")
16429 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16430 (set (match_operand:QI 8 "register_operand" "")
16431 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16432 (set (reg FLAGS_REG)
16433 (compare (match_dup 7) (match_dup 8)))
16435 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16437 (set (reg:CC FLAGS_REG)
16438 (compare:CC (mem:BLK (match_dup 4))
16439 (mem:BLK (match_dup 5))))
16440 (use (match_dup 6))
16441 (use (match_dup 3))
16442 (clobber (match_dup 0))
16443 (clobber (match_dup 1))
16444 (clobber (match_dup 2))])]
16447 ;; ...and this one handles cmpstrn*_1.
16450 (set (reg:CC FLAGS_REG)
16451 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16453 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16454 (mem:BLK (match_operand 5 "register_operand" "")))
16456 (use (match_operand:SI 3 "immediate_operand" ""))
16457 (use (reg:CC FLAGS_REG))
16458 (clobber (match_operand 0 "register_operand" ""))
16459 (clobber (match_operand 1 "register_operand" ""))
16460 (clobber (match_operand 2 "register_operand" ""))])
16461 (set (match_operand:QI 7 "register_operand" "")
16462 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16463 (set (match_operand:QI 8 "register_operand" "")
16464 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16465 (set (reg FLAGS_REG)
16466 (compare (match_dup 7) (match_dup 8)))
16468 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16470 (set (reg:CC FLAGS_REG)
16471 (if_then_else:CC (ne (match_dup 6)
16473 (compare:CC (mem:BLK (match_dup 4))
16474 (mem:BLK (match_dup 5)))
16476 (use (match_dup 3))
16477 (use (reg:CC FLAGS_REG))
16478 (clobber (match_dup 0))
16479 (clobber (match_dup 1))
16480 (clobber (match_dup 2))])]
16485 ;; Conditional move instructions.
16487 (define_expand "mov<mode>cc"
16488 [(set (match_operand:SWIM 0 "register_operand" "")
16489 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16490 (match_operand:SWIM 2 "general_operand" "")
16491 (match_operand:SWIM 3 "general_operand" "")))]
16493 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16495 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16496 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16497 ;; So just document what we're doing explicitly.
16499 (define_expand "x86_mov<mode>cc_0_m1"
16501 [(set (match_operand:SWI48 0 "register_operand" "")
16502 (if_then_else:SWI48
16503 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16504 [(match_operand 1 "flags_reg_operand" "")
16508 (clobber (reg:CC FLAGS_REG))])]
16512 (define_insn "*x86_mov<mode>cc_0_m1"
16513 [(set (match_operand:SWI48 0 "register_operand" "=r")
16514 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16515 [(reg FLAGS_REG) (const_int 0)])
16518 (clobber (reg:CC FLAGS_REG))]
16520 "sbb{<imodesuffix>}\t%0, %0"
16521 ; Since we don't have the proper number of operands for an alu insn,
16522 ; fill in all the blanks.
16523 [(set_attr "type" "alu")
16524 (set_attr "use_carry" "1")
16525 (set_attr "pent_pair" "pu")
16526 (set_attr "memory" "none")
16527 (set_attr "imm_disp" "false")
16528 (set_attr "mode" "<MODE>")
16529 (set_attr "length_immediate" "0")])
16531 (define_insn "*x86_mov<mode>cc_0_m1_se"
16532 [(set (match_operand:SWI48 0 "register_operand" "=r")
16533 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16534 [(reg FLAGS_REG) (const_int 0)])
16537 (clobber (reg:CC FLAGS_REG))]
16539 "sbb{<imodesuffix>}\t%0, %0"
16540 [(set_attr "type" "alu")
16541 (set_attr "use_carry" "1")
16542 (set_attr "pent_pair" "pu")
16543 (set_attr "memory" "none")
16544 (set_attr "imm_disp" "false")
16545 (set_attr "mode" "<MODE>")
16546 (set_attr "length_immediate" "0")])
16548 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16549 [(set (match_operand:SWI48 0 "register_operand" "=r")
16550 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16551 [(reg FLAGS_REG) (const_int 0)])))]
16553 "sbb{<imodesuffix>}\t%0, %0"
16554 [(set_attr "type" "alu")
16555 (set_attr "use_carry" "1")
16556 (set_attr "pent_pair" "pu")
16557 (set_attr "memory" "none")
16558 (set_attr "imm_disp" "false")
16559 (set_attr "mode" "<MODE>")
16560 (set_attr "length_immediate" "0")])
16562 (define_insn "*mov<mode>cc_noc"
16563 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16564 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16565 [(reg FLAGS_REG) (const_int 0)])
16566 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16567 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16568 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16570 cmov%O2%C1\t{%2, %0|%0, %2}
16571 cmov%O2%c1\t{%3, %0|%0, %3}"
16572 [(set_attr "type" "icmov")
16573 (set_attr "mode" "<MODE>")])
16575 (define_insn_and_split "*movqicc_noc"
16576 [(set (match_operand:QI 0 "register_operand" "=r,r")
16577 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16578 [(match_operand 4 "flags_reg_operand" "")
16580 (match_operand:QI 2 "register_operand" "r,0")
16581 (match_operand:QI 3 "register_operand" "0,r")))]
16582 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16584 "&& reload_completed"
16585 [(set (match_dup 0)
16586 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16589 "operands[0] = gen_lowpart (SImode, operands[0]);
16590 operands[2] = gen_lowpart (SImode, operands[2]);
16591 operands[3] = gen_lowpart (SImode, operands[3]);"
16592 [(set_attr "type" "icmov")
16593 (set_attr "mode" "SI")])
16595 (define_expand "mov<mode>cc"
16596 [(set (match_operand:X87MODEF 0 "register_operand" "")
16597 (if_then_else:X87MODEF
16598 (match_operand 1 "ix86_fp_comparison_operator" "")
16599 (match_operand:X87MODEF 2 "register_operand" "")
16600 (match_operand:X87MODEF 3 "register_operand" "")))]
16601 "(TARGET_80387 && TARGET_CMOVE)
16602 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16603 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16605 (define_insn "*movsfcc_1_387"
16606 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16607 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16608 [(reg FLAGS_REG) (const_int 0)])
16609 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16610 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16611 "TARGET_80387 && TARGET_CMOVE
16612 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16614 fcmov%F1\t{%2, %0|%0, %2}
16615 fcmov%f1\t{%3, %0|%0, %3}
16616 cmov%O2%C1\t{%2, %0|%0, %2}
16617 cmov%O2%c1\t{%3, %0|%0, %3}"
16618 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16619 (set_attr "mode" "SF,SF,SI,SI")])
16621 (define_insn "*movdfcc_1"
16622 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16623 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16624 [(reg FLAGS_REG) (const_int 0)])
16625 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16626 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16627 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16628 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16630 fcmov%F1\t{%2, %0|%0, %2}
16631 fcmov%f1\t{%3, %0|%0, %3}
16634 [(set_attr "type" "fcmov,fcmov,multi,multi")
16635 (set_attr "mode" "DF")])
16637 (define_insn "*movdfcc_1_rex64"
16638 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16639 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16640 [(reg FLAGS_REG) (const_int 0)])
16641 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16642 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16643 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16644 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16646 fcmov%F1\t{%2, %0|%0, %2}
16647 fcmov%f1\t{%3, %0|%0, %3}
16648 cmov%O2%C1\t{%2, %0|%0, %2}
16649 cmov%O2%c1\t{%3, %0|%0, %3}"
16650 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16651 (set_attr "mode" "DF")])
16654 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16655 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16656 [(match_operand 4 "flags_reg_operand" "")
16658 (match_operand:DF 2 "nonimmediate_operand" "")
16659 (match_operand:DF 3 "nonimmediate_operand" "")))]
16660 "!TARGET_64BIT && reload_completed"
16661 [(set (match_dup 2)
16662 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16666 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16670 split_di (&operands[2], 2, &operands[5], &operands[7]);
16671 split_di (&operands[0], 1, &operands[2], &operands[3]);
16674 (define_insn "*movxfcc_1"
16675 [(set (match_operand:XF 0 "register_operand" "=f,f")
16676 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16677 [(reg FLAGS_REG) (const_int 0)])
16678 (match_operand:XF 2 "register_operand" "f,0")
16679 (match_operand:XF 3 "register_operand" "0,f")))]
16680 "TARGET_80387 && TARGET_CMOVE"
16682 fcmov%F1\t{%2, %0|%0, %2}
16683 fcmov%f1\t{%3, %0|%0, %3}"
16684 [(set_attr "type" "fcmov")
16685 (set_attr "mode" "XF")])
16687 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16688 ;; the scalar versions to have only XMM registers as operands.
16690 ;; XOP conditional move
16691 (define_insn "*xop_pcmov_<mode>"
16692 [(set (match_operand:MODEF 0 "register_operand" "=x")
16693 (if_then_else:MODEF
16694 (match_operand:MODEF 1 "register_operand" "x")
16695 (match_operand:MODEF 2 "register_operand" "x")
16696 (match_operand:MODEF 3 "register_operand" "x")))]
16698 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16699 [(set_attr "type" "sse4arg")])
16701 ;; These versions of the min/max patterns are intentionally ignorant of
16702 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16703 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16704 ;; are undefined in this condition, we're certain this is correct.
16706 (define_insn "*avx_<code><mode>3"
16707 [(set (match_operand:MODEF 0 "register_operand" "=x")
16709 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16710 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16711 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16712 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16713 [(set_attr "type" "sseadd")
16714 (set_attr "prefix" "vex")
16715 (set_attr "mode" "<MODE>")])
16717 (define_insn "<code><mode>3"
16718 [(set (match_operand:MODEF 0 "register_operand" "=x")
16720 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16721 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16722 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16723 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16724 [(set_attr "type" "sseadd")
16725 (set_attr "mode" "<MODE>")])
16727 ;; These versions of the min/max patterns implement exactly the operations
16728 ;; min = (op1 < op2 ? op1 : op2)
16729 ;; max = (!(op1 < op2) ? op1 : op2)
16730 ;; Their operands are not commutative, and thus they may be used in the
16731 ;; presence of -0.0 and NaN.
16733 (define_insn "*avx_ieee_smin<mode>3"
16734 [(set (match_operand:MODEF 0 "register_operand" "=x")
16736 [(match_operand:MODEF 1 "register_operand" "x")
16737 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16739 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16740 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16741 [(set_attr "type" "sseadd")
16742 (set_attr "prefix" "vex")
16743 (set_attr "mode" "<MODE>")])
16745 (define_insn "*ieee_smin<mode>3"
16746 [(set (match_operand:MODEF 0 "register_operand" "=x")
16748 [(match_operand:MODEF 1 "register_operand" "0")
16749 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16751 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16752 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16753 [(set_attr "type" "sseadd")
16754 (set_attr "mode" "<MODE>")])
16756 (define_insn "*avx_ieee_smax<mode>3"
16757 [(set (match_operand:MODEF 0 "register_operand" "=x")
16759 [(match_operand:MODEF 1 "register_operand" "0")
16760 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16762 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16763 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16764 [(set_attr "type" "sseadd")
16765 (set_attr "prefix" "vex")
16766 (set_attr "mode" "<MODE>")])
16768 (define_insn "*ieee_smax<mode>3"
16769 [(set (match_operand:MODEF 0 "register_operand" "=x")
16771 [(match_operand:MODEF 1 "register_operand" "0")
16772 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16774 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16775 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16776 [(set_attr "type" "sseadd")
16777 (set_attr "mode" "<MODE>")])
16779 ;; Make two stack loads independent:
16781 ;; fld %st(0) -> fld bb
16782 ;; fmul bb fmul %st(1), %st
16784 ;; Actually we only match the last two instructions for simplicity.
16786 [(set (match_operand 0 "fp_register_operand" "")
16787 (match_operand 1 "fp_register_operand" ""))
16789 (match_operator 2 "binary_fp_operator"
16791 (match_operand 3 "memory_operand" "")]))]
16792 "REGNO (operands[0]) != REGNO (operands[1])"
16793 [(set (match_dup 0) (match_dup 3))
16794 (set (match_dup 0) (match_dup 4))]
16796 ;; The % modifier is not operational anymore in peephole2's, so we have to
16797 ;; swap the operands manually in the case of addition and multiplication.
16798 "if (COMMUTATIVE_ARITH_P (operands[2]))
16799 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16800 operands[0], operands[1]);
16802 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16803 operands[1], operands[0]);")
16805 ;; Conditional addition patterns
16806 (define_expand "add<mode>cc"
16807 [(match_operand:SWI 0 "register_operand" "")
16808 (match_operand 1 "comparison_operator" "")
16809 (match_operand:SWI 2 "register_operand" "")
16810 (match_operand:SWI 3 "const_int_operand" "")]
16812 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16815 ;; Misc patterns (?)
16817 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16818 ;; Otherwise there will be nothing to keep
16820 ;; [(set (reg ebp) (reg esp))]
16821 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16822 ;; (clobber (eflags)]
16823 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16825 ;; in proper program order.
16826 (define_insn "pro_epilogue_adjust_stack_1"
16827 [(set (match_operand:SI 0 "register_operand" "=r,r")
16828 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16829 (match_operand:SI 2 "immediate_operand" "i,i")))
16830 (clobber (reg:CC FLAGS_REG))
16831 (clobber (mem:BLK (scratch)))]
16834 switch (get_attr_type (insn))
16837 return "mov{l}\t{%1, %0|%0, %1}";
16840 if (CONST_INT_P (operands[2])
16841 && (INTVAL (operands[2]) == 128
16842 || (INTVAL (operands[2]) < 0
16843 && INTVAL (operands[2]) != -128)))
16845 operands[2] = GEN_INT (-INTVAL (operands[2]));
16846 return "sub{l}\t{%2, %0|%0, %2}";
16848 return "add{l}\t{%2, %0|%0, %2}";
16851 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16852 return "lea{l}\t{%a2, %0|%0, %a2}";
16855 gcc_unreachable ();
16858 [(set (attr "type")
16859 (cond [(and (eq_attr "alternative" "0")
16860 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16861 (const_string "alu")
16862 (match_operand:SI 2 "const0_operand" "")
16863 (const_string "imov")
16865 (const_string "lea")))
16866 (set (attr "length_immediate")
16867 (cond [(eq_attr "type" "imov")
16869 (and (eq_attr "type" "alu")
16870 (match_operand 2 "const128_operand" ""))
16873 (const_string "*")))
16874 (set_attr "mode" "SI")])
16876 (define_insn "pro_epilogue_adjust_stack_rex64"
16877 [(set (match_operand:DI 0 "register_operand" "=r,r")
16878 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16879 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16880 (clobber (reg:CC FLAGS_REG))
16881 (clobber (mem:BLK (scratch)))]
16884 switch (get_attr_type (insn))
16887 return "mov{q}\t{%1, %0|%0, %1}";
16890 if (CONST_INT_P (operands[2])
16891 /* Avoid overflows. */
16892 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
16893 && (INTVAL (operands[2]) == 128
16894 || (INTVAL (operands[2]) < 0
16895 && INTVAL (operands[2]) != -128)))
16897 operands[2] = GEN_INT (-INTVAL (operands[2]));
16898 return "sub{q}\t{%2, %0|%0, %2}";
16900 return "add{q}\t{%2, %0|%0, %2}";
16903 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16904 return "lea{q}\t{%a2, %0|%0, %a2}";
16907 gcc_unreachable ();
16910 [(set (attr "type")
16911 (cond [(and (eq_attr "alternative" "0")
16912 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16913 (const_string "alu")
16914 (match_operand:DI 2 "const0_operand" "")
16915 (const_string "imov")
16917 (const_string "lea")))
16918 (set (attr "length_immediate")
16919 (cond [(eq_attr "type" "imov")
16921 (and (eq_attr "type" "alu")
16922 (match_operand 2 "const128_operand" ""))
16925 (const_string "*")))
16926 (set_attr "mode" "DI")])
16928 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16929 [(set (match_operand:DI 0 "register_operand" "=r,r")
16930 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16931 (match_operand:DI 3 "immediate_operand" "i,i")))
16932 (use (match_operand:DI 2 "register_operand" "r,r"))
16933 (clobber (reg:CC FLAGS_REG))
16934 (clobber (mem:BLK (scratch)))]
16937 switch (get_attr_type (insn))
16940 return "add{q}\t{%2, %0|%0, %2}";
16943 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16944 return "lea{q}\t{%a2, %0|%0, %a2}";
16947 gcc_unreachable ();
16950 [(set_attr "type" "alu,lea")
16951 (set_attr "mode" "DI")])
16953 (define_insn "allocate_stack_worker_32"
16954 [(set (match_operand:SI 0 "register_operand" "=a")
16955 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16956 UNSPECV_STACK_PROBE))
16957 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16958 (clobber (reg:CC FLAGS_REG))]
16959 "!TARGET_64BIT && TARGET_STACK_PROBE"
16961 [(set_attr "type" "multi")
16962 (set_attr "length" "5")])
16964 (define_insn "allocate_stack_worker_64"
16965 [(set (match_operand:DI 0 "register_operand" "=a")
16966 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16967 UNSPECV_STACK_PROBE))
16968 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16969 (clobber (reg:DI R10_REG))
16970 (clobber (reg:DI R11_REG))
16971 (clobber (reg:CC FLAGS_REG))]
16972 "TARGET_64BIT && TARGET_STACK_PROBE"
16974 [(set_attr "type" "multi")
16975 (set_attr "length" "5")])
16977 (define_expand "allocate_stack"
16978 [(match_operand 0 "register_operand" "")
16979 (match_operand 1 "general_operand" "")]
16980 "TARGET_STACK_PROBE"
16984 #ifndef CHECK_STACK_LIMIT
16985 #define CHECK_STACK_LIMIT 0
16988 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16989 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16991 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16992 stack_pointer_rtx, 0, OPTAB_DIRECT);
16993 if (x != stack_pointer_rtx)
16994 emit_move_insn (stack_pointer_rtx, x);
16998 x = copy_to_mode_reg (Pmode, operands[1]);
17000 x = gen_allocate_stack_worker_64 (x, x);
17002 x = gen_allocate_stack_worker_32 (x, x);
17006 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17010 ;; Use IOR for stack probes, this is shorter.
17011 (define_expand "probe_stack"
17012 [(match_operand 0 "memory_operand" "")]
17015 if (GET_MODE (operands[0]) == DImode)
17016 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
17018 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
17022 (define_expand "builtin_setjmp_receiver"
17023 [(label_ref (match_operand 0 "" ""))]
17024 "!TARGET_64BIT && flag_pic"
17030 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
17031 rtx label_rtx = gen_label_rtx ();
17032 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17033 xops[0] = xops[1] = picreg;
17034 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17035 ix86_expand_binary_operator (MINUS, SImode, xops);
17039 emit_insn (gen_set_got (pic_offset_table_rtx));
17043 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17046 [(set (match_operand 0 "register_operand" "")
17047 (match_operator 3 "promotable_binary_operator"
17048 [(match_operand 1 "register_operand" "")
17049 (match_operand 2 "aligned_operand" "")]))
17050 (clobber (reg:CC FLAGS_REG))]
17051 "! TARGET_PARTIAL_REG_STALL && reload_completed
17052 && ((GET_MODE (operands[0]) == HImode
17053 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17054 /* ??? next two lines just !satisfies_constraint_K (...) */
17055 || !CONST_INT_P (operands[2])
17056 || satisfies_constraint_K (operands[2])))
17057 || (GET_MODE (operands[0]) == QImode
17058 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17059 [(parallel [(set (match_dup 0)
17060 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17061 (clobber (reg:CC FLAGS_REG))])]
17062 "operands[0] = gen_lowpart (SImode, operands[0]);
17063 operands[1] = gen_lowpart (SImode, operands[1]);
17064 if (GET_CODE (operands[3]) != ASHIFT)
17065 operands[2] = gen_lowpart (SImode, operands[2]);
17066 PUT_MODE (operands[3], SImode);")
17068 ; Promote the QImode tests, as i386 has encoding of the AND
17069 ; instruction with 32-bit sign-extended immediate and thus the
17070 ; instruction size is unchanged, except in the %eax case for
17071 ; which it is increased by one byte, hence the ! optimize_size.
17073 [(set (match_operand 0 "flags_reg_operand" "")
17074 (match_operator 2 "compare_operator"
17075 [(and (match_operand 3 "aligned_operand" "")
17076 (match_operand 4 "const_int_operand" ""))
17078 (set (match_operand 1 "register_operand" "")
17079 (and (match_dup 3) (match_dup 4)))]
17080 "! TARGET_PARTIAL_REG_STALL && reload_completed
17081 && optimize_insn_for_speed_p ()
17082 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17083 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17084 /* Ensure that the operand will remain sign-extended immediate. */
17085 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17086 [(parallel [(set (match_dup 0)
17087 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17090 (and:SI (match_dup 3) (match_dup 4)))])]
17093 = gen_int_mode (INTVAL (operands[4])
17094 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17095 operands[1] = gen_lowpart (SImode, operands[1]);
17096 operands[3] = gen_lowpart (SImode, operands[3]);
17099 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17100 ; the TEST instruction with 32-bit sign-extended immediate and thus
17101 ; the instruction size would at least double, which is not what we
17102 ; want even with ! optimize_size.
17104 [(set (match_operand 0 "flags_reg_operand" "")
17105 (match_operator 1 "compare_operator"
17106 [(and (match_operand:HI 2 "aligned_operand" "")
17107 (match_operand:HI 3 "const_int_operand" ""))
17109 "! TARGET_PARTIAL_REG_STALL && reload_completed
17110 && ! TARGET_FAST_PREFIX
17111 && optimize_insn_for_speed_p ()
17112 /* Ensure that the operand will remain sign-extended immediate. */
17113 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17114 [(set (match_dup 0)
17115 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17119 = gen_int_mode (INTVAL (operands[3])
17120 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17121 operands[2] = gen_lowpart (SImode, operands[2]);
17125 [(set (match_operand 0 "register_operand" "")
17126 (neg (match_operand 1 "register_operand" "")))
17127 (clobber (reg:CC FLAGS_REG))]
17128 "! TARGET_PARTIAL_REG_STALL && reload_completed
17129 && (GET_MODE (operands[0]) == HImode
17130 || (GET_MODE (operands[0]) == QImode
17131 && (TARGET_PROMOTE_QImode
17132 || optimize_insn_for_size_p ())))"
17133 [(parallel [(set (match_dup 0)
17134 (neg:SI (match_dup 1)))
17135 (clobber (reg:CC FLAGS_REG))])]
17136 "operands[0] = gen_lowpart (SImode, operands[0]);
17137 operands[1] = gen_lowpart (SImode, operands[1]);")
17140 [(set (match_operand 0 "register_operand" "")
17141 (not (match_operand 1 "register_operand" "")))]
17142 "! TARGET_PARTIAL_REG_STALL && reload_completed
17143 && (GET_MODE (operands[0]) == HImode
17144 || (GET_MODE (operands[0]) == QImode
17145 && (TARGET_PROMOTE_QImode
17146 || optimize_insn_for_size_p ())))"
17147 [(set (match_dup 0)
17148 (not:SI (match_dup 1)))]
17149 "operands[0] = gen_lowpart (SImode, operands[0]);
17150 operands[1] = gen_lowpart (SImode, operands[1]);")
17153 [(set (match_operand 0 "register_operand" "")
17154 (if_then_else (match_operator 1 "comparison_operator"
17155 [(reg FLAGS_REG) (const_int 0)])
17156 (match_operand 2 "register_operand" "")
17157 (match_operand 3 "register_operand" "")))]
17158 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17159 && (GET_MODE (operands[0]) == HImode
17160 || (GET_MODE (operands[0]) == QImode
17161 && (TARGET_PROMOTE_QImode
17162 || optimize_insn_for_size_p ())))"
17163 [(set (match_dup 0)
17164 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17165 "operands[0] = gen_lowpart (SImode, operands[0]);
17166 operands[2] = gen_lowpart (SImode, operands[2]);
17167 operands[3] = gen_lowpart (SImode, operands[3]);")
17170 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17171 ;; transform a complex memory operation into two memory to register operations.
17173 ;; Don't push memory operands
17175 [(set (match_operand:SI 0 "push_operand" "")
17176 (match_operand:SI 1 "memory_operand" ""))
17177 (match_scratch:SI 2 "r")]
17178 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17179 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17180 [(set (match_dup 2) (match_dup 1))
17181 (set (match_dup 0) (match_dup 2))]
17185 [(set (match_operand:DI 0 "push_operand" "")
17186 (match_operand:DI 1 "memory_operand" ""))
17187 (match_scratch:DI 2 "r")]
17188 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17189 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17190 [(set (match_dup 2) (match_dup 1))
17191 (set (match_dup 0) (match_dup 2))]
17194 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17197 [(set (match_operand:SF 0 "push_operand" "")
17198 (match_operand:SF 1 "memory_operand" ""))
17199 (match_scratch:SF 2 "r")]
17200 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17201 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17202 [(set (match_dup 2) (match_dup 1))
17203 (set (match_dup 0) (match_dup 2))]
17207 [(set (match_operand:HI 0 "push_operand" "")
17208 (match_operand:HI 1 "memory_operand" ""))
17209 (match_scratch:HI 2 "r")]
17210 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17211 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17212 [(set (match_dup 2) (match_dup 1))
17213 (set (match_dup 0) (match_dup 2))]
17217 [(set (match_operand:QI 0 "push_operand" "")
17218 (match_operand:QI 1 "memory_operand" ""))
17219 (match_scratch:QI 2 "q")]
17220 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17221 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17222 [(set (match_dup 2) (match_dup 1))
17223 (set (match_dup 0) (match_dup 2))]
17226 ;; Don't move an immediate directly to memory when the instruction
17229 [(match_scratch:SI 1 "r")
17230 (set (match_operand:SI 0 "memory_operand" "")
17232 "optimize_insn_for_speed_p ()
17233 && ! TARGET_USE_MOV0
17234 && TARGET_SPLIT_LONG_MOVES
17235 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17236 && peep2_regno_dead_p (0, FLAGS_REG)"
17237 [(parallel [(set (match_dup 1) (const_int 0))
17238 (clobber (reg:CC FLAGS_REG))])
17239 (set (match_dup 0) (match_dup 1))]
17243 [(match_scratch:HI 1 "r")
17244 (set (match_operand:HI 0 "memory_operand" "")
17246 "optimize_insn_for_speed_p ()
17247 && ! TARGET_USE_MOV0
17248 && TARGET_SPLIT_LONG_MOVES
17249 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17250 && peep2_regno_dead_p (0, FLAGS_REG)"
17251 [(parallel [(set (match_dup 2) (const_int 0))
17252 (clobber (reg:CC FLAGS_REG))])
17253 (set (match_dup 0) (match_dup 1))]
17254 "operands[2] = gen_lowpart (SImode, operands[1]);")
17257 [(match_scratch:QI 1 "q")
17258 (set (match_operand:QI 0 "memory_operand" "")
17260 "optimize_insn_for_speed_p ()
17261 && ! TARGET_USE_MOV0
17262 && TARGET_SPLIT_LONG_MOVES
17263 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17264 && peep2_regno_dead_p (0, FLAGS_REG)"
17265 [(parallel [(set (match_dup 2) (const_int 0))
17266 (clobber (reg:CC FLAGS_REG))])
17267 (set (match_dup 0) (match_dup 1))]
17268 "operands[2] = gen_lowpart (SImode, operands[1]);")
17271 [(match_scratch:SI 2 "r")
17272 (set (match_operand:SI 0 "memory_operand" "")
17273 (match_operand:SI 1 "immediate_operand" ""))]
17274 "optimize_insn_for_speed_p ()
17275 && TARGET_SPLIT_LONG_MOVES
17276 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17277 [(set (match_dup 2) (match_dup 1))
17278 (set (match_dup 0) (match_dup 2))]
17282 [(match_scratch:HI 2 "r")
17283 (set (match_operand:HI 0 "memory_operand" "")
17284 (match_operand:HI 1 "immediate_operand" ""))]
17285 "optimize_insn_for_speed_p ()
17286 && TARGET_SPLIT_LONG_MOVES
17287 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17288 [(set (match_dup 2) (match_dup 1))
17289 (set (match_dup 0) (match_dup 2))]
17293 [(match_scratch:QI 2 "q")
17294 (set (match_operand:QI 0 "memory_operand" "")
17295 (match_operand:QI 1 "immediate_operand" ""))]
17296 "optimize_insn_for_speed_p ()
17297 && TARGET_SPLIT_LONG_MOVES
17298 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17299 [(set (match_dup 2) (match_dup 1))
17300 (set (match_dup 0) (match_dup 2))]
17303 ;; Don't compare memory with zero, load and use a test instead.
17305 [(set (match_operand 0 "flags_reg_operand" "")
17306 (match_operator 1 "compare_operator"
17307 [(match_operand:SI 2 "memory_operand" "")
17309 (match_scratch:SI 3 "r")]
17310 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17311 [(set (match_dup 3) (match_dup 2))
17312 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17315 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17316 ;; Don't split NOTs with a displacement operand, because resulting XOR
17317 ;; will not be pairable anyway.
17319 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17320 ;; represented using a modRM byte. The XOR replacement is long decoded,
17321 ;; so this split helps here as well.
17323 ;; Note: Can't do this as a regular split because we can't get proper
17324 ;; lifetime information then.
17327 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17328 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17329 "optimize_insn_for_speed_p ()
17330 && ((TARGET_NOT_UNPAIRABLE
17331 && (!MEM_P (operands[0])
17332 || !memory_displacement_operand (operands[0], SImode)))
17333 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
17334 && peep2_regno_dead_p (0, FLAGS_REG)"
17335 [(parallel [(set (match_dup 0)
17336 (xor:SI (match_dup 1) (const_int -1)))
17337 (clobber (reg:CC FLAGS_REG))])]
17341 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17342 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17343 "optimize_insn_for_speed_p ()
17344 && ((TARGET_NOT_UNPAIRABLE
17345 && (!MEM_P (operands[0])
17346 || !memory_displacement_operand (operands[0], HImode)))
17347 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
17348 && peep2_regno_dead_p (0, FLAGS_REG)"
17349 [(parallel [(set (match_dup 0)
17350 (xor:HI (match_dup 1) (const_int -1)))
17351 (clobber (reg:CC FLAGS_REG))])]
17355 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17356 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17357 "optimize_insn_for_speed_p ()
17358 && ((TARGET_NOT_UNPAIRABLE
17359 && (!MEM_P (operands[0])
17360 || !memory_displacement_operand (operands[0], QImode)))
17361 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
17362 && peep2_regno_dead_p (0, FLAGS_REG)"
17363 [(parallel [(set (match_dup 0)
17364 (xor:QI (match_dup 1) (const_int -1)))
17365 (clobber (reg:CC FLAGS_REG))])]
17368 ;; Non pairable "test imm, reg" instructions can be translated to
17369 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17370 ;; byte opcode instead of two, have a short form for byte operands),
17371 ;; so do it for other CPUs as well. Given that the value was dead,
17372 ;; this should not create any new dependencies. Pass on the sub-word
17373 ;; versions if we're concerned about partial register stalls.
17376 [(set (match_operand 0 "flags_reg_operand" "")
17377 (match_operator 1 "compare_operator"
17378 [(and:SI (match_operand:SI 2 "register_operand" "")
17379 (match_operand:SI 3 "immediate_operand" ""))
17381 "ix86_match_ccmode (insn, CCNOmode)
17382 && (true_regnum (operands[2]) != AX_REG
17383 || satisfies_constraint_K (operands[3]))
17384 && peep2_reg_dead_p (1, operands[2])"
17386 [(set (match_dup 0)
17387 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17390 (and:SI (match_dup 2) (match_dup 3)))])]
17393 ;; We don't need to handle HImode case, because it will be promoted to SImode
17394 ;; on ! TARGET_PARTIAL_REG_STALL
17397 [(set (match_operand 0 "flags_reg_operand" "")
17398 (match_operator 1 "compare_operator"
17399 [(and:QI (match_operand:QI 2 "register_operand" "")
17400 (match_operand:QI 3 "immediate_operand" ""))
17402 "! TARGET_PARTIAL_REG_STALL
17403 && ix86_match_ccmode (insn, CCNOmode)
17404 && true_regnum (operands[2]) != AX_REG
17405 && peep2_reg_dead_p (1, operands[2])"
17407 [(set (match_dup 0)
17408 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17411 (and:QI (match_dup 2) (match_dup 3)))])]
17415 [(set (match_operand 0 "flags_reg_operand" "")
17416 (match_operator 1 "compare_operator"
17419 (match_operand 2 "ext_register_operand" "")
17422 (match_operand 3 "const_int_operand" ""))
17424 "! TARGET_PARTIAL_REG_STALL
17425 && ix86_match_ccmode (insn, CCNOmode)
17426 && true_regnum (operands[2]) != AX_REG
17427 && peep2_reg_dead_p (1, operands[2])"
17428 [(parallel [(set (match_dup 0)
17437 (set (zero_extract:SI (match_dup 2)
17448 ;; Don't do logical operations with memory inputs.
17450 [(match_scratch:SI 2 "r")
17451 (parallel [(set (match_operand:SI 0 "register_operand" "")
17452 (match_operator:SI 3 "arith_or_logical_operator"
17454 (match_operand:SI 1 "memory_operand" "")]))
17455 (clobber (reg:CC FLAGS_REG))])]
17456 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17457 [(set (match_dup 2) (match_dup 1))
17458 (parallel [(set (match_dup 0)
17459 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17460 (clobber (reg:CC FLAGS_REG))])]
17464 [(match_scratch:SI 2 "r")
17465 (parallel [(set (match_operand:SI 0 "register_operand" "")
17466 (match_operator:SI 3 "arith_or_logical_operator"
17467 [(match_operand:SI 1 "memory_operand" "")
17469 (clobber (reg:CC FLAGS_REG))])]
17470 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17471 [(set (match_dup 2) (match_dup 1))
17472 (parallel [(set (match_dup 0)
17473 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17474 (clobber (reg:CC FLAGS_REG))])]
17477 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17478 ;; refers to the destination of the load!
17481 [(set (match_operand:SI 0 "register_operand" "")
17482 (match_operand:SI 1 "register_operand" ""))
17483 (parallel [(set (match_dup 0)
17484 (match_operator:SI 3 "commutative_operator"
17486 (match_operand:SI 2 "memory_operand" "")]))
17487 (clobber (reg:CC FLAGS_REG))])]
17488 "REGNO (operands[0]) != REGNO (operands[1])
17489 && GENERAL_REGNO_P (REGNO (operands[0]))
17490 && GENERAL_REGNO_P (REGNO (operands[1]))"
17491 [(set (match_dup 0) (match_dup 4))
17492 (parallel [(set (match_dup 0)
17493 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17494 (clobber (reg:CC FLAGS_REG))])]
17495 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17498 [(set (match_operand 0 "register_operand" "")
17499 (match_operand 1 "register_operand" ""))
17501 (match_operator 3 "commutative_operator"
17503 (match_operand 2 "memory_operand" "")]))]
17504 "REGNO (operands[0]) != REGNO (operands[1])
17505 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17506 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17507 [(set (match_dup 0) (match_dup 2))
17509 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17512 ; Don't do logical operations with memory outputs
17514 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17515 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17516 ; the same decoder scheduling characteristics as the original.
17519 [(match_scratch:SI 2 "r")
17520 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17521 (match_operator:SI 3 "arith_or_logical_operator"
17523 (match_operand:SI 1 "nonmemory_operand" "")]))
17524 (clobber (reg:CC FLAGS_REG))])]
17525 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17526 /* Do not split stack checking probes. */
17527 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17528 [(set (match_dup 2) (match_dup 0))
17529 (parallel [(set (match_dup 2)
17530 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17531 (clobber (reg:CC FLAGS_REG))])
17532 (set (match_dup 0) (match_dup 2))]
17536 [(match_scratch:SI 2 "r")
17537 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17538 (match_operator:SI 3 "arith_or_logical_operator"
17539 [(match_operand:SI 1 "nonmemory_operand" "")
17541 (clobber (reg:CC FLAGS_REG))])]
17542 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17543 /* Do not split stack checking probes. */
17544 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17545 [(set (match_dup 2) (match_dup 0))
17546 (parallel [(set (match_dup 2)
17547 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17548 (clobber (reg:CC FLAGS_REG))])
17549 (set (match_dup 0) (match_dup 2))]
17552 ;; Attempt to always use XOR for zeroing registers.
17554 [(set (match_operand 0 "register_operand" "")
17555 (match_operand 1 "const0_operand" ""))]
17556 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17557 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17558 && GENERAL_REG_P (operands[0])
17559 && peep2_regno_dead_p (0, FLAGS_REG)"
17560 [(parallel [(set (match_dup 0) (const_int 0))
17561 (clobber (reg:CC FLAGS_REG))])]
17563 operands[0] = gen_lowpart (word_mode, operands[0]);
17567 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17569 "(GET_MODE (operands[0]) == QImode
17570 || GET_MODE (operands[0]) == HImode)
17571 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17572 && peep2_regno_dead_p (0, FLAGS_REG)"
17573 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17574 (clobber (reg:CC FLAGS_REG))])])
17576 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17578 [(set (match_operand 0 "register_operand" "")
17580 "(GET_MODE (operands[0]) == HImode
17581 || GET_MODE (operands[0]) == SImode
17582 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17583 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17584 && peep2_regno_dead_p (0, FLAGS_REG)"
17585 [(parallel [(set (match_dup 0) (const_int -1))
17586 (clobber (reg:CC FLAGS_REG))])]
17587 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17590 ;; Attempt to convert simple leas to adds. These can be created by
17593 [(set (match_operand:SI 0 "register_operand" "")
17594 (plus:SI (match_dup 0)
17595 (match_operand:SI 1 "nonmemory_operand" "")))]
17596 "peep2_regno_dead_p (0, FLAGS_REG)"
17597 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17598 (clobber (reg:CC FLAGS_REG))])]
17602 [(set (match_operand:SI 0 "register_operand" "")
17603 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17604 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17605 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17606 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17607 (clobber (reg:CC FLAGS_REG))])]
17608 "operands[2] = gen_lowpart (SImode, operands[2]);")
17611 [(set (match_operand:DI 0 "register_operand" "")
17612 (plus:DI (match_dup 0)
17613 (match_operand:DI 1 "x86_64_general_operand" "")))]
17614 "peep2_regno_dead_p (0, FLAGS_REG)"
17615 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17616 (clobber (reg:CC FLAGS_REG))])]
17620 [(set (match_operand:SI 0 "register_operand" "")
17621 (mult:SI (match_dup 0)
17622 (match_operand:SI 1 "const_int_operand" "")))]
17623 "exact_log2 (INTVAL (operands[1])) >= 0
17624 && peep2_regno_dead_p (0, FLAGS_REG)"
17625 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17626 (clobber (reg:CC FLAGS_REG))])]
17627 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17630 [(set (match_operand:DI 0 "register_operand" "")
17631 (mult:DI (match_dup 0)
17632 (match_operand:DI 1 "const_int_operand" "")))]
17633 "exact_log2 (INTVAL (operands[1])) >= 0
17634 && peep2_regno_dead_p (0, FLAGS_REG)"
17635 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17636 (clobber (reg:CC FLAGS_REG))])]
17637 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17640 [(set (match_operand:SI 0 "register_operand" "")
17641 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17642 (match_operand:DI 2 "const_int_operand" "")) 0))]
17643 "exact_log2 (INTVAL (operands[2])) >= 0
17644 && REGNO (operands[0]) == REGNO (operands[1])
17645 && peep2_regno_dead_p (0, FLAGS_REG)"
17646 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17647 (clobber (reg:CC FLAGS_REG))])]
17648 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17650 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17651 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17652 ;; many CPUs it is also faster, since special hardware to avoid esp
17653 ;; dependencies is present.
17655 ;; While some of these conversions may be done using splitters, we use peepholes
17656 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17658 ;; Convert prologue esp subtractions to push.
17659 ;; We need register to push. In order to keep verify_flow_info happy we have
17661 ;; - use scratch and clobber it in order to avoid dependencies
17662 ;; - use already live register
17663 ;; We can't use the second way right now, since there is no reliable way how to
17664 ;; verify that given register is live. First choice will also most likely in
17665 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17666 ;; call clobbered registers are dead. We may want to use base pointer as an
17667 ;; alternative when no register is available later.
17670 [(match_scratch:SI 0 "r")
17671 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17672 (clobber (reg:CC FLAGS_REG))
17673 (clobber (mem:BLK (scratch)))])]
17674 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17675 [(clobber (match_dup 0))
17676 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17677 (clobber (mem:BLK (scratch)))])])
17680 [(match_scratch:SI 0 "r")
17681 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17682 (clobber (reg:CC FLAGS_REG))
17683 (clobber (mem:BLK (scratch)))])]
17684 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17685 [(clobber (match_dup 0))
17686 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17687 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17688 (clobber (mem:BLK (scratch)))])])
17690 ;; Convert esp subtractions to push.
17692 [(match_scratch:SI 0 "r")
17693 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17694 (clobber (reg:CC FLAGS_REG))])]
17695 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17696 [(clobber (match_dup 0))
17697 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17700 [(match_scratch:SI 0 "r")
17701 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17702 (clobber (reg:CC FLAGS_REG))])]
17703 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17704 [(clobber (match_dup 0))
17705 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17706 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17708 ;; Convert epilogue deallocator to pop.
17710 [(match_scratch:SI 0 "r")
17711 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17712 (clobber (reg:CC FLAGS_REG))
17713 (clobber (mem:BLK (scratch)))])]
17714 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17715 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17716 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17717 (clobber (mem:BLK (scratch)))])]
17720 ;; Two pops case is tricky, since pop causes dependency on destination register.
17721 ;; We use two registers if available.
17723 [(match_scratch:SI 0 "r")
17724 (match_scratch:SI 1 "r")
17725 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17726 (clobber (reg:CC FLAGS_REG))
17727 (clobber (mem:BLK (scratch)))])]
17728 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17729 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17730 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17731 (clobber (mem:BLK (scratch)))])
17732 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17733 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17737 [(match_scratch:SI 0 "r")
17738 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17739 (clobber (reg:CC FLAGS_REG))
17740 (clobber (mem:BLK (scratch)))])]
17741 "optimize_insn_for_size_p ()"
17742 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17743 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17744 (clobber (mem:BLK (scratch)))])
17745 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17746 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17749 ;; Convert esp additions to pop.
17751 [(match_scratch:SI 0 "r")
17752 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17753 (clobber (reg:CC FLAGS_REG))])]
17755 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17756 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17759 ;; Two pops case is tricky, since pop causes dependency on destination register.
17760 ;; We use two registers if available.
17762 [(match_scratch:SI 0 "r")
17763 (match_scratch:SI 1 "r")
17764 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17765 (clobber (reg:CC FLAGS_REG))])]
17767 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17768 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17769 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17770 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17774 [(match_scratch:SI 0 "r")
17775 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17776 (clobber (reg:CC FLAGS_REG))])]
17777 "optimize_insn_for_size_p ()"
17778 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17779 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17780 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17781 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17784 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17785 ;; required and register dies. Similarly for 128 to -128.
17787 [(set (match_operand 0 "flags_reg_operand" "")
17788 (match_operator 1 "compare_operator"
17789 [(match_operand 2 "register_operand" "")
17790 (match_operand 3 "const_int_operand" "")]))]
17791 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17792 && incdec_operand (operands[3], GET_MODE (operands[3])))
17793 || (!TARGET_FUSE_CMP_AND_BRANCH
17794 && INTVAL (operands[3]) == 128))
17795 && ix86_match_ccmode (insn, CCGCmode)
17796 && peep2_reg_dead_p (1, operands[2])"
17797 [(parallel [(set (match_dup 0)
17798 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17799 (clobber (match_dup 2))])]
17803 [(match_scratch:DI 0 "r")
17804 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17805 (clobber (reg:CC FLAGS_REG))
17806 (clobber (mem:BLK (scratch)))])]
17807 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17808 [(clobber (match_dup 0))
17809 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17810 (clobber (mem:BLK (scratch)))])])
17813 [(match_scratch:DI 0 "r")
17814 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17815 (clobber (reg:CC FLAGS_REG))
17816 (clobber (mem:BLK (scratch)))])]
17817 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17818 [(clobber (match_dup 0))
17819 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17820 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17821 (clobber (mem:BLK (scratch)))])])
17823 ;; Convert esp subtractions to push.
17825 [(match_scratch:DI 0 "r")
17826 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17827 (clobber (reg:CC FLAGS_REG))])]
17828 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17829 [(clobber (match_dup 0))
17830 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17833 [(match_scratch:DI 0 "r")
17834 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17835 (clobber (reg:CC FLAGS_REG))])]
17836 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17837 [(clobber (match_dup 0))
17838 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17839 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17841 ;; Convert epilogue deallocator to pop.
17843 [(match_scratch:DI 0 "r")
17844 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17845 (clobber (reg:CC FLAGS_REG))
17846 (clobber (mem:BLK (scratch)))])]
17847 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17848 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17849 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17850 (clobber (mem:BLK (scratch)))])]
17853 ;; Two pops case is tricky, since pop causes dependency on destination register.
17854 ;; We use two registers if available.
17856 [(match_scratch:DI 0 "r")
17857 (match_scratch:DI 1 "r")
17858 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17859 (clobber (reg:CC FLAGS_REG))
17860 (clobber (mem:BLK (scratch)))])]
17861 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17862 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17863 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17864 (clobber (mem:BLK (scratch)))])
17865 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17866 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17870 [(match_scratch:DI 0 "r")
17871 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17872 (clobber (reg:CC FLAGS_REG))
17873 (clobber (mem:BLK (scratch)))])]
17874 "optimize_insn_for_size_p ()"
17875 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17876 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17877 (clobber (mem:BLK (scratch)))])
17878 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17879 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17882 ;; Convert esp additions to pop.
17884 [(match_scratch:DI 0 "r")
17885 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17886 (clobber (reg:CC FLAGS_REG))])]
17888 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17889 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17892 ;; Two pops case is tricky, since pop causes dependency on destination register.
17893 ;; We use two registers if available.
17895 [(match_scratch:DI 0 "r")
17896 (match_scratch:DI 1 "r")
17897 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17898 (clobber (reg:CC FLAGS_REG))])]
17900 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17901 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17902 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17903 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17907 [(match_scratch:DI 0 "r")
17908 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17909 (clobber (reg:CC FLAGS_REG))])]
17910 "optimize_insn_for_size_p ()"
17911 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17912 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17913 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17914 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17917 ;; Convert imul by three, five and nine into lea
17920 [(set (match_operand:SI 0 "register_operand" "")
17921 (mult:SI (match_operand:SI 1 "register_operand" "")
17922 (match_operand:SI 2 "const_int_operand" "")))
17923 (clobber (reg:CC FLAGS_REG))])]
17924 "INTVAL (operands[2]) == 3
17925 || INTVAL (operands[2]) == 5
17926 || INTVAL (operands[2]) == 9"
17927 [(set (match_dup 0)
17928 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
17930 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17934 [(set (match_operand:SI 0 "register_operand" "")
17935 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17936 (match_operand:SI 2 "const_int_operand" "")))
17937 (clobber (reg:CC FLAGS_REG))])]
17938 "optimize_insn_for_speed_p ()
17939 && (INTVAL (operands[2]) == 3
17940 || INTVAL (operands[2]) == 5
17941 || INTVAL (operands[2]) == 9)"
17942 [(set (match_dup 0) (match_dup 1))
17944 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
17946 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17950 [(set (match_operand:DI 0 "register_operand" "")
17951 (mult:DI (match_operand:DI 1 "register_operand" "")
17952 (match_operand:DI 2 "const_int_operand" "")))
17953 (clobber (reg:CC FLAGS_REG))])]
17955 && (INTVAL (operands[2]) == 3
17956 || INTVAL (operands[2]) == 5
17957 || INTVAL (operands[2]) == 9)"
17958 [(set (match_dup 0)
17959 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
17961 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17965 [(set (match_operand:DI 0 "register_operand" "")
17966 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17967 (match_operand:DI 2 "const_int_operand" "")))
17968 (clobber (reg:CC FLAGS_REG))])]
17970 && optimize_insn_for_speed_p ()
17971 && (INTVAL (operands[2]) == 3
17972 || INTVAL (operands[2]) == 5
17973 || INTVAL (operands[2]) == 9)"
17974 [(set (match_dup 0) (match_dup 1))
17976 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
17978 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17980 ;; Imul $32bit_imm, mem, reg is vector decoded, while
17981 ;; imul $32bit_imm, reg, reg is direct decoded.
17983 [(match_scratch:DI 3 "r")
17984 (parallel [(set (match_operand:DI 0 "register_operand" "")
17985 (mult:DI (match_operand:DI 1 "memory_operand" "")
17986 (match_operand:DI 2 "immediate_operand" "")))
17987 (clobber (reg:CC FLAGS_REG))])]
17988 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17989 && !satisfies_constraint_K (operands[2])"
17990 [(set (match_dup 3) (match_dup 1))
17991 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
17992 (clobber (reg:CC FLAGS_REG))])]
17996 [(match_scratch:SI 3 "r")
17997 (parallel [(set (match_operand:SI 0 "register_operand" "")
17998 (mult:SI (match_operand:SI 1 "memory_operand" "")
17999 (match_operand:SI 2 "immediate_operand" "")))
18000 (clobber (reg:CC FLAGS_REG))])]
18001 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18002 && !satisfies_constraint_K (operands[2])"
18003 [(set (match_dup 3) (match_dup 1))
18004 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18005 (clobber (reg:CC FLAGS_REG))])]
18009 [(match_scratch:SI 3 "r")
18010 (parallel [(set (match_operand:DI 0 "register_operand" "")
18012 (mult:SI (match_operand:SI 1 "memory_operand" "")
18013 (match_operand:SI 2 "immediate_operand" ""))))
18014 (clobber (reg:CC FLAGS_REG))])]
18015 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18016 && !satisfies_constraint_K (operands[2])"
18017 [(set (match_dup 3) (match_dup 1))
18018 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18019 (clobber (reg:CC FLAGS_REG))])]
18022 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18023 ;; Convert it into imul reg, reg
18024 ;; It would be better to force assembler to encode instruction using long
18025 ;; immediate, but there is apparently no way to do so.
18027 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18028 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18029 (match_operand:DI 2 "const_int_operand" "")))
18030 (clobber (reg:CC FLAGS_REG))])
18031 (match_scratch:DI 3 "r")]
18032 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18033 && satisfies_constraint_K (operands[2])"
18034 [(set (match_dup 3) (match_dup 2))
18035 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18036 (clobber (reg:CC FLAGS_REG))])]
18038 if (!rtx_equal_p (operands[0], operands[1]))
18039 emit_move_insn (operands[0], operands[1]);
18043 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18044 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18045 (match_operand:SI 2 "const_int_operand" "")))
18046 (clobber (reg:CC FLAGS_REG))])
18047 (match_scratch:SI 3 "r")]
18048 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18049 && satisfies_constraint_K (operands[2])"
18050 [(set (match_dup 3) (match_dup 2))
18051 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18052 (clobber (reg:CC FLAGS_REG))])]
18054 if (!rtx_equal_p (operands[0], operands[1]))
18055 emit_move_insn (operands[0], operands[1]);
18059 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18060 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18061 (match_operand:HI 2 "immediate_operand" "")))
18062 (clobber (reg:CC FLAGS_REG))])
18063 (match_scratch:HI 3 "r")]
18064 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
18065 [(set (match_dup 3) (match_dup 2))
18066 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18067 (clobber (reg:CC FLAGS_REG))])]
18069 if (!rtx_equal_p (operands[0], operands[1]))
18070 emit_move_insn (operands[0], operands[1]);
18073 ;; After splitting up read-modify operations, array accesses with memory
18074 ;; operands might end up in form:
18076 ;; movl 4(%esp), %edx
18078 ;; instead of pre-splitting:
18080 ;; addl 4(%esp), %eax
18082 ;; movl 4(%esp), %edx
18083 ;; leal (%edx,%eax,4), %eax
18086 [(parallel [(set (match_operand 0 "register_operand" "")
18087 (ashift (match_operand 1 "register_operand" "")
18088 (match_operand 2 "const_int_operand" "")))
18089 (clobber (reg:CC FLAGS_REG))])
18090 (set (match_operand 3 "register_operand")
18091 (match_operand 4 "x86_64_general_operand" ""))
18092 (parallel [(set (match_operand 5 "register_operand" "")
18093 (plus (match_operand 6 "register_operand" "")
18094 (match_operand 7 "register_operand" "")))
18095 (clobber (reg:CC FLAGS_REG))])]
18096 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
18097 /* Validate MODE for lea. */
18098 && ((!TARGET_PARTIAL_REG_STALL
18099 && (GET_MODE (operands[0]) == QImode
18100 || GET_MODE (operands[0]) == HImode))
18101 || GET_MODE (operands[0]) == SImode
18102 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18103 /* We reorder load and the shift. */
18104 && !rtx_equal_p (operands[1], operands[3])
18105 && !reg_overlap_mentioned_p (operands[0], operands[4])
18106 /* Last PLUS must consist of operand 0 and 3. */
18107 && !rtx_equal_p (operands[0], operands[3])
18108 && (rtx_equal_p (operands[3], operands[6])
18109 || rtx_equal_p (operands[3], operands[7]))
18110 && (rtx_equal_p (operands[0], operands[6])
18111 || rtx_equal_p (operands[0], operands[7]))
18112 /* The intermediate operand 0 must die or be same as output. */
18113 && (rtx_equal_p (operands[0], operands[5])
18114 || peep2_reg_dead_p (3, operands[0]))"
18115 [(set (match_dup 3) (match_dup 4))
18116 (set (match_dup 0) (match_dup 1))]
18118 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
18119 int scale = 1 << INTVAL (operands[2]);
18120 rtx index = gen_lowpart (Pmode, operands[1]);
18121 rtx base = gen_lowpart (Pmode, operands[3]);
18122 rtx dest = gen_lowpart (mode, operands[5]);
18124 operands[1] = gen_rtx_PLUS (Pmode, base,
18125 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
18127 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18128 operands[0] = dest;
18131 ;; Call-value patterns last so that the wildcard operand does not
18132 ;; disrupt insn-recog's switch tables.
18134 (define_insn "*call_value_pop_0"
18135 [(set (match_operand 0 "" "")
18136 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18137 (match_operand:SI 2 "" "")))
18138 (set (reg:SI SP_REG)
18139 (plus:SI (reg:SI SP_REG)
18140 (match_operand:SI 3 "immediate_operand" "")))]
18143 if (SIBLING_CALL_P (insn))
18146 return "call\t%P1";
18148 [(set_attr "type" "callv")])
18150 (define_insn "*call_value_pop_1"
18151 [(set (match_operand 0 "" "")
18152 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18153 (match_operand:SI 2 "" "")))
18154 (set (reg:SI SP_REG)
18155 (plus:SI (reg:SI SP_REG)
18156 (match_operand:SI 3 "immediate_operand" "i")))]
18157 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18159 if (constant_call_address_operand (operands[1], Pmode))
18160 return "call\t%P1";
18161 return "call\t%A1";
18163 [(set_attr "type" "callv")])
18165 (define_insn "*sibcall_value_pop_1"
18166 [(set (match_operand 0 "" "")
18167 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18168 (match_operand:SI 2 "" "")))
18169 (set (reg:SI SP_REG)
18170 (plus:SI (reg:SI SP_REG)
18171 (match_operand:SI 3 "immediate_operand" "i,i")))]
18172 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18176 [(set_attr "type" "callv")])
18178 (define_insn "*call_value_0"
18179 [(set (match_operand 0 "" "")
18180 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18181 (match_operand:SI 2 "" "")))]
18184 if (SIBLING_CALL_P (insn))
18187 return "call\t%P1";
18189 [(set_attr "type" "callv")])
18191 (define_insn "*call_value_0_rex64"
18192 [(set (match_operand 0 "" "")
18193 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18194 (match_operand:DI 2 "const_int_operand" "")))]
18197 if (SIBLING_CALL_P (insn))
18200 return "call\t%P1";
18202 [(set_attr "type" "callv")])
18204 (define_insn "*call_value_0_rex64_ms_sysv"
18205 [(set (match_operand 0 "" "")
18206 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18207 (match_operand:DI 2 "const_int_operand" "")))
18208 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18209 (clobber (reg:TI XMM6_REG))
18210 (clobber (reg:TI XMM7_REG))
18211 (clobber (reg:TI XMM8_REG))
18212 (clobber (reg:TI XMM9_REG))
18213 (clobber (reg:TI XMM10_REG))
18214 (clobber (reg:TI XMM11_REG))
18215 (clobber (reg:TI XMM12_REG))
18216 (clobber (reg:TI XMM13_REG))
18217 (clobber (reg:TI XMM14_REG))
18218 (clobber (reg:TI XMM15_REG))
18219 (clobber (reg:DI SI_REG))
18220 (clobber (reg:DI DI_REG))]
18221 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18223 if (SIBLING_CALL_P (insn))
18226 return "call\t%P1";
18228 [(set_attr "type" "callv")])
18230 (define_insn "*call_value_1"
18231 [(set (match_operand 0 "" "")
18232 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18233 (match_operand:SI 2 "" "")))]
18234 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18236 if (constant_call_address_operand (operands[1], Pmode))
18237 return "call\t%P1";
18238 return "call\t%A1";
18240 [(set_attr "type" "callv")])
18242 (define_insn "*sibcall_value_1"
18243 [(set (match_operand 0 "" "")
18244 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18245 (match_operand:SI 2 "" "")))]
18246 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18250 [(set_attr "type" "callv")])
18252 (define_insn "*call_value_1_rex64"
18253 [(set (match_operand 0 "" "")
18254 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18255 (match_operand:DI 2 "" "")))]
18256 "TARGET_64BIT && !SIBLING_CALL_P (insn)
18257 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
18259 if (constant_call_address_operand (operands[1], Pmode))
18260 return "call\t%P1";
18261 return "call\t%A1";
18263 [(set_attr "type" "callv")])
18265 (define_insn "*call_value_1_rex64_ms_sysv"
18266 [(set (match_operand 0 "" "")
18267 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18268 (match_operand:DI 2 "" "")))
18269 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18270 (clobber (reg:TI XMM6_REG))
18271 (clobber (reg:TI XMM7_REG))
18272 (clobber (reg:TI XMM8_REG))
18273 (clobber (reg:TI XMM9_REG))
18274 (clobber (reg:TI XMM10_REG))
18275 (clobber (reg:TI XMM11_REG))
18276 (clobber (reg:TI XMM12_REG))
18277 (clobber (reg:TI XMM13_REG))
18278 (clobber (reg:TI XMM14_REG))
18279 (clobber (reg:TI XMM15_REG))
18280 (clobber (reg:DI SI_REG))
18281 (clobber (reg:DI DI_REG))]
18282 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18284 if (constant_call_address_operand (operands[1], Pmode))
18285 return "call\t%P1";
18286 return "call\t%A1";
18288 [(set_attr "type" "callv")])
18290 (define_insn "*call_value_1_rex64_large"
18291 [(set (match_operand 0 "" "")
18292 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
18293 (match_operand:DI 2 "" "")))]
18294 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18296 [(set_attr "type" "callv")])
18298 (define_insn "*sibcall_value_1_rex64"
18299 [(set (match_operand 0 "" "")
18300 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
18301 (match_operand:DI 2 "" "")))]
18302 "TARGET_64BIT && SIBLING_CALL_P (insn)"
18306 [(set_attr "type" "callv")])
18308 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18309 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18310 ;; caught for use by garbage collectors and the like. Using an insn that
18311 ;; maps to SIGILL makes it more likely the program will rightfully die.
18312 ;; Keeping with tradition, "6" is in honor of #UD.
18313 (define_insn "trap"
18314 [(trap_if (const_int 1) (const_int 6))]
18316 { return ASM_SHORT "0x0b0f"; }
18317 [(set_attr "length" "2")])
18319 (define_expand "sse_prologue_save"
18320 [(parallel [(set (match_operand:BLK 0 "" "")
18321 (unspec:BLK [(reg:DI XMM0_REG)
18328 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18329 (clobber (match_operand:DI 1 "register_operand" ""))
18330 (use (match_operand:DI 2 "immediate_operand" ""))
18331 (use (label_ref:DI (match_operand 3 "" "")))
18332 (clobber (match_operand:DI 4 "register_operand" ""))
18333 (use (match_dup 1))])]
18337 ;; Pre-reload version of prologue save. Until after prologue generation we don't know
18338 ;; what the size of save instruction will be.
18339 ;; Operand 0+operand 6 is the memory save area
18340 ;; Operand 1 is number of registers to save (will get overwritten to operand 5)
18341 ;; Operand 2 is number of non-vaargs SSE arguments
18342 ;; Operand 3 is label starting the save block
18343 ;; Operand 4 is used for temporary computation of jump address
18344 (define_insn "*sse_prologue_save_insn1"
18345 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18346 (match_operand:DI 6 "const_int_operand" "n")))
18347 (unspec:BLK [(reg:DI XMM0_REG)
18354 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18355 (clobber (match_operand:DI 1 "register_operand" "=r"))
18356 (use (match_operand:DI 2 "const_int_operand" "i"))
18357 (use (label_ref:DI (match_operand 3 "" "X")))
18358 (clobber (match_operand:DI 4 "register_operand" "=&r"))
18359 (use (match_operand:DI 5 "register_operand" "1"))]
18361 && INTVAL (operands[6]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18362 && INTVAL (operands[6]) + INTVAL (operands[2]) * 16 >= -128"
18364 [(set_attr "type" "other")
18365 (set_attr "memory" "store")
18366 (set_attr "mode" "DI")])
18368 ;; We know size of save instruction; expand the computation of jump address
18369 ;; in the jumptable.
18371 [(parallel [(set (match_operand:BLK 0 "" "")
18372 (unspec:BLK [(reg:DI XMM0_REG)
18379 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18380 (clobber (match_operand:DI 1 "register_operand" ""))
18381 (use (match_operand:DI 2 "const_int_operand" ""))
18382 (use (match_operand 3 "" ""))
18383 (clobber (match_operand:DI 4 "register_operand" ""))
18384 (use (match_operand:DI 5 "register_operand" ""))])]
18386 [(parallel [(set (match_dup 0)
18387 (unspec:BLK [(reg:DI XMM0_REG)
18394 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
18395 (use (match_dup 1))
18396 (use (match_dup 2))
18397 (use (match_dup 3))
18398 (use (match_dup 5))])]
18400 /* Movaps is 4 bytes, AVX and movsd is 5 bytes. */
18401 int size = 4 + (TARGET_AVX || crtl->stack_alignment_needed < 128);
18403 /* Compute address to jump to:
18404 label - eax*size + nnamed_sse_arguments*size. */
18406 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
18409 gen_rtx_MULT (Pmode, operands[1],
18412 else if (size == 4)
18413 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
18414 gen_rtx_MULT (Pmode, operands[1],
18417 gcc_unreachable ();
18418 if (INTVAL (operands[2]))
18421 gen_rtx_CONST (DImode,
18422 gen_rtx_PLUS (DImode,
18424 GEN_INT (INTVAL (operands[2])
18427 emit_move_insn (operands[1], operands[3]);
18428 emit_insn (gen_subdi3 (operands[1], operands[1], operands[4]));
18429 operands[5] = GEN_INT (size);
18432 (define_insn "sse_prologue_save_insn"
18433 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18434 (match_operand:DI 4 "const_int_operand" "n")))
18435 (unspec:BLK [(reg:DI XMM0_REG)
18442 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
18443 (use (match_operand:DI 1 "register_operand" "r"))
18444 (use (match_operand:DI 2 "const_int_operand" "i"))
18445 (use (label_ref:DI (match_operand 3 "" "X")))
18446 (use (match_operand:DI 5 "const_int_operand" "i"))]
18448 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18449 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
18452 operands[0] = gen_rtx_MEM (Pmode,
18453 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
18454 /* VEX instruction with a REX prefix will #UD. */
18455 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
18456 gcc_unreachable ();
18458 output_asm_insn ("jmp\t%A1", operands);
18459 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
18461 operands[4] = adjust_address (operands[0], DImode, i*16);
18462 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
18463 PUT_MODE (operands[4], TImode);
18464 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
18465 output_asm_insn ("rex", operands);
18466 if (crtl->stack_alignment_needed < 128)
18467 output_asm_insn ("%vmovsd\t{%5, %4|%4, %5}", operands);
18469 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
18471 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18472 CODE_LABEL_NUMBER (operands[3]));
18475 [(set_attr "type" "other")
18476 (set_attr "length_immediate" "0")
18477 (set_attr "length_address" "0")
18478 ;; 2 bytes for jump and opernds[4] bytes for each save.
18479 (set (attr "length")
18480 (plus (const_int 2)
18481 (mult (symbol_ref ("INTVAL (operands[5])"))
18482 (symbol_ref ("X86_64_SSE_REGPARM_MAX - INTVAL (operands[2])")))))
18483 (set_attr "memory" "store")
18484 (set_attr "modrm" "0")
18485 (set_attr "prefix" "maybe_vex")
18486 (set_attr "mode" "DI")])
18488 (define_expand "prefetch"
18489 [(prefetch (match_operand 0 "address_operand" "")
18490 (match_operand:SI 1 "const_int_operand" "")
18491 (match_operand:SI 2 "const_int_operand" ""))]
18492 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
18494 int rw = INTVAL (operands[1]);
18495 int locality = INTVAL (operands[2]);
18497 gcc_assert (rw == 0 || rw == 1);
18498 gcc_assert (locality >= 0 && locality <= 3);
18499 gcc_assert (GET_MODE (operands[0]) == Pmode
18500 || GET_MODE (operands[0]) == VOIDmode);
18502 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18503 supported by SSE counterpart or the SSE prefetch is not available
18504 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18506 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
18507 operands[2] = GEN_INT (3);
18509 operands[1] = const0_rtx;
18512 (define_insn "*prefetch_sse"
18513 [(prefetch (match_operand:SI 0 "address_operand" "p")
18515 (match_operand:SI 1 "const_int_operand" ""))]
18516 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
18518 static const char * const patterns[4] = {
18519 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18522 int locality = INTVAL (operands[1]);
18523 gcc_assert (locality >= 0 && locality <= 3);
18525 return patterns[locality];
18527 [(set_attr "type" "sse")
18528 (set_attr "atom_sse_attr" "prefetch")
18529 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18530 (set_attr "memory" "none")])
18532 (define_insn "*prefetch_sse_rex"
18533 [(prefetch (match_operand:DI 0 "address_operand" "p")
18535 (match_operand:SI 1 "const_int_operand" ""))]
18536 "TARGET_PREFETCH_SSE && TARGET_64BIT"
18538 static const char * const patterns[4] = {
18539 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18542 int locality = INTVAL (operands[1]);
18543 gcc_assert (locality >= 0 && locality <= 3);
18545 return patterns[locality];
18547 [(set_attr "type" "sse")
18548 (set_attr "atom_sse_attr" "prefetch")
18549 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18550 (set_attr "memory" "none")])
18552 (define_insn "*prefetch_3dnow"
18553 [(prefetch (match_operand:SI 0 "address_operand" "p")
18554 (match_operand:SI 1 "const_int_operand" "n")
18556 "TARGET_3DNOW && !TARGET_64BIT"
18558 if (INTVAL (operands[1]) == 0)
18559 return "prefetch\t%a0";
18561 return "prefetchw\t%a0";
18563 [(set_attr "type" "mmx")
18564 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18565 (set_attr "memory" "none")])
18567 (define_insn "*prefetch_3dnow_rex"
18568 [(prefetch (match_operand:DI 0 "address_operand" "p")
18569 (match_operand:SI 1 "const_int_operand" "n")
18571 "TARGET_3DNOW && TARGET_64BIT"
18573 if (INTVAL (operands[1]) == 0)
18574 return "prefetch\t%a0";
18576 return "prefetchw\t%a0";
18578 [(set_attr "type" "mmx")
18579 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18580 (set_attr "memory" "none")])
18582 (define_expand "stack_protect_set"
18583 [(match_operand 0 "memory_operand" "")
18584 (match_operand 1 "memory_operand" "")]
18587 #ifdef TARGET_THREAD_SSP_OFFSET
18589 emit_insn (gen_stack_tls_protect_set_di (operands[0],
18590 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18592 emit_insn (gen_stack_tls_protect_set_si (operands[0],
18593 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18596 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18598 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18603 (define_insn "stack_protect_set_si"
18604 [(set (match_operand:SI 0 "memory_operand" "=m")
18605 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18606 (set (match_scratch:SI 2 "=&r") (const_int 0))
18607 (clobber (reg:CC FLAGS_REG))]
18609 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18610 [(set_attr "type" "multi")])
18612 (define_insn "stack_protect_set_di"
18613 [(set (match_operand:DI 0 "memory_operand" "=m")
18614 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18615 (set (match_scratch:DI 2 "=&r") (const_int 0))
18616 (clobber (reg:CC FLAGS_REG))]
18618 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18619 [(set_attr "type" "multi")])
18621 (define_insn "stack_tls_protect_set_si"
18622 [(set (match_operand:SI 0 "memory_operand" "=m")
18623 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18624 (set (match_scratch:SI 2 "=&r") (const_int 0))
18625 (clobber (reg:CC FLAGS_REG))]
18627 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18628 [(set_attr "type" "multi")])
18630 (define_insn "stack_tls_protect_set_di"
18631 [(set (match_operand:DI 0 "memory_operand" "=m")
18632 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18633 (set (match_scratch:DI 2 "=&r") (const_int 0))
18634 (clobber (reg:CC FLAGS_REG))]
18637 /* The kernel uses a different segment register for performance reasons; a
18638 system call would not have to trash the userspace segment register,
18639 which would be expensive */
18640 if (ix86_cmodel != CM_KERNEL)
18641 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18643 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18645 [(set_attr "type" "multi")])
18647 (define_expand "stack_protect_test"
18648 [(match_operand 0 "memory_operand" "")
18649 (match_operand 1 "memory_operand" "")
18650 (match_operand 2 "" "")]
18653 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18655 #ifdef TARGET_THREAD_SSP_OFFSET
18657 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18658 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18660 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18661 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18664 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18666 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18669 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18670 flags, const0_rtx, operands[2]));
18674 (define_insn "stack_protect_test_si"
18675 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18676 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18677 (match_operand:SI 2 "memory_operand" "m")]
18679 (clobber (match_scratch:SI 3 "=&r"))]
18681 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18682 [(set_attr "type" "multi")])
18684 (define_insn "stack_protect_test_di"
18685 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18686 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18687 (match_operand:DI 2 "memory_operand" "m")]
18689 (clobber (match_scratch:DI 3 "=&r"))]
18691 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18692 [(set_attr "type" "multi")])
18694 (define_insn "stack_tls_protect_test_si"
18695 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18696 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18697 (match_operand:SI 2 "const_int_operand" "i")]
18698 UNSPEC_SP_TLS_TEST))
18699 (clobber (match_scratch:SI 3 "=r"))]
18701 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18702 [(set_attr "type" "multi")])
18704 (define_insn "stack_tls_protect_test_di"
18705 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18706 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18707 (match_operand:DI 2 "const_int_operand" "i")]
18708 UNSPEC_SP_TLS_TEST))
18709 (clobber (match_scratch:DI 3 "=r"))]
18712 /* The kernel uses a different segment register for performance reasons; a
18713 system call would not have to trash the userspace segment register,
18714 which would be expensive */
18715 if (ix86_cmodel != CM_KERNEL)
18716 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18718 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18720 [(set_attr "type" "multi")])
18722 (define_insn "sse4_2_crc32<mode>"
18723 [(set (match_operand:SI 0 "register_operand" "=r")
18725 [(match_operand:SI 1 "register_operand" "0")
18726 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18728 "TARGET_SSE4_2 || TARGET_CRC32"
18729 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18730 [(set_attr "type" "sselog1")
18731 (set_attr "prefix_rep" "1")
18732 (set_attr "prefix_extra" "1")
18733 (set (attr "prefix_data16")
18734 (if_then_else (match_operand:HI 2 "" "")
18736 (const_string "*")))
18737 (set (attr "prefix_rex")
18738 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18740 (const_string "*")))
18741 (set_attr "mode" "SI")])
18743 (define_insn "sse4_2_crc32di"
18744 [(set (match_operand:DI 0 "register_operand" "=r")
18746 [(match_operand:DI 1 "register_operand" "0")
18747 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18749 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18750 "crc32{q}\t{%2, %0|%0, %2}"
18751 [(set_attr "type" "sselog1")
18752 (set_attr "prefix_rep" "1")
18753 (set_attr "prefix_extra" "1")
18754 (set_attr "mode" "DI")])
18756 (define_expand "rdpmc"
18757 [(match_operand:DI 0 "register_operand" "")
18758 (match_operand:SI 1 "register_operand" "")]
18761 rtx reg = gen_reg_rtx (DImode);
18764 /* Force operand 1 into ECX. */
18765 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18766 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18767 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18772 rtvec vec = rtvec_alloc (2);
18773 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18774 rtx upper = gen_reg_rtx (DImode);
18775 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18776 gen_rtvec (1, const0_rtx),
18778 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18779 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18781 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18782 NULL, 1, OPTAB_DIRECT);
18783 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18787 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18788 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18792 (define_insn "*rdpmc"
18793 [(set (match_operand:DI 0 "register_operand" "=A")
18794 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18798 [(set_attr "type" "other")
18799 (set_attr "length" "2")])
18801 (define_insn "*rdpmc_rex64"
18802 [(set (match_operand:DI 0 "register_operand" "=a")
18803 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18805 (set (match_operand:DI 1 "register_operand" "=d")
18806 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18809 [(set_attr "type" "other")
18810 (set_attr "length" "2")])
18812 (define_expand "rdtsc"
18813 [(set (match_operand:DI 0 "register_operand" "")
18814 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18819 rtvec vec = rtvec_alloc (2);
18820 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18821 rtx upper = gen_reg_rtx (DImode);
18822 rtx lower = gen_reg_rtx (DImode);
18823 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18824 gen_rtvec (1, const0_rtx),
18826 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18827 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18829 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18830 NULL, 1, OPTAB_DIRECT);
18831 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18833 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18838 (define_insn "*rdtsc"
18839 [(set (match_operand:DI 0 "register_operand" "=A")
18840 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18843 [(set_attr "type" "other")
18844 (set_attr "length" "2")])
18846 (define_insn "*rdtsc_rex64"
18847 [(set (match_operand:DI 0 "register_operand" "=a")
18848 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18849 (set (match_operand:DI 1 "register_operand" "=d")
18850 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18853 [(set_attr "type" "other")
18854 (set_attr "length" "2")])
18856 (define_expand "rdtscp"
18857 [(match_operand:DI 0 "register_operand" "")
18858 (match_operand:SI 1 "memory_operand" "")]
18861 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18862 gen_rtvec (1, const0_rtx),
18864 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18865 gen_rtvec (1, const0_rtx),
18867 rtx reg = gen_reg_rtx (DImode);
18868 rtx tmp = gen_reg_rtx (SImode);
18872 rtvec vec = rtvec_alloc (3);
18873 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18874 rtx upper = gen_reg_rtx (DImode);
18875 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18876 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18877 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18879 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18880 NULL, 1, OPTAB_DIRECT);
18881 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18886 rtvec vec = rtvec_alloc (2);
18887 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18888 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18889 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18892 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18893 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18897 (define_insn "*rdtscp"
18898 [(set (match_operand:DI 0 "register_operand" "=A")
18899 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18900 (set (match_operand:SI 1 "register_operand" "=c")
18901 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18904 [(set_attr "type" "other")
18905 (set_attr "length" "3")])
18907 (define_insn "*rdtscp_rex64"
18908 [(set (match_operand:DI 0 "register_operand" "=a")
18909 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18910 (set (match_operand:DI 1 "register_operand" "=d")
18911 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18912 (set (match_operand:SI 2 "register_operand" "=c")
18913 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18916 [(set_attr "type" "other")
18917 (set_attr "length" "3")])
18919 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18921 ;; LWP instructions
18923 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18925 (define_expand "lwp_llwpcb"
18926 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18927 UNSPECV_LLWP_INTRINSIC)]
18931 (define_insn "*lwp_llwpcb<mode>1"
18932 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18933 UNSPECV_LLWP_INTRINSIC)]
18936 [(set_attr "type" "lwp")
18937 (set_attr "mode" "<MODE>")
18938 (set_attr "length" "5")])
18940 (define_expand "lwp_slwpcb"
18941 [(set (match_operand 0 "register_operand" "=r")
18942 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18946 emit_insn (gen_lwp_slwpcbdi (operands[0]));
18948 emit_insn (gen_lwp_slwpcbsi (operands[0]));
18952 (define_insn "lwp_slwpcb<mode>"
18953 [(set (match_operand:P 0 "register_operand" "=r")
18954 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18957 [(set_attr "type" "lwp")
18958 (set_attr "mode" "<MODE>")
18959 (set_attr "length" "5")])
18961 (define_expand "lwp_lwpval<mode>3"
18962 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18963 (match_operand:SI 2 "nonimmediate_operand" "rm")
18964 (match_operand:SI 3 "const_int_operand" "i")]
18965 UNSPECV_LWPVAL_INTRINSIC)]
18967 "/* Avoid unused variable warning. */
18970 (define_insn "*lwp_lwpval<mode>3_1"
18971 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18972 (match_operand:SI 1 "nonimmediate_operand" "rm")
18973 (match_operand:SI 2 "const_int_operand" "i")]
18974 UNSPECV_LWPVAL_INTRINSIC)]
18976 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18977 [(set_attr "type" "lwp")
18978 (set_attr "mode" "<MODE>")
18979 (set (attr "length")
18980 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18982 (define_expand "lwp_lwpins<mode>3"
18983 [(set (reg:CCC FLAGS_REG)
18984 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18985 (match_operand:SI 2 "nonimmediate_operand" "rm")
18986 (match_operand:SI 3 "const_int_operand" "i")]
18987 UNSPECV_LWPINS_INTRINSIC))
18988 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18989 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18993 (define_insn "*lwp_lwpins<mode>3_1"
18994 [(set (reg:CCC FLAGS_REG)
18995 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18996 (match_operand:SI 1 "nonimmediate_operand" "rm")
18997 (match_operand:SI 2 "const_int_operand" "i")]
18998 UNSPECV_LWPINS_INTRINSIC))]
19000 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19001 [(set_attr "type" "lwp")
19002 (set_attr "mode" "<MODE>")
19003 (set (attr "length")
19004 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19008 (include "sync.md")