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,
346 generic64,amdfam10,bdver1"
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 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3117 return "%vxorps\t%0, %d0";
3119 return "%vxorpd\t%0, %d0";
3121 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3122 return "%vxorps\t%0, %d0";
3124 return "%vpxor\t%0, %d0";
3131 switch (get_attr_mode (insn))
3134 return "%vmovaps\t{%1, %0|%0, %1}";
3136 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3137 return "%vmovaps\t{%1, %0|%0, %1}";
3139 return "%vmovapd\t{%1, %0|%0, %1}";
3141 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3142 return "%vmovaps\t{%1, %0|%0, %1}";
3144 return "%vmovdqa\t{%1, %0|%0, %1}";
3146 return "%vmovq\t{%1, %0|%0, %1}";
3150 if (REG_P (operands[0]) && REG_P (operands[1]))
3151 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3153 return "vmovsd\t{%1, %0|%0, %1}";
3156 return "movsd\t{%1, %0|%0, %1}";
3160 if (REG_P (operands[0]))
3161 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3163 return "vmovlpd\t{%1, %0|%0, %1}";
3166 return "movlpd\t{%1, %0|%0, %1}";
3170 if (REG_P (operands[0]))
3171 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3173 return "vmovlps\t{%1, %0|%0, %1}";
3176 return "movlps\t{%1, %0|%0, %1}";
3185 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3186 (set (attr "prefix")
3187 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3188 (const_string "orig")
3189 (const_string "maybe_vex")))
3190 (set (attr "prefix_data16")
3191 (if_then_else (eq_attr "mode" "V1DF")
3193 (const_string "*")))
3195 (cond [(eq_attr "alternative" "0,1,2")
3197 (eq_attr "alternative" "3,4")
3200 /* For SSE1, we have many fewer alternatives. */
3201 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3202 (cond [(eq_attr "alternative" "5,6")
3203 (const_string "V4SF")
3205 (const_string "V2SF"))
3207 /* xorps is one byte shorter. */
3208 (eq_attr "alternative" "5")
3209 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3211 (const_string "V4SF")
3212 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3216 (const_string "V2DF"))
3218 /* For architectures resolving dependencies on
3219 whole SSE registers use APD move to break dependency
3220 chains, otherwise use short move to avoid extra work.
3222 movaps encodes one byte shorter. */
3223 (eq_attr "alternative" "6")
3225 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3227 (const_string "V4SF")
3228 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3230 (const_string "V2DF")
3232 (const_string "DF"))
3233 /* For architectures resolving dependencies on register
3234 parts we may avoid extra work to zero out upper part
3236 (eq_attr "alternative" "7")
3238 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3240 (const_string "V1DF")
3241 (const_string "DF"))
3243 (const_string "DF")))])
3245 (define_insn "*movdf_integer_rex64"
3246 [(set (match_operand:DF 0 "nonimmediate_operand"
3247 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3248 (match_operand:DF 1 "general_operand"
3249 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3250 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3251 && (reload_in_progress || reload_completed
3252 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3253 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3254 && optimize_function_for_size_p (cfun)
3255 && standard_80387_constant_p (operands[1]))
3256 || GET_CODE (operands[1]) != CONST_DOUBLE
3257 || memory_operand (operands[0], DFmode))"
3259 switch (which_alternative)
3263 return output_387_reg_move (insn, operands);
3266 return standard_80387_constant_opcode (operands[1]);
3273 switch (get_attr_mode (insn))
3276 return "%vxorps\t%0, %d0";
3278 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3279 return "%vxorps\t%0, %d0";
3281 return "%vxorpd\t%0, %d0";
3283 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3284 return "%vxorps\t%0, %d0";
3286 return "%vpxor\t%0, %d0";
3293 switch (get_attr_mode (insn))
3296 return "%vmovaps\t{%1, %0|%0, %1}";
3298 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3299 return "%vmovaps\t{%1, %0|%0, %1}";
3301 return "%vmovapd\t{%1, %0|%0, %1}";
3303 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3304 return "%vmovaps\t{%1, %0|%0, %1}";
3306 return "%vmovdqa\t{%1, %0|%0, %1}";
3308 return "%vmovq\t{%1, %0|%0, %1}";
3312 if (REG_P (operands[0]) && REG_P (operands[1]))
3313 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3315 return "vmovsd\t{%1, %0|%0, %1}";
3318 return "movsd\t{%1, %0|%0, %1}";
3320 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3322 return "%vmovlps\t{%1, %d0|%d0, %1}";
3329 return "%vmovd\t{%1, %0|%0, %1}";
3335 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3336 (set (attr "prefix")
3337 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3338 (const_string "orig")
3339 (const_string "maybe_vex")))
3340 (set (attr "prefix_data16")
3341 (if_then_else (eq_attr "mode" "V1DF")
3343 (const_string "*")))
3345 (cond [(eq_attr "alternative" "0,1,2")
3347 (eq_attr "alternative" "3,4,9,10")
3350 /* For SSE1, we have many fewer alternatives. */
3351 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3352 (cond [(eq_attr "alternative" "5,6")
3353 (const_string "V4SF")
3355 (const_string "V2SF"))
3357 /* xorps is one byte shorter. */
3358 (eq_attr "alternative" "5")
3359 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3361 (const_string "V4SF")
3362 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3366 (const_string "V2DF"))
3368 /* For architectures resolving dependencies on
3369 whole SSE registers use APD move to break dependency
3370 chains, otherwise use short move to avoid extra work.
3372 movaps encodes one byte shorter. */
3373 (eq_attr "alternative" "6")
3375 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3377 (const_string "V4SF")
3378 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3380 (const_string "V2DF")
3382 (const_string "DF"))
3383 /* For architectures resolving dependencies on register
3384 parts we may avoid extra work to zero out upper part
3386 (eq_attr "alternative" "7")
3388 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3390 (const_string "V1DF")
3391 (const_string "DF"))
3393 (const_string "DF")))])
3395 (define_insn "*movdf_integer"
3396 [(set (match_operand:DF 0 "nonimmediate_operand"
3397 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3398 (match_operand:DF 1 "general_operand"
3399 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3400 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3401 && optimize_function_for_speed_p (cfun)
3402 && TARGET_INTEGER_DFMODE_MOVES
3403 && (reload_in_progress || reload_completed
3404 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3405 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3406 && optimize_function_for_size_p (cfun)
3407 && standard_80387_constant_p (operands[1]))
3408 || GET_CODE (operands[1]) != CONST_DOUBLE
3409 || memory_operand (operands[0], DFmode))"
3411 switch (which_alternative)
3415 return output_387_reg_move (insn, operands);
3418 return standard_80387_constant_opcode (operands[1]);
3425 switch (get_attr_mode (insn))
3428 return "xorps\t%0, %0";
3430 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3431 return "xorps\t%0, %0";
3433 return "xorpd\t%0, %0";
3435 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3436 return "xorps\t%0, %0";
3438 return "pxor\t%0, %0";
3445 switch (get_attr_mode (insn))
3448 return "movaps\t{%1, %0|%0, %1}";
3450 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3451 return "movaps\t{%1, %0|%0, %1}";
3453 return "movapd\t{%1, %0|%0, %1}";
3455 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3456 return "movaps\t{%1, %0|%0, %1}";
3458 return "movdqa\t{%1, %0|%0, %1}";
3460 return "movq\t{%1, %0|%0, %1}";
3462 return "movsd\t{%1, %0|%0, %1}";
3464 return "movlpd\t{%1, %0|%0, %1}";
3466 return "movlps\t{%1, %0|%0, %1}";
3475 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3476 (set (attr "prefix_data16")
3477 (if_then_else (eq_attr "mode" "V1DF")
3479 (const_string "*")))
3481 (cond [(eq_attr "alternative" "0,1,2")
3483 (eq_attr "alternative" "3,4")
3486 /* For SSE1, we have many fewer alternatives. */
3487 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3488 (cond [(eq_attr "alternative" "5,6")
3489 (const_string "V4SF")
3491 (const_string "V2SF"))
3493 /* xorps is one byte shorter. */
3494 (eq_attr "alternative" "5")
3495 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3497 (const_string "V4SF")
3498 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3502 (const_string "V2DF"))
3504 /* For architectures resolving dependencies on
3505 whole SSE registers use APD move to break dependency
3506 chains, otherwise use short move to avoid extra work.
3508 movaps encodes one byte shorter. */
3509 (eq_attr "alternative" "6")
3511 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3513 (const_string "V4SF")
3514 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3516 (const_string "V2DF")
3518 (const_string "DF"))
3519 /* For architectures resolving dependencies on register
3520 parts we may avoid extra work to zero out upper part
3522 (eq_attr "alternative" "7")
3524 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3526 (const_string "V1DF")
3527 (const_string "DF"))
3529 (const_string "DF")))])
3532 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3533 (match_operand:DF 1 "general_operand" ""))]
3535 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3536 && ! (ANY_FP_REG_P (operands[0]) ||
3537 (GET_CODE (operands[0]) == SUBREG
3538 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3539 && ! (ANY_FP_REG_P (operands[1]) ||
3540 (GET_CODE (operands[1]) == SUBREG
3541 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3543 "ix86_split_long_move (operands); DONE;")
3545 (define_insn "*swapdf"
3546 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3547 (match_operand:DF 1 "fp_register_operand" "+f"))
3550 "reload_completed || TARGET_80387"
3552 if (STACK_TOP_P (operands[0]))
3557 [(set_attr "type" "fxch")
3558 (set_attr "mode" "DF")])
3560 (define_expand "movxf"
3561 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3562 (match_operand:XF 1 "general_operand" ""))]
3564 "ix86_expand_move (XFmode, operands); DONE;")
3566 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3567 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3568 ;; Pushing using integer instructions is longer except for constants
3569 ;; and direct memory references.
3570 ;; (assuming that any given constant is pushed only once, but this ought to be
3571 ;; handled elsewhere).
3573 (define_insn "*pushxf_nointeger"
3574 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3575 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3576 "optimize_function_for_size_p (cfun)"
3578 /* This insn should be already split before reg-stack. */
3581 [(set_attr "type" "multi")
3582 (set_attr "unit" "i387,*,*")
3583 (set_attr "mode" "XF,SI,SI")])
3585 (define_insn "*pushxf_integer"
3586 [(set (match_operand:XF 0 "push_operand" "=<,<")
3587 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3588 "optimize_function_for_speed_p (cfun)"
3590 /* This insn should be already split before reg-stack. */
3593 [(set_attr "type" "multi")
3594 (set_attr "unit" "i387,*")
3595 (set_attr "mode" "XF,SI")])
3598 [(set (match_operand 0 "push_operand" "")
3599 (match_operand 1 "general_operand" ""))]
3601 && (GET_MODE (operands[0]) == XFmode
3602 || GET_MODE (operands[0]) == DFmode)
3603 && !ANY_FP_REG_P (operands[1])"
3605 "ix86_split_long_move (operands); DONE;")
3608 [(set (match_operand:XF 0 "push_operand" "")
3609 (match_operand:XF 1 "any_fp_register_operand" ""))]
3611 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3612 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3613 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3615 ;; Do not use integer registers when optimizing for size
3616 (define_insn "*movxf_nointeger"
3617 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3618 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3619 "optimize_function_for_size_p (cfun)
3620 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3621 && (reload_in_progress || reload_completed
3622 || standard_80387_constant_p (operands[1])
3623 || GET_CODE (operands[1]) != CONST_DOUBLE
3624 || memory_operand (operands[0], XFmode))"
3626 switch (which_alternative)
3630 return output_387_reg_move (insn, operands);
3633 return standard_80387_constant_opcode (operands[1]);
3641 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3642 (set_attr "mode" "XF,XF,XF,SI,SI")])
3644 (define_insn "*movxf_integer"
3645 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3646 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3647 "optimize_function_for_speed_p (cfun)
3648 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3649 && (reload_in_progress || reload_completed
3650 || GET_CODE (operands[1]) != CONST_DOUBLE
3651 || memory_operand (operands[0], XFmode))"
3653 switch (which_alternative)
3657 return output_387_reg_move (insn, operands);
3660 return standard_80387_constant_opcode (operands[1]);
3669 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3670 (set_attr "mode" "XF,XF,XF,SI,SI")])
3672 (define_expand "movtf"
3673 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3674 (match_operand:TF 1 "nonimmediate_operand" ""))]
3677 ix86_expand_move (TFmode, operands);
3681 (define_insn "*movtf_internal"
3682 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3683 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3685 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3687 switch (which_alternative)
3691 if (get_attr_mode (insn) == MODE_V4SF)
3692 return "%vmovaps\t{%1, %0|%0, %1}";
3694 return "%vmovdqa\t{%1, %0|%0, %1}";
3696 if (get_attr_mode (insn) == MODE_V4SF)
3697 return "%vxorps\t%0, %d0";
3699 return "%vpxor\t%0, %d0";
3707 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3708 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3710 (cond [(eq_attr "alternative" "0,2")
3712 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3714 (const_string "V4SF")
3715 (const_string "TI"))
3716 (eq_attr "alternative" "1")
3718 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3720 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3722 (const_string "V4SF")
3723 (const_string "TI"))]
3724 (const_string "DI")))])
3726 (define_insn "*pushtf_sse"
3727 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3728 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3731 /* This insn should be already split before reg-stack. */
3734 [(set_attr "type" "multi")
3735 (set_attr "unit" "sse,*,*")
3736 (set_attr "mode" "TF,SI,SI")])
3739 [(set (match_operand:TF 0 "push_operand" "")
3740 (match_operand:TF 1 "general_operand" ""))]
3741 "TARGET_SSE2 && reload_completed
3742 && !SSE_REG_P (operands[1])"
3744 "ix86_split_long_move (operands); DONE;")
3747 [(set (match_operand:TF 0 "push_operand" "")
3748 (match_operand:TF 1 "any_fp_register_operand" ""))]
3750 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3751 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3755 [(set (match_operand 0 "nonimmediate_operand" "")
3756 (match_operand 1 "general_operand" ""))]
3758 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3759 && GET_MODE (operands[0]) == XFmode
3760 && ! (ANY_FP_REG_P (operands[0]) ||
3761 (GET_CODE (operands[0]) == SUBREG
3762 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3763 && ! (ANY_FP_REG_P (operands[1]) ||
3764 (GET_CODE (operands[1]) == SUBREG
3765 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3767 "ix86_split_long_move (operands); DONE;")
3770 [(set (match_operand 0 "register_operand" "")
3771 (match_operand 1 "memory_operand" ""))]
3773 && MEM_P (operands[1])
3774 && (GET_MODE (operands[0]) == TFmode
3775 || GET_MODE (operands[0]) == XFmode
3776 || GET_MODE (operands[0]) == SFmode
3777 || GET_MODE (operands[0]) == DFmode)
3778 && (operands[2] = find_constant_src (insn))"
3779 [(set (match_dup 0) (match_dup 2))]
3781 rtx c = operands[2];
3782 rtx r = operands[0];
3784 if (GET_CODE (r) == SUBREG)
3789 if (!standard_sse_constant_p (c))
3792 else if (FP_REG_P (r))
3794 if (!standard_80387_constant_p (c))
3797 else if (MMX_REG_P (r))
3802 [(set (match_operand 0 "register_operand" "")
3803 (float_extend (match_operand 1 "memory_operand" "")))]
3805 && MEM_P (operands[1])
3806 && (GET_MODE (operands[0]) == TFmode
3807 || GET_MODE (operands[0]) == XFmode
3808 || GET_MODE (operands[0]) == SFmode
3809 || GET_MODE (operands[0]) == DFmode)
3810 && (operands[2] = find_constant_src (insn))"
3811 [(set (match_dup 0) (match_dup 2))]
3813 rtx c = operands[2];
3814 rtx r = operands[0];
3816 if (GET_CODE (r) == SUBREG)
3821 if (!standard_sse_constant_p (c))
3824 else if (FP_REG_P (r))
3826 if (!standard_80387_constant_p (c))
3829 else if (MMX_REG_P (r))
3833 (define_insn "swapxf"
3834 [(set (match_operand:XF 0 "register_operand" "+f")
3835 (match_operand:XF 1 "register_operand" "+f"))
3840 if (STACK_TOP_P (operands[0]))
3845 [(set_attr "type" "fxch")
3846 (set_attr "mode" "XF")])
3848 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3850 [(set (match_operand:X87MODEF 0 "register_operand" "")
3851 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3852 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3853 && (standard_80387_constant_p (operands[1]) == 8
3854 || standard_80387_constant_p (operands[1]) == 9)"
3855 [(set (match_dup 0)(match_dup 1))
3857 (neg:X87MODEF (match_dup 0)))]
3861 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3862 if (real_isnegzero (&r))
3863 operands[1] = CONST0_RTX (<MODE>mode);
3865 operands[1] = CONST1_RTX (<MODE>mode);
3869 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3870 (match_operand:TF 1 "general_operand" ""))]
3872 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3874 "ix86_split_long_move (operands); DONE;")
3876 ;; Zero extension instructions
3878 (define_expand "zero_extendhisi2"
3879 [(set (match_operand:SI 0 "register_operand" "")
3880 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3883 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3885 operands[1] = force_reg (HImode, operands[1]);
3886 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3891 (define_insn "zero_extendhisi2_and"
3892 [(set (match_operand:SI 0 "register_operand" "=r")
3893 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
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" "SI")])
3901 [(set (match_operand:SI 0 "register_operand" "")
3902 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3903 (clobber (reg:CC FLAGS_REG))]
3904 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3905 && optimize_function_for_speed_p (cfun)"
3906 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3907 (clobber (reg:CC FLAGS_REG))])]
3910 (define_insn "*zero_extendhisi2_movzwl"
3911 [(set (match_operand:SI 0 "register_operand" "=r")
3912 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3913 "!TARGET_ZERO_EXTEND_WITH_AND
3914 || optimize_function_for_size_p (cfun)"
3915 "movz{wl|x}\t{%1, %0|%0, %1}"
3916 [(set_attr "type" "imovx")
3917 (set_attr "mode" "SI")])
3919 (define_expand "zero_extendqihi2"
3921 [(set (match_operand:HI 0 "register_operand" "")
3922 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3923 (clobber (reg:CC FLAGS_REG))])]
3927 (define_insn "*zero_extendqihi2_and"
3928 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3929 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3930 (clobber (reg:CC FLAGS_REG))]
3931 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3933 [(set_attr "type" "alu1")
3934 (set_attr "mode" "HI")])
3936 (define_insn "*zero_extendqihi2_movzbw_and"
3937 [(set (match_operand:HI 0 "register_operand" "=r,r")
3938 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3939 (clobber (reg:CC FLAGS_REG))]
3940 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3942 [(set_attr "type" "imovx,alu1")
3943 (set_attr "mode" "HI")])
3945 ; zero extend to SImode here to avoid partial register stalls
3946 (define_insn "*zero_extendqihi2_movzbl"
3947 [(set (match_operand:HI 0 "register_operand" "=r")
3948 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3949 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3950 && reload_completed"
3951 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3952 [(set_attr "type" "imovx")
3953 (set_attr "mode" "SI")])
3955 ;; For the movzbw case strip only the clobber
3957 [(set (match_operand:HI 0 "register_operand" "")
3958 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3959 (clobber (reg:CC FLAGS_REG))]
3961 && (!TARGET_ZERO_EXTEND_WITH_AND
3962 || optimize_function_for_size_p (cfun))
3963 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3964 [(set (match_operand:HI 0 "register_operand" "")
3965 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3967 ;; When source and destination does not overlap, clear destination
3968 ;; first and then do the movb
3970 [(set (match_operand:HI 0 "register_operand" "")
3971 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3972 (clobber (reg:CC FLAGS_REG))]
3974 && ANY_QI_REG_P (operands[0])
3975 && (TARGET_ZERO_EXTEND_WITH_AND
3976 && optimize_function_for_speed_p (cfun))
3977 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3978 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3980 operands[2] = gen_lowpart (QImode, operands[0]);
3981 ix86_expand_clear (operands[0]);
3984 ;; Rest is handled by single and.
3986 [(set (match_operand:HI 0 "register_operand" "")
3987 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3988 (clobber (reg:CC FLAGS_REG))]
3990 && true_regnum (operands[0]) == true_regnum (operands[1])"
3991 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3992 (clobber (reg:CC FLAGS_REG))])]
3995 (define_expand "zero_extendqisi2"
3997 [(set (match_operand:SI 0 "register_operand" "")
3998 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3999 (clobber (reg:CC FLAGS_REG))])]
4003 (define_insn "*zero_extendqisi2_and"
4004 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
4005 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4006 (clobber (reg:CC FLAGS_REG))]
4007 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4009 [(set_attr "type" "alu1")
4010 (set_attr "mode" "SI")])
4012 (define_insn "*zero_extendqisi2_movzbl_and"
4013 [(set (match_operand:SI 0 "register_operand" "=r,r")
4014 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4015 (clobber (reg:CC FLAGS_REG))]
4016 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4018 [(set_attr "type" "imovx,alu1")
4019 (set_attr "mode" "SI")])
4021 (define_insn "*zero_extendqisi2_movzbl"
4022 [(set (match_operand:SI 0 "register_operand" "=r")
4023 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4024 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4025 && reload_completed"
4026 "movz{bl|x}\t{%1, %0|%0, %1}"
4027 [(set_attr "type" "imovx")
4028 (set_attr "mode" "SI")])
4030 ;; For the movzbl case strip only the clobber
4032 [(set (match_operand:SI 0 "register_operand" "")
4033 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4034 (clobber (reg:CC FLAGS_REG))]
4036 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4037 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4039 (zero_extend:SI (match_dup 1)))])
4041 ;; When source and destination does not overlap, clear destination
4042 ;; first and then do the movb
4044 [(set (match_operand:SI 0 "register_operand" "")
4045 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4046 (clobber (reg:CC FLAGS_REG))]
4048 && ANY_QI_REG_P (operands[0])
4049 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4050 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4051 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4052 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
4054 operands[2] = gen_lowpart (QImode, operands[0]);
4055 ix86_expand_clear (operands[0]);
4058 ;; Rest is handled by single and.
4060 [(set (match_operand:SI 0 "register_operand" "")
4061 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4062 (clobber (reg:CC FLAGS_REG))]
4064 && true_regnum (operands[0]) == true_regnum (operands[1])"
4065 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4066 (clobber (reg:CC FLAGS_REG))])]
4069 ;; %%% Kill me once multi-word ops are sane.
4070 (define_expand "zero_extendsidi2"
4071 [(set (match_operand:DI 0 "register_operand" "")
4072 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4077 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4082 (define_insn "zero_extendsidi2_32"
4083 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4085 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
4086 (clobber (reg:CC FLAGS_REG))]
4092 movd\t{%1, %0|%0, %1}
4093 movd\t{%1, %0|%0, %1}
4094 %vmovd\t{%1, %0|%0, %1}
4095 %vmovd\t{%1, %0|%0, %1}"
4096 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4097 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4098 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4100 (define_insn "zero_extendsidi2_rex64"
4101 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4103 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4106 mov\t{%k1, %k0|%k0, %k1}
4108 movd\t{%1, %0|%0, %1}
4109 movd\t{%1, %0|%0, %1}
4110 %vmovd\t{%1, %0|%0, %1}
4111 %vmovd\t{%1, %0|%0, %1}"
4112 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4113 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4114 (set_attr "prefix_0f" "0,*,*,*,*,*")
4115 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4118 [(set (match_operand:DI 0 "memory_operand" "")
4119 (zero_extend:DI (match_dup 0)))]
4121 [(set (match_dup 4) (const_int 0))]
4122 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4125 [(set (match_operand:DI 0 "register_operand" "")
4126 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4127 (clobber (reg:CC FLAGS_REG))]
4128 "!TARGET_64BIT && reload_completed
4129 && true_regnum (operands[0]) == true_regnum (operands[1])"
4130 [(set (match_dup 4) (const_int 0))]
4131 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4134 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4135 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4136 (clobber (reg:CC FLAGS_REG))]
4137 "!TARGET_64BIT && reload_completed
4138 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4139 [(set (match_dup 3) (match_dup 1))
4140 (set (match_dup 4) (const_int 0))]
4141 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4143 (define_insn "zero_extendhidi2"
4144 [(set (match_operand:DI 0 "register_operand" "=r")
4145 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4147 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4148 [(set_attr "type" "imovx")
4149 (set_attr "mode" "SI")])
4151 (define_insn "zero_extendqidi2"
4152 [(set (match_operand:DI 0 "register_operand" "=r")
4153 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4155 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4156 [(set_attr "type" "imovx")
4157 (set_attr "mode" "SI")])
4159 ;; Sign extension instructions
4161 (define_expand "extendsidi2"
4162 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4163 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4164 (clobber (reg:CC FLAGS_REG))
4165 (clobber (match_scratch:SI 2 ""))])]
4170 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4175 (define_insn "*extendsidi2_1"
4176 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4177 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4178 (clobber (reg:CC FLAGS_REG))
4179 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4183 (define_insn "extendsidi2_rex64"
4184 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4185 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4189 movs{lq|x}\t{%1, %0|%0, %1}"
4190 [(set_attr "type" "imovx")
4191 (set_attr "mode" "DI")
4192 (set_attr "prefix_0f" "0")
4193 (set_attr "modrm" "0,1")])
4195 (define_insn "extendhidi2"
4196 [(set (match_operand:DI 0 "register_operand" "=r")
4197 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4199 "movs{wq|x}\t{%1, %0|%0, %1}"
4200 [(set_attr "type" "imovx")
4201 (set_attr "mode" "DI")])
4203 (define_insn "extendqidi2"
4204 [(set (match_operand:DI 0 "register_operand" "=r")
4205 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4207 "movs{bq|x}\t{%1, %0|%0, %1}"
4208 [(set_attr "type" "imovx")
4209 (set_attr "mode" "DI")])
4211 ;; Extend to memory case when source register does die.
4213 [(set (match_operand:DI 0 "memory_operand" "")
4214 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4215 (clobber (reg:CC FLAGS_REG))
4216 (clobber (match_operand:SI 2 "register_operand" ""))]
4218 && dead_or_set_p (insn, operands[1])
4219 && !reg_mentioned_p (operands[1], operands[0]))"
4220 [(set (match_dup 3) (match_dup 1))
4221 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4222 (clobber (reg:CC FLAGS_REG))])
4223 (set (match_dup 4) (match_dup 1))]
4224 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4226 ;; Extend to memory case when source register does not die.
4228 [(set (match_operand:DI 0 "memory_operand" "")
4229 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4230 (clobber (reg:CC FLAGS_REG))
4231 (clobber (match_operand:SI 2 "register_operand" ""))]
4235 split_di (&operands[0], 1, &operands[3], &operands[4]);
4237 emit_move_insn (operands[3], operands[1]);
4239 /* Generate a cltd if possible and doing so it profitable. */
4240 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4241 && true_regnum (operands[1]) == AX_REG
4242 && true_regnum (operands[2]) == DX_REG)
4244 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4248 emit_move_insn (operands[2], operands[1]);
4249 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4251 emit_move_insn (operands[4], operands[2]);
4255 ;; Extend to register case. Optimize case where source and destination
4256 ;; registers match and cases where we can use cltd.
4258 [(set (match_operand:DI 0 "register_operand" "")
4259 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4260 (clobber (reg:CC FLAGS_REG))
4261 (clobber (match_scratch:SI 2 ""))]
4265 split_di (&operands[0], 1, &operands[3], &operands[4]);
4267 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4268 emit_move_insn (operands[3], operands[1]);
4270 /* Generate a cltd if possible and doing so it profitable. */
4271 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4272 && true_regnum (operands[3]) == AX_REG
4273 && true_regnum (operands[4]) == DX_REG)
4275 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4279 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4280 emit_move_insn (operands[4], operands[1]);
4282 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4286 (define_insn "extendhisi2"
4287 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4288 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4291 switch (get_attr_prefix_0f (insn))
4294 return "{cwtl|cwde}";
4296 return "movs{wl|x}\t{%1, %0|%0, %1}";
4299 [(set_attr "type" "imovx")
4300 (set_attr "mode" "SI")
4301 (set (attr "prefix_0f")
4302 ;; movsx is short decodable while cwtl is vector decoded.
4303 (if_then_else (and (eq_attr "cpu" "!k6")
4304 (eq_attr "alternative" "0"))
4306 (const_string "1")))
4308 (if_then_else (eq_attr "prefix_0f" "0")
4310 (const_string "1")))])
4312 (define_insn "*extendhisi2_zext"
4313 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4315 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4318 switch (get_attr_prefix_0f (insn))
4321 return "{cwtl|cwde}";
4323 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4326 [(set_attr "type" "imovx")
4327 (set_attr "mode" "SI")
4328 (set (attr "prefix_0f")
4329 ;; movsx is short decodable while cwtl is vector decoded.
4330 (if_then_else (and (eq_attr "cpu" "!k6")
4331 (eq_attr "alternative" "0"))
4333 (const_string "1")))
4335 (if_then_else (eq_attr "prefix_0f" "0")
4337 (const_string "1")))])
4339 (define_insn "extendqihi2"
4340 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4341 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4344 switch (get_attr_prefix_0f (insn))
4347 return "{cbtw|cbw}";
4349 return "movs{bw|x}\t{%1, %0|%0, %1}";
4352 [(set_attr "type" "imovx")
4353 (set_attr "mode" "HI")
4354 (set (attr "prefix_0f")
4355 ;; movsx is short decodable while cwtl is vector decoded.
4356 (if_then_else (and (eq_attr "cpu" "!k6")
4357 (eq_attr "alternative" "0"))
4359 (const_string "1")))
4361 (if_then_else (eq_attr "prefix_0f" "0")
4363 (const_string "1")))])
4365 (define_insn "extendqisi2"
4366 [(set (match_operand:SI 0 "register_operand" "=r")
4367 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4369 "movs{bl|x}\t{%1, %0|%0, %1}"
4370 [(set_attr "type" "imovx")
4371 (set_attr "mode" "SI")])
4373 (define_insn "*extendqisi2_zext"
4374 [(set (match_operand:DI 0 "register_operand" "=r")
4376 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4378 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4379 [(set_attr "type" "imovx")
4380 (set_attr "mode" "SI")])
4382 ;; Conversions between float and double.
4384 ;; These are all no-ops in the model used for the 80387. So just
4387 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4388 (define_insn "*dummy_extendsfdf2"
4389 [(set (match_operand:DF 0 "push_operand" "=<")
4390 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4395 [(set (match_operand:DF 0 "push_operand" "")
4396 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4398 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4399 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4401 (define_insn "*dummy_extendsfxf2"
4402 [(set (match_operand:XF 0 "push_operand" "=<")
4403 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4408 [(set (match_operand:XF 0 "push_operand" "")
4409 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4411 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4412 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4413 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4416 [(set (match_operand:XF 0 "push_operand" "")
4417 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4419 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4420 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4421 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4423 (define_expand "extendsfdf2"
4424 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4425 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4426 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4428 /* ??? Needed for compress_float_constant since all fp constants
4429 are LEGITIMATE_CONSTANT_P. */
4430 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4432 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4433 && standard_80387_constant_p (operands[1]) > 0)
4435 operands[1] = simplify_const_unary_operation
4436 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4437 emit_move_insn_1 (operands[0], operands[1]);
4440 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4444 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4446 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4448 We do the conversion post reload to avoid producing of 128bit spills
4449 that might lead to ICE on 32bit target. The sequence unlikely combine
4452 [(set (match_operand:DF 0 "register_operand" "")
4454 (match_operand:SF 1 "nonimmediate_operand" "")))]
4455 "TARGET_USE_VECTOR_FP_CONVERTS
4456 && optimize_insn_for_speed_p ()
4457 && reload_completed && SSE_REG_P (operands[0])"
4462 (parallel [(const_int 0) (const_int 1)]))))]
4464 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4465 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4466 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4467 Try to avoid move when unpacking can be done in source. */
4468 if (REG_P (operands[1]))
4470 /* If it is unsafe to overwrite upper half of source, we need
4471 to move to destination and unpack there. */
4472 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4473 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4474 && true_regnum (operands[0]) != true_regnum (operands[1]))
4476 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4477 emit_move_insn (tmp, operands[1]);
4480 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4481 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4485 emit_insn (gen_vec_setv4sf_0 (operands[3],
4486 CONST0_RTX (V4SFmode), operands[1]));
4489 (define_insn "*extendsfdf2_mixed"
4490 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4492 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4493 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4495 switch (which_alternative)
4499 return output_387_reg_move (insn, operands);
4502 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4508 [(set_attr "type" "fmov,fmov,ssecvt")
4509 (set_attr "prefix" "orig,orig,maybe_vex")
4510 (set_attr "mode" "SF,XF,DF")])
4512 (define_insn "*extendsfdf2_sse"
4513 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4514 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4515 "TARGET_SSE2 && TARGET_SSE_MATH"
4516 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4517 [(set_attr "type" "ssecvt")
4518 (set_attr "prefix" "maybe_vex")
4519 (set_attr "mode" "DF")])
4521 (define_insn "*extendsfdf2_i387"
4522 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4523 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4525 "* return output_387_reg_move (insn, operands);"
4526 [(set_attr "type" "fmov")
4527 (set_attr "mode" "SF,XF")])
4529 (define_expand "extend<mode>xf2"
4530 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4531 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4534 /* ??? Needed for compress_float_constant since all fp constants
4535 are LEGITIMATE_CONSTANT_P. */
4536 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4538 if (standard_80387_constant_p (operands[1]) > 0)
4540 operands[1] = simplify_const_unary_operation
4541 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4542 emit_move_insn_1 (operands[0], operands[1]);
4545 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4549 (define_insn "*extend<mode>xf2_i387"
4550 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4552 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4554 "* return output_387_reg_move (insn, operands);"
4555 [(set_attr "type" "fmov")
4556 (set_attr "mode" "<MODE>,XF")])
4558 ;; %%% This seems bad bad news.
4559 ;; This cannot output into an f-reg because there is no way to be sure
4560 ;; of truncating in that case. Otherwise this is just like a simple move
4561 ;; insn. So we pretend we can output to a reg in order to get better
4562 ;; register preferencing, but we really use a stack slot.
4564 ;; Conversion from DFmode to SFmode.
4566 (define_expand "truncdfsf2"
4567 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4569 (match_operand:DF 1 "nonimmediate_operand" "")))]
4570 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4572 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4574 else if (flag_unsafe_math_optimizations)
4578 enum ix86_stack_slot slot = (virtuals_instantiated
4581 rtx temp = assign_386_stack_local (SFmode, slot);
4582 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4587 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4589 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4591 We do the conversion post reload to avoid producing of 128bit spills
4592 that might lead to ICE on 32bit target. The sequence unlikely combine
4595 [(set (match_operand:SF 0 "register_operand" "")
4597 (match_operand:DF 1 "nonimmediate_operand" "")))]
4598 "TARGET_USE_VECTOR_FP_CONVERTS
4599 && optimize_insn_for_speed_p ()
4600 && reload_completed && SSE_REG_P (operands[0])"
4603 (float_truncate:V2SF
4607 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4608 operands[3] = CONST0_RTX (V2SFmode);
4609 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4610 /* Use movsd for loading from memory, unpcklpd for registers.
4611 Try to avoid move when unpacking can be done in source, or SSE3
4612 movddup is available. */
4613 if (REG_P (operands[1]))
4616 && true_regnum (operands[0]) != true_regnum (operands[1])
4617 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4618 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4620 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4621 emit_move_insn (tmp, operands[1]);
4624 else if (!TARGET_SSE3)
4625 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4626 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4629 emit_insn (gen_sse2_loadlpd (operands[4],
4630 CONST0_RTX (V2DFmode), operands[1]));
4633 (define_expand "truncdfsf2_with_temp"
4634 [(parallel [(set (match_operand:SF 0 "" "")
4635 (float_truncate:SF (match_operand:DF 1 "" "")))
4636 (clobber (match_operand:SF 2 "" ""))])]
4639 (define_insn "*truncdfsf_fast_mixed"
4640 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4642 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4643 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4645 switch (which_alternative)
4648 return output_387_reg_move (insn, operands);
4650 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4655 [(set_attr "type" "fmov,ssecvt")
4656 (set_attr "prefix" "orig,maybe_vex")
4657 (set_attr "mode" "SF")])
4659 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4660 ;; because nothing we do here is unsafe.
4661 (define_insn "*truncdfsf_fast_sse"
4662 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4664 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4665 "TARGET_SSE2 && TARGET_SSE_MATH"
4666 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4667 [(set_attr "type" "ssecvt")
4668 (set_attr "prefix" "maybe_vex")
4669 (set_attr "mode" "SF")])
4671 (define_insn "*truncdfsf_fast_i387"
4672 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4674 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4675 "TARGET_80387 && flag_unsafe_math_optimizations"
4676 "* return output_387_reg_move (insn, operands);"
4677 [(set_attr "type" "fmov")
4678 (set_attr "mode" "SF")])
4680 (define_insn "*truncdfsf_mixed"
4681 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4683 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4684 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4685 "TARGET_MIX_SSE_I387"
4687 switch (which_alternative)
4690 return output_387_reg_move (insn, operands);
4692 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4698 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4699 (set_attr "unit" "*,*,i387,i387,i387")
4700 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4701 (set_attr "mode" "SF")])
4703 (define_insn "*truncdfsf_i387"
4704 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4706 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4707 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4710 switch (which_alternative)
4713 return output_387_reg_move (insn, operands);
4719 [(set_attr "type" "fmov,multi,multi,multi")
4720 (set_attr "unit" "*,i387,i387,i387")
4721 (set_attr "mode" "SF")])
4723 (define_insn "*truncdfsf2_i387_1"
4724 [(set (match_operand:SF 0 "memory_operand" "=m")
4726 (match_operand:DF 1 "register_operand" "f")))]
4728 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4729 && !TARGET_MIX_SSE_I387"
4730 "* return output_387_reg_move (insn, operands);"
4731 [(set_attr "type" "fmov")
4732 (set_attr "mode" "SF")])
4735 [(set (match_operand:SF 0 "register_operand" "")
4737 (match_operand:DF 1 "fp_register_operand" "")))
4738 (clobber (match_operand 2 "" ""))]
4740 [(set (match_dup 2) (match_dup 1))
4741 (set (match_dup 0) (match_dup 2))]
4743 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4746 ;; Conversion from XFmode to {SF,DF}mode
4748 (define_expand "truncxf<mode>2"
4749 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4750 (float_truncate:MODEF
4751 (match_operand:XF 1 "register_operand" "")))
4752 (clobber (match_dup 2))])]
4755 if (flag_unsafe_math_optimizations)
4757 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4758 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4759 if (reg != operands[0])
4760 emit_move_insn (operands[0], reg);
4765 enum ix86_stack_slot slot = (virtuals_instantiated
4768 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4772 (define_insn "*truncxfsf2_mixed"
4773 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4775 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4776 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4779 gcc_assert (!which_alternative);
4780 return output_387_reg_move (insn, operands);
4782 [(set_attr "type" "fmov,multi,multi,multi")
4783 (set_attr "unit" "*,i387,i387,i387")
4784 (set_attr "mode" "SF")])
4786 (define_insn "*truncxfdf2_mixed"
4787 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4789 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4790 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4793 gcc_assert (!which_alternative);
4794 return output_387_reg_move (insn, operands);
4796 [(set_attr "type" "fmov,multi,multi,multi")
4797 (set_attr "unit" "*,i387,i387,i387")
4798 (set_attr "mode" "DF")])
4800 (define_insn "truncxf<mode>2_i387_noop"
4801 [(set (match_operand:MODEF 0 "register_operand" "=f")
4802 (float_truncate:MODEF
4803 (match_operand:XF 1 "register_operand" "f")))]
4804 "TARGET_80387 && flag_unsafe_math_optimizations"
4805 "* return output_387_reg_move (insn, operands);"
4806 [(set_attr "type" "fmov")
4807 (set_attr "mode" "<MODE>")])
4809 (define_insn "*truncxf<mode>2_i387"
4810 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4811 (float_truncate:MODEF
4812 (match_operand:XF 1 "register_operand" "f")))]
4814 "* return output_387_reg_move (insn, operands);"
4815 [(set_attr "type" "fmov")
4816 (set_attr "mode" "<MODE>")])
4819 [(set (match_operand:MODEF 0 "register_operand" "")
4820 (float_truncate:MODEF
4821 (match_operand:XF 1 "register_operand" "")))
4822 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4823 "TARGET_80387 && reload_completed"
4824 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4825 (set (match_dup 0) (match_dup 2))]
4829 [(set (match_operand:MODEF 0 "memory_operand" "")
4830 (float_truncate:MODEF
4831 (match_operand:XF 1 "register_operand" "")))
4832 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4834 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4837 ;; Signed conversion to DImode.
4839 (define_expand "fix_truncxfdi2"
4840 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4841 (fix:DI (match_operand:XF 1 "register_operand" "")))
4842 (clobber (reg:CC FLAGS_REG))])]
4847 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4852 (define_expand "fix_trunc<mode>di2"
4853 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4854 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4855 (clobber (reg:CC FLAGS_REG))])]
4856 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4859 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4861 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4864 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4866 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4867 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4868 if (out != operands[0])
4869 emit_move_insn (operands[0], out);
4874 ;; Signed conversion to SImode.
4876 (define_expand "fix_truncxfsi2"
4877 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4878 (fix:SI (match_operand:XF 1 "register_operand" "")))
4879 (clobber (reg:CC FLAGS_REG))])]
4884 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4889 (define_expand "fix_trunc<mode>si2"
4890 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4891 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4892 (clobber (reg:CC FLAGS_REG))])]
4893 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4896 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4898 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4901 if (SSE_FLOAT_MODE_P (<MODE>mode))
4903 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4904 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4905 if (out != operands[0])
4906 emit_move_insn (operands[0], out);
4911 ;; Signed conversion to HImode.
4913 (define_expand "fix_trunc<mode>hi2"
4914 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4915 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4916 (clobber (reg:CC FLAGS_REG))])]
4918 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4922 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4927 ;; Unsigned conversion to SImode.
4929 (define_expand "fixuns_trunc<mode>si2"
4931 [(set (match_operand:SI 0 "register_operand" "")
4933 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4935 (clobber (match_scratch:<ssevecmode> 3 ""))
4936 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4937 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4939 enum machine_mode mode = <MODE>mode;
4940 enum machine_mode vecmode = <ssevecmode>mode;
4941 REAL_VALUE_TYPE TWO31r;
4944 if (optimize_insn_for_size_p ())
4947 real_ldexp (&TWO31r, &dconst1, 31);
4948 two31 = const_double_from_real_value (TWO31r, mode);
4949 two31 = ix86_build_const_vector (mode, true, two31);
4950 operands[2] = force_reg (vecmode, two31);
4953 (define_insn_and_split "*fixuns_trunc<mode>_1"
4954 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4956 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4957 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4958 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4959 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4960 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4961 && optimize_function_for_speed_p (cfun)"
4963 "&& reload_completed"
4966 ix86_split_convert_uns_si_sse (operands);
4970 ;; Unsigned conversion to HImode.
4971 ;; Without these patterns, we'll try the unsigned SI conversion which
4972 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4974 (define_expand "fixuns_trunc<mode>hi2"
4976 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4977 (set (match_operand:HI 0 "nonimmediate_operand" "")
4978 (subreg:HI (match_dup 2) 0))]
4979 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4980 "operands[2] = gen_reg_rtx (SImode);")
4982 ;; When SSE is available, it is always faster to use it!
4983 (define_insn "fix_trunc<mode>di_sse"
4984 [(set (match_operand:DI 0 "register_operand" "=r,r")
4985 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4986 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4987 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4988 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4989 [(set_attr "type" "sseicvt")
4990 (set_attr "prefix" "maybe_vex")
4991 (set_attr "prefix_rex" "1")
4992 (set_attr "mode" "<MODE>")
4993 (set_attr "athlon_decode" "double,vector")
4994 (set_attr "amdfam10_decode" "double,double")])
4996 (define_insn "fix_trunc<mode>si_sse"
4997 [(set (match_operand:SI 0 "register_operand" "=r,r")
4998 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4999 "SSE_FLOAT_MODE_P (<MODE>mode)
5000 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5001 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
5002 [(set_attr "type" "sseicvt")
5003 (set_attr "prefix" "maybe_vex")
5004 (set_attr "mode" "<MODE>")
5005 (set_attr "athlon_decode" "double,vector")
5006 (set_attr "amdfam10_decode" "double,double")])
5008 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
5010 [(set (match_operand:MODEF 0 "register_operand" "")
5011 (match_operand:MODEF 1 "memory_operand" ""))
5012 (set (match_operand:SSEMODEI24 2 "register_operand" "")
5013 (fix:SSEMODEI24 (match_dup 0)))]
5014 "TARGET_SHORTEN_X87_SSE
5015 && peep2_reg_dead_p (2, operands[0])"
5016 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
5019 ;; Avoid vector decoded forms of the instruction.
5021 [(match_scratch:DF 2 "Y2")
5022 (set (match_operand:SSEMODEI24 0 "register_operand" "")
5023 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
5024 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5025 [(set (match_dup 2) (match_dup 1))
5026 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5030 [(match_scratch:SF 2 "x")
5031 (set (match_operand:SSEMODEI24 0 "register_operand" "")
5032 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
5033 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5034 [(set (match_dup 2) (match_dup 1))
5035 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5038 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5039 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5040 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5041 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5043 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5044 && (TARGET_64BIT || <MODE>mode != DImode))
5046 && can_create_pseudo_p ()"
5051 if (memory_operand (operands[0], VOIDmode))
5052 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5055 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5056 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5062 [(set_attr "type" "fisttp")
5063 (set_attr "mode" "<MODE>")])
5065 (define_insn "fix_trunc<mode>_i387_fisttp"
5066 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5067 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5068 (clobber (match_scratch:XF 2 "=&1f"))]
5069 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5071 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5072 && (TARGET_64BIT || <MODE>mode != DImode))
5073 && TARGET_SSE_MATH)"
5074 "* return output_fix_trunc (insn, operands, 1);"
5075 [(set_attr "type" "fisttp")
5076 (set_attr "mode" "<MODE>")])
5078 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5079 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5080 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5081 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5082 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5083 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5085 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5086 && (TARGET_64BIT || <MODE>mode != DImode))
5087 && TARGET_SSE_MATH)"
5089 [(set_attr "type" "fisttp")
5090 (set_attr "mode" "<MODE>")])
5093 [(set (match_operand:X87MODEI 0 "register_operand" "")
5094 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5095 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5096 (clobber (match_scratch 3 ""))]
5098 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5099 (clobber (match_dup 3))])
5100 (set (match_dup 0) (match_dup 2))]
5104 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5105 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5106 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5107 (clobber (match_scratch 3 ""))]
5109 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5110 (clobber (match_dup 3))])]
5113 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5114 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5115 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5116 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5117 ;; function in i386.c.
5118 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5119 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5120 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5121 (clobber (reg:CC FLAGS_REG))]
5122 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5124 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5125 && (TARGET_64BIT || <MODE>mode != DImode))
5126 && can_create_pseudo_p ()"
5131 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5133 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5134 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5135 if (memory_operand (operands[0], VOIDmode))
5136 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5137 operands[2], operands[3]));
5140 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5141 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5142 operands[2], operands[3],
5147 [(set_attr "type" "fistp")
5148 (set_attr "i387_cw" "trunc")
5149 (set_attr "mode" "<MODE>")])
5151 (define_insn "fix_truncdi_i387"
5152 [(set (match_operand:DI 0 "memory_operand" "=m")
5153 (fix:DI (match_operand 1 "register_operand" "f")))
5154 (use (match_operand:HI 2 "memory_operand" "m"))
5155 (use (match_operand:HI 3 "memory_operand" "m"))
5156 (clobber (match_scratch:XF 4 "=&1f"))]
5157 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5159 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5160 "* return output_fix_trunc (insn, operands, 0);"
5161 [(set_attr "type" "fistp")
5162 (set_attr "i387_cw" "trunc")
5163 (set_attr "mode" "DI")])
5165 (define_insn "fix_truncdi_i387_with_temp"
5166 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5167 (fix:DI (match_operand 1 "register_operand" "f,f")))
5168 (use (match_operand:HI 2 "memory_operand" "m,m"))
5169 (use (match_operand:HI 3 "memory_operand" "m,m"))
5170 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5171 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5172 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5174 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5176 [(set_attr "type" "fistp")
5177 (set_attr "i387_cw" "trunc")
5178 (set_attr "mode" "DI")])
5181 [(set (match_operand:DI 0 "register_operand" "")
5182 (fix:DI (match_operand 1 "register_operand" "")))
5183 (use (match_operand:HI 2 "memory_operand" ""))
5184 (use (match_operand:HI 3 "memory_operand" ""))
5185 (clobber (match_operand:DI 4 "memory_operand" ""))
5186 (clobber (match_scratch 5 ""))]
5188 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5191 (clobber (match_dup 5))])
5192 (set (match_dup 0) (match_dup 4))]
5196 [(set (match_operand:DI 0 "memory_operand" "")
5197 (fix:DI (match_operand 1 "register_operand" "")))
5198 (use (match_operand:HI 2 "memory_operand" ""))
5199 (use (match_operand:HI 3 "memory_operand" ""))
5200 (clobber (match_operand:DI 4 "memory_operand" ""))
5201 (clobber (match_scratch 5 ""))]
5203 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5206 (clobber (match_dup 5))])]
5209 (define_insn "fix_trunc<mode>_i387"
5210 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5211 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5212 (use (match_operand:HI 2 "memory_operand" "m"))
5213 (use (match_operand:HI 3 "memory_operand" "m"))]
5214 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5216 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5217 "* return output_fix_trunc (insn, operands, 0);"
5218 [(set_attr "type" "fistp")
5219 (set_attr "i387_cw" "trunc")
5220 (set_attr "mode" "<MODE>")])
5222 (define_insn "fix_trunc<mode>_i387_with_temp"
5223 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5224 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5225 (use (match_operand:HI 2 "memory_operand" "m,m"))
5226 (use (match_operand:HI 3 "memory_operand" "m,m"))
5227 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5228 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5230 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5232 [(set_attr "type" "fistp")
5233 (set_attr "i387_cw" "trunc")
5234 (set_attr "mode" "<MODE>")])
5237 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5238 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5239 (use (match_operand:HI 2 "memory_operand" ""))
5240 (use (match_operand:HI 3 "memory_operand" ""))
5241 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5243 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5245 (use (match_dup 3))])
5246 (set (match_dup 0) (match_dup 4))]
5250 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5251 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5252 (use (match_operand:HI 2 "memory_operand" ""))
5253 (use (match_operand:HI 3 "memory_operand" ""))
5254 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5256 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5258 (use (match_dup 3))])]
5261 (define_insn "x86_fnstcw_1"
5262 [(set (match_operand:HI 0 "memory_operand" "=m")
5263 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5266 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5267 (set_attr "mode" "HI")
5268 (set_attr "unit" "i387")])
5270 (define_insn "x86_fldcw_1"
5271 [(set (reg:HI FPCR_REG)
5272 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5275 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5276 (set_attr "mode" "HI")
5277 (set_attr "unit" "i387")
5278 (set_attr "athlon_decode" "vector")
5279 (set_attr "amdfam10_decode" "vector")])
5281 ;; Conversion between fixed point and floating point.
5283 ;; Even though we only accept memory inputs, the backend _really_
5284 ;; wants to be able to do this between registers.
5286 (define_expand "floathi<mode>2"
5287 [(set (match_operand:X87MODEF 0 "register_operand" "")
5288 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5290 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5291 || TARGET_MIX_SSE_I387)"
5294 ;; Pre-reload splitter to add memory clobber to the pattern.
5295 (define_insn_and_split "*floathi<mode>2_1"
5296 [(set (match_operand:X87MODEF 0 "register_operand" "")
5297 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5299 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5300 || TARGET_MIX_SSE_I387)
5301 && can_create_pseudo_p ()"
5304 [(parallel [(set (match_dup 0)
5305 (float:X87MODEF (match_dup 1)))
5306 (clobber (match_dup 2))])]
5307 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5309 (define_insn "*floathi<mode>2_i387_with_temp"
5310 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5311 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5312 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5314 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5315 || TARGET_MIX_SSE_I387)"
5317 [(set_attr "type" "fmov,multi")
5318 (set_attr "mode" "<MODE>")
5319 (set_attr "unit" "*,i387")
5320 (set_attr "fp_int_src" "true")])
5322 (define_insn "*floathi<mode>2_i387"
5323 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5324 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5326 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5327 || TARGET_MIX_SSE_I387)"
5329 [(set_attr "type" "fmov")
5330 (set_attr "mode" "<MODE>")
5331 (set_attr "fp_int_src" "true")])
5334 [(set (match_operand:X87MODEF 0 "register_operand" "")
5335 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5336 (clobber (match_operand:HI 2 "memory_operand" ""))]
5338 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5339 || TARGET_MIX_SSE_I387)
5340 && reload_completed"
5341 [(set (match_dup 2) (match_dup 1))
5342 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5346 [(set (match_operand:X87MODEF 0 "register_operand" "")
5347 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5348 (clobber (match_operand:HI 2 "memory_operand" ""))]
5350 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5351 || TARGET_MIX_SSE_I387)
5352 && reload_completed"
5353 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5356 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5357 [(set (match_operand:X87MODEF 0 "register_operand" "")
5359 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5361 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5362 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5364 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5365 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5366 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5368 rtx reg = gen_reg_rtx (XFmode);
5371 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5373 if (<X87MODEF:MODE>mode == SFmode)
5374 insn = gen_truncxfsf2 (operands[0], reg);
5375 else if (<X87MODEF:MODE>mode == DFmode)
5376 insn = gen_truncxfdf2 (operands[0], reg);
5385 ;; Pre-reload splitter to add memory clobber to the pattern.
5386 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5387 [(set (match_operand:X87MODEF 0 "register_operand" "")
5388 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5390 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5391 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5392 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5393 || TARGET_MIX_SSE_I387))
5394 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5395 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5396 && ((<SSEMODEI24:MODE>mode == SImode
5397 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5398 && optimize_function_for_speed_p (cfun)
5399 && flag_trapping_math)
5400 || !(TARGET_INTER_UNIT_CONVERSIONS
5401 || optimize_function_for_size_p (cfun)))))
5402 && can_create_pseudo_p ()"
5405 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5406 (clobber (match_dup 2))])]
5408 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5410 /* Avoid store forwarding (partial memory) stall penalty
5411 by passing DImode value through XMM registers. */
5412 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5413 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5414 && optimize_function_for_speed_p (cfun))
5416 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5423 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5424 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5426 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5427 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5428 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5429 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5431 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5432 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5433 (set_attr "unit" "*,i387,*,*,*")
5434 (set_attr "athlon_decode" "*,*,double,direct,double")
5435 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5436 (set_attr "fp_int_src" "true")])
5438 (define_insn "*floatsi<mode>2_vector_mixed"
5439 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5440 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5441 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5442 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5446 [(set_attr "type" "fmov,sseicvt")
5447 (set_attr "mode" "<MODE>,<ssevecmode>")
5448 (set_attr "unit" "i387,*")
5449 (set_attr "athlon_decode" "*,direct")
5450 (set_attr "amdfam10_decode" "*,double")
5451 (set_attr "fp_int_src" "true")])
5453 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5454 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5456 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5457 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5458 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5459 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5461 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5462 (set_attr "mode" "<MODEF:MODE>")
5463 (set_attr "unit" "*,i387,*,*")
5464 (set_attr "athlon_decode" "*,*,double,direct")
5465 (set_attr "amdfam10_decode" "*,*,vector,double")
5466 (set_attr "fp_int_src" "true")])
5469 [(set (match_operand:MODEF 0 "register_operand" "")
5470 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5471 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5472 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5473 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5474 && TARGET_INTER_UNIT_CONVERSIONS
5476 && (SSE_REG_P (operands[0])
5477 || (GET_CODE (operands[0]) == SUBREG
5478 && SSE_REG_P (operands[0])))"
5479 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5483 [(set (match_operand:MODEF 0 "register_operand" "")
5484 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5485 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5486 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5487 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5488 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5490 && (SSE_REG_P (operands[0])
5491 || (GET_CODE (operands[0]) == SUBREG
5492 && SSE_REG_P (operands[0])))"
5493 [(set (match_dup 2) (match_dup 1))
5494 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5497 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5498 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5500 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5501 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5502 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5503 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5506 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5507 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5508 [(set_attr "type" "fmov,sseicvt,sseicvt")
5509 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5510 (set_attr "mode" "<MODEF:MODE>")
5511 (set (attr "prefix_rex")
5513 (and (eq_attr "prefix" "maybe_vex")
5514 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5516 (const_string "*")))
5517 (set_attr "unit" "i387,*,*")
5518 (set_attr "athlon_decode" "*,double,direct")
5519 (set_attr "amdfam10_decode" "*,vector,double")
5520 (set_attr "fp_int_src" "true")])
5522 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5523 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5525 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5526 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5527 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5528 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5531 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5532 [(set_attr "type" "fmov,sseicvt")
5533 (set_attr "prefix" "orig,maybe_vex")
5534 (set_attr "mode" "<MODEF:MODE>")
5535 (set (attr "prefix_rex")
5537 (and (eq_attr "prefix" "maybe_vex")
5538 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5540 (const_string "*")))
5541 (set_attr "athlon_decode" "*,direct")
5542 (set_attr "amdfam10_decode" "*,double")
5543 (set_attr "fp_int_src" "true")])
5545 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5546 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5548 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5549 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5550 "TARGET_SSE2 && TARGET_SSE_MATH
5551 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5553 [(set_attr "type" "sseicvt")
5554 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5555 (set_attr "athlon_decode" "double,direct,double")
5556 (set_attr "amdfam10_decode" "vector,double,double")
5557 (set_attr "fp_int_src" "true")])
5559 (define_insn "*floatsi<mode>2_vector_sse"
5560 [(set (match_operand:MODEF 0 "register_operand" "=x")
5561 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5562 "TARGET_SSE2 && TARGET_SSE_MATH
5563 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5565 [(set_attr "type" "sseicvt")
5566 (set_attr "mode" "<MODE>")
5567 (set_attr "athlon_decode" "direct")
5568 (set_attr "amdfam10_decode" "double")
5569 (set_attr "fp_int_src" "true")])
5572 [(set (match_operand:MODEF 0 "register_operand" "")
5573 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5574 (clobber (match_operand:SI 2 "memory_operand" ""))]
5575 "TARGET_SSE2 && TARGET_SSE_MATH
5576 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5578 && (SSE_REG_P (operands[0])
5579 || (GET_CODE (operands[0]) == SUBREG
5580 && SSE_REG_P (operands[0])))"
5583 rtx op1 = operands[1];
5585 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5587 if (GET_CODE (op1) == SUBREG)
5588 op1 = SUBREG_REG (op1);
5590 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5592 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5593 emit_insn (gen_sse2_loadld (operands[4],
5594 CONST0_RTX (V4SImode), operands[1]));
5596 /* We can ignore possible trapping value in the
5597 high part of SSE register for non-trapping math. */
5598 else if (SSE_REG_P (op1) && !flag_trapping_math)
5599 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5602 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5603 emit_move_insn (operands[2], operands[1]);
5604 emit_insn (gen_sse2_loadld (operands[4],
5605 CONST0_RTX (V4SImode), operands[2]));
5608 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5613 [(set (match_operand:MODEF 0 "register_operand" "")
5614 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5615 (clobber (match_operand:SI 2 "memory_operand" ""))]
5616 "TARGET_SSE2 && TARGET_SSE_MATH
5617 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5619 && (SSE_REG_P (operands[0])
5620 || (GET_CODE (operands[0]) == SUBREG
5621 && SSE_REG_P (operands[0])))"
5624 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5626 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5628 emit_insn (gen_sse2_loadld (operands[4],
5629 CONST0_RTX (V4SImode), operands[1]));
5631 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5636 [(set (match_operand:MODEF 0 "register_operand" "")
5637 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5638 "TARGET_SSE2 && TARGET_SSE_MATH
5639 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5641 && (SSE_REG_P (operands[0])
5642 || (GET_CODE (operands[0]) == SUBREG
5643 && SSE_REG_P (operands[0])))"
5646 rtx op1 = operands[1];
5648 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5650 if (GET_CODE (op1) == SUBREG)
5651 op1 = SUBREG_REG (op1);
5653 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5655 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5656 emit_insn (gen_sse2_loadld (operands[4],
5657 CONST0_RTX (V4SImode), operands[1]));
5659 /* We can ignore possible trapping value in the
5660 high part of SSE register for non-trapping math. */
5661 else if (SSE_REG_P (op1) && !flag_trapping_math)
5662 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5666 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5671 [(set (match_operand:MODEF 0 "register_operand" "")
5672 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5673 "TARGET_SSE2 && TARGET_SSE_MATH
5674 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5676 && (SSE_REG_P (operands[0])
5677 || (GET_CODE (operands[0]) == SUBREG
5678 && SSE_REG_P (operands[0])))"
5681 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5683 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5685 emit_insn (gen_sse2_loadld (operands[4],
5686 CONST0_RTX (V4SImode), operands[1]));
5688 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5692 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5693 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5695 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5696 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5697 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5698 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5700 [(set_attr "type" "sseicvt")
5701 (set_attr "mode" "<MODEF:MODE>")
5702 (set_attr "athlon_decode" "double,direct")
5703 (set_attr "amdfam10_decode" "vector,double")
5704 (set_attr "fp_int_src" "true")])
5706 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5707 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5709 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5710 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5711 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5712 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5713 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5714 [(set_attr "type" "sseicvt")
5715 (set_attr "prefix" "maybe_vex")
5716 (set_attr "mode" "<MODEF:MODE>")
5717 (set (attr "prefix_rex")
5719 (and (eq_attr "prefix" "maybe_vex")
5720 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5722 (const_string "*")))
5723 (set_attr "athlon_decode" "double,direct")
5724 (set_attr "amdfam10_decode" "vector,double")
5725 (set_attr "fp_int_src" "true")])
5728 [(set (match_operand:MODEF 0 "register_operand" "")
5729 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5730 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5731 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5732 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5733 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5735 && (SSE_REG_P (operands[0])
5736 || (GET_CODE (operands[0]) == SUBREG
5737 && SSE_REG_P (operands[0])))"
5738 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5741 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5742 [(set (match_operand:MODEF 0 "register_operand" "=x")
5744 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5745 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5746 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5747 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5748 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5749 [(set_attr "type" "sseicvt")
5750 (set_attr "prefix" "maybe_vex")
5751 (set_attr "mode" "<MODEF:MODE>")
5752 (set (attr "prefix_rex")
5754 (and (eq_attr "prefix" "maybe_vex")
5755 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5757 (const_string "*")))
5758 (set_attr "athlon_decode" "direct")
5759 (set_attr "amdfam10_decode" "double")
5760 (set_attr "fp_int_src" "true")])
5763 [(set (match_operand:MODEF 0 "register_operand" "")
5764 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5765 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5766 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5767 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5768 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5770 && (SSE_REG_P (operands[0])
5771 || (GET_CODE (operands[0]) == SUBREG
5772 && SSE_REG_P (operands[0])))"
5773 [(set (match_dup 2) (match_dup 1))
5774 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5778 [(set (match_operand:MODEF 0 "register_operand" "")
5779 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5780 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5781 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5782 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5784 && (SSE_REG_P (operands[0])
5785 || (GET_CODE (operands[0]) == SUBREG
5786 && SSE_REG_P (operands[0])))"
5787 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5790 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5791 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5793 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5794 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5796 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5800 [(set_attr "type" "fmov,multi")
5801 (set_attr "mode" "<X87MODEF:MODE>")
5802 (set_attr "unit" "*,i387")
5803 (set_attr "fp_int_src" "true")])
5805 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5806 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5808 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5810 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5812 [(set_attr "type" "fmov")
5813 (set_attr "mode" "<X87MODEF:MODE>")
5814 (set_attr "fp_int_src" "true")])
5817 [(set (match_operand:X87MODEF 0 "register_operand" "")
5818 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5819 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5821 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5823 && FP_REG_P (operands[0])"
5824 [(set (match_dup 2) (match_dup 1))
5825 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5829 [(set (match_operand:X87MODEF 0 "register_operand" "")
5830 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5831 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5833 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5835 && FP_REG_P (operands[0])"
5836 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5839 ;; Avoid store forwarding (partial memory) stall penalty
5840 ;; by passing DImode value through XMM registers. */
5842 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5843 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5845 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5846 (clobber (match_scratch:V4SI 3 "=X,x"))
5847 (clobber (match_scratch:V4SI 4 "=X,x"))
5848 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5849 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5850 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5851 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5853 [(set_attr "type" "multi")
5854 (set_attr "mode" "<X87MODEF:MODE>")
5855 (set_attr "unit" "i387")
5856 (set_attr "fp_int_src" "true")])
5859 [(set (match_operand:X87MODEF 0 "register_operand" "")
5860 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5861 (clobber (match_scratch:V4SI 3 ""))
5862 (clobber (match_scratch:V4SI 4 ""))
5863 (clobber (match_operand:DI 2 "memory_operand" ""))]
5864 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5865 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5866 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5868 && FP_REG_P (operands[0])"
5869 [(set (match_dup 2) (match_dup 3))
5870 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5872 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5873 Assemble the 64-bit DImode value in an xmm register. */
5874 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5875 gen_rtx_SUBREG (SImode, operands[1], 0)));
5876 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5877 gen_rtx_SUBREG (SImode, operands[1], 4)));
5878 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5881 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5885 [(set (match_operand:X87MODEF 0 "register_operand" "")
5886 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5887 (clobber (match_scratch:V4SI 3 ""))
5888 (clobber (match_scratch:V4SI 4 ""))
5889 (clobber (match_operand:DI 2 "memory_operand" ""))]
5890 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5891 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5892 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5894 && FP_REG_P (operands[0])"
5895 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5898 ;; Avoid store forwarding (partial memory) stall penalty by extending
5899 ;; SImode value to DImode through XMM register instead of pushing two
5900 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5901 ;; targets benefit from this optimization. Also note that fild
5902 ;; loads from memory only.
5904 (define_insn "*floatunssi<mode>2_1"
5905 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5906 (unsigned_float:X87MODEF
5907 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5908 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5909 (clobber (match_scratch:SI 3 "=X,x"))]
5911 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5914 [(set_attr "type" "multi")
5915 (set_attr "mode" "<MODE>")])
5918 [(set (match_operand:X87MODEF 0 "register_operand" "")
5919 (unsigned_float:X87MODEF
5920 (match_operand:SI 1 "register_operand" "")))
5921 (clobber (match_operand:DI 2 "memory_operand" ""))
5922 (clobber (match_scratch:SI 3 ""))]
5924 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5926 && reload_completed"
5927 [(set (match_dup 2) (match_dup 1))
5929 (float:X87MODEF (match_dup 2)))]
5930 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5933 [(set (match_operand:X87MODEF 0 "register_operand" "")
5934 (unsigned_float:X87MODEF
5935 (match_operand:SI 1 "memory_operand" "")))
5936 (clobber (match_operand:DI 2 "memory_operand" ""))
5937 (clobber (match_scratch:SI 3 ""))]
5939 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5941 && reload_completed"
5942 [(set (match_dup 2) (match_dup 3))
5944 (float:X87MODEF (match_dup 2)))]
5946 emit_move_insn (operands[3], operands[1]);
5947 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5950 (define_expand "floatunssi<mode>2"
5952 [(set (match_operand:X87MODEF 0 "register_operand" "")
5953 (unsigned_float:X87MODEF
5954 (match_operand:SI 1 "nonimmediate_operand" "")))
5955 (clobber (match_dup 2))
5956 (clobber (match_scratch:SI 3 ""))])]
5958 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5960 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5962 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5964 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5969 enum ix86_stack_slot slot = (virtuals_instantiated
5972 operands[2] = assign_386_stack_local (DImode, slot);
5976 (define_expand "floatunsdisf2"
5977 [(use (match_operand:SF 0 "register_operand" ""))
5978 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5979 "TARGET_64BIT && TARGET_SSE_MATH"
5980 "x86_emit_floatuns (operands); DONE;")
5982 (define_expand "floatunsdidf2"
5983 [(use (match_operand:DF 0 "register_operand" ""))
5984 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5985 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5986 && TARGET_SSE2 && TARGET_SSE_MATH"
5989 x86_emit_floatuns (operands);
5991 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5997 (define_expand "add<mode>3"
5998 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5999 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6000 (match_operand:SDWIM 2 "<general_operand>" "")))]
6002 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6004 (define_insn_and_split "*add<dwi>3_doubleword"
6005 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6007 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6008 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6009 (clobber (reg:CC FLAGS_REG))]
6010 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6013 [(parallel [(set (reg:CC FLAGS_REG)
6014 (unspec:CC [(match_dup 1) (match_dup 2)]
6017 (plus:DWIH (match_dup 1) (match_dup 2)))])
6018 (parallel [(set (match_dup 3)
6022 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6024 (clobber (reg:CC FLAGS_REG))])]
6025 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6027 (define_insn "*add<mode>3_cc"
6028 [(set (reg:CC FLAGS_REG)
6030 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6031 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
6033 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
6034 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6035 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6036 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6037 [(set_attr "type" "alu")
6038 (set_attr "mode" "<MODE>")])
6040 (define_insn "addqi3_cc"
6041 [(set (reg:CC FLAGS_REG)
6043 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6044 (match_operand:QI 2 "general_operand" "qn,qm")]
6046 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6047 (plus:QI (match_dup 1) (match_dup 2)))]
6048 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6049 "add{b}\t{%2, %0|%0, %2}"
6050 [(set_attr "type" "alu")
6051 (set_attr "mode" "QI")])
6053 (define_insn "*lea_1"
6054 [(set (match_operand:DWIH 0 "register_operand" "=r")
6055 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
6057 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
6058 [(set_attr "type" "lea")
6059 (set_attr "mode" "<MODE>")])
6061 (define_insn "*lea_2"
6062 [(set (match_operand:SI 0 "register_operand" "=r")
6063 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6065 "lea{l}\t{%a1, %0|%0, %a1}"
6066 [(set_attr "type" "lea")
6067 (set_attr "mode" "SI")])
6069 (define_insn "*lea_2_zext"
6070 [(set (match_operand:DI 0 "register_operand" "=r")
6072 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6074 "lea{l}\t{%a1, %k0|%k0, %a1}"
6075 [(set_attr "type" "lea")
6076 (set_attr "mode" "SI")])
6078 (define_insn "*add<mode>_1"
6079 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6081 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6082 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6083 (clobber (reg:CC FLAGS_REG))]
6084 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6086 switch (get_attr_type (insn))
6089 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6090 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6093 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6094 if (operands[2] == const1_rtx)
6095 return "inc{<imodesuffix>}\t%0";
6098 gcc_assert (operands[2] == constm1_rtx);
6099 return "dec{<imodesuffix>}\t%0";
6103 /* Use add as much as possible to replace lea for AGU optimization. */
6104 if (which_alternative == 2 && TARGET_OPT_AGU)
6105 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6107 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6108 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6109 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6111 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6115 (cond [(and (eq_attr "alternative" "2")
6116 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6117 (const_string "lea")
6118 (eq_attr "alternative" "3")
6119 (const_string "lea")
6120 ; Current assemblers are broken and do not allow @GOTOFF in
6121 ; ought but a memory context.
6122 (match_operand:SWI48 2 "pic_symbolic_operand" "")
6123 (const_string "lea")
6124 (match_operand:SWI48 2 "incdec_operand" "")
6125 (const_string "incdec")
6127 (const_string "alu")))
6128 (set (attr "length_immediate")
6130 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6132 (const_string "*")))
6133 (set_attr "mode" "<MODE>")])
6135 ;; It may seem that nonimmediate operand is proper one for operand 1.
6136 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6137 ;; we take care in ix86_binary_operator_ok to not allow two memory
6138 ;; operands so proper swapping will be done in reload. This allow
6139 ;; patterns constructed from addsi_1 to match.
6141 (define_insn "*addsi_1_zext"
6142 [(set (match_operand:DI 0 "register_operand" "=r,r")
6144 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6145 (match_operand:SI 2 "general_operand" "g,li"))))
6146 (clobber (reg:CC FLAGS_REG))]
6147 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6149 switch (get_attr_type (insn))
6152 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6153 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6156 if (operands[2] == const1_rtx)
6157 return "inc{l}\t%k0";
6160 gcc_assert (operands[2] == constm1_rtx);
6161 return "dec{l}\t%k0";
6165 if (x86_maybe_negate_const_int (&operands[2], SImode))
6166 return "sub{l}\t{%2, %k0|%k0, %2}";
6168 return "add{l}\t{%2, %k0|%k0, %2}";
6172 (cond [(eq_attr "alternative" "1")
6173 (const_string "lea")
6174 ; Current assemblers are broken and do not allow @GOTOFF in
6175 ; ought but a memory context.
6176 (match_operand:SI 2 "pic_symbolic_operand" "")
6177 (const_string "lea")
6178 (match_operand:SI 2 "incdec_operand" "")
6179 (const_string "incdec")
6181 (const_string "alu")))
6182 (set (attr "length_immediate")
6184 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6186 (const_string "*")))
6187 (set_attr "mode" "SI")])
6189 (define_insn "*addhi_1"
6190 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6191 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6192 (match_operand:HI 2 "general_operand" "rn,rm")))
6193 (clobber (reg:CC FLAGS_REG))]
6194 "TARGET_PARTIAL_REG_STALL
6195 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6197 switch (get_attr_type (insn))
6200 if (operands[2] == const1_rtx)
6201 return "inc{w}\t%0";
6204 gcc_assert (operands[2] == constm1_rtx);
6205 return "dec{w}\t%0";
6209 if (x86_maybe_negate_const_int (&operands[2], HImode))
6210 return "sub{w}\t{%2, %0|%0, %2}";
6212 return "add{w}\t{%2, %0|%0, %2}";
6216 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6217 (const_string "incdec")
6218 (const_string "alu")))
6219 (set (attr "length_immediate")
6221 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6223 (const_string "*")))
6224 (set_attr "mode" "HI")])
6226 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6227 ;; type optimizations enabled by define-splits. This is not important
6228 ;; for PII, and in fact harmful because of partial register stalls.
6230 (define_insn "*addhi_1_lea"
6231 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6232 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6233 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6234 (clobber (reg:CC FLAGS_REG))]
6235 "!TARGET_PARTIAL_REG_STALL
6236 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6238 switch (get_attr_type (insn))
6243 if (operands[2] == const1_rtx)
6244 return "inc{w}\t%0";
6247 gcc_assert (operands[2] == constm1_rtx);
6248 return "dec{w}\t%0";
6252 if (x86_maybe_negate_const_int (&operands[2], HImode))
6253 return "sub{w}\t{%2, %0|%0, %2}";
6255 return "add{w}\t{%2, %0|%0, %2}";
6259 (if_then_else (eq_attr "alternative" "2")
6260 (const_string "lea")
6261 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6262 (const_string "incdec")
6263 (const_string "alu"))))
6264 (set (attr "length_immediate")
6266 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6268 (const_string "*")))
6269 (set_attr "mode" "HI,HI,SI")])
6271 (define_insn "*addqi_1"
6272 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6273 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6274 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6275 (clobber (reg:CC FLAGS_REG))]
6276 "TARGET_PARTIAL_REG_STALL
6277 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6279 int widen = (which_alternative == 2);
6280 switch (get_attr_type (insn))
6283 if (operands[2] == const1_rtx)
6284 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6287 gcc_assert (operands[2] == constm1_rtx);
6288 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6292 if (x86_maybe_negate_const_int (&operands[2], QImode))
6295 return "sub{l}\t{%2, %k0|%k0, %2}";
6297 return "sub{b}\t{%2, %0|%0, %2}";
6300 return "add{l}\t{%k2, %k0|%k0, %k2}";
6302 return "add{b}\t{%2, %0|%0, %2}";
6306 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6307 (const_string "incdec")
6308 (const_string "alu")))
6309 (set (attr "length_immediate")
6311 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6313 (const_string "*")))
6314 (set_attr "mode" "QI,QI,SI")])
6316 ;; %%% Potential partial reg stall on alternative 2. What to do?
6317 (define_insn "*addqi_1_lea"
6318 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6319 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6320 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6321 (clobber (reg:CC FLAGS_REG))]
6322 "!TARGET_PARTIAL_REG_STALL
6323 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6325 int widen = (which_alternative == 2);
6326 switch (get_attr_type (insn))
6331 if (operands[2] == const1_rtx)
6332 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6335 gcc_assert (operands[2] == constm1_rtx);
6336 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6340 if (x86_maybe_negate_const_int (&operands[2], QImode))
6343 return "sub{l}\t{%2, %k0|%k0, %2}";
6345 return "sub{b}\t{%2, %0|%0, %2}";
6348 return "add{l}\t{%k2, %k0|%k0, %k2}";
6350 return "add{b}\t{%2, %0|%0, %2}";
6354 (if_then_else (eq_attr "alternative" "3")
6355 (const_string "lea")
6356 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6357 (const_string "incdec")
6358 (const_string "alu"))))
6359 (set (attr "length_immediate")
6361 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6363 (const_string "*")))
6364 (set_attr "mode" "QI,QI,SI,SI")])
6366 (define_insn "*addqi_1_slp"
6367 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6368 (plus:QI (match_dup 0)
6369 (match_operand:QI 1 "general_operand" "qn,qnm")))
6370 (clobber (reg:CC FLAGS_REG))]
6371 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6372 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6374 switch (get_attr_type (insn))
6377 if (operands[1] == const1_rtx)
6378 return "inc{b}\t%0";
6381 gcc_assert (operands[1] == constm1_rtx);
6382 return "dec{b}\t%0";
6386 if (x86_maybe_negate_const_int (&operands[1], QImode))
6387 return "sub{b}\t{%1, %0|%0, %1}";
6389 return "add{b}\t{%1, %0|%0, %1}";
6393 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6394 (const_string "incdec")
6395 (const_string "alu1")))
6396 (set (attr "memory")
6397 (if_then_else (match_operand 1 "memory_operand" "")
6398 (const_string "load")
6399 (const_string "none")))
6400 (set_attr "mode" "QI")])
6402 (define_insn "*add<mode>_2"
6403 [(set (reg FLAGS_REG)
6406 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6407 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6409 (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6410 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6411 "ix86_match_ccmode (insn, CCGOCmode)
6412 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6413 /* Current assemblers are broken and do not allow @GOTOFF in
6414 ought but a memory context. */
6415 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6417 switch (get_attr_type (insn))
6420 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6421 if (operands[2] == const1_rtx)
6422 return "inc{<imodesuffix>}\t%0";
6425 gcc_assert (operands[2] == constm1_rtx);
6426 return "dec{<imodesuffix>}\t%0";
6430 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6431 /* ???? In DImode, we ought to handle there the 32bit case too
6432 - do we need new constraint? */
6433 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6434 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6436 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6440 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6441 (const_string "incdec")
6442 (const_string "alu")))
6443 (set (attr "length_immediate")
6445 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6447 (const_string "*")))
6448 (set_attr "mode" "<MODE>")])
6450 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6451 (define_insn "*addsi_2_zext"
6452 [(set (reg FLAGS_REG)
6454 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6455 (match_operand:SI 2 "general_operand" "g"))
6457 (set (match_operand:DI 0 "register_operand" "=r")
6458 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6459 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6460 && ix86_binary_operator_ok (PLUS, SImode, operands)
6461 /* Current assemblers are broken and do not allow @GOTOFF in
6462 ought but a memory context. */
6463 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6465 switch (get_attr_type (insn))
6468 if (operands[2] == const1_rtx)
6469 return "inc{l}\t%k0";
6472 gcc_assert (operands[2] == constm1_rtx);
6473 return "dec{l}\t%k0";
6477 if (x86_maybe_negate_const_int (&operands[2], SImode))
6478 return "sub{l}\t{%2, %k0|%k0, %2}";
6480 return "add{l}\t{%2, %k0|%k0, %2}";
6484 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6485 (const_string "incdec")
6486 (const_string "alu")))
6487 (set (attr "length_immediate")
6489 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6491 (const_string "*")))
6492 (set_attr "mode" "SI")])
6494 (define_insn "*addhi_2"
6495 [(set (reg FLAGS_REG)
6497 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6498 (match_operand:HI 2 "general_operand" "rmn,rn"))
6500 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6501 (plus:HI (match_dup 1) (match_dup 2)))]
6502 "ix86_match_ccmode (insn, CCGOCmode)
6503 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6505 switch (get_attr_type (insn))
6508 if (operands[2] == const1_rtx)
6509 return "inc{w}\t%0";
6512 gcc_assert (operands[2] == constm1_rtx);
6513 return "dec{w}\t%0";
6517 if (x86_maybe_negate_const_int (&operands[2], HImode))
6518 return "sub{w}\t{%2, %0|%0, %2}";
6520 return "add{w}\t{%2, %0|%0, %2}";
6524 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6525 (const_string "incdec")
6526 (const_string "alu")))
6527 (set (attr "length_immediate")
6529 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6531 (const_string "*")))
6532 (set_attr "mode" "HI")])
6534 (define_insn "*addqi_2"
6535 [(set (reg FLAGS_REG)
6537 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6538 (match_operand:QI 2 "general_operand" "qmn,qn"))
6540 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6541 (plus:QI (match_dup 1) (match_dup 2)))]
6542 "ix86_match_ccmode (insn, CCGOCmode)
6543 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6545 switch (get_attr_type (insn))
6548 if (operands[2] == const1_rtx)
6549 return "inc{b}\t%0";
6552 gcc_assert (operands[2] == constm1_rtx
6553 || (CONST_INT_P (operands[2])
6554 && INTVAL (operands[2]) == 255));
6555 return "dec{b}\t%0";
6559 if (x86_maybe_negate_const_int (&operands[2], QImode))
6560 return "sub{b}\t{%2, %0|%0, %2}";
6562 return "add{b}\t{%2, %0|%0, %2}";
6566 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6567 (const_string "incdec")
6568 (const_string "alu")))
6569 (set_attr "mode" "QI")])
6571 (define_insn "*add<mode>_3"
6572 [(set (reg FLAGS_REG)
6574 (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6575 (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6576 (clobber (match_scratch:SWI48 0 "=r"))]
6577 "ix86_match_ccmode (insn, CCZmode)
6578 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6579 /* Current assemblers are broken and do not allow @GOTOFF in
6580 ought but a memory context. */
6581 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6583 switch (get_attr_type (insn))
6586 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6587 if (operands[2] == const1_rtx)
6588 return "inc{<imodesuffix>}\t%0";
6591 gcc_assert (operands[2] == constm1_rtx);
6592 return "dec{<imodesuffix>}\t%0";
6596 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6597 /* ???? In DImode, we ought to handle there the 32bit case too
6598 - do we need new constraint? */
6599 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6600 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6602 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6606 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6607 (const_string "incdec")
6608 (const_string "alu")))
6609 (set (attr "length_immediate")
6611 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6613 (const_string "*")))
6614 (set_attr "mode" "<MODE>")])
6616 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6617 (define_insn "*addsi_3_zext"
6618 [(set (reg FLAGS_REG)
6620 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6621 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6622 (set (match_operand:DI 0 "register_operand" "=r")
6623 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6624 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6625 && ix86_binary_operator_ok (PLUS, SImode, operands)
6626 /* Current assemblers are broken and do not allow @GOTOFF in
6627 ought but a memory context. */
6628 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6630 switch (get_attr_type (insn))
6633 if (operands[2] == const1_rtx)
6634 return "inc{l}\t%k0";
6637 gcc_assert (operands[2] == constm1_rtx);
6638 return "dec{l}\t%k0";
6642 if (x86_maybe_negate_const_int (&operands[2], SImode))
6643 return "sub{l}\t{%2, %k0|%k0, %2}";
6645 return "add{l}\t{%2, %k0|%k0, %2}";
6649 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6650 (const_string "incdec")
6651 (const_string "alu")))
6652 (set (attr "length_immediate")
6654 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6656 (const_string "*")))
6657 (set_attr "mode" "SI")])
6659 (define_insn "*addhi_3"
6660 [(set (reg FLAGS_REG)
6662 (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6663 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6664 (clobber (match_scratch:HI 0 "=r"))]
6665 "ix86_match_ccmode (insn, CCZmode)
6666 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6668 switch (get_attr_type (insn))
6671 if (operands[2] == const1_rtx)
6672 return "inc{w}\t%0";
6675 gcc_assert (operands[2] == constm1_rtx);
6676 return "dec{w}\t%0";
6680 if (x86_maybe_negate_const_int (&operands[2], HImode))
6681 return "sub{w}\t{%2, %0|%0, %2}";
6683 return "add{w}\t{%2, %0|%0, %2}";
6687 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6688 (const_string "incdec")
6689 (const_string "alu")))
6690 (set (attr "length_immediate")
6692 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6694 (const_string "*")))
6695 (set_attr "mode" "HI")])
6697 (define_insn "*addqi_3"
6698 [(set (reg FLAGS_REG)
6700 (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6701 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6702 (clobber (match_scratch:QI 0 "=q"))]
6703 "ix86_match_ccmode (insn, CCZmode)
6704 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6706 switch (get_attr_type (insn))
6709 if (operands[2] == const1_rtx)
6710 return "inc{b}\t%0";
6713 gcc_assert (operands[2] == constm1_rtx
6714 || (CONST_INT_P (operands[2])
6715 && INTVAL (operands[2]) == 255));
6716 return "dec{b}\t%0";
6720 if (x86_maybe_negate_const_int (&operands[2], QImode))
6721 return "sub{b}\t{%2, %0|%0, %2}";
6723 return "add{b}\t{%2, %0|%0, %2}";
6727 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6728 (const_string "incdec")
6729 (const_string "alu")))
6730 (set_attr "mode" "QI")])
6732 ; For comparisons against 1, -1 and 128, we may generate better code
6733 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6734 ; is matched then. We can't accept general immediate, because for
6735 ; case of overflows, the result is messed up.
6736 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6737 ; only for comparisons not depending on it.
6739 (define_insn "*adddi_4"
6740 [(set (reg FLAGS_REG)
6742 (match_operand:DI 1 "nonimmediate_operand" "0")
6743 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6744 (clobber (match_scratch:DI 0 "=rm"))]
6746 && ix86_match_ccmode (insn, CCGCmode)"
6748 switch (get_attr_type (insn))
6751 if (operands[2] == constm1_rtx)
6752 return "inc{q}\t%0";
6755 gcc_assert (operands[2] == const1_rtx);
6756 return "dec{q}\t%0";
6760 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6761 if (x86_maybe_negate_const_int (&operands[2], DImode))
6762 return "add{q}\t{%2, %0|%0, %2}";
6764 return "sub{q}\t{%2, %0|%0, %2}";
6768 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6769 (const_string "incdec")
6770 (const_string "alu")))
6771 (set (attr "length_immediate")
6773 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6775 (const_string "*")))
6776 (set_attr "mode" "DI")])
6778 ; For comparisons against 1, -1 and 128, we may generate better code
6779 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6780 ; is matched then. We can't accept general immediate, because for
6781 ; case of overflows, the result is messed up.
6782 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6783 ; only for comparisons not depending on it.
6785 (define_insn "*addsi_4"
6786 [(set (reg FLAGS_REG)
6788 (match_operand:SI 1 "nonimmediate_operand" "0")
6789 (match_operand:SI 2 "const_int_operand" "n")))
6790 (clobber (match_scratch:SI 0 "=rm"))]
6791 "ix86_match_ccmode (insn, CCGCmode)"
6793 switch (get_attr_type (insn))
6796 if (operands[2] == constm1_rtx)
6797 return "inc{l}\t%0";
6800 gcc_assert (operands[2] == const1_rtx);
6801 return "dec{l}\t%0";
6805 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6806 if (x86_maybe_negate_const_int (&operands[2], SImode))
6807 return "add{l}\t{%2, %0|%0, %2}";
6809 return "sub{l}\t{%2, %0|%0, %2}";
6813 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6814 (const_string "incdec")
6815 (const_string "alu")))
6816 (set (attr "length_immediate")
6818 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6820 (const_string "*")))
6821 (set_attr "mode" "SI")])
6823 ; See comments above addsi_4 for details.
6825 (define_insn "*addhi_4"
6826 [(set (reg FLAGS_REG)
6828 (match_operand:HI 1 "nonimmediate_operand" "0")
6829 (match_operand:HI 2 "const_int_operand" "n")))
6830 (clobber (match_scratch:HI 0 "=rm"))]
6831 "ix86_match_ccmode (insn, CCGCmode)"
6833 switch (get_attr_type (insn))
6836 if (operands[2] == constm1_rtx)
6837 return "inc{w}\t%0";
6840 gcc_assert (operands[2] == const1_rtx);
6841 return "dec{w}\t%0";
6845 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6846 if (x86_maybe_negate_const_int (&operands[2], HImode))
6847 return "add{w}\t{%2, %0|%0, %2}";
6849 return "sub{w}\t{%2, %0|%0, %2}";
6853 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6854 (const_string "incdec")
6855 (const_string "alu")))
6856 (set (attr "length_immediate")
6858 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6860 (const_string "*")))
6861 (set_attr "mode" "HI")])
6863 ; See comments above addsi_4 for details.
6865 (define_insn "*addqi_4"
6866 [(set (reg FLAGS_REG)
6868 (match_operand:QI 1 "nonimmediate_operand" "0")
6869 (match_operand:QI 2 "const_int_operand" "n")))
6870 (clobber (match_scratch:QI 0 "=qm"))]
6871 "ix86_match_ccmode (insn, CCGCmode)"
6873 switch (get_attr_type (insn))
6876 if (operands[2] == constm1_rtx
6877 || (CONST_INT_P (operands[2])
6878 && INTVAL (operands[2]) == 255))
6879 return "inc{b}\t%0";
6882 gcc_assert (operands[2] == const1_rtx);
6883 return "dec{b}\t%0";
6887 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6888 if (x86_maybe_negate_const_int (&operands[2], QImode))
6889 return "add{b}\t{%2, %0|%0, %2}";
6891 return "sub{b}\t{%2, %0|%0, %2}";
6895 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6896 (const_string "incdec")
6897 (const_string "alu")))
6898 (set_attr "mode" "QI")])
6900 (define_insn "*add<mode>_5"
6901 [(set (reg FLAGS_REG)
6904 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6905 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6907 (clobber (match_scratch:SWI48 0 "=r"))]
6908 "ix86_match_ccmode (insn, CCGOCmode)
6909 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6910 /* Current assemblers are broken and do not allow @GOTOFF in
6911 ought but a memory context. */
6912 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6914 switch (get_attr_type (insn))
6917 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6918 if (operands[2] == const1_rtx)
6919 return "inc{<imodesuffix>}\t%0";
6922 gcc_assert (operands[2] == constm1_rtx);
6923 return "dec{<imodesuffix>}\t%0";
6927 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6928 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6929 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6931 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6935 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6936 (const_string "incdec")
6937 (const_string "alu")))
6938 (set (attr "length_immediate")
6940 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6942 (const_string "*")))
6943 (set_attr "mode" "<MODE>")])
6945 (define_insn "*addhi_5"
6946 [(set (reg FLAGS_REG)
6948 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6949 (match_operand:HI 2 "general_operand" "rmn"))
6951 (clobber (match_scratch:HI 0 "=r"))]
6952 "ix86_match_ccmode (insn, CCGOCmode)
6953 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6955 switch (get_attr_type (insn))
6958 if (operands[2] == const1_rtx)
6959 return "inc{w}\t%0";
6962 gcc_assert (operands[2] == constm1_rtx);
6963 return "dec{w}\t%0";
6967 if (x86_maybe_negate_const_int (&operands[2], HImode))
6968 return "sub{w}\t{%2, %0|%0, %2}";
6970 return "add{w}\t{%2, %0|%0, %2}";
6974 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6975 (const_string "incdec")
6976 (const_string "alu")))
6977 (set (attr "length_immediate")
6979 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6981 (const_string "*")))
6982 (set_attr "mode" "HI")])
6984 (define_insn "*addqi_5"
6985 [(set (reg FLAGS_REG)
6987 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6988 (match_operand:QI 2 "general_operand" "qmn"))
6990 (clobber (match_scratch:QI 0 "=q"))]
6991 "ix86_match_ccmode (insn, CCGOCmode)
6992 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6994 switch (get_attr_type (insn))
6997 if (operands[2] == const1_rtx)
6998 return "inc{b}\t%0";
7001 gcc_assert (operands[2] == constm1_rtx
7002 || (CONST_INT_P (operands[2])
7003 && INTVAL (operands[2]) == 255));
7004 return "dec{b}\t%0";
7008 if (x86_maybe_negate_const_int (&operands[2], QImode))
7009 return "sub{b}\t{%2, %0|%0, %2}";
7011 return "add{b}\t{%2, %0|%0, %2}";
7015 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7016 (const_string "incdec")
7017 (const_string "alu")))
7018 (set_attr "mode" "QI")])
7020 (define_insn "*addqi_ext_1_rex64"
7021 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7026 (match_operand 1 "ext_register_operand" "0")
7029 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7030 (clobber (reg:CC FLAGS_REG))]
7033 switch (get_attr_type (insn))
7036 if (operands[2] == const1_rtx)
7037 return "inc{b}\t%h0";
7040 gcc_assert (operands[2] == constm1_rtx
7041 || (CONST_INT_P (operands[2])
7042 && INTVAL (operands[2]) == 255));
7043 return "dec{b}\t%h0";
7047 return "add{b}\t{%2, %h0|%h0, %2}";
7051 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7052 (const_string "incdec")
7053 (const_string "alu")))
7054 (set_attr "modrm" "1")
7055 (set_attr "mode" "QI")])
7057 (define_insn "addqi_ext_1"
7058 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7063 (match_operand 1 "ext_register_operand" "0")
7066 (match_operand:QI 2 "general_operand" "Qmn")))
7067 (clobber (reg:CC FLAGS_REG))]
7070 switch (get_attr_type (insn))
7073 if (operands[2] == const1_rtx)
7074 return "inc{b}\t%h0";
7077 gcc_assert (operands[2] == constm1_rtx
7078 || (CONST_INT_P (operands[2])
7079 && INTVAL (operands[2]) == 255));
7080 return "dec{b}\t%h0";
7084 return "add{b}\t{%2, %h0|%h0, %2}";
7088 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7089 (const_string "incdec")
7090 (const_string "alu")))
7091 (set_attr "modrm" "1")
7092 (set_attr "mode" "QI")])
7094 (define_insn "*addqi_ext_2"
7095 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7100 (match_operand 1 "ext_register_operand" "%0")
7104 (match_operand 2 "ext_register_operand" "Q")
7107 (clobber (reg:CC FLAGS_REG))]
7109 "add{b}\t{%h2, %h0|%h0, %h2}"
7110 [(set_attr "type" "alu")
7111 (set_attr "mode" "QI")])
7113 ;; The lea patterns for non-Pmodes needs to be matched by
7114 ;; several insns converted to real lea by splitters.
7116 (define_insn_and_split "*lea_general_1"
7117 [(set (match_operand 0 "register_operand" "=r")
7118 (plus (plus (match_operand 1 "index_register_operand" "l")
7119 (match_operand 2 "register_operand" "r"))
7120 (match_operand 3 "immediate_operand" "i")))]
7121 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7122 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7123 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7124 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7125 && GET_MODE (operands[0]) == GET_MODE (operands[2])
7126 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7127 || GET_MODE (operands[3]) == VOIDmode)"
7129 "&& reload_completed"
7133 operands[0] = gen_lowpart (SImode, operands[0]);
7134 operands[1] = gen_lowpart (Pmode, operands[1]);
7135 operands[2] = gen_lowpart (Pmode, operands[2]);
7136 operands[3] = gen_lowpart (Pmode, operands[3]);
7137 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7139 if (Pmode != SImode)
7140 pat = gen_rtx_SUBREG (SImode, pat, 0);
7141 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7144 [(set_attr "type" "lea")
7145 (set_attr "mode" "SI")])
7147 (define_insn_and_split "*lea_general_1_zext"
7148 [(set (match_operand:DI 0 "register_operand" "=r")
7151 (match_operand:SI 1 "index_register_operand" "l")
7152 (match_operand:SI 2 "register_operand" "r"))
7153 (match_operand:SI 3 "immediate_operand" "i"))))]
7156 "&& reload_completed"
7158 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7160 (match_dup 3)) 0)))]
7162 operands[1] = gen_lowpart (Pmode, operands[1]);
7163 operands[2] = gen_lowpart (Pmode, operands[2]);
7164 operands[3] = gen_lowpart (Pmode, operands[3]);
7166 [(set_attr "type" "lea")
7167 (set_attr "mode" "SI")])
7169 (define_insn_and_split "*lea_general_2"
7170 [(set (match_operand 0 "register_operand" "=r")
7171 (plus (mult (match_operand 1 "index_register_operand" "l")
7172 (match_operand 2 "const248_operand" "i"))
7173 (match_operand 3 "nonmemory_operand" "ri")))]
7174 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7175 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7176 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7177 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7178 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7179 || GET_MODE (operands[3]) == VOIDmode)"
7181 "&& reload_completed"
7185 operands[0] = gen_lowpart (SImode, operands[0]);
7186 operands[1] = gen_lowpart (Pmode, operands[1]);
7187 operands[3] = gen_lowpart (Pmode, operands[3]);
7188 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7190 if (Pmode != SImode)
7191 pat = gen_rtx_SUBREG (SImode, pat, 0);
7192 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7195 [(set_attr "type" "lea")
7196 (set_attr "mode" "SI")])
7198 (define_insn_and_split "*lea_general_2_zext"
7199 [(set (match_operand:DI 0 "register_operand" "=r")
7202 (match_operand:SI 1 "index_register_operand" "l")
7203 (match_operand:SI 2 "const248_operand" "n"))
7204 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7207 "&& reload_completed"
7209 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7211 (match_dup 3)) 0)))]
7213 operands[1] = gen_lowpart (Pmode, operands[1]);
7214 operands[3] = gen_lowpart (Pmode, operands[3]);
7216 [(set_attr "type" "lea")
7217 (set_attr "mode" "SI")])
7219 (define_insn_and_split "*lea_general_3"
7220 [(set (match_operand 0 "register_operand" "=r")
7221 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7222 (match_operand 2 "const248_operand" "i"))
7223 (match_operand 3 "register_operand" "r"))
7224 (match_operand 4 "immediate_operand" "i")))]
7225 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7226 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7227 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7228 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7229 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7231 "&& reload_completed"
7235 operands[0] = gen_lowpart (SImode, operands[0]);
7236 operands[1] = gen_lowpart (Pmode, operands[1]);
7237 operands[3] = gen_lowpart (Pmode, operands[3]);
7238 operands[4] = gen_lowpart (Pmode, operands[4]);
7239 pat = gen_rtx_PLUS (Pmode,
7240 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7244 if (Pmode != SImode)
7245 pat = gen_rtx_SUBREG (SImode, pat, 0);
7246 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7249 [(set_attr "type" "lea")
7250 (set_attr "mode" "SI")])
7252 (define_insn_and_split "*lea_general_3_zext"
7253 [(set (match_operand:DI 0 "register_operand" "=r")
7257 (match_operand:SI 1 "index_register_operand" "l")
7258 (match_operand:SI 2 "const248_operand" "n"))
7259 (match_operand:SI 3 "register_operand" "r"))
7260 (match_operand:SI 4 "immediate_operand" "i"))))]
7263 "&& reload_completed"
7265 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7268 (match_dup 4)) 0)))]
7270 operands[1] = gen_lowpart (Pmode, operands[1]);
7271 operands[3] = gen_lowpart (Pmode, operands[3]);
7272 operands[4] = gen_lowpart (Pmode, operands[4]);
7274 [(set_attr "type" "lea")
7275 (set_attr "mode" "SI")])
7277 ;; Convert lea to the lea pattern to avoid flags dependency.
7279 [(set (match_operand:DI 0 "register_operand" "")
7280 (plus:DI (match_operand:DI 1 "register_operand" "")
7281 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7282 (clobber (reg:CC FLAGS_REG))]
7283 "TARGET_64BIT && reload_completed
7284 && ix86_lea_for_add_ok (PLUS, insn, operands)"
7286 (plus:DI (match_dup 1)
7290 ;; Convert lea to the lea pattern to avoid flags dependency.
7292 [(set (match_operand 0 "register_operand" "")
7293 (plus (match_operand 1 "register_operand" "")
7294 (match_operand 2 "nonmemory_operand" "")))
7295 (clobber (reg:CC FLAGS_REG))]
7296 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
7300 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7301 may confuse gen_lowpart. */
7302 if (GET_MODE (operands[0]) != Pmode)
7304 operands[1] = gen_lowpart (Pmode, operands[1]);
7305 operands[2] = gen_lowpart (Pmode, operands[2]);
7307 operands[0] = gen_lowpart (SImode, operands[0]);
7308 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7309 if (Pmode != SImode)
7310 pat = gen_rtx_SUBREG (SImode, pat, 0);
7311 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7315 ;; Convert lea to the lea pattern to avoid flags dependency.
7317 [(set (match_operand:DI 0 "register_operand" "")
7319 (plus:SI (match_operand:SI 1 "register_operand" "")
7320 (match_operand:SI 2 "nonmemory_operand" ""))))
7321 (clobber (reg:CC FLAGS_REG))]
7322 "TARGET_64BIT && reload_completed
7323 && true_regnum (operands[0]) != true_regnum (operands[1])"
7325 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7327 operands[1] = gen_lowpart (Pmode, operands[1]);
7328 operands[2] = gen_lowpart (Pmode, operands[2]);
7331 ;; Subtract instructions
7333 (define_expand "sub<mode>3"
7334 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7335 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7336 (match_operand:SDWIM 2 "<general_operand>" "")))]
7338 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7340 (define_insn_and_split "*sub<dwi>3_doubleword"
7341 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7343 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7344 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7345 (clobber (reg:CC FLAGS_REG))]
7346 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7349 [(parallel [(set (reg:CC FLAGS_REG)
7350 (compare:CC (match_dup 1) (match_dup 2)))
7352 (minus:DWIH (match_dup 1) (match_dup 2)))])
7353 (parallel [(set (match_dup 3)
7357 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7359 (clobber (reg:CC FLAGS_REG))])]
7360 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7362 (define_insn "*sub<mode>_1"
7363 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7365 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7366 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7367 (clobber (reg:CC FLAGS_REG))]
7368 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7369 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7370 [(set_attr "type" "alu")
7371 (set_attr "mode" "<MODE>")])
7373 (define_insn "*subsi_1_zext"
7374 [(set (match_operand:DI 0 "register_operand" "=r")
7376 (minus:SI (match_operand:SI 1 "register_operand" "0")
7377 (match_operand:SI 2 "general_operand" "g"))))
7378 (clobber (reg:CC FLAGS_REG))]
7379 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7380 "sub{l}\t{%2, %k0|%k0, %2}"
7381 [(set_attr "type" "alu")
7382 (set_attr "mode" "SI")])
7384 (define_insn "*subqi_1_slp"
7385 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7386 (minus:QI (match_dup 0)
7387 (match_operand:QI 1 "general_operand" "qn,qm")))
7388 (clobber (reg:CC FLAGS_REG))]
7389 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7390 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7391 "sub{b}\t{%1, %0|%0, %1}"
7392 [(set_attr "type" "alu1")
7393 (set_attr "mode" "QI")])
7395 (define_insn "*sub<mode>_2"
7396 [(set (reg FLAGS_REG)
7399 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7400 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7402 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7403 (minus:SWI (match_dup 1) (match_dup 2)))]
7404 "ix86_match_ccmode (insn, CCGOCmode)
7405 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7406 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7407 [(set_attr "type" "alu")
7408 (set_attr "mode" "<MODE>")])
7410 (define_insn "*subsi_2_zext"
7411 [(set (reg FLAGS_REG)
7413 (minus:SI (match_operand:SI 1 "register_operand" "0")
7414 (match_operand:SI 2 "general_operand" "g"))
7416 (set (match_operand:DI 0 "register_operand" "=r")
7418 (minus:SI (match_dup 1)
7420 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7421 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7422 "sub{l}\t{%2, %k0|%k0, %2}"
7423 [(set_attr "type" "alu")
7424 (set_attr "mode" "SI")])
7426 (define_insn "*sub<mode>_3"
7427 [(set (reg FLAGS_REG)
7428 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7429 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7430 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7431 (minus:SWI (match_dup 1) (match_dup 2)))]
7432 "ix86_match_ccmode (insn, CCmode)
7433 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7434 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7435 [(set_attr "type" "alu")
7436 (set_attr "mode" "<MODE>")])
7438 (define_insn "*subsi_3_zext"
7439 [(set (reg FLAGS_REG)
7440 (compare (match_operand:SI 1 "register_operand" "0")
7441 (match_operand:SI 2 "general_operand" "g")))
7442 (set (match_operand:DI 0 "register_operand" "=r")
7444 (minus:SI (match_dup 1)
7446 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7447 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7448 "sub{l}\t{%2, %1|%1, %2}"
7449 [(set_attr "type" "alu")
7450 (set_attr "mode" "SI")])
7452 ;; Add with carry and subtract with borrow
7454 (define_expand "<plusminus_insn><mode>3_carry"
7456 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7458 (match_operand:SWI 1 "nonimmediate_operand" "")
7459 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7460 [(match_operand 3 "flags_reg_operand" "")
7462 (match_operand:SWI 2 "<general_operand>" ""))))
7463 (clobber (reg:CC FLAGS_REG))])]
7464 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7467 (define_insn "*<plusminus_insn><mode>3_carry"
7468 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7470 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7472 (match_operator 3 "ix86_carry_flag_operator"
7473 [(reg FLAGS_REG) (const_int 0)])
7474 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7475 (clobber (reg:CC FLAGS_REG))]
7476 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7477 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7478 [(set_attr "type" "alu")
7479 (set_attr "use_carry" "1")
7480 (set_attr "pent_pair" "pu")
7481 (set_attr "mode" "<MODE>")])
7483 (define_insn "*addsi3_carry_zext"
7484 [(set (match_operand:DI 0 "register_operand" "=r")
7486 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7487 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7488 [(reg FLAGS_REG) (const_int 0)])
7489 (match_operand:SI 2 "general_operand" "g")))))
7490 (clobber (reg:CC FLAGS_REG))]
7491 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7492 "adc{l}\t{%2, %k0|%k0, %2}"
7493 [(set_attr "type" "alu")
7494 (set_attr "use_carry" "1")
7495 (set_attr "pent_pair" "pu")
7496 (set_attr "mode" "SI")])
7498 (define_insn "*subsi3_carry_zext"
7499 [(set (match_operand:DI 0 "register_operand" "=r")
7501 (minus:SI (match_operand:SI 1 "register_operand" "0")
7502 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7503 [(reg FLAGS_REG) (const_int 0)])
7504 (match_operand:SI 2 "general_operand" "g")))))
7505 (clobber (reg:CC FLAGS_REG))]
7506 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7507 "sbb{l}\t{%2, %k0|%k0, %2}"
7508 [(set_attr "type" "alu")
7509 (set_attr "pent_pair" "pu")
7510 (set_attr "mode" "SI")])
7512 ;; Overflow setting add and subtract instructions
7514 (define_insn "*add<mode>3_cconly_overflow"
7515 [(set (reg:CCC FLAGS_REG)
7518 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7519 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7521 (clobber (match_scratch:SWI 0 "=<r>"))]
7522 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7523 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7524 [(set_attr "type" "alu")
7525 (set_attr "mode" "<MODE>")])
7527 (define_insn "*sub<mode>3_cconly_overflow"
7528 [(set (reg:CCC FLAGS_REG)
7531 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7532 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7535 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7536 [(set_attr "type" "icmp")
7537 (set_attr "mode" "<MODE>")])
7539 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7540 [(set (reg:CCC FLAGS_REG)
7543 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7544 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7546 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7547 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7548 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7549 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7550 [(set_attr "type" "alu")
7551 (set_attr "mode" "<MODE>")])
7553 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7554 [(set (reg:CCC FLAGS_REG)
7557 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7558 (match_operand:SI 2 "general_operand" "g"))
7560 (set (match_operand:DI 0 "register_operand" "=r")
7561 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7562 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7563 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7564 [(set_attr "type" "alu")
7565 (set_attr "mode" "SI")])
7567 ;; The patterns that match these are at the end of this file.
7569 (define_expand "<plusminus_insn>xf3"
7570 [(set (match_operand:XF 0 "register_operand" "")
7572 (match_operand:XF 1 "register_operand" "")
7573 (match_operand:XF 2 "register_operand" "")))]
7577 (define_expand "<plusminus_insn><mode>3"
7578 [(set (match_operand:MODEF 0 "register_operand" "")
7580 (match_operand:MODEF 1 "register_operand" "")
7581 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7582 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7583 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7586 ;; Multiply instructions
7588 (define_expand "mul<mode>3"
7589 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7591 (match_operand:SWIM248 1 "register_operand" "")
7592 (match_operand:SWIM248 2 "<general_operand>" "")))
7593 (clobber (reg:CC FLAGS_REG))])]
7597 (define_expand "mulqi3"
7598 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7600 (match_operand:QI 1 "register_operand" "")
7601 (match_operand:QI 2 "nonimmediate_operand" "")))
7602 (clobber (reg:CC FLAGS_REG))])]
7603 "TARGET_QIMODE_MATH"
7607 ;; IMUL reg32/64, reg32/64, imm8 Direct
7608 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7609 ;; IMUL reg32/64, reg32/64, imm32 Direct
7610 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7611 ;; IMUL reg32/64, reg32/64 Direct
7612 ;; IMUL reg32/64, mem32/64 Direct
7614 (define_insn "*mul<mode>3_1"
7615 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7617 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7618 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7619 (clobber (reg:CC FLAGS_REG))]
7620 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7622 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7623 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7624 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7625 [(set_attr "type" "imul")
7626 (set_attr "prefix_0f" "0,0,1")
7627 (set (attr "athlon_decode")
7628 (cond [(eq_attr "cpu" "athlon")
7629 (const_string "vector")
7630 (eq_attr "alternative" "1")
7631 (const_string "vector")
7632 (and (eq_attr "alternative" "2")
7633 (match_operand 1 "memory_operand" ""))
7634 (const_string "vector")]
7635 (const_string "direct")))
7636 (set (attr "amdfam10_decode")
7637 (cond [(and (eq_attr "alternative" "0,1")
7638 (match_operand 1 "memory_operand" ""))
7639 (const_string "vector")]
7640 (const_string "direct")))
7641 (set_attr "mode" "<MODE>")])
7643 (define_insn "*mulsi3_1_zext"
7644 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7646 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7647 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7648 (clobber (reg:CC FLAGS_REG))]
7650 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7652 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7653 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7654 imul{l}\t{%2, %k0|%k0, %2}"
7655 [(set_attr "type" "imul")
7656 (set_attr "prefix_0f" "0,0,1")
7657 (set (attr "athlon_decode")
7658 (cond [(eq_attr "cpu" "athlon")
7659 (const_string "vector")
7660 (eq_attr "alternative" "1")
7661 (const_string "vector")
7662 (and (eq_attr "alternative" "2")
7663 (match_operand 1 "memory_operand" ""))
7664 (const_string "vector")]
7665 (const_string "direct")))
7666 (set (attr "amdfam10_decode")
7667 (cond [(and (eq_attr "alternative" "0,1")
7668 (match_operand 1 "memory_operand" ""))
7669 (const_string "vector")]
7670 (const_string "direct")))
7671 (set_attr "mode" "SI")])
7674 ;; IMUL reg16, reg16, imm8 VectorPath
7675 ;; IMUL reg16, mem16, imm8 VectorPath
7676 ;; IMUL reg16, reg16, imm16 VectorPath
7677 ;; IMUL reg16, mem16, imm16 VectorPath
7678 ;; IMUL reg16, reg16 Direct
7679 ;; IMUL reg16, mem16 Direct
7681 (define_insn "*mulhi3_1"
7682 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7683 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7684 (match_operand:HI 2 "general_operand" "K,n,mr")))
7685 (clobber (reg:CC FLAGS_REG))]
7687 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7689 imul{w}\t{%2, %1, %0|%0, %1, %2}
7690 imul{w}\t{%2, %1, %0|%0, %1, %2}
7691 imul{w}\t{%2, %0|%0, %2}"
7692 [(set_attr "type" "imul")
7693 (set_attr "prefix_0f" "0,0,1")
7694 (set (attr "athlon_decode")
7695 (cond [(eq_attr "cpu" "athlon")
7696 (const_string "vector")
7697 (eq_attr "alternative" "1,2")
7698 (const_string "vector")]
7699 (const_string "direct")))
7700 (set (attr "amdfam10_decode")
7701 (cond [(eq_attr "alternative" "0,1")
7702 (const_string "vector")]
7703 (const_string "direct")))
7704 (set_attr "mode" "HI")])
7710 (define_insn "*mulqi3_1"
7711 [(set (match_operand:QI 0 "register_operand" "=a")
7712 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7713 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7714 (clobber (reg:CC FLAGS_REG))]
7716 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7718 [(set_attr "type" "imul")
7719 (set_attr "length_immediate" "0")
7720 (set (attr "athlon_decode")
7721 (if_then_else (eq_attr "cpu" "athlon")
7722 (const_string "vector")
7723 (const_string "direct")))
7724 (set_attr "amdfam10_decode" "direct")
7725 (set_attr "mode" "QI")])
7727 (define_expand "<u>mul<mode><dwi>3"
7728 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7731 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7733 (match_operand:DWIH 2 "register_operand" ""))))
7734 (clobber (reg:CC FLAGS_REG))])]
7738 (define_expand "<u>mulqihi3"
7739 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7742 (match_operand:QI 1 "nonimmediate_operand" ""))
7744 (match_operand:QI 2 "register_operand" ""))))
7745 (clobber (reg:CC FLAGS_REG))])]
7746 "TARGET_QIMODE_MATH"
7749 (define_insn "*<u>mul<mode><dwi>3_1"
7750 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7753 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7755 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7756 (clobber (reg:CC FLAGS_REG))]
7757 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7758 "<sgnprefix>mul{<imodesuffix>}\t%2"
7759 [(set_attr "type" "imul")
7760 (set_attr "length_immediate" "0")
7761 (set (attr "athlon_decode")
7762 (if_then_else (eq_attr "cpu" "athlon")
7763 (const_string "vector")
7764 (const_string "double")))
7765 (set_attr "amdfam10_decode" "double")
7766 (set_attr "mode" "<MODE>")])
7768 (define_insn "*<u>mulqihi3_1"
7769 [(set (match_operand:HI 0 "register_operand" "=a")
7772 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7774 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7775 (clobber (reg:CC FLAGS_REG))]
7777 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7778 "<sgnprefix>mul{b}\t%2"
7779 [(set_attr "type" "imul")
7780 (set_attr "length_immediate" "0")
7781 (set (attr "athlon_decode")
7782 (if_then_else (eq_attr "cpu" "athlon")
7783 (const_string "vector")
7784 (const_string "direct")))
7785 (set_attr "amdfam10_decode" "direct")
7786 (set_attr "mode" "QI")])
7788 (define_expand "<s>mul<mode>3_highpart"
7789 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7794 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7796 (match_operand:SWI48 2 "register_operand" "")))
7798 (clobber (match_scratch:SWI48 3 ""))
7799 (clobber (reg:CC FLAGS_REG))])]
7801 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7803 (define_insn "*<s>muldi3_highpart_1"
7804 [(set (match_operand:DI 0 "register_operand" "=d")
7809 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7811 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7813 (clobber (match_scratch:DI 3 "=1"))
7814 (clobber (reg:CC FLAGS_REG))]
7816 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7817 "<sgnprefix>mul{q}\t%2"
7818 [(set_attr "type" "imul")
7819 (set_attr "length_immediate" "0")
7820 (set (attr "athlon_decode")
7821 (if_then_else (eq_attr "cpu" "athlon")
7822 (const_string "vector")
7823 (const_string "double")))
7824 (set_attr "amdfam10_decode" "double")
7825 (set_attr "mode" "DI")])
7827 (define_insn "*<s>mulsi3_highpart_1"
7828 [(set (match_operand:SI 0 "register_operand" "=d")
7833 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7835 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7837 (clobber (match_scratch:SI 3 "=1"))
7838 (clobber (reg:CC FLAGS_REG))]
7839 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7840 "<sgnprefix>mul{l}\t%2"
7841 [(set_attr "type" "imul")
7842 (set_attr "length_immediate" "0")
7843 (set (attr "athlon_decode")
7844 (if_then_else (eq_attr "cpu" "athlon")
7845 (const_string "vector")
7846 (const_string "double")))
7847 (set_attr "amdfam10_decode" "double")
7848 (set_attr "mode" "SI")])
7850 (define_insn "*<s>mulsi3_highpart_zext"
7851 [(set (match_operand:DI 0 "register_operand" "=d")
7852 (zero_extend:DI (truncate:SI
7854 (mult:DI (any_extend:DI
7855 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7857 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7859 (clobber (match_scratch:SI 3 "=1"))
7860 (clobber (reg:CC FLAGS_REG))]
7862 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7863 "<sgnprefix>mul{l}\t%2"
7864 [(set_attr "type" "imul")
7865 (set_attr "length_immediate" "0")
7866 (set (attr "athlon_decode")
7867 (if_then_else (eq_attr "cpu" "athlon")
7868 (const_string "vector")
7869 (const_string "double")))
7870 (set_attr "amdfam10_decode" "double")
7871 (set_attr "mode" "SI")])
7873 ;; The patterns that match these are at the end of this file.
7875 (define_expand "mulxf3"
7876 [(set (match_operand:XF 0 "register_operand" "")
7877 (mult:XF (match_operand:XF 1 "register_operand" "")
7878 (match_operand:XF 2 "register_operand" "")))]
7882 (define_expand "mul<mode>3"
7883 [(set (match_operand:MODEF 0 "register_operand" "")
7884 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7885 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7886 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7887 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7890 ;; Divide instructions
7892 (define_insn "<u>divqi3"
7893 [(set (match_operand:QI 0 "register_operand" "=a")
7895 (match_operand:HI 1 "register_operand" "0")
7896 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7897 (clobber (reg:CC FLAGS_REG))]
7898 "TARGET_QIMODE_MATH"
7899 "<sgnprefix>div{b}\t%2"
7900 [(set_attr "type" "idiv")
7901 (set_attr "mode" "QI")])
7903 ;; The patterns that match these are at the end of this file.
7905 (define_expand "divxf3"
7906 [(set (match_operand:XF 0 "register_operand" "")
7907 (div:XF (match_operand:XF 1 "register_operand" "")
7908 (match_operand:XF 2 "register_operand" "")))]
7912 (define_expand "divdf3"
7913 [(set (match_operand:DF 0 "register_operand" "")
7914 (div:DF (match_operand:DF 1 "register_operand" "")
7915 (match_operand:DF 2 "nonimmediate_operand" "")))]
7916 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7917 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7920 (define_expand "divsf3"
7921 [(set (match_operand:SF 0 "register_operand" "")
7922 (div:SF (match_operand:SF 1 "register_operand" "")
7923 (match_operand:SF 2 "nonimmediate_operand" "")))]
7924 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7927 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7928 && flag_finite_math_only && !flag_trapping_math
7929 && flag_unsafe_math_optimizations)
7931 ix86_emit_swdivsf (operands[0], operands[1],
7932 operands[2], SFmode);
7937 ;; Divmod instructions.
7939 (define_expand "divmod<mode>4"
7940 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7942 (match_operand:SWIM248 1 "register_operand" "")
7943 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7944 (set (match_operand:SWIM248 3 "register_operand" "")
7945 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7946 (clobber (reg:CC FLAGS_REG))])]
7950 (define_insn_and_split "*divmod<mode>4"
7951 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7952 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7953 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7954 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7955 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7956 (clobber (reg:CC FLAGS_REG))]
7960 [(parallel [(set (match_dup 1)
7961 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7962 (clobber (reg:CC FLAGS_REG))])
7963 (parallel [(set (match_dup 0)
7964 (div:SWIM248 (match_dup 2) (match_dup 3)))
7966 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7968 (clobber (reg:CC FLAGS_REG))])]
7970 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7972 if (<MODE>mode != HImode
7973 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7974 operands[4] = operands[2];
7977 /* Avoid use of cltd in favor of a mov+shift. */
7978 emit_move_insn (operands[1], operands[2]);
7979 operands[4] = operands[1];
7982 [(set_attr "type" "multi")
7983 (set_attr "mode" "<MODE>")])
7985 (define_insn "*divmod<mode>4_noext"
7986 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7987 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7988 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7989 (set (match_operand:SWIM248 1 "register_operand" "=d")
7990 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7991 (use (match_operand:SWIM248 4 "register_operand" "1"))
7992 (clobber (reg:CC FLAGS_REG))]
7994 "idiv{<imodesuffix>}\t%3"
7995 [(set_attr "type" "idiv")
7996 (set_attr "mode" "<MODE>")])
7998 (define_expand "udivmod<mode>4"
7999 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8001 (match_operand:SWIM248 1 "register_operand" "")
8002 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8003 (set (match_operand:SWIM248 3 "register_operand" "")
8004 (umod:SWIM248 (match_dup 1) (match_dup 2)))
8005 (clobber (reg:CC FLAGS_REG))])]
8009 (define_insn_and_split "*udivmod<mode>4"
8010 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8011 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8012 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8013 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8014 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8015 (clobber (reg:CC FLAGS_REG))]
8019 [(set (match_dup 1) (const_int 0))
8020 (parallel [(set (match_dup 0)
8021 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8023 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8025 (clobber (reg:CC FLAGS_REG))])]
8027 [(set_attr "type" "multi")
8028 (set_attr "mode" "<MODE>")])
8030 (define_insn "*udivmod<mode>4_noext"
8031 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8032 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8033 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8034 (set (match_operand:SWIM248 1 "register_operand" "=d")
8035 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8036 (use (match_operand:SWIM248 4 "register_operand" "1"))
8037 (clobber (reg:CC FLAGS_REG))]
8039 "div{<imodesuffix>}\t%3"
8040 [(set_attr "type" "idiv")
8041 (set_attr "mode" "<MODE>")])
8043 ;; We cannot use div/idiv for double division, because it causes
8044 ;; "division by zero" on the overflow and that's not what we expect
8045 ;; from truncate. Because true (non truncating) double division is
8046 ;; never generated, we can't create this insn anyway.
8049 ; [(set (match_operand:SI 0 "register_operand" "=a")
8051 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8053 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8054 ; (set (match_operand:SI 3 "register_operand" "=d")
8056 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8057 ; (clobber (reg:CC FLAGS_REG))]
8059 ; "div{l}\t{%2, %0|%0, %2}"
8060 ; [(set_attr "type" "idiv")])
8062 ;;- Logical AND instructions
8064 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8065 ;; Note that this excludes ah.
8067 (define_expand "testsi_ccno_1"
8068 [(set (reg:CCNO FLAGS_REG)
8070 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8071 (match_operand:SI 1 "nonmemory_operand" ""))
8076 (define_expand "testqi_ccz_1"
8077 [(set (reg:CCZ FLAGS_REG)
8078 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8079 (match_operand:QI 1 "nonmemory_operand" ""))
8084 (define_insn "*testdi_1"
8085 [(set (reg FLAGS_REG)
8088 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8089 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8091 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8092 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8094 test{l}\t{%k1, %k0|%k0, %k1}
8095 test{l}\t{%k1, %k0|%k0, %k1}
8096 test{q}\t{%1, %0|%0, %1}
8097 test{q}\t{%1, %0|%0, %1}
8098 test{q}\t{%1, %0|%0, %1}"
8099 [(set_attr "type" "test")
8100 (set_attr "modrm" "0,1,0,1,1")
8101 (set_attr "mode" "SI,SI,DI,DI,DI")])
8103 (define_insn "*testqi_1_maybe_si"
8104 [(set (reg FLAGS_REG)
8107 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8108 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8110 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8111 && ix86_match_ccmode (insn,
8112 CONST_INT_P (operands[1])
8113 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8115 if (which_alternative == 3)
8117 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8118 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8119 return "test{l}\t{%1, %k0|%k0, %1}";
8121 return "test{b}\t{%1, %0|%0, %1}";
8123 [(set_attr "type" "test")
8124 (set_attr "modrm" "0,1,1,1")
8125 (set_attr "mode" "QI,QI,QI,SI")
8126 (set_attr "pent_pair" "uv,np,uv,np")])
8128 (define_insn "*test<mode>_1"
8129 [(set (reg FLAGS_REG)
8132 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8133 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8135 "ix86_match_ccmode (insn, CCNOmode)
8136 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8137 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8138 [(set_attr "type" "test")
8139 (set_attr "modrm" "0,1,1")
8140 (set_attr "mode" "<MODE>")
8141 (set_attr "pent_pair" "uv,np,uv")])
8143 (define_expand "testqi_ext_ccno_0"
8144 [(set (reg:CCNO FLAGS_REG)
8148 (match_operand 0 "ext_register_operand" "")
8151 (match_operand 1 "const_int_operand" ""))
8156 (define_insn "*testqi_ext_0"
8157 [(set (reg FLAGS_REG)
8161 (match_operand 0 "ext_register_operand" "Q")
8164 (match_operand 1 "const_int_operand" "n"))
8166 "ix86_match_ccmode (insn, CCNOmode)"
8167 "test{b}\t{%1, %h0|%h0, %1}"
8168 [(set_attr "type" "test")
8169 (set_attr "mode" "QI")
8170 (set_attr "length_immediate" "1")
8171 (set_attr "modrm" "1")
8172 (set_attr "pent_pair" "np")])
8174 (define_insn "*testqi_ext_1_rex64"
8175 [(set (reg FLAGS_REG)
8179 (match_operand 0 "ext_register_operand" "Q")
8183 (match_operand:QI 1 "register_operand" "Q")))
8185 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8186 "test{b}\t{%1, %h0|%h0, %1}"
8187 [(set_attr "type" "test")
8188 (set_attr "mode" "QI")])
8190 (define_insn "*testqi_ext_1"
8191 [(set (reg FLAGS_REG)
8195 (match_operand 0 "ext_register_operand" "Q")
8199 (match_operand:QI 1 "general_operand" "Qm")))
8201 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8202 "test{b}\t{%1, %h0|%h0, %1}"
8203 [(set_attr "type" "test")
8204 (set_attr "mode" "QI")])
8206 (define_insn "*testqi_ext_2"
8207 [(set (reg FLAGS_REG)
8211 (match_operand 0 "ext_register_operand" "Q")
8215 (match_operand 1 "ext_register_operand" "Q")
8219 "ix86_match_ccmode (insn, CCNOmode)"
8220 "test{b}\t{%h1, %h0|%h0, %h1}"
8221 [(set_attr "type" "test")
8222 (set_attr "mode" "QI")])
8224 (define_insn "*testqi_ext_3_rex64"
8225 [(set (reg FLAGS_REG)
8226 (compare (zero_extract:DI
8227 (match_operand 0 "nonimmediate_operand" "rm")
8228 (match_operand:DI 1 "const_int_operand" "")
8229 (match_operand:DI 2 "const_int_operand" ""))
8232 && ix86_match_ccmode (insn, CCNOmode)
8233 && INTVAL (operands[1]) > 0
8234 && INTVAL (operands[2]) >= 0
8235 /* Ensure that resulting mask is zero or sign extended operand. */
8236 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8237 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8238 && INTVAL (operands[1]) > 32))
8239 && (GET_MODE (operands[0]) == SImode
8240 || GET_MODE (operands[0]) == DImode
8241 || GET_MODE (operands[0]) == HImode
8242 || GET_MODE (operands[0]) == QImode)"
8245 ;; Combine likes to form bit extractions for some tests. Humor it.
8246 (define_insn "*testqi_ext_3"
8247 [(set (reg FLAGS_REG)
8248 (compare (zero_extract:SI
8249 (match_operand 0 "nonimmediate_operand" "rm")
8250 (match_operand:SI 1 "const_int_operand" "")
8251 (match_operand:SI 2 "const_int_operand" ""))
8253 "ix86_match_ccmode (insn, CCNOmode)
8254 && INTVAL (operands[1]) > 0
8255 && INTVAL (operands[2]) >= 0
8256 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8257 && (GET_MODE (operands[0]) == SImode
8258 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8259 || GET_MODE (operands[0]) == HImode
8260 || GET_MODE (operands[0]) == QImode)"
8264 [(set (match_operand 0 "flags_reg_operand" "")
8265 (match_operator 1 "compare_operator"
8267 (match_operand 2 "nonimmediate_operand" "")
8268 (match_operand 3 "const_int_operand" "")
8269 (match_operand 4 "const_int_operand" ""))
8271 "ix86_match_ccmode (insn, CCNOmode)"
8272 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8274 rtx val = operands[2];
8275 HOST_WIDE_INT len = INTVAL (operands[3]);
8276 HOST_WIDE_INT pos = INTVAL (operands[4]);
8278 enum machine_mode mode, submode;
8280 mode = GET_MODE (val);
8283 /* ??? Combine likes to put non-volatile mem extractions in QImode
8284 no matter the size of the test. So find a mode that works. */
8285 if (! MEM_VOLATILE_P (val))
8287 mode = smallest_mode_for_size (pos + len, MODE_INT);
8288 val = adjust_address (val, mode, 0);
8291 else if (GET_CODE (val) == SUBREG
8292 && (submode = GET_MODE (SUBREG_REG (val)),
8293 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8294 && pos + len <= GET_MODE_BITSIZE (submode)
8295 && GET_MODE_CLASS (submode) == MODE_INT)
8297 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8299 val = SUBREG_REG (val);
8301 else if (mode == HImode && pos + len <= 8)
8303 /* Small HImode tests can be converted to QImode. */
8305 val = gen_lowpart (QImode, val);
8308 if (len == HOST_BITS_PER_WIDE_INT)
8311 mask = ((HOST_WIDE_INT)1 << len) - 1;
8314 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8317 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8318 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8319 ;; this is relatively important trick.
8320 ;; Do the conversion only post-reload to avoid limiting of the register class
8323 [(set (match_operand 0 "flags_reg_operand" "")
8324 (match_operator 1 "compare_operator"
8325 [(and (match_operand 2 "register_operand" "")
8326 (match_operand 3 "const_int_operand" ""))
8329 && QI_REG_P (operands[2])
8330 && GET_MODE (operands[2]) != QImode
8331 && ((ix86_match_ccmode (insn, CCZmode)
8332 && !(INTVAL (operands[3]) & ~(255 << 8)))
8333 || (ix86_match_ccmode (insn, CCNOmode)
8334 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8337 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8340 "operands[2] = gen_lowpart (SImode, operands[2]);
8341 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8344 [(set (match_operand 0 "flags_reg_operand" "")
8345 (match_operator 1 "compare_operator"
8346 [(and (match_operand 2 "nonimmediate_operand" "")
8347 (match_operand 3 "const_int_operand" ""))
8350 && GET_MODE (operands[2]) != QImode
8351 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8352 && ((ix86_match_ccmode (insn, CCZmode)
8353 && !(INTVAL (operands[3]) & ~255))
8354 || (ix86_match_ccmode (insn, CCNOmode)
8355 && !(INTVAL (operands[3]) & ~127)))"
8357 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8359 "operands[2] = gen_lowpart (QImode, operands[2]);
8360 operands[3] = gen_lowpart (QImode, operands[3]);")
8362 ;; %%% This used to optimize known byte-wide and operations to memory,
8363 ;; and sometimes to QImode registers. If this is considered useful,
8364 ;; it should be done with splitters.
8366 (define_expand "and<mode>3"
8367 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8368 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8369 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8371 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8373 (define_insn "*anddi_1"
8374 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8376 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8377 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8378 (clobber (reg:CC FLAGS_REG))]
8379 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8381 switch (get_attr_type (insn))
8385 enum machine_mode mode;
8387 gcc_assert (CONST_INT_P (operands[2]));
8388 if (INTVAL (operands[2]) == 0xff)
8392 gcc_assert (INTVAL (operands[2]) == 0xffff);
8396 operands[1] = gen_lowpart (mode, operands[1]);
8398 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8400 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8404 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8405 if (get_attr_mode (insn) == MODE_SI)
8406 return "and{l}\t{%k2, %k0|%k0, %k2}";
8408 return "and{q}\t{%2, %0|%0, %2}";
8411 [(set_attr "type" "alu,alu,alu,imovx")
8412 (set_attr "length_immediate" "*,*,*,0")
8413 (set (attr "prefix_rex")
8415 (and (eq_attr "type" "imovx")
8416 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8417 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8419 (const_string "*")))
8420 (set_attr "mode" "SI,DI,DI,SI")])
8422 (define_insn "*andsi_1"
8423 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8424 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8425 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8426 (clobber (reg:CC FLAGS_REG))]
8427 "ix86_binary_operator_ok (AND, SImode, operands)"
8429 switch (get_attr_type (insn))
8433 enum machine_mode mode;
8435 gcc_assert (CONST_INT_P (operands[2]));
8436 if (INTVAL (operands[2]) == 0xff)
8440 gcc_assert (INTVAL (operands[2]) == 0xffff);
8444 operands[1] = gen_lowpart (mode, operands[1]);
8446 return "movz{bl|x}\t{%1, %0|%0, %1}";
8448 return "movz{wl|x}\t{%1, %0|%0, %1}";
8452 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8453 return "and{l}\t{%2, %0|%0, %2}";
8456 [(set_attr "type" "alu,alu,imovx")
8457 (set (attr "prefix_rex")
8459 (and (eq_attr "type" "imovx")
8460 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8461 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8463 (const_string "*")))
8464 (set_attr "length_immediate" "*,*,0")
8465 (set_attr "mode" "SI")])
8467 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8468 (define_insn "*andsi_1_zext"
8469 [(set (match_operand:DI 0 "register_operand" "=r")
8471 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8472 (match_operand:SI 2 "general_operand" "g"))))
8473 (clobber (reg:CC FLAGS_REG))]
8474 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8475 "and{l}\t{%2, %k0|%k0, %2}"
8476 [(set_attr "type" "alu")
8477 (set_attr "mode" "SI")])
8479 (define_insn "*andhi_1"
8480 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8481 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8482 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8483 (clobber (reg:CC FLAGS_REG))]
8484 "ix86_binary_operator_ok (AND, HImode, operands)"
8486 switch (get_attr_type (insn))
8489 gcc_assert (CONST_INT_P (operands[2]));
8490 gcc_assert (INTVAL (operands[2]) == 0xff);
8491 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8494 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8496 return "and{w}\t{%2, %0|%0, %2}";
8499 [(set_attr "type" "alu,alu,imovx")
8500 (set_attr "length_immediate" "*,*,0")
8501 (set (attr "prefix_rex")
8503 (and (eq_attr "type" "imovx")
8504 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8506 (const_string "*")))
8507 (set_attr "mode" "HI,HI,SI")])
8509 ;; %%% Potential partial reg stall on alternative 2. What to do?
8510 (define_insn "*andqi_1"
8511 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8512 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8513 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8514 (clobber (reg:CC FLAGS_REG))]
8515 "ix86_binary_operator_ok (AND, QImode, operands)"
8517 and{b}\t{%2, %0|%0, %2}
8518 and{b}\t{%2, %0|%0, %2}
8519 and{l}\t{%k2, %k0|%k0, %k2}"
8520 [(set_attr "type" "alu")
8521 (set_attr "mode" "QI,QI,SI")])
8523 (define_insn "*andqi_1_slp"
8524 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8525 (and:QI (match_dup 0)
8526 (match_operand:QI 1 "general_operand" "qn,qmn")))
8527 (clobber (reg:CC FLAGS_REG))]
8528 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8529 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8530 "and{b}\t{%1, %0|%0, %1}"
8531 [(set_attr "type" "alu1")
8532 (set_attr "mode" "QI")])
8535 [(set (match_operand 0 "register_operand" "")
8537 (const_int -65536)))
8538 (clobber (reg:CC FLAGS_REG))]
8539 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8540 || optimize_function_for_size_p (cfun)"
8541 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8542 "operands[1] = gen_lowpart (HImode, operands[0]);")
8545 [(set (match_operand 0 "ext_register_operand" "")
8548 (clobber (reg:CC FLAGS_REG))]
8549 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8550 && reload_completed"
8551 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8552 "operands[1] = gen_lowpart (QImode, operands[0]);")
8555 [(set (match_operand 0 "ext_register_operand" "")
8557 (const_int -65281)))
8558 (clobber (reg:CC FLAGS_REG))]
8559 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8560 && reload_completed"
8561 [(parallel [(set (zero_extract:SI (match_dup 0)
8565 (zero_extract:SI (match_dup 0)
8568 (zero_extract:SI (match_dup 0)
8571 (clobber (reg:CC FLAGS_REG))])]
8572 "operands[0] = gen_lowpart (SImode, operands[0]);")
8574 (define_insn "*anddi_2"
8575 [(set (reg FLAGS_REG)
8578 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8579 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8581 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8582 (and:DI (match_dup 1) (match_dup 2)))]
8583 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8584 && ix86_binary_operator_ok (AND, DImode, operands)"
8586 and{l}\t{%k2, %k0|%k0, %k2}
8587 and{q}\t{%2, %0|%0, %2}
8588 and{q}\t{%2, %0|%0, %2}"
8589 [(set_attr "type" "alu")
8590 (set_attr "mode" "SI,DI,DI")])
8592 (define_insn "*andqi_2_maybe_si"
8593 [(set (reg FLAGS_REG)
8595 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8596 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8598 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8599 (and:QI (match_dup 1) (match_dup 2)))]
8600 "ix86_binary_operator_ok (AND, QImode, operands)
8601 && ix86_match_ccmode (insn,
8602 CONST_INT_P (operands[2])
8603 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8605 if (which_alternative == 2)
8607 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8608 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8609 return "and{l}\t{%2, %k0|%k0, %2}";
8611 return "and{b}\t{%2, %0|%0, %2}";
8613 [(set_attr "type" "alu")
8614 (set_attr "mode" "QI,QI,SI")])
8616 (define_insn "*and<mode>_2"
8617 [(set (reg FLAGS_REG)
8618 (compare (and:SWI124
8619 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8620 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8622 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8623 (and:SWI124 (match_dup 1) (match_dup 2)))]
8624 "ix86_match_ccmode (insn, CCNOmode)
8625 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8626 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8627 [(set_attr "type" "alu")
8628 (set_attr "mode" "<MODE>")])
8630 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8631 (define_insn "*andsi_2_zext"
8632 [(set (reg FLAGS_REG)
8634 (match_operand:SI 1 "nonimmediate_operand" "%0")
8635 (match_operand:SI 2 "general_operand" "g"))
8637 (set (match_operand:DI 0 "register_operand" "=r")
8638 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8639 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8640 && ix86_binary_operator_ok (AND, SImode, operands)"
8641 "and{l}\t{%2, %k0|%k0, %2}"
8642 [(set_attr "type" "alu")
8643 (set_attr "mode" "SI")])
8645 (define_insn "*andqi_2_slp"
8646 [(set (reg FLAGS_REG)
8648 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8649 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8651 (set (strict_low_part (match_dup 0))
8652 (and:QI (match_dup 0) (match_dup 1)))]
8653 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8654 && ix86_match_ccmode (insn, CCNOmode)
8655 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8656 "and{b}\t{%1, %0|%0, %1}"
8657 [(set_attr "type" "alu1")
8658 (set_attr "mode" "QI")])
8660 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8661 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8662 ;; for a QImode operand, which of course failed.
8663 (define_insn "andqi_ext_0"
8664 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8669 (match_operand 1 "ext_register_operand" "0")
8672 (match_operand 2 "const_int_operand" "n")))
8673 (clobber (reg:CC FLAGS_REG))]
8675 "and{b}\t{%2, %h0|%h0, %2}"
8676 [(set_attr "type" "alu")
8677 (set_attr "length_immediate" "1")
8678 (set_attr "modrm" "1")
8679 (set_attr "mode" "QI")])
8681 ;; Generated by peephole translating test to and. This shows up
8682 ;; often in fp comparisons.
8683 (define_insn "*andqi_ext_0_cc"
8684 [(set (reg FLAGS_REG)
8688 (match_operand 1 "ext_register_operand" "0")
8691 (match_operand 2 "const_int_operand" "n"))
8693 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8702 "ix86_match_ccmode (insn, CCNOmode)"
8703 "and{b}\t{%2, %h0|%h0, %2}"
8704 [(set_attr "type" "alu")
8705 (set_attr "length_immediate" "1")
8706 (set_attr "modrm" "1")
8707 (set_attr "mode" "QI")])
8709 (define_insn "*andqi_ext_1_rex64"
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"))))
8720 (clobber (reg:CC FLAGS_REG))]
8722 "and{b}\t{%2, %h0|%h0, %2}"
8723 [(set_attr "type" "alu")
8724 (set_attr "length_immediate" "0")
8725 (set_attr "mode" "QI")])
8727 (define_insn "*andqi_ext_1"
8728 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8733 (match_operand 1 "ext_register_operand" "0")
8737 (match_operand:QI 2 "general_operand" "Qm"))))
8738 (clobber (reg:CC FLAGS_REG))]
8740 "and{b}\t{%2, %h0|%h0, %2}"
8741 [(set_attr "type" "alu")
8742 (set_attr "length_immediate" "0")
8743 (set_attr "mode" "QI")])
8745 (define_insn "*andqi_ext_2"
8746 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8751 (match_operand 1 "ext_register_operand" "%0")
8755 (match_operand 2 "ext_register_operand" "Q")
8758 (clobber (reg:CC FLAGS_REG))]
8760 "and{b}\t{%h2, %h0|%h0, %h2}"
8761 [(set_attr "type" "alu")
8762 (set_attr "length_immediate" "0")
8763 (set_attr "mode" "QI")])
8765 ;; Convert wide AND instructions with immediate operand to shorter QImode
8766 ;; equivalents when possible.
8767 ;; Don't do the splitting with memory operands, since it introduces risk
8768 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8769 ;; for size, but that can (should?) be handled by generic code instead.
8771 [(set (match_operand 0 "register_operand" "")
8772 (and (match_operand 1 "register_operand" "")
8773 (match_operand 2 "const_int_operand" "")))
8774 (clobber (reg:CC FLAGS_REG))]
8776 && QI_REG_P (operands[0])
8777 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8778 && !(~INTVAL (operands[2]) & ~(255 << 8))
8779 && GET_MODE (operands[0]) != QImode"
8780 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8781 (and:SI (zero_extract:SI (match_dup 1)
8782 (const_int 8) (const_int 8))
8784 (clobber (reg:CC FLAGS_REG))])]
8785 "operands[0] = gen_lowpart (SImode, operands[0]);
8786 operands[1] = gen_lowpart (SImode, operands[1]);
8787 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8789 ;; Since AND can be encoded with sign extended immediate, this is only
8790 ;; profitable when 7th bit is not set.
8792 [(set (match_operand 0 "register_operand" "")
8793 (and (match_operand 1 "general_operand" "")
8794 (match_operand 2 "const_int_operand" "")))
8795 (clobber (reg:CC FLAGS_REG))]
8797 && ANY_QI_REG_P (operands[0])
8798 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8799 && !(~INTVAL (operands[2]) & ~255)
8800 && !(INTVAL (operands[2]) & 128)
8801 && GET_MODE (operands[0]) != QImode"
8802 [(parallel [(set (strict_low_part (match_dup 0))
8803 (and:QI (match_dup 1)
8805 (clobber (reg:CC FLAGS_REG))])]
8806 "operands[0] = gen_lowpart (QImode, operands[0]);
8807 operands[1] = gen_lowpart (QImode, operands[1]);
8808 operands[2] = gen_lowpart (QImode, operands[2]);")
8810 ;; Logical inclusive and exclusive OR instructions
8812 ;; %%% This used to optimize known byte-wide and operations to memory.
8813 ;; If this is considered useful, it should be done with splitters.
8815 (define_expand "<code><mode>3"
8816 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8817 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8818 (match_operand:SWIM 2 "<general_operand>" "")))]
8820 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8822 (define_insn "*<code><mode>_1"
8823 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8825 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8826 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8827 (clobber (reg:CC FLAGS_REG))]
8828 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8829 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8830 [(set_attr "type" "alu")
8831 (set_attr "mode" "<MODE>")])
8833 ;; %%% Potential partial reg stall on alternative 2. What to do?
8834 (define_insn "*<code>qi_1"
8835 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8836 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8837 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8838 (clobber (reg:CC FLAGS_REG))]
8839 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8841 <logic>{b}\t{%2, %0|%0, %2}
8842 <logic>{b}\t{%2, %0|%0, %2}
8843 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8844 [(set_attr "type" "alu")
8845 (set_attr "mode" "QI,QI,SI")])
8847 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8848 (define_insn "*<code>si_1_zext"
8849 [(set (match_operand:DI 0 "register_operand" "=r")
8851 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8852 (match_operand:SI 2 "general_operand" "g"))))
8853 (clobber (reg:CC FLAGS_REG))]
8854 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8855 "<logic>{l}\t{%2, %k0|%k0, %2}"
8856 [(set_attr "type" "alu")
8857 (set_attr "mode" "SI")])
8859 (define_insn "*<code>si_1_zext_imm"
8860 [(set (match_operand:DI 0 "register_operand" "=r")
8862 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8863 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8864 (clobber (reg:CC FLAGS_REG))]
8865 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8866 "<logic>{l}\t{%2, %k0|%k0, %2}"
8867 [(set_attr "type" "alu")
8868 (set_attr "mode" "SI")])
8870 (define_insn "*<code>qi_1_slp"
8871 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8872 (any_or:QI (match_dup 0)
8873 (match_operand:QI 1 "general_operand" "qmn,qn")))
8874 (clobber (reg:CC FLAGS_REG))]
8875 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8876 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8877 "<logic>{b}\t{%1, %0|%0, %1}"
8878 [(set_attr "type" "alu1")
8879 (set_attr "mode" "QI")])
8881 (define_insn "*<code><mode>_2"
8882 [(set (reg FLAGS_REG)
8883 (compare (any_or:SWI
8884 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8885 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8887 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8888 (any_or:SWI (match_dup 1) (match_dup 2)))]
8889 "ix86_match_ccmode (insn, CCNOmode)
8890 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8891 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8892 [(set_attr "type" "alu")
8893 (set_attr "mode" "<MODE>")])
8895 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8896 ;; ??? Special case for immediate operand is missing - it is tricky.
8897 (define_insn "*<code>si_2_zext"
8898 [(set (reg FLAGS_REG)
8899 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8900 (match_operand:SI 2 "general_operand" "g"))
8902 (set (match_operand:DI 0 "register_operand" "=r")
8903 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8904 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8905 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8906 "<logic>{l}\t{%2, %k0|%k0, %2}"
8907 [(set_attr "type" "alu")
8908 (set_attr "mode" "SI")])
8910 (define_insn "*<code>si_2_zext_imm"
8911 [(set (reg FLAGS_REG)
8913 (match_operand:SI 1 "nonimmediate_operand" "%0")
8914 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8916 (set (match_operand:DI 0 "register_operand" "=r")
8917 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8918 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8919 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8920 "<logic>{l}\t{%2, %k0|%k0, %2}"
8921 [(set_attr "type" "alu")
8922 (set_attr "mode" "SI")])
8924 (define_insn "*<code>qi_2_slp"
8925 [(set (reg FLAGS_REG)
8926 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8927 (match_operand:QI 1 "general_operand" "qmn,qn"))
8929 (set (strict_low_part (match_dup 0))
8930 (any_or:QI (match_dup 0) (match_dup 1)))]
8931 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8932 && ix86_match_ccmode (insn, CCNOmode)
8933 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8934 "<logic>{b}\t{%1, %0|%0, %1}"
8935 [(set_attr "type" "alu1")
8936 (set_attr "mode" "QI")])
8938 (define_insn "*<code><mode>_3"
8939 [(set (reg FLAGS_REG)
8940 (compare (any_or:SWI
8941 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8942 (match_operand:SWI 2 "<general_operand>" "<g>"))
8944 (clobber (match_scratch:SWI 0 "=<r>"))]
8945 "ix86_match_ccmode (insn, CCNOmode)
8946 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8947 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8948 [(set_attr "type" "alu")
8949 (set_attr "mode" "<MODE>")])
8951 (define_insn "*<code>qi_ext_0"
8952 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8957 (match_operand 1 "ext_register_operand" "0")
8960 (match_operand 2 "const_int_operand" "n")))
8961 (clobber (reg:CC FLAGS_REG))]
8962 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8963 "<logic>{b}\t{%2, %h0|%h0, %2}"
8964 [(set_attr "type" "alu")
8965 (set_attr "length_immediate" "1")
8966 (set_attr "modrm" "1")
8967 (set_attr "mode" "QI")])
8969 (define_insn "*<code>qi_ext_1_rex64"
8970 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8975 (match_operand 1 "ext_register_operand" "0")
8979 (match_operand 2 "ext_register_operand" "Q"))))
8980 (clobber (reg:CC FLAGS_REG))]
8982 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8983 "<logic>{b}\t{%2, %h0|%h0, %2}"
8984 [(set_attr "type" "alu")
8985 (set_attr "length_immediate" "0")
8986 (set_attr "mode" "QI")])
8988 (define_insn "*<code>qi_ext_1"
8989 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8994 (match_operand 1 "ext_register_operand" "0")
8998 (match_operand:QI 2 "general_operand" "Qm"))))
8999 (clobber (reg:CC FLAGS_REG))]
9001 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9002 "<logic>{b}\t{%2, %h0|%h0, %2}"
9003 [(set_attr "type" "alu")
9004 (set_attr "length_immediate" "0")
9005 (set_attr "mode" "QI")])
9007 (define_insn "*<code>qi_ext_2"
9008 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9012 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9015 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9018 (clobber (reg:CC FLAGS_REG))]
9019 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9020 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9021 [(set_attr "type" "alu")
9022 (set_attr "length_immediate" "0")
9023 (set_attr "mode" "QI")])
9026 [(set (match_operand 0 "register_operand" "")
9027 (any_or (match_operand 1 "register_operand" "")
9028 (match_operand 2 "const_int_operand" "")))
9029 (clobber (reg:CC FLAGS_REG))]
9031 && QI_REG_P (operands[0])
9032 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9033 && !(INTVAL (operands[2]) & ~(255 << 8))
9034 && GET_MODE (operands[0]) != QImode"
9035 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9036 (any_or:SI (zero_extract:SI (match_dup 1)
9037 (const_int 8) (const_int 8))
9039 (clobber (reg:CC FLAGS_REG))])]
9040 "operands[0] = gen_lowpart (SImode, operands[0]);
9041 operands[1] = gen_lowpart (SImode, operands[1]);
9042 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9044 ;; Since OR can be encoded with sign extended immediate, this is only
9045 ;; profitable when 7th bit is set.
9047 [(set (match_operand 0 "register_operand" "")
9048 (any_or (match_operand 1 "general_operand" "")
9049 (match_operand 2 "const_int_operand" "")))
9050 (clobber (reg:CC FLAGS_REG))]
9052 && ANY_QI_REG_P (operands[0])
9053 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9054 && !(INTVAL (operands[2]) & ~255)
9055 && (INTVAL (operands[2]) & 128)
9056 && GET_MODE (operands[0]) != QImode"
9057 [(parallel [(set (strict_low_part (match_dup 0))
9058 (any_or:QI (match_dup 1)
9060 (clobber (reg:CC FLAGS_REG))])]
9061 "operands[0] = gen_lowpart (QImode, operands[0]);
9062 operands[1] = gen_lowpart (QImode, operands[1]);
9063 operands[2] = gen_lowpart (QImode, operands[2]);")
9065 (define_expand "xorqi_cc_ext_1"
9067 (set (reg:CCNO FLAGS_REG)
9071 (match_operand 1 "ext_register_operand" "")
9074 (match_operand:QI 2 "general_operand" ""))
9076 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9088 (define_insn "*xorqi_cc_ext_1_rex64"
9089 [(set (reg FLAGS_REG)
9093 (match_operand 1 "ext_register_operand" "0")
9096 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9098 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9107 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9108 "xor{b}\t{%2, %h0|%h0, %2}"
9109 [(set_attr "type" "alu")
9110 (set_attr "modrm" "1")
9111 (set_attr "mode" "QI")])
9113 (define_insn "*xorqi_cc_ext_1"
9114 [(set (reg FLAGS_REG)
9118 (match_operand 1 "ext_register_operand" "0")
9121 (match_operand:QI 2 "general_operand" "qmn"))
9123 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9132 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9133 "xor{b}\t{%2, %h0|%h0, %2}"
9134 [(set_attr "type" "alu")
9135 (set_attr "modrm" "1")
9136 (set_attr "mode" "QI")])
9138 ;; Negation instructions
9140 (define_expand "neg<mode>2"
9141 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9142 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9144 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9146 (define_insn_and_split "*neg<dwi>2_doubleword"
9147 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9148 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9149 (clobber (reg:CC FLAGS_REG))]
9150 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9154 [(set (reg:CCZ FLAGS_REG)
9155 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9156 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9159 (plus:DWIH (match_dup 3)
9160 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9162 (clobber (reg:CC FLAGS_REG))])
9165 (neg:DWIH (match_dup 2)))
9166 (clobber (reg:CC FLAGS_REG))])]
9167 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9169 (define_insn "*neg<mode>2_1"
9170 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9171 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9172 (clobber (reg:CC FLAGS_REG))]
9173 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9174 "neg{<imodesuffix>}\t%0"
9175 [(set_attr "type" "negnot")
9176 (set_attr "mode" "<MODE>")])
9178 ;; Combine is quite creative about this pattern.
9179 (define_insn "*negsi2_1_zext"
9180 [(set (match_operand:DI 0 "register_operand" "=r")
9182 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9185 (clobber (reg:CC FLAGS_REG))]
9186 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9188 [(set_attr "type" "negnot")
9189 (set_attr "mode" "SI")])
9191 ;; The problem with neg is that it does not perform (compare x 0),
9192 ;; it really performs (compare 0 x), which leaves us with the zero
9193 ;; flag being the only useful item.
9195 (define_insn "*neg<mode>2_cmpz"
9196 [(set (reg:CCZ FLAGS_REG)
9198 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9200 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9201 (neg:SWI (match_dup 1)))]
9202 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9203 "neg{<imodesuffix>}\t%0"
9204 [(set_attr "type" "negnot")
9205 (set_attr "mode" "<MODE>")])
9207 (define_insn "*negsi2_cmpz_zext"
9208 [(set (reg:CCZ FLAGS_REG)
9212 (match_operand:DI 1 "register_operand" "0")
9216 (set (match_operand:DI 0 "register_operand" "=r")
9217 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9220 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9222 [(set_attr "type" "negnot")
9223 (set_attr "mode" "SI")])
9225 ;; Changing of sign for FP values is doable using integer unit too.
9227 (define_expand "<code><mode>2"
9228 [(set (match_operand:X87MODEF 0 "register_operand" "")
9229 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9230 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9231 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9233 (define_insn "*absneg<mode>2_mixed"
9234 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9235 (match_operator:MODEF 3 "absneg_operator"
9236 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9237 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9238 (clobber (reg:CC FLAGS_REG))]
9239 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9242 (define_insn "*absneg<mode>2_sse"
9243 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9244 (match_operator:MODEF 3 "absneg_operator"
9245 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9246 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9247 (clobber (reg:CC FLAGS_REG))]
9248 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9251 (define_insn "*absneg<mode>2_i387"
9252 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9253 (match_operator:X87MODEF 3 "absneg_operator"
9254 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9255 (use (match_operand 2 "" ""))
9256 (clobber (reg:CC FLAGS_REG))]
9257 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9260 (define_expand "<code>tf2"
9261 [(set (match_operand:TF 0 "register_operand" "")
9262 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9264 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9266 (define_insn "*absnegtf2_sse"
9267 [(set (match_operand:TF 0 "register_operand" "=x,x")
9268 (match_operator:TF 3 "absneg_operator"
9269 [(match_operand:TF 1 "register_operand" "0,x")]))
9270 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9271 (clobber (reg:CC FLAGS_REG))]
9275 ;; Splitters for fp abs and neg.
9278 [(set (match_operand 0 "fp_register_operand" "")
9279 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9280 (use (match_operand 2 "" ""))
9281 (clobber (reg:CC FLAGS_REG))]
9283 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9286 [(set (match_operand 0 "register_operand" "")
9287 (match_operator 3 "absneg_operator"
9288 [(match_operand 1 "register_operand" "")]))
9289 (use (match_operand 2 "nonimmediate_operand" ""))
9290 (clobber (reg:CC FLAGS_REG))]
9291 "reload_completed && SSE_REG_P (operands[0])"
9292 [(set (match_dup 0) (match_dup 3))]
9294 enum machine_mode mode = GET_MODE (operands[0]);
9295 enum machine_mode vmode = GET_MODE (operands[2]);
9298 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9299 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9300 if (operands_match_p (operands[0], operands[2]))
9303 operands[1] = operands[2];
9306 if (GET_CODE (operands[3]) == ABS)
9307 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9309 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9314 [(set (match_operand:SF 0 "register_operand" "")
9315 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9316 (use (match_operand:V4SF 2 "" ""))
9317 (clobber (reg:CC FLAGS_REG))]
9319 [(parallel [(set (match_dup 0) (match_dup 1))
9320 (clobber (reg:CC FLAGS_REG))])]
9323 operands[0] = gen_lowpart (SImode, operands[0]);
9324 if (GET_CODE (operands[1]) == ABS)
9326 tmp = gen_int_mode (0x7fffffff, SImode);
9327 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9331 tmp = gen_int_mode (0x80000000, SImode);
9332 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9338 [(set (match_operand:DF 0 "register_operand" "")
9339 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9340 (use (match_operand 2 "" ""))
9341 (clobber (reg:CC FLAGS_REG))]
9343 [(parallel [(set (match_dup 0) (match_dup 1))
9344 (clobber (reg:CC FLAGS_REG))])]
9349 tmp = gen_lowpart (DImode, operands[0]);
9350 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9353 if (GET_CODE (operands[1]) == ABS)
9356 tmp = gen_rtx_NOT (DImode, tmp);
9360 operands[0] = gen_highpart (SImode, operands[0]);
9361 if (GET_CODE (operands[1]) == ABS)
9363 tmp = gen_int_mode (0x7fffffff, SImode);
9364 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9368 tmp = gen_int_mode (0x80000000, SImode);
9369 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9376 [(set (match_operand:XF 0 "register_operand" "")
9377 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9378 (use (match_operand 2 "" ""))
9379 (clobber (reg:CC FLAGS_REG))]
9381 [(parallel [(set (match_dup 0) (match_dup 1))
9382 (clobber (reg:CC FLAGS_REG))])]
9385 operands[0] = gen_rtx_REG (SImode,
9386 true_regnum (operands[0])
9387 + (TARGET_64BIT ? 1 : 2));
9388 if (GET_CODE (operands[1]) == ABS)
9390 tmp = GEN_INT (0x7fff);
9391 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9395 tmp = GEN_INT (0x8000);
9396 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9401 ;; Conditionalize these after reload. If they match before reload, we
9402 ;; lose the clobber and ability to use integer instructions.
9404 (define_insn "*<code><mode>2_1"
9405 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9406 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9408 && (reload_completed
9409 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9410 "f<absneg_mnemonic>"
9411 [(set_attr "type" "fsgn")
9412 (set_attr "mode" "<MODE>")])
9414 (define_insn "*<code>extendsfdf2"
9415 [(set (match_operand:DF 0 "register_operand" "=f")
9416 (absneg:DF (float_extend:DF
9417 (match_operand:SF 1 "register_operand" "0"))))]
9418 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9419 "f<absneg_mnemonic>"
9420 [(set_attr "type" "fsgn")
9421 (set_attr "mode" "DF")])
9423 (define_insn "*<code>extendsfxf2"
9424 [(set (match_operand:XF 0 "register_operand" "=f")
9425 (absneg:XF (float_extend:XF
9426 (match_operand:SF 1 "register_operand" "0"))))]
9428 "f<absneg_mnemonic>"
9429 [(set_attr "type" "fsgn")
9430 (set_attr "mode" "XF")])
9432 (define_insn "*<code>extenddfxf2"
9433 [(set (match_operand:XF 0 "register_operand" "=f")
9434 (absneg:XF (float_extend:XF
9435 (match_operand:DF 1 "register_operand" "0"))))]
9437 "f<absneg_mnemonic>"
9438 [(set_attr "type" "fsgn")
9439 (set_attr "mode" "XF")])
9441 ;; Copysign instructions
9443 (define_mode_iterator CSGNMODE [SF DF TF])
9444 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9446 (define_expand "copysign<mode>3"
9447 [(match_operand:CSGNMODE 0 "register_operand" "")
9448 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9449 (match_operand:CSGNMODE 2 "register_operand" "")]
9450 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9451 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9453 ix86_expand_copysign (operands);
9457 (define_insn_and_split "copysign<mode>3_const"
9458 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9460 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9461 (match_operand:CSGNMODE 2 "register_operand" "0")
9462 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9464 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9465 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9467 "&& reload_completed"
9470 ix86_split_copysign_const (operands);
9474 (define_insn "copysign<mode>3_var"
9475 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9477 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9478 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9479 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9480 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9482 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9483 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9484 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9488 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9490 [(match_operand:CSGNMODE 2 "register_operand" "")
9491 (match_operand:CSGNMODE 3 "register_operand" "")
9492 (match_operand:<CSGNVMODE> 4 "" "")
9493 (match_operand:<CSGNVMODE> 5 "" "")]
9495 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9496 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9497 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9498 && reload_completed"
9501 ix86_split_copysign_var (operands);
9505 ;; One complement instructions
9507 (define_expand "one_cmpl<mode>2"
9508 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9509 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9511 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9513 (define_insn "*one_cmpl<mode>2_1"
9514 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9515 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9516 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9517 "not{<imodesuffix>}\t%0"
9518 [(set_attr "type" "negnot")
9519 (set_attr "mode" "<MODE>")])
9521 ;; %%% Potential partial reg stall on alternative 1. What to do?
9522 (define_insn "*one_cmplqi2_1"
9523 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9524 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9525 "ix86_unary_operator_ok (NOT, QImode, operands)"
9529 [(set_attr "type" "negnot")
9530 (set_attr "mode" "QI,SI")])
9532 ;; ??? Currently never generated - xor is used instead.
9533 (define_insn "*one_cmplsi2_1_zext"
9534 [(set (match_operand:DI 0 "register_operand" "=r")
9536 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9537 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9539 [(set_attr "type" "negnot")
9540 (set_attr "mode" "SI")])
9542 (define_insn "*one_cmpl<mode>2_2"
9543 [(set (reg FLAGS_REG)
9544 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9546 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9547 (not:SWI (match_dup 1)))]
9548 "ix86_match_ccmode (insn, CCNOmode)
9549 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9551 [(set_attr "type" "alu1")
9552 (set_attr "mode" "<MODE>")])
9555 [(set (match_operand 0 "flags_reg_operand" "")
9556 (match_operator 2 "compare_operator"
9557 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9559 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9560 (not:SWI (match_dup 3)))]
9561 "ix86_match_ccmode (insn, CCNOmode)"
9562 [(parallel [(set (match_dup 0)
9563 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9566 (xor:SWI (match_dup 3) (const_int -1)))])]
9569 ;; ??? Currently never generated - xor is used instead.
9570 (define_insn "*one_cmplsi2_2_zext"
9571 [(set (reg FLAGS_REG)
9572 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9574 (set (match_operand:DI 0 "register_operand" "=r")
9575 (zero_extend:DI (not:SI (match_dup 1))))]
9576 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9577 && ix86_unary_operator_ok (NOT, SImode, operands)"
9579 [(set_attr "type" "alu1")
9580 (set_attr "mode" "SI")])
9583 [(set (match_operand 0 "flags_reg_operand" "")
9584 (match_operator 2 "compare_operator"
9585 [(not:SI (match_operand:SI 3 "register_operand" ""))
9587 (set (match_operand:DI 1 "register_operand" "")
9588 (zero_extend:DI (not:SI (match_dup 3))))]
9589 "ix86_match_ccmode (insn, CCNOmode)"
9590 [(parallel [(set (match_dup 0)
9591 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9594 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9597 ;; Shift instructions
9599 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9600 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9601 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9602 ;; from the assembler input.
9604 ;; This instruction shifts the target reg/mem as usual, but instead of
9605 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9606 ;; is a left shift double, bits are taken from the high order bits of
9607 ;; reg, else if the insn is a shift right double, bits are taken from the
9608 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9609 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9611 ;; Since sh[lr]d does not change the `reg' operand, that is done
9612 ;; separately, making all shifts emit pairs of shift double and normal
9613 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9614 ;; support a 63 bit shift, each shift where the count is in a reg expands
9615 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9617 ;; If the shift count is a constant, we need never emit more than one
9618 ;; shift pair, instead using moves and sign extension for counts greater
9621 (define_expand "ashl<mode>3"
9622 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9623 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9624 (match_operand:QI 2 "nonmemory_operand" "")))]
9626 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9628 (define_insn "*ashl<mode>3_doubleword"
9629 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9630 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9631 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9632 (clobber (reg:CC FLAGS_REG))]
9635 [(set_attr "type" "multi")])
9638 [(set (match_operand:DWI 0 "register_operand" "")
9639 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9640 (match_operand:QI 2 "nonmemory_operand" "")))
9641 (clobber (reg:CC FLAGS_REG))]
9642 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9644 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9646 ;; By default we don't ask for a scratch register, because when DWImode
9647 ;; values are manipulated, registers are already at a premium. But if
9648 ;; we have one handy, we won't turn it away.
9651 [(match_scratch:DWIH 3 "r")
9652 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9654 (match_operand:<DWI> 1 "nonmemory_operand" "")
9655 (match_operand:QI 2 "nonmemory_operand" "")))
9656 (clobber (reg:CC FLAGS_REG))])
9660 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9662 (define_insn "x86_64_shld"
9663 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9664 (ior:DI (ashift:DI (match_dup 0)
9665 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9666 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9667 (minus:QI (const_int 64) (match_dup 2)))))
9668 (clobber (reg:CC FLAGS_REG))]
9670 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9671 [(set_attr "type" "ishift")
9672 (set_attr "prefix_0f" "1")
9673 (set_attr "mode" "DI")
9674 (set_attr "athlon_decode" "vector")
9675 (set_attr "amdfam10_decode" "vector")])
9677 (define_insn "x86_shld"
9678 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9679 (ior:SI (ashift:SI (match_dup 0)
9680 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9681 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9682 (minus:QI (const_int 32) (match_dup 2)))))
9683 (clobber (reg:CC FLAGS_REG))]
9685 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9686 [(set_attr "type" "ishift")
9687 (set_attr "prefix_0f" "1")
9688 (set_attr "mode" "SI")
9689 (set_attr "pent_pair" "np")
9690 (set_attr "athlon_decode" "vector")
9691 (set_attr "amdfam10_decode" "vector")])
9693 (define_expand "x86_shift<mode>_adj_1"
9694 [(set (reg:CCZ FLAGS_REG)
9695 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9698 (set (match_operand:SWI48 0 "register_operand" "")
9699 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9700 (match_operand:SWI48 1 "register_operand" "")
9703 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9704 (match_operand:SWI48 3 "register_operand" "r")
9707 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9709 (define_expand "x86_shift<mode>_adj_2"
9710 [(use (match_operand:SWI48 0 "register_operand" ""))
9711 (use (match_operand:SWI48 1 "register_operand" ""))
9712 (use (match_operand:QI 2 "register_operand" ""))]
9715 rtx label = gen_label_rtx ();
9718 emit_insn (gen_testqi_ccz_1 (operands[2],
9719 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9721 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9722 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9723 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9724 gen_rtx_LABEL_REF (VOIDmode, label),
9726 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9727 JUMP_LABEL (tmp) = label;
9729 emit_move_insn (operands[0], operands[1]);
9730 ix86_expand_clear (operands[1]);
9733 LABEL_NUSES (label) = 1;
9738 (define_insn "*ashl<mode>3_1"
9739 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9740 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9741 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9742 (clobber (reg:CC FLAGS_REG))]
9743 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9745 switch (get_attr_type (insn))
9751 gcc_assert (operands[2] == const1_rtx);
9752 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9753 return "add{<imodesuffix>}\t%0, %0";
9756 if (operands[2] == const1_rtx
9757 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9758 return "sal{<imodesuffix>}\t%0";
9760 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9764 (cond [(eq_attr "alternative" "1")
9765 (const_string "lea")
9766 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9768 (match_operand 0 "register_operand" ""))
9769 (match_operand 2 "const1_operand" ""))
9770 (const_string "alu")
9772 (const_string "ishift")))
9773 (set (attr "length_immediate")
9775 (ior (eq_attr "type" "alu")
9776 (and (eq_attr "type" "ishift")
9777 (and (match_operand 2 "const1_operand" "")
9778 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9781 (const_string "*")))
9782 (set_attr "mode" "<MODE>")])
9784 (define_insn "*ashlsi3_1_zext"
9785 [(set (match_operand:DI 0 "register_operand" "=r,r")
9787 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9788 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9789 (clobber (reg:CC FLAGS_REG))]
9790 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9792 switch (get_attr_type (insn))
9798 gcc_assert (operands[2] == const1_rtx);
9799 return "add{l}\t%k0, %k0";
9802 if (operands[2] == const1_rtx
9803 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9804 return "sal{l}\t%k0";
9806 return "sal{l}\t{%2, %k0|%k0, %2}";
9810 (cond [(eq_attr "alternative" "1")
9811 (const_string "lea")
9812 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9814 (match_operand 2 "const1_operand" ""))
9815 (const_string "alu")
9817 (const_string "ishift")))
9818 (set (attr "length_immediate")
9820 (ior (eq_attr "type" "alu")
9821 (and (eq_attr "type" "ishift")
9822 (and (match_operand 2 "const1_operand" "")
9823 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9826 (const_string "*")))
9827 (set_attr "mode" "SI")])
9829 (define_insn "*ashlhi3_1"
9830 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9831 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9832 (match_operand:QI 2 "nonmemory_operand" "cI")))
9833 (clobber (reg:CC FLAGS_REG))]
9834 "TARGET_PARTIAL_REG_STALL
9835 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9837 switch (get_attr_type (insn))
9840 gcc_assert (operands[2] == const1_rtx);
9841 return "add{w}\t%0, %0";
9844 if (operands[2] == const1_rtx
9845 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9846 return "sal{w}\t%0";
9848 return "sal{w}\t{%2, %0|%0, %2}";
9852 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9854 (match_operand 0 "register_operand" ""))
9855 (match_operand 2 "const1_operand" ""))
9856 (const_string "alu")
9858 (const_string "ishift")))
9859 (set (attr "length_immediate")
9861 (ior (eq_attr "type" "alu")
9862 (and (eq_attr "type" "ishift")
9863 (and (match_operand 2 "const1_operand" "")
9864 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9867 (const_string "*")))
9868 (set_attr "mode" "HI")])
9870 (define_insn "*ashlhi3_1_lea"
9871 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9872 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9873 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9874 (clobber (reg:CC FLAGS_REG))]
9875 "!TARGET_PARTIAL_REG_STALL
9876 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9878 switch (get_attr_type (insn))
9884 gcc_assert (operands[2] == const1_rtx);
9885 return "add{w}\t%0, %0";
9888 if (operands[2] == const1_rtx
9889 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9890 return "sal{w}\t%0";
9892 return "sal{w}\t{%2, %0|%0, %2}";
9896 (cond [(eq_attr "alternative" "1")
9897 (const_string "lea")
9898 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9900 (match_operand 0 "register_operand" ""))
9901 (match_operand 2 "const1_operand" ""))
9902 (const_string "alu")
9904 (const_string "ishift")))
9905 (set (attr "length_immediate")
9907 (ior (eq_attr "type" "alu")
9908 (and (eq_attr "type" "ishift")
9909 (and (match_operand 2 "const1_operand" "")
9910 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9913 (const_string "*")))
9914 (set_attr "mode" "HI,SI")])
9916 (define_insn "*ashlqi3_1"
9917 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9918 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9919 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9920 (clobber (reg:CC FLAGS_REG))]
9921 "TARGET_PARTIAL_REG_STALL
9922 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9924 switch (get_attr_type (insn))
9927 gcc_assert (operands[2] == const1_rtx);
9928 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9929 return "add{l}\t%k0, %k0";
9931 return "add{b}\t%0, %0";
9934 if (operands[2] == const1_rtx
9935 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9937 if (get_attr_mode (insn) == MODE_SI)
9938 return "sal{l}\t%k0";
9940 return "sal{b}\t%0";
9944 if (get_attr_mode (insn) == MODE_SI)
9945 return "sal{l}\t{%2, %k0|%k0, %2}";
9947 return "sal{b}\t{%2, %0|%0, %2}";
9952 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9954 (match_operand 0 "register_operand" ""))
9955 (match_operand 2 "const1_operand" ""))
9956 (const_string "alu")
9958 (const_string "ishift")))
9959 (set (attr "length_immediate")
9961 (ior (eq_attr "type" "alu")
9962 (and (eq_attr "type" "ishift")
9963 (and (match_operand 2 "const1_operand" "")
9964 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9967 (const_string "*")))
9968 (set_attr "mode" "QI,SI")])
9970 ;; %%% Potential partial reg stall on alternative 2. What to do?
9971 (define_insn "*ashlqi3_1_lea"
9972 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9973 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9974 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9975 (clobber (reg:CC FLAGS_REG))]
9976 "!TARGET_PARTIAL_REG_STALL
9977 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9979 switch (get_attr_type (insn))
9985 gcc_assert (operands[2] == const1_rtx);
9986 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9987 return "add{l}\t%k0, %k0";
9989 return "add{b}\t%0, %0";
9992 if (operands[2] == const1_rtx
9993 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9995 if (get_attr_mode (insn) == MODE_SI)
9996 return "sal{l}\t%k0";
9998 return "sal{b}\t%0";
10002 if (get_attr_mode (insn) == MODE_SI)
10003 return "sal{l}\t{%2, %k0|%k0, %2}";
10005 return "sal{b}\t{%2, %0|%0, %2}";
10009 [(set (attr "type")
10010 (cond [(eq_attr "alternative" "2")
10011 (const_string "lea")
10012 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10014 (match_operand 0 "register_operand" ""))
10015 (match_operand 2 "const1_operand" ""))
10016 (const_string "alu")
10018 (const_string "ishift")))
10019 (set (attr "length_immediate")
10021 (ior (eq_attr "type" "alu")
10022 (and (eq_attr "type" "ishift")
10023 (and (match_operand 2 "const1_operand" "")
10024 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10027 (const_string "*")))
10028 (set_attr "mode" "QI,SI,SI")])
10030 (define_insn "*ashlqi3_1_slp"
10031 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10032 (ashift:QI (match_dup 0)
10033 (match_operand:QI 1 "nonmemory_operand" "cI")))
10034 (clobber (reg:CC FLAGS_REG))]
10035 "(optimize_function_for_size_p (cfun)
10036 || !TARGET_PARTIAL_FLAG_REG_STALL
10037 || (operands[1] == const1_rtx
10039 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10041 switch (get_attr_type (insn))
10044 gcc_assert (operands[1] == const1_rtx);
10045 return "add{b}\t%0, %0";
10048 if (operands[1] == const1_rtx
10049 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10050 return "sal{b}\t%0";
10052 return "sal{b}\t{%1, %0|%0, %1}";
10055 [(set (attr "type")
10056 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10058 (match_operand 0 "register_operand" ""))
10059 (match_operand 1 "const1_operand" ""))
10060 (const_string "alu")
10062 (const_string "ishift1")))
10063 (set (attr "length_immediate")
10065 (ior (eq_attr "type" "alu")
10066 (and (eq_attr "type" "ishift1")
10067 (and (match_operand 1 "const1_operand" "")
10068 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10071 (const_string "*")))
10072 (set_attr "mode" "QI")])
10074 ;; Convert lea to the lea pattern to avoid flags dependency.
10076 [(set (match_operand:DI 0 "register_operand" "")
10077 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10078 (match_operand:QI 2 "const_int_operand" "")))
10079 (clobber (reg:CC FLAGS_REG))]
10080 "TARGET_64BIT && reload_completed
10081 && true_regnum (operands[0]) != true_regnum (operands[1])"
10082 [(set (match_dup 0)
10083 (mult:DI (match_dup 1)
10085 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10087 ;; Convert lea to the lea pattern to avoid flags dependency.
10089 [(set (match_operand 0 "register_operand" "")
10090 (ashift (match_operand 1 "index_register_operand" "")
10091 (match_operand:QI 2 "const_int_operand" "")))
10092 (clobber (reg:CC FLAGS_REG))]
10094 && true_regnum (operands[0]) != true_regnum (operands[1])
10095 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10099 enum machine_mode mode = GET_MODE (operands[0]);
10101 if (GET_MODE_SIZE (mode) < 4)
10102 operands[0] = gen_lowpart (SImode, operands[0]);
10104 operands[1] = gen_lowpart (Pmode, operands[1]);
10105 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10107 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10108 if (Pmode != SImode)
10109 pat = gen_rtx_SUBREG (SImode, pat, 0);
10110 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10114 ;; Rare case of shifting RSP is handled by generating move and shift
10116 [(set (match_operand 0 "register_operand" "")
10117 (ashift (match_operand 1 "register_operand" "")
10118 (match_operand:QI 2 "const_int_operand" "")))
10119 (clobber (reg:CC FLAGS_REG))]
10121 && true_regnum (operands[0]) != true_regnum (operands[1])"
10125 emit_move_insn (operands[0], operands[1]);
10126 pat = gen_rtx_SET (VOIDmode, operands[0],
10127 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10128 operands[0], operands[2]));
10129 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10130 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10134 ;; Convert lea to the lea pattern to avoid flags dependency.
10136 [(set (match_operand:DI 0 "register_operand" "")
10138 (ashift:SI (match_operand:SI 1 "register_operand" "")
10139 (match_operand:QI 2 "const_int_operand" ""))))
10140 (clobber (reg:CC FLAGS_REG))]
10141 "TARGET_64BIT && reload_completed
10142 && true_regnum (operands[0]) != true_regnum (operands[1])"
10143 [(set (match_dup 0)
10144 (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10146 operands[1] = gen_lowpart (Pmode, operands[1]);
10147 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10150 ;; This pattern can't accept a variable shift count, since shifts by
10151 ;; zero don't affect the flags. We assume that shifts by constant
10152 ;; zero are optimized away.
10153 (define_insn "*ashl<mode>3_cmp"
10154 [(set (reg FLAGS_REG)
10156 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10157 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10159 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10160 (ashift:SWI (match_dup 1) (match_dup 2)))]
10161 "(optimize_function_for_size_p (cfun)
10162 || !TARGET_PARTIAL_FLAG_REG_STALL
10163 || (operands[2] == const1_rtx
10165 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10166 && ix86_match_ccmode (insn, CCGOCmode)
10167 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10169 switch (get_attr_type (insn))
10172 gcc_assert (operands[2] == const1_rtx);
10173 return "add{<imodesuffix>}\t%0, %0";
10176 if (operands[2] == const1_rtx
10177 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10178 return "sal{<imodesuffix>}\t%0";
10180 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10183 [(set (attr "type")
10184 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10186 (match_operand 0 "register_operand" ""))
10187 (match_operand 2 "const1_operand" ""))
10188 (const_string "alu")
10190 (const_string "ishift")))
10191 (set (attr "length_immediate")
10193 (ior (eq_attr "type" "alu")
10194 (and (eq_attr "type" "ishift")
10195 (and (match_operand 2 "const1_operand" "")
10196 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10199 (const_string "*")))
10200 (set_attr "mode" "<MODE>")])
10202 (define_insn "*ashlsi3_cmp_zext"
10203 [(set (reg FLAGS_REG)
10205 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10206 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10208 (set (match_operand:DI 0 "register_operand" "=r")
10209 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10211 && (optimize_function_for_size_p (cfun)
10212 || !TARGET_PARTIAL_FLAG_REG_STALL
10213 || (operands[2] == const1_rtx
10215 || TARGET_DOUBLE_WITH_ADD)))
10216 && ix86_match_ccmode (insn, CCGOCmode)
10217 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10219 switch (get_attr_type (insn))
10222 gcc_assert (operands[2] == const1_rtx);
10223 return "add{l}\t%k0, %k0";
10226 if (operands[2] == const1_rtx
10227 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10228 return "sal{l}\t%k0";
10230 return "sal{l}\t{%2, %k0|%k0, %2}";
10233 [(set (attr "type")
10234 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10236 (match_operand 2 "const1_operand" ""))
10237 (const_string "alu")
10239 (const_string "ishift")))
10240 (set (attr "length_immediate")
10242 (ior (eq_attr "type" "alu")
10243 (and (eq_attr "type" "ishift")
10244 (and (match_operand 2 "const1_operand" "")
10245 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10248 (const_string "*")))
10249 (set_attr "mode" "SI")])
10251 (define_insn "*ashl<mode>3_cconly"
10252 [(set (reg FLAGS_REG)
10254 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10255 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10257 (clobber (match_scratch:SWI 0 "=<r>"))]
10258 "(optimize_function_for_size_p (cfun)
10259 || !TARGET_PARTIAL_FLAG_REG_STALL
10260 || (operands[2] == const1_rtx
10262 || TARGET_DOUBLE_WITH_ADD)))
10263 && ix86_match_ccmode (insn, CCGOCmode)
10264 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10266 switch (get_attr_type (insn))
10269 gcc_assert (operands[2] == const1_rtx);
10270 return "add{<imodesuffix>}\t%0, %0";
10273 if (operands[2] == const1_rtx
10274 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10275 return "sal{<imodesuffix>}\t%0";
10277 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10280 [(set (attr "type")
10281 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10283 (match_operand 0 "register_operand" ""))
10284 (match_operand 2 "const1_operand" ""))
10285 (const_string "alu")
10287 (const_string "ishift")))
10288 (set (attr "length_immediate")
10290 (ior (eq_attr "type" "alu")
10291 (and (eq_attr "type" "ishift")
10292 (and (match_operand 2 "const1_operand" "")
10293 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10296 (const_string "*")))
10297 (set_attr "mode" "<MODE>")])
10299 ;; See comment above `ashl<mode>3' about how this works.
10301 (define_expand "<shiftrt_insn><mode>3"
10302 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
10303 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
10304 (match_operand:QI 2 "nonmemory_operand" "")))]
10306 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10308 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
10309 [(set (match_operand:DWI 0 "register_operand" "=r")
10310 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10311 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10312 (clobber (reg:CC FLAGS_REG))]
10315 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10317 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10318 [(set_attr "type" "multi")])
10320 ;; By default we don't ask for a scratch register, because when DWImode
10321 ;; values are manipulated, registers are already at a premium. But if
10322 ;; we have one handy, we won't turn it away.
10325 [(match_scratch:DWIH 3 "r")
10326 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
10328 (match_operand:<DWI> 1 "register_operand" "")
10329 (match_operand:QI 2 "nonmemory_operand" "")))
10330 (clobber (reg:CC FLAGS_REG))])
10334 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
10336 (define_insn "x86_64_shrd"
10337 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10338 (ior:DI (ashiftrt:DI (match_dup 0)
10339 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10340 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10341 (minus:QI (const_int 64) (match_dup 2)))))
10342 (clobber (reg:CC FLAGS_REG))]
10344 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10345 [(set_attr "type" "ishift")
10346 (set_attr "prefix_0f" "1")
10347 (set_attr "mode" "DI")
10348 (set_attr "athlon_decode" "vector")
10349 (set_attr "amdfam10_decode" "vector")])
10351 (define_insn "x86_shrd"
10352 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10353 (ior:SI (ashiftrt:SI (match_dup 0)
10354 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10355 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10356 (minus:QI (const_int 32) (match_dup 2)))))
10357 (clobber (reg:CC FLAGS_REG))]
10359 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10360 [(set_attr "type" "ishift")
10361 (set_attr "prefix_0f" "1")
10362 (set_attr "mode" "SI")
10363 (set_attr "pent_pair" "np")
10364 (set_attr "athlon_decode" "vector")
10365 (set_attr "amdfam10_decode" "vector")])
10367 (define_insn "ashrdi3_cvt"
10368 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10369 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10370 (match_operand:QI 2 "const_int_operand" "")))
10371 (clobber (reg:CC FLAGS_REG))]
10372 "TARGET_64BIT && INTVAL (operands[2]) == 63
10373 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10374 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10377 sar{q}\t{%2, %0|%0, %2}"
10378 [(set_attr "type" "imovx,ishift")
10379 (set_attr "prefix_0f" "0,*")
10380 (set_attr "length_immediate" "0,*")
10381 (set_attr "modrm" "0,1")
10382 (set_attr "mode" "DI")])
10384 (define_insn "ashrsi3_cvt"
10385 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10386 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10387 (match_operand:QI 2 "const_int_operand" "")))
10388 (clobber (reg:CC FLAGS_REG))]
10389 "INTVAL (operands[2]) == 31
10390 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10391 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10394 sar{l}\t{%2, %0|%0, %2}"
10395 [(set_attr "type" "imovx,ishift")
10396 (set_attr "prefix_0f" "0,*")
10397 (set_attr "length_immediate" "0,*")
10398 (set_attr "modrm" "0,1")
10399 (set_attr "mode" "SI")])
10401 (define_insn "*ashrsi3_cvt_zext"
10402 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10404 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10405 (match_operand:QI 2 "const_int_operand" ""))))
10406 (clobber (reg:CC FLAGS_REG))]
10407 "TARGET_64BIT && INTVAL (operands[2]) == 31
10408 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10409 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10412 sar{l}\t{%2, %k0|%k0, %2}"
10413 [(set_attr "type" "imovx,ishift")
10414 (set_attr "prefix_0f" "0,*")
10415 (set_attr "length_immediate" "0,*")
10416 (set_attr "modrm" "0,1")
10417 (set_attr "mode" "SI")])
10419 (define_expand "x86_shift<mode>_adj_3"
10420 [(use (match_operand:SWI48 0 "register_operand" ""))
10421 (use (match_operand:SWI48 1 "register_operand" ""))
10422 (use (match_operand:QI 2 "register_operand" ""))]
10425 rtx label = gen_label_rtx ();
10428 emit_insn (gen_testqi_ccz_1 (operands[2],
10429 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10431 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10432 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10433 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10434 gen_rtx_LABEL_REF (VOIDmode, label),
10436 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10437 JUMP_LABEL (tmp) = label;
10439 emit_move_insn (operands[0], operands[1]);
10440 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10441 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10442 emit_label (label);
10443 LABEL_NUSES (label) = 1;
10448 (define_insn "*<shiftrt_insn><mode>3_1"
10449 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10450 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10451 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10452 (clobber (reg:CC FLAGS_REG))]
10453 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10455 if (operands[2] == const1_rtx
10456 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10457 return "<shiftrt>{<imodesuffix>}\t%0";
10459 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10461 [(set_attr "type" "ishift")
10462 (set (attr "length_immediate")
10464 (and (match_operand 2 "const1_operand" "")
10465 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10468 (const_string "*")))
10469 (set_attr "mode" "<MODE>")])
10471 (define_insn "*<shiftrt_insn>si3_1_zext"
10472 [(set (match_operand:DI 0 "register_operand" "=r")
10474 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10475 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10476 (clobber (reg:CC FLAGS_REG))]
10477 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10479 if (operands[2] == const1_rtx
10480 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10481 return "<shiftrt>{l}\t%k0";
10483 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10485 [(set_attr "type" "ishift")
10486 (set (attr "length_immediate")
10488 (and (match_operand 2 "const1_operand" "")
10489 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10492 (const_string "*")))
10493 (set_attr "mode" "SI")])
10495 (define_insn "*<shiftrt_insn>qi3_1_slp"
10496 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10497 (any_shiftrt:QI (match_dup 0)
10498 (match_operand:QI 1 "nonmemory_operand" "cI")))
10499 (clobber (reg:CC FLAGS_REG))]
10500 "(optimize_function_for_size_p (cfun)
10501 || !TARGET_PARTIAL_REG_STALL
10502 || (operands[1] == const1_rtx
10503 && TARGET_SHIFT1))"
10505 if (operands[1] == const1_rtx
10506 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10507 return "<shiftrt>{b}\t%0";
10509 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10511 [(set_attr "type" "ishift1")
10512 (set (attr "length_immediate")
10514 (and (match_operand 1 "const1_operand" "")
10515 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10518 (const_string "*")))
10519 (set_attr "mode" "QI")])
10521 ;; This pattern can't accept a variable shift count, since shifts by
10522 ;; zero don't affect the flags. We assume that shifts by constant
10523 ;; zero are optimized away.
10524 (define_insn "*<shiftrt_insn><mode>3_cmp"
10525 [(set (reg FLAGS_REG)
10528 (match_operand:SWI 1 "nonimmediate_operand" "0")
10529 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10531 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10532 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10533 "(optimize_function_for_size_p (cfun)
10534 || !TARGET_PARTIAL_FLAG_REG_STALL
10535 || (operands[2] == const1_rtx
10537 && ix86_match_ccmode (insn, CCGOCmode)
10538 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10540 if (operands[2] == const1_rtx
10541 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10542 return "<shiftrt>{<imodesuffix>}\t%0";
10544 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10546 [(set_attr "type" "ishift")
10547 (set (attr "length_immediate")
10549 (and (match_operand 2 "const1_operand" "")
10550 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10553 (const_string "*")))
10554 (set_attr "mode" "<MODE>")])
10556 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10557 [(set (reg FLAGS_REG)
10559 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10560 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10562 (set (match_operand:DI 0 "register_operand" "=r")
10563 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10565 && (optimize_function_for_size_p (cfun)
10566 || !TARGET_PARTIAL_FLAG_REG_STALL
10567 || (operands[2] == const1_rtx
10569 && ix86_match_ccmode (insn, CCGOCmode)
10570 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10572 if (operands[2] == const1_rtx
10573 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10574 return "<shiftrt>{l}\t%k0";
10576 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10578 [(set_attr "type" "ishift")
10579 (set (attr "length_immediate")
10581 (and (match_operand 2 "const1_operand" "")
10582 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10585 (const_string "*")))
10586 (set_attr "mode" "SI")])
10588 (define_insn "*<shiftrt_insn><mode>3_cconly"
10589 [(set (reg FLAGS_REG)
10592 (match_operand:SWI 1 "nonimmediate_operand" "0")
10593 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10595 (clobber (match_scratch:SWI 0 "=<r>"))]
10596 "(optimize_function_for_size_p (cfun)
10597 || !TARGET_PARTIAL_FLAG_REG_STALL
10598 || (operands[2] == const1_rtx
10600 && ix86_match_ccmode (insn, CCGOCmode)
10601 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10603 if (operands[2] == const1_rtx
10604 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10605 return "<shiftrt>{<imodesuffix>}\t%0";
10607 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10609 [(set_attr "type" "ishift")
10610 (set (attr "length_immediate")
10612 (and (match_operand 2 "const1_operand" "")
10613 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10616 (const_string "*")))
10617 (set_attr "mode" "<MODE>")])
10619 ;; Rotate instructions
10621 (define_expand "<rotate_insn>ti3"
10622 [(set (match_operand:TI 0 "register_operand" "")
10623 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10624 (match_operand:QI 2 "nonmemory_operand" "")))]
10627 if (const_1_to_63_operand (operands[2], VOIDmode))
10628 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10629 (operands[0], operands[1], operands[2]));
10636 (define_expand "<rotate_insn>di3"
10637 [(set (match_operand:DI 0 "shiftdi_operand" "")
10638 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10639 (match_operand:QI 2 "nonmemory_operand" "")))]
10643 ix86_expand_binary_operator (<CODE>, DImode, operands);
10644 else if (const_1_to_31_operand (operands[2], VOIDmode))
10645 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10646 (operands[0], operands[1], operands[2]));
10653 (define_expand "<rotate_insn><mode>3"
10654 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10655 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10656 (match_operand:QI 2 "nonmemory_operand" "")))]
10658 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10660 ;; Implement rotation using two double-precision
10661 ;; shift instructions and a scratch register.
10663 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10664 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10665 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10666 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10667 (clobber (reg:CC FLAGS_REG))
10668 (clobber (match_scratch:DWIH 3 "=&r"))]
10672 [(set (match_dup 3) (match_dup 4))
10674 [(set (match_dup 4)
10675 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10676 (lshiftrt:DWIH (match_dup 5)
10677 (minus:QI (match_dup 6) (match_dup 2)))))
10678 (clobber (reg:CC FLAGS_REG))])
10680 [(set (match_dup 5)
10681 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10682 (lshiftrt:DWIH (match_dup 3)
10683 (minus:QI (match_dup 6) (match_dup 2)))))
10684 (clobber (reg:CC FLAGS_REG))])]
10686 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10688 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10691 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10692 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10693 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10694 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10695 (clobber (reg:CC FLAGS_REG))
10696 (clobber (match_scratch:DWIH 3 "=&r"))]
10700 [(set (match_dup 3) (match_dup 4))
10702 [(set (match_dup 4)
10703 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10704 (ashift:DWIH (match_dup 5)
10705 (minus:QI (match_dup 6) (match_dup 2)))))
10706 (clobber (reg:CC FLAGS_REG))])
10708 [(set (match_dup 5)
10709 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10710 (ashift:DWIH (match_dup 3)
10711 (minus:QI (match_dup 6) (match_dup 2)))))
10712 (clobber (reg:CC FLAGS_REG))])]
10714 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10716 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10719 (define_insn "*<rotate_insn><mode>3_1"
10720 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10721 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10722 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10723 (clobber (reg:CC FLAGS_REG))]
10724 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10726 if (operands[2] == const1_rtx
10727 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10728 return "<rotate>{<imodesuffix>}\t%0";
10730 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10732 [(set_attr "type" "rotate")
10733 (set (attr "length_immediate")
10735 (and (match_operand 2 "const1_operand" "")
10736 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10739 (const_string "*")))
10740 (set_attr "mode" "<MODE>")])
10742 (define_insn "*<rotate_insn>si3_1_zext"
10743 [(set (match_operand:DI 0 "register_operand" "=r")
10745 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10746 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10747 (clobber (reg:CC FLAGS_REG))]
10748 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10750 if (operands[2] == const1_rtx
10751 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10752 return "<rotate>{l}\t%k0";
10754 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10756 [(set_attr "type" "rotate")
10757 (set (attr "length_immediate")
10759 (and (match_operand 2 "const1_operand" "")
10760 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10763 (const_string "*")))
10764 (set_attr "mode" "SI")])
10766 (define_insn "*<rotate_insn>qi3_1_slp"
10767 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10768 (any_rotate:QI (match_dup 0)
10769 (match_operand:QI 1 "nonmemory_operand" "cI")))
10770 (clobber (reg:CC FLAGS_REG))]
10771 "(optimize_function_for_size_p (cfun)
10772 || !TARGET_PARTIAL_REG_STALL
10773 || (operands[1] == const1_rtx
10774 && TARGET_SHIFT1))"
10776 if (operands[1] == const1_rtx
10777 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10778 return "<rotate>{b}\t%0";
10780 return "<rotate>{b}\t{%1, %0|%0, %1}";
10782 [(set_attr "type" "rotate1")
10783 (set (attr "length_immediate")
10785 (and (match_operand 1 "const1_operand" "")
10786 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10789 (const_string "*")))
10790 (set_attr "mode" "QI")])
10793 [(set (match_operand:HI 0 "register_operand" "")
10794 (any_rotate:HI (match_dup 0) (const_int 8)))
10795 (clobber (reg:CC FLAGS_REG))]
10797 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10798 [(parallel [(set (strict_low_part (match_dup 0))
10799 (bswap:HI (match_dup 0)))
10800 (clobber (reg:CC FLAGS_REG))])]
10803 ;; Bit set / bit test instructions
10805 (define_expand "extv"
10806 [(set (match_operand:SI 0 "register_operand" "")
10807 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10808 (match_operand:SI 2 "const8_operand" "")
10809 (match_operand:SI 3 "const8_operand" "")))]
10812 /* Handle extractions from %ah et al. */
10813 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10816 /* From mips.md: extract_bit_field doesn't verify that our source
10817 matches the predicate, so check it again here. */
10818 if (! ext_register_operand (operands[1], VOIDmode))
10822 (define_expand "extzv"
10823 [(set (match_operand:SI 0 "register_operand" "")
10824 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10825 (match_operand:SI 2 "const8_operand" "")
10826 (match_operand:SI 3 "const8_operand" "")))]
10829 /* Handle extractions from %ah et al. */
10830 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10833 /* From mips.md: extract_bit_field doesn't verify that our source
10834 matches the predicate, so check it again here. */
10835 if (! ext_register_operand (operands[1], VOIDmode))
10839 (define_expand "insv"
10840 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10841 (match_operand 1 "const8_operand" "")
10842 (match_operand 2 "const8_operand" ""))
10843 (match_operand 3 "register_operand" ""))]
10846 /* Handle insertions to %ah et al. */
10847 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10850 /* From mips.md: insert_bit_field doesn't verify that our source
10851 matches the predicate, so check it again here. */
10852 if (! ext_register_operand (operands[0], VOIDmode))
10856 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
10858 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10863 ;; %%% bts, btr, btc, bt.
10864 ;; In general these instructions are *slow* when applied to memory,
10865 ;; since they enforce atomic operation. When applied to registers,
10866 ;; it depends on the cpu implementation. They're never faster than
10867 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10868 ;; no point. But in 64-bit, we can't hold the relevant immediates
10869 ;; within the instruction itself, so operating on bits in the high
10870 ;; 32-bits of a register becomes easier.
10872 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10873 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10874 ;; negdf respectively, so they can never be disabled entirely.
10876 (define_insn "*btsq"
10877 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10879 (match_operand:DI 1 "const_0_to_63_operand" ""))
10881 (clobber (reg:CC FLAGS_REG))]
10882 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10883 "bts{q}\t{%1, %0|%0, %1}"
10884 [(set_attr "type" "alu1")
10885 (set_attr "prefix_0f" "1")
10886 (set_attr "mode" "DI")])
10888 (define_insn "*btrq"
10889 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10891 (match_operand:DI 1 "const_0_to_63_operand" ""))
10893 (clobber (reg:CC FLAGS_REG))]
10894 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10895 "btr{q}\t{%1, %0|%0, %1}"
10896 [(set_attr "type" "alu1")
10897 (set_attr "prefix_0f" "1")
10898 (set_attr "mode" "DI")])
10900 (define_insn "*btcq"
10901 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10903 (match_operand:DI 1 "const_0_to_63_operand" ""))
10904 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10905 (clobber (reg:CC FLAGS_REG))]
10906 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10907 "btc{q}\t{%1, %0|%0, %1}"
10908 [(set_attr "type" "alu1")
10909 (set_attr "prefix_0f" "1")
10910 (set_attr "mode" "DI")])
10912 ;; Allow Nocona to avoid these instructions if a register is available.
10915 [(match_scratch:DI 2 "r")
10916 (parallel [(set (zero_extract:DI
10917 (match_operand:DI 0 "register_operand" "")
10919 (match_operand:DI 1 "const_0_to_63_operand" ""))
10921 (clobber (reg:CC FLAGS_REG))])]
10922 "TARGET_64BIT && !TARGET_USE_BT"
10925 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10928 if (HOST_BITS_PER_WIDE_INT >= 64)
10929 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10930 else if (i < HOST_BITS_PER_WIDE_INT)
10931 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10933 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10935 op1 = immed_double_const (lo, hi, DImode);
10938 emit_move_insn (operands[2], op1);
10942 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10947 [(match_scratch:DI 2 "r")
10948 (parallel [(set (zero_extract:DI
10949 (match_operand:DI 0 "register_operand" "")
10951 (match_operand:DI 1 "const_0_to_63_operand" ""))
10953 (clobber (reg:CC FLAGS_REG))])]
10954 "TARGET_64BIT && !TARGET_USE_BT"
10957 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10960 if (HOST_BITS_PER_WIDE_INT >= 64)
10961 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10962 else if (i < HOST_BITS_PER_WIDE_INT)
10963 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10965 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10967 op1 = immed_double_const (~lo, ~hi, DImode);
10970 emit_move_insn (operands[2], op1);
10974 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10979 [(match_scratch:DI 2 "r")
10980 (parallel [(set (zero_extract:DI
10981 (match_operand:DI 0 "register_operand" "")
10983 (match_operand:DI 1 "const_0_to_63_operand" ""))
10984 (not:DI (zero_extract:DI
10985 (match_dup 0) (const_int 1) (match_dup 1))))
10986 (clobber (reg:CC FLAGS_REG))])]
10987 "TARGET_64BIT && !TARGET_USE_BT"
10990 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10993 if (HOST_BITS_PER_WIDE_INT >= 64)
10994 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10995 else if (i < HOST_BITS_PER_WIDE_INT)
10996 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10998 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
11000 op1 = immed_double_const (lo, hi, DImode);
11003 emit_move_insn (operands[2], op1);
11007 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
11011 (define_insn "*bt<mode>"
11012 [(set (reg:CCC FLAGS_REG)
11014 (zero_extract:SWI48
11015 (match_operand:SWI48 0 "register_operand" "r")
11017 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
11019 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11020 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
11021 [(set_attr "type" "alu1")
11022 (set_attr "prefix_0f" "1")
11023 (set_attr "mode" "<MODE>")])
11025 ;; Store-flag instructions.
11027 ;; For all sCOND expanders, also expand the compare or test insn that
11028 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
11030 (define_insn_and_split "*setcc_di_1"
11031 [(set (match_operand:DI 0 "register_operand" "=q")
11032 (match_operator:DI 1 "ix86_comparison_operator"
11033 [(reg FLAGS_REG) (const_int 0)]))]
11034 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11036 "&& reload_completed"
11037 [(set (match_dup 2) (match_dup 1))
11038 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11040 PUT_MODE (operands[1], QImode);
11041 operands[2] = gen_lowpart (QImode, operands[0]);
11044 (define_insn_and_split "*setcc_si_1_and"
11045 [(set (match_operand:SI 0 "register_operand" "=q")
11046 (match_operator:SI 1 "ix86_comparison_operator"
11047 [(reg FLAGS_REG) (const_int 0)]))
11048 (clobber (reg:CC FLAGS_REG))]
11049 "!TARGET_PARTIAL_REG_STALL
11050 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11052 "&& reload_completed"
11053 [(set (match_dup 2) (match_dup 1))
11054 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11055 (clobber (reg:CC FLAGS_REG))])]
11057 PUT_MODE (operands[1], QImode);
11058 operands[2] = gen_lowpart (QImode, operands[0]);
11061 (define_insn_and_split "*setcc_si_1_movzbl"
11062 [(set (match_operand:SI 0 "register_operand" "=q")
11063 (match_operator:SI 1 "ix86_comparison_operator"
11064 [(reg FLAGS_REG) (const_int 0)]))]
11065 "!TARGET_PARTIAL_REG_STALL
11066 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11068 "&& reload_completed"
11069 [(set (match_dup 2) (match_dup 1))
11070 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11072 PUT_MODE (operands[1], QImode);
11073 operands[2] = gen_lowpart (QImode, operands[0]);
11076 (define_insn "*setcc_qi"
11077 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11078 (match_operator:QI 1 "ix86_comparison_operator"
11079 [(reg FLAGS_REG) (const_int 0)]))]
11082 [(set_attr "type" "setcc")
11083 (set_attr "mode" "QI")])
11085 (define_insn "*setcc_qi_slp"
11086 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11087 (match_operator:QI 1 "ix86_comparison_operator"
11088 [(reg FLAGS_REG) (const_int 0)]))]
11091 [(set_attr "type" "setcc")
11092 (set_attr "mode" "QI")])
11094 ;; In general it is not safe to assume too much about CCmode registers,
11095 ;; so simplify-rtx stops when it sees a second one. Under certain
11096 ;; conditions this is safe on x86, so help combine not create
11103 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11104 (ne:QI (match_operator 1 "ix86_comparison_operator"
11105 [(reg FLAGS_REG) (const_int 0)])
11108 [(set (match_dup 0) (match_dup 1))]
11110 PUT_MODE (operands[1], QImode);
11114 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11115 (ne:QI (match_operator 1 "ix86_comparison_operator"
11116 [(reg FLAGS_REG) (const_int 0)])
11119 [(set (match_dup 0) (match_dup 1))]
11121 PUT_MODE (operands[1], QImode);
11125 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11126 (eq:QI (match_operator 1 "ix86_comparison_operator"
11127 [(reg FLAGS_REG) (const_int 0)])
11130 [(set (match_dup 0) (match_dup 1))]
11132 rtx new_op1 = copy_rtx (operands[1]);
11133 operands[1] = new_op1;
11134 PUT_MODE (new_op1, QImode);
11135 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11136 GET_MODE (XEXP (new_op1, 0))));
11138 /* Make sure that (a) the CCmode we have for the flags is strong
11139 enough for the reversed compare or (b) we have a valid FP compare. */
11140 if (! ix86_comparison_operator (new_op1, VOIDmode))
11145 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11146 (eq:QI (match_operator 1 "ix86_comparison_operator"
11147 [(reg FLAGS_REG) (const_int 0)])
11150 [(set (match_dup 0) (match_dup 1))]
11152 rtx new_op1 = copy_rtx (operands[1]);
11153 operands[1] = new_op1;
11154 PUT_MODE (new_op1, QImode);
11155 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11156 GET_MODE (XEXP (new_op1, 0))));
11158 /* Make sure that (a) the CCmode we have for the flags is strong
11159 enough for the reversed compare or (b) we have a valid FP compare. */
11160 if (! ix86_comparison_operator (new_op1, VOIDmode))
11164 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11165 ;; subsequent logical operations are used to imitate conditional moves.
11166 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11169 (define_insn "*avx_setcc<mode>"
11170 [(set (match_operand:MODEF 0 "register_operand" "=x")
11171 (match_operator:MODEF 1 "avx_comparison_float_operator"
11172 [(match_operand:MODEF 2 "register_operand" "x")
11173 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11175 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
11176 [(set_attr "type" "ssecmp")
11177 (set_attr "prefix" "vex")
11178 (set_attr "length_immediate" "1")
11179 (set_attr "mode" "<MODE>")])
11181 (define_insn "*sse_setcc<mode>"
11182 [(set (match_operand:MODEF 0 "register_operand" "=x")
11183 (match_operator:MODEF 1 "sse_comparison_operator"
11184 [(match_operand:MODEF 2 "register_operand" "0")
11185 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11186 "SSE_FLOAT_MODE_P (<MODE>mode)"
11187 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
11188 [(set_attr "type" "ssecmp")
11189 (set_attr "length_immediate" "1")
11190 (set_attr "mode" "<MODE>")])
11192 ;; Basic conditional jump instructions.
11193 ;; We ignore the overflow flag for signed branch instructions.
11195 (define_insn "*jcc_1"
11197 (if_then_else (match_operator 1 "ix86_comparison_operator"
11198 [(reg FLAGS_REG) (const_int 0)])
11199 (label_ref (match_operand 0 "" ""))
11203 [(set_attr "type" "ibr")
11204 (set_attr "modrm" "0")
11205 (set (attr "length")
11206 (if_then_else (and (ge (minus (match_dup 0) (pc))
11208 (lt (minus (match_dup 0) (pc))
11213 (define_insn "*jcc_2"
11215 (if_then_else (match_operator 1 "ix86_comparison_operator"
11216 [(reg FLAGS_REG) (const_int 0)])
11218 (label_ref (match_operand 0 "" ""))))]
11221 [(set_attr "type" "ibr")
11222 (set_attr "modrm" "0")
11223 (set (attr "length")
11224 (if_then_else (and (ge (minus (match_dup 0) (pc))
11226 (lt (minus (match_dup 0) (pc))
11231 ;; In general it is not safe to assume too much about CCmode registers,
11232 ;; so simplify-rtx stops when it sees a second one. Under certain
11233 ;; conditions this is safe on x86, so help combine not create
11241 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11242 [(reg FLAGS_REG) (const_int 0)])
11244 (label_ref (match_operand 1 "" ""))
11248 (if_then_else (match_dup 0)
11249 (label_ref (match_dup 1))
11252 PUT_MODE (operands[0], VOIDmode);
11257 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11258 [(reg FLAGS_REG) (const_int 0)])
11260 (label_ref (match_operand 1 "" ""))
11264 (if_then_else (match_dup 0)
11265 (label_ref (match_dup 1))
11268 rtx new_op0 = copy_rtx (operands[0]);
11269 operands[0] = new_op0;
11270 PUT_MODE (new_op0, VOIDmode);
11271 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11272 GET_MODE (XEXP (new_op0, 0))));
11274 /* Make sure that (a) the CCmode we have for the flags is strong
11275 enough for the reversed compare or (b) we have a valid FP compare. */
11276 if (! ix86_comparison_operator (new_op0, VOIDmode))
11280 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11281 ;; pass generates from shift insn with QImode operand. Actually, the mode
11282 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11283 ;; appropriate modulo of the bit offset value.
11285 (define_insn_and_split "*jcc_bt<mode>"
11287 (if_then_else (match_operator 0 "bt_comparison_operator"
11288 [(zero_extract:SWI48
11289 (match_operand:SWI48 1 "register_operand" "r")
11292 (match_operand:QI 2 "register_operand" "r")))
11294 (label_ref (match_operand 3 "" ""))
11296 (clobber (reg:CC FLAGS_REG))]
11297 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
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 3))
11312 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11314 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11317 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11318 ;; also for DImode, this is what combine produces.
11319 (define_insn_and_split "*jcc_bt<mode>_mask"
11321 (if_then_else (match_operator 0 "bt_comparison_operator"
11322 [(zero_extract:SWI48
11323 (match_operand:SWI48 1 "register_operand" "r")
11326 (match_operand:SI 2 "register_operand" "r")
11327 (match_operand:SI 3 "const_int_operand" "n")))])
11328 (label_ref (match_operand 4 "" ""))
11330 (clobber (reg:CC FLAGS_REG))]
11331 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11332 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11333 == GET_MODE_BITSIZE (<MODE>mode)-1"
11336 [(set (reg:CCC FLAGS_REG)
11338 (zero_extract:SWI48
11344 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11345 (label_ref (match_dup 4))
11348 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11350 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11353 (define_insn_and_split "*jcc_btsi_1"
11355 (if_then_else (match_operator 0 "bt_comparison_operator"
11358 (match_operand:SI 1 "register_operand" "r")
11359 (match_operand:QI 2 "register_operand" "r"))
11362 (label_ref (match_operand 3 "" ""))
11364 (clobber (reg:CC FLAGS_REG))]
11365 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11368 [(set (reg:CCC FLAGS_REG)
11376 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11377 (label_ref (match_dup 3))
11380 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11382 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11385 ;; avoid useless masking of bit offset operand
11386 (define_insn_and_split "*jcc_btsi_mask_1"
11389 (match_operator 0 "bt_comparison_operator"
11392 (match_operand:SI 1 "register_operand" "r")
11395 (match_operand:SI 2 "register_operand" "r")
11396 (match_operand:SI 3 "const_int_operand" "n")) 0))
11399 (label_ref (match_operand 4 "" ""))
11401 (clobber (reg:CC FLAGS_REG))]
11402 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11403 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11406 [(set (reg:CCC FLAGS_REG)
11414 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11415 (label_ref (match_dup 4))
11417 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11419 ;; Define combination compare-and-branch fp compare instructions to help
11422 (define_insn "*fp_jcc_3_387"
11424 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11425 [(match_operand 1 "register_operand" "f")
11426 (match_operand 2 "nonimmediate_operand" "fm")])
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"))]
11433 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11434 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11435 && SELECT_CC_MODE (GET_CODE (operands[0]),
11436 operands[1], operands[2]) == CCFPmode
11440 (define_insn "*fp_jcc_4_387"
11442 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11443 [(match_operand 1 "register_operand" "f")
11444 (match_operand 2 "nonimmediate_operand" "fm")])
11446 (label_ref (match_operand 3 "" ""))))
11447 (clobber (reg:CCFP FPSR_REG))
11448 (clobber (reg:CCFP FLAGS_REG))
11449 (clobber (match_scratch:HI 4 "=a"))]
11451 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11452 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11453 && SELECT_CC_MODE (GET_CODE (operands[0]),
11454 operands[1], operands[2]) == CCFPmode
11458 (define_insn "*fp_jcc_5_387"
11460 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11461 [(match_operand 1 "register_operand" "f")
11462 (match_operand 2 "register_operand" "f")])
11463 (label_ref (match_operand 3 "" ""))
11465 (clobber (reg:CCFP FPSR_REG))
11466 (clobber (reg:CCFP FLAGS_REG))
11467 (clobber (match_scratch:HI 4 "=a"))]
11468 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11469 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11473 (define_insn "*fp_jcc_6_387"
11475 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11476 [(match_operand 1 "register_operand" "f")
11477 (match_operand 2 "register_operand" "f")])
11479 (label_ref (match_operand 3 "" ""))))
11480 (clobber (reg:CCFP FPSR_REG))
11481 (clobber (reg:CCFP FLAGS_REG))
11482 (clobber (match_scratch:HI 4 "=a"))]
11483 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11484 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11488 (define_insn "*fp_jcc_7_387"
11490 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11491 [(match_operand 1 "register_operand" "f")
11492 (match_operand 2 "const0_operand" "")])
11493 (label_ref (match_operand 3 "" ""))
11495 (clobber (reg:CCFP FPSR_REG))
11496 (clobber (reg:CCFP FLAGS_REG))
11497 (clobber (match_scratch:HI 4 "=a"))]
11498 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11499 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11500 && SELECT_CC_MODE (GET_CODE (operands[0]),
11501 operands[1], operands[2]) == CCFPmode
11505 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
11506 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11507 ;; with a precedence over other operators and is always put in the first
11508 ;; place. Swap condition and operands to match ficom instruction.
11510 (define_insn "*fp_jcc_8<mode>_387"
11512 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11513 [(match_operator 1 "float_operator"
11514 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11515 (match_operand 3 "register_operand" "f,f")])
11516 (label_ref (match_operand 4 "" ""))
11518 (clobber (reg:CCFP FPSR_REG))
11519 (clobber (reg:CCFP FLAGS_REG))
11520 (clobber (match_scratch:HI 5 "=a,a"))]
11521 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11522 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11523 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11524 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11530 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11531 [(match_operand 1 "register_operand" "")
11532 (match_operand 2 "nonimmediate_operand" "")])
11533 (match_operand 3 "" "")
11534 (match_operand 4 "" "")))
11535 (clobber (reg:CCFP FPSR_REG))
11536 (clobber (reg:CCFP FLAGS_REG))]
11540 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11541 operands[3], operands[4], NULL_RTX, NULL_RTX);
11547 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11548 [(match_operand 1 "register_operand" "")
11549 (match_operand 2 "general_operand" "")])
11550 (match_operand 3 "" "")
11551 (match_operand 4 "" "")))
11552 (clobber (reg:CCFP FPSR_REG))
11553 (clobber (reg:CCFP FLAGS_REG))
11554 (clobber (match_scratch:HI 5 "=a"))]
11558 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11559 operands[3], operands[4], operands[5], NULL_RTX);
11565 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11566 [(match_operator 1 "float_operator"
11567 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11568 (match_operand 3 "register_operand" "")])
11569 (match_operand 4 "" "")
11570 (match_operand 5 "" "")))
11571 (clobber (reg:CCFP FPSR_REG))
11572 (clobber (reg:CCFP FLAGS_REG))
11573 (clobber (match_scratch:HI 6 "=a"))]
11577 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11579 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11580 operands[3], operands[7],
11581 operands[4], operands[5], operands[6], NULL_RTX);
11585 ;; %%% Kill this when reload knows how to do it.
11588 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11589 [(match_operator 1 "float_operator"
11590 [(match_operand:X87MODEI12 2 "register_operand" "")])
11591 (match_operand 3 "register_operand" "")])
11592 (match_operand 4 "" "")
11593 (match_operand 5 "" "")))
11594 (clobber (reg:CCFP FPSR_REG))
11595 (clobber (reg:CCFP FLAGS_REG))
11596 (clobber (match_scratch:HI 6 "=a"))]
11600 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11601 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11603 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11604 operands[3], operands[7],
11605 operands[4], operands[5], operands[6], operands[2]);
11609 ;; Unconditional and other jump instructions
11611 (define_insn "jump"
11613 (label_ref (match_operand 0 "" "")))]
11616 [(set_attr "type" "ibr")
11617 (set (attr "length")
11618 (if_then_else (and (ge (minus (match_dup 0) (pc))
11620 (lt (minus (match_dup 0) (pc))
11624 (set_attr "modrm" "0")])
11626 (define_expand "indirect_jump"
11627 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11631 (define_insn "*indirect_jump"
11632 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11635 [(set_attr "type" "ibr")
11636 (set_attr "length_immediate" "0")])
11638 (define_expand "tablejump"
11639 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11640 (use (label_ref (match_operand 1 "" "")))])]
11643 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11644 relative. Convert the relative address to an absolute address. */
11648 enum rtx_code code;
11650 /* We can't use @GOTOFF for text labels on VxWorks;
11651 see gotoff_operand. */
11652 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11656 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11658 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11662 op1 = pic_offset_table_rtx;
11667 op0 = pic_offset_table_rtx;
11671 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11676 (define_insn "*tablejump_1"
11677 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11678 (use (label_ref (match_operand 1 "" "")))]
11681 [(set_attr "type" "ibr")
11682 (set_attr "length_immediate" "0")])
11684 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11687 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11688 (set (match_operand:QI 1 "register_operand" "")
11689 (match_operator:QI 2 "ix86_comparison_operator"
11690 [(reg FLAGS_REG) (const_int 0)]))
11691 (set (match_operand 3 "q_regs_operand" "")
11692 (zero_extend (match_dup 1)))]
11693 "(peep2_reg_dead_p (3, operands[1])
11694 || operands_match_p (operands[1], operands[3]))
11695 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11696 [(set (match_dup 4) (match_dup 0))
11697 (set (strict_low_part (match_dup 5))
11700 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11701 operands[5] = gen_lowpart (QImode, operands[3]);
11702 ix86_expand_clear (operands[3]);
11705 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11708 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11709 (set (match_operand:QI 1 "register_operand" "")
11710 (match_operator:QI 2 "ix86_comparison_operator"
11711 [(reg FLAGS_REG) (const_int 0)]))
11712 (parallel [(set (match_operand 3 "q_regs_operand" "")
11713 (zero_extend (match_dup 1)))
11714 (clobber (reg:CC FLAGS_REG))])]
11715 "(peep2_reg_dead_p (3, operands[1])
11716 || operands_match_p (operands[1], operands[3]))
11717 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11718 [(set (match_dup 4) (match_dup 0))
11719 (set (strict_low_part (match_dup 5))
11722 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11723 operands[5] = gen_lowpart (QImode, operands[3]);
11724 ix86_expand_clear (operands[3]);
11727 ;; Call instructions.
11729 ;; The predicates normally associated with named expanders are not properly
11730 ;; checked for calls. This is a bug in the generic code, but it isn't that
11731 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11733 ;; P6 processors will jump to the address after the decrement when %esp
11734 ;; is used as a call operand, so they will execute return address as a code.
11735 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11737 ;; Call subroutine returning no value.
11739 (define_expand "call_pop"
11740 [(parallel [(call (match_operand:QI 0 "" "")
11741 (match_operand:SI 1 "" ""))
11742 (set (reg:SI SP_REG)
11743 (plus:SI (reg:SI SP_REG)
11744 (match_operand:SI 3 "" "")))])]
11747 ix86_expand_call (NULL, operands[0], operands[1],
11748 operands[2], operands[3], 0);
11752 (define_insn "*call_pop_0"
11753 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11754 (match_operand:SI 1 "" ""))
11755 (set (reg:SI SP_REG)
11756 (plus:SI (reg:SI SP_REG)
11757 (match_operand:SI 2 "immediate_operand" "")))]
11760 if (SIBLING_CALL_P (insn))
11763 return "call\t%P0";
11765 [(set_attr "type" "call")])
11767 (define_insn "*call_pop_1"
11768 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11769 (match_operand:SI 1 "" ""))
11770 (set (reg:SI SP_REG)
11771 (plus:SI (reg:SI SP_REG)
11772 (match_operand:SI 2 "immediate_operand" "i")))]
11773 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11775 if (constant_call_address_operand (operands[0], Pmode))
11776 return "call\t%P0";
11777 return "call\t%A0";
11779 [(set_attr "type" "call")])
11781 (define_insn "*sibcall_pop_1"
11782 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11783 (match_operand:SI 1 "" ""))
11784 (set (reg:SI SP_REG)
11785 (plus:SI (reg:SI SP_REG)
11786 (match_operand:SI 2 "immediate_operand" "i,i")))]
11787 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11791 [(set_attr "type" "call")])
11793 (define_expand "call"
11794 [(call (match_operand:QI 0 "" "")
11795 (match_operand 1 "" ""))
11796 (use (match_operand 2 "" ""))]
11799 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11803 (define_expand "sibcall"
11804 [(call (match_operand:QI 0 "" "")
11805 (match_operand 1 "" ""))
11806 (use (match_operand 2 "" ""))]
11809 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11813 (define_insn "*call_0"
11814 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11815 (match_operand 1 "" ""))]
11818 if (SIBLING_CALL_P (insn))
11821 return "call\t%P0";
11823 [(set_attr "type" "call")])
11825 (define_insn "*call_1"
11826 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11827 (match_operand 1 "" ""))]
11828 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11830 if (constant_call_address_operand (operands[0], Pmode))
11831 return "call\t%P0";
11832 return "call\t%A0";
11834 [(set_attr "type" "call")])
11836 (define_insn "*sibcall_1"
11837 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11838 (match_operand 1 "" ""))]
11839 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11843 [(set_attr "type" "call")])
11845 (define_insn "*call_1_rex64"
11846 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11847 (match_operand 1 "" ""))]
11848 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11849 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11851 if (constant_call_address_operand (operands[0], Pmode))
11852 return "call\t%P0";
11853 return "call\t%A0";
11855 [(set_attr "type" "call")])
11857 (define_insn "*call_1_rex64_ms_sysv"
11858 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11859 (match_operand 1 "" ""))
11860 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11861 (clobber (reg:TI XMM6_REG))
11862 (clobber (reg:TI XMM7_REG))
11863 (clobber (reg:TI XMM8_REG))
11864 (clobber (reg:TI XMM9_REG))
11865 (clobber (reg:TI XMM10_REG))
11866 (clobber (reg:TI XMM11_REG))
11867 (clobber (reg:TI XMM12_REG))
11868 (clobber (reg:TI XMM13_REG))
11869 (clobber (reg:TI XMM14_REG))
11870 (clobber (reg:TI XMM15_REG))
11871 (clobber (reg:DI SI_REG))
11872 (clobber (reg:DI DI_REG))]
11873 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11875 if (constant_call_address_operand (operands[0], Pmode))
11876 return "call\t%P0";
11877 return "call\t%A0";
11879 [(set_attr "type" "call")])
11881 (define_insn "*call_1_rex64_large"
11882 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11883 (match_operand 1 "" ""))]
11884 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11886 [(set_attr "type" "call")])
11888 (define_insn "*sibcall_1_rex64"
11889 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11890 (match_operand 1 "" ""))]
11891 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11895 [(set_attr "type" "call")])
11897 ;; Call subroutine, returning value in operand 0
11898 (define_expand "call_value_pop"
11899 [(parallel [(set (match_operand 0 "" "")
11900 (call (match_operand:QI 1 "" "")
11901 (match_operand:SI 2 "" "")))
11902 (set (reg:SI SP_REG)
11903 (plus:SI (reg:SI SP_REG)
11904 (match_operand:SI 4 "" "")))])]
11907 ix86_expand_call (operands[0], operands[1], operands[2],
11908 operands[3], operands[4], 0);
11912 (define_expand "call_value"
11913 [(set (match_operand 0 "" "")
11914 (call (match_operand:QI 1 "" "")
11915 (match_operand:SI 2 "" "")))
11916 (use (match_operand:SI 3 "" ""))]
11917 ;; Operand 3 is not used on the i386.
11920 ix86_expand_call (operands[0], operands[1], operands[2],
11921 operands[3], NULL, 0);
11925 (define_expand "sibcall_value"
11926 [(set (match_operand 0 "" "")
11927 (call (match_operand:QI 1 "" "")
11928 (match_operand:SI 2 "" "")))
11929 (use (match_operand:SI 3 "" ""))]
11930 ;; Operand 3 is not used on the i386.
11933 ix86_expand_call (operands[0], operands[1], operands[2],
11934 operands[3], NULL, 1);
11938 ;; Call subroutine returning any type.
11940 (define_expand "untyped_call"
11941 [(parallel [(call (match_operand 0 "" "")
11943 (match_operand 1 "" "")
11944 (match_operand 2 "" "")])]
11949 /* In order to give reg-stack an easier job in validating two
11950 coprocessor registers as containing a possible return value,
11951 simply pretend the untyped call returns a complex long double
11954 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11955 and should have the default ABI. */
11957 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11958 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11959 operands[0], const0_rtx,
11960 GEN_INT ((TARGET_64BIT
11961 ? (ix86_abi == SYSV_ABI
11962 ? X86_64_SSE_REGPARM_MAX
11963 : X86_64_MS_SSE_REGPARM_MAX)
11964 : X86_32_SSE_REGPARM_MAX)
11968 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11970 rtx set = XVECEXP (operands[2], 0, i);
11971 emit_move_insn (SET_DEST (set), SET_SRC (set));
11974 /* The optimizer does not know that the call sets the function value
11975 registers we stored in the result block. We avoid problems by
11976 claiming that all hard registers are used and clobbered at this
11978 emit_insn (gen_blockage ());
11983 ;; Prologue and epilogue instructions
11985 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11986 ;; all of memory. This blocks insns from being moved across this point.
11988 (define_insn "blockage"
11989 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11992 [(set_attr "length" "0")])
11994 ;; Do not schedule instructions accessing memory across this point.
11996 (define_expand "memory_blockage"
11997 [(set (match_dup 0)
11998 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12001 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12002 MEM_VOLATILE_P (operands[0]) = 1;
12005 (define_insn "*memory_blockage"
12006 [(set (match_operand:BLK 0 "" "")
12007 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12010 [(set_attr "length" "0")])
12012 ;; As USE insns aren't meaningful after reload, this is used instead
12013 ;; to prevent deleting instructions setting registers for PIC code
12014 (define_insn "prologue_use"
12015 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
12018 [(set_attr "length" "0")])
12020 ;; Insn emitted into the body of a function to return from a function.
12021 ;; This is only done if the function's epilogue is known to be simple.
12022 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12024 (define_expand "return"
12026 "ix86_can_use_return_insn_p ()"
12028 if (crtl->args.pops_args)
12030 rtx popc = GEN_INT (crtl->args.pops_args);
12031 emit_jump_insn (gen_return_pop_internal (popc));
12036 (define_insn "return_internal"
12040 [(set_attr "length" "1")
12041 (set_attr "atom_unit" "jeu")
12042 (set_attr "length_immediate" "0")
12043 (set_attr "modrm" "0")])
12045 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12046 ;; instruction Athlon and K8 have.
12048 (define_insn "return_internal_long"
12050 (unspec [(const_int 0)] UNSPEC_REP)]
12053 [(set_attr "length" "2")
12054 (set_attr "atom_unit" "jeu")
12055 (set_attr "length_immediate" "0")
12056 (set_attr "prefix_rep" "1")
12057 (set_attr "modrm" "0")])
12059 (define_insn "return_pop_internal"
12061 (use (match_operand:SI 0 "const_int_operand" ""))]
12064 [(set_attr "length" "3")
12065 (set_attr "atom_unit" "jeu")
12066 (set_attr "length_immediate" "2")
12067 (set_attr "modrm" "0")])
12069 (define_insn "return_indirect_internal"
12071 (use (match_operand:SI 0 "register_operand" "r"))]
12074 [(set_attr "type" "ibr")
12075 (set_attr "length_immediate" "0")])
12081 [(set_attr "length" "1")
12082 (set_attr "length_immediate" "0")
12083 (set_attr "modrm" "0")])
12085 (define_insn "vswapmov"
12086 [(set (match_operand:SI 0 "register_operand" "=r")
12087 (match_operand:SI 1 "register_operand" "r"))
12088 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
12090 "movl.s\t{%1, %0|%0, %1}"
12091 [(set_attr "length" "2")
12092 (set_attr "length_immediate" "0")
12093 (set_attr "modrm" "0")])
12095 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12096 ;; branch prediction penalty for the third jump in a 16-byte
12100 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
12103 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12104 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12106 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12107 The align insn is used to avoid 3 jump instructions in the row to improve
12108 branch prediction and the benefits hardly outweigh the cost of extra 8
12109 nops on the average inserted by full alignment pseudo operation. */
12113 [(set_attr "length" "16")])
12115 (define_expand "prologue"
12118 "ix86_expand_prologue (); DONE;")
12120 (define_insn "set_got"
12121 [(set (match_operand:SI 0 "register_operand" "=r")
12122 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12123 (clobber (reg:CC FLAGS_REG))]
12125 { return output_set_got (operands[0], NULL_RTX); }
12126 [(set_attr "type" "multi")
12127 (set_attr "length" "12")])
12129 (define_insn "set_got_labelled"
12130 [(set (match_operand:SI 0 "register_operand" "=r")
12131 (unspec:SI [(label_ref (match_operand 1 "" ""))]
12133 (clobber (reg:CC FLAGS_REG))]
12135 { return output_set_got (operands[0], operands[1]); }
12136 [(set_attr "type" "multi")
12137 (set_attr "length" "12")])
12139 (define_insn "set_got_rex64"
12140 [(set (match_operand:DI 0 "register_operand" "=r")
12141 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12143 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12144 [(set_attr "type" "lea")
12145 (set_attr "length_address" "4")
12146 (set_attr "mode" "DI")])
12148 (define_insn "set_rip_rex64"
12149 [(set (match_operand:DI 0 "register_operand" "=r")
12150 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
12152 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12153 [(set_attr "type" "lea")
12154 (set_attr "length_address" "4")
12155 (set_attr "mode" "DI")])
12157 (define_insn "set_got_offset_rex64"
12158 [(set (match_operand:DI 0 "register_operand" "=r")
12160 [(label_ref (match_operand 1 "" ""))]
12161 UNSPEC_SET_GOT_OFFSET))]
12163 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12164 [(set_attr "type" "imov")
12165 (set_attr "length_immediate" "0")
12166 (set_attr "length_address" "8")
12167 (set_attr "mode" "DI")])
12169 (define_expand "epilogue"
12172 "ix86_expand_epilogue (1); DONE;")
12174 (define_expand "sibcall_epilogue"
12177 "ix86_expand_epilogue (0); DONE;")
12179 (define_expand "eh_return"
12180 [(use (match_operand 0 "register_operand" ""))]
12183 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12185 /* Tricky bit: we write the address of the handler to which we will
12186 be returning into someone else's stack frame, one word below the
12187 stack address we wish to restore. */
12188 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12189 tmp = plus_constant (tmp, -UNITS_PER_WORD);
12190 tmp = gen_rtx_MEM (Pmode, tmp);
12191 emit_move_insn (tmp, ra);
12193 emit_jump_insn (gen_eh_return_internal ());
12198 (define_insn_and_split "eh_return_internal"
12202 "epilogue_completed"
12204 "ix86_expand_epilogue (2); DONE;")
12206 (define_insn "leave"
12207 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12208 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12209 (clobber (mem:BLK (scratch)))]
12212 [(set_attr "type" "leave")])
12214 (define_insn "leave_rex64"
12215 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12216 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12217 (clobber (mem:BLK (scratch)))]
12220 [(set_attr "type" "leave")])
12222 ;; Bit manipulation instructions.
12224 (define_expand "ffs<mode>2"
12225 [(set (match_dup 2) (const_int -1))
12226 (parallel [(set (reg:CCZ FLAGS_REG)
12228 (match_operand:SWI48 1 "nonimmediate_operand" "")
12230 (set (match_operand:SWI48 0 "register_operand" "")
12231 (ctz:SWI48 (match_dup 1)))])
12232 (set (match_dup 0) (if_then_else:SWI48
12233 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12236 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12237 (clobber (reg:CC FLAGS_REG))])]
12240 if (<MODE>mode == SImode && !TARGET_CMOVE)
12242 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12245 operands[2] = gen_reg_rtx (<MODE>mode);
12248 (define_insn_and_split "ffssi2_no_cmove"
12249 [(set (match_operand:SI 0 "register_operand" "=r")
12250 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12251 (clobber (match_scratch:SI 2 "=&q"))
12252 (clobber (reg:CC FLAGS_REG))]
12255 "&& reload_completed"
12256 [(parallel [(set (reg:CCZ FLAGS_REG)
12257 (compare:CCZ (match_dup 1) (const_int 0)))
12258 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12259 (set (strict_low_part (match_dup 3))
12260 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12261 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12262 (clobber (reg:CC FLAGS_REG))])
12263 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12264 (clobber (reg:CC FLAGS_REG))])
12265 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12266 (clobber (reg:CC FLAGS_REG))])]
12268 operands[3] = gen_lowpart (QImode, operands[2]);
12269 ix86_expand_clear (operands[2]);
12272 (define_insn "*ffs<mode>_1"
12273 [(set (reg:CCZ FLAGS_REG)
12274 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12276 (set (match_operand:SWI48 0 "register_operand" "=r")
12277 (ctz:SWI48 (match_dup 1)))]
12279 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12280 [(set_attr "type" "alu1")
12281 (set_attr "prefix_0f" "1")
12282 (set_attr "mode" "<MODE>")])
12284 (define_insn "ctz<mode>2"
12285 [(set (match_operand:SWI48 0 "register_operand" "=r")
12286 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12287 (clobber (reg:CC FLAGS_REG))]
12289 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12290 [(set_attr "type" "alu1")
12291 (set_attr "prefix_0f" "1")
12292 (set_attr "mode" "<MODE>")])
12294 (define_expand "clz<mode>2"
12296 [(set (match_operand:SWI248 0 "register_operand" "")
12299 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12300 (clobber (reg:CC FLAGS_REG))])
12302 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12303 (clobber (reg:CC FLAGS_REG))])]
12308 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12311 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12314 (define_insn "clz<mode>2_abm"
12315 [(set (match_operand:SWI248 0 "register_operand" "=r")
12316 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12317 (clobber (reg:CC FLAGS_REG))]
12319 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12320 [(set_attr "prefix_rep" "1")
12321 (set_attr "type" "bitmanip")
12322 (set_attr "mode" "<MODE>")])
12324 (define_insn "bsr_rex64"
12325 [(set (match_operand:DI 0 "register_operand" "=r")
12326 (minus:DI (const_int 63)
12327 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12328 (clobber (reg:CC FLAGS_REG))]
12330 "bsr{q}\t{%1, %0|%0, %1}"
12331 [(set_attr "type" "alu1")
12332 (set_attr "prefix_0f" "1")
12333 (set_attr "mode" "DI")])
12336 [(set (match_operand:SI 0 "register_operand" "=r")
12337 (minus:SI (const_int 31)
12338 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12339 (clobber (reg:CC FLAGS_REG))]
12341 "bsr{l}\t{%1, %0|%0, %1}"
12342 [(set_attr "type" "alu1")
12343 (set_attr "prefix_0f" "1")
12344 (set_attr "mode" "SI")])
12346 (define_insn "*bsrhi"
12347 [(set (match_operand:HI 0 "register_operand" "=r")
12348 (minus:HI (const_int 15)
12349 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12350 (clobber (reg:CC FLAGS_REG))]
12352 "bsr{w}\t{%1, %0|%0, %1}"
12353 [(set_attr "type" "alu1")
12354 (set_attr "prefix_0f" "1")
12355 (set_attr "mode" "HI")])
12357 (define_insn "popcount<mode>2"
12358 [(set (match_operand:SWI248 0 "register_operand" "=r")
12360 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12361 (clobber (reg:CC FLAGS_REG))]
12365 return "popcnt\t{%1, %0|%0, %1}";
12367 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12370 [(set_attr "prefix_rep" "1")
12371 (set_attr "type" "bitmanip")
12372 (set_attr "mode" "<MODE>")])
12374 (define_insn "*popcount<mode>2_cmp"
12375 [(set (reg FLAGS_REG)
12378 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12380 (set (match_operand:SWI248 0 "register_operand" "=r")
12381 (popcount:SWI248 (match_dup 1)))]
12382 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12385 return "popcnt\t{%1, %0|%0, %1}";
12387 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12390 [(set_attr "prefix_rep" "1")
12391 (set_attr "type" "bitmanip")
12392 (set_attr "mode" "<MODE>")])
12394 (define_insn "*popcountsi2_cmp_zext"
12395 [(set (reg FLAGS_REG)
12397 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12399 (set (match_operand:DI 0 "register_operand" "=r")
12400 (zero_extend:DI(popcount:SI (match_dup 1))))]
12401 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12404 return "popcnt\t{%1, %0|%0, %1}";
12406 return "popcnt{l}\t{%1, %0|%0, %1}";
12409 [(set_attr "prefix_rep" "1")
12410 (set_attr "type" "bitmanip")
12411 (set_attr "mode" "SI")])
12413 (define_expand "bswap<mode>2"
12414 [(set (match_operand:SWI48 0 "register_operand" "")
12415 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12418 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12420 rtx x = operands[0];
12422 emit_move_insn (x, operands[1]);
12423 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12424 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12425 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12430 (define_insn "*bswap<mode>2_movbe"
12431 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12432 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12434 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12437 movbe\t{%1, %0|%0, %1}
12438 movbe\t{%1, %0|%0, %1}"
12439 [(set_attr "type" "bitmanip,imov,imov")
12440 (set_attr "modrm" "0,1,1")
12441 (set_attr "prefix_0f" "*,1,1")
12442 (set_attr "prefix_extra" "*,1,1")
12443 (set_attr "mode" "<MODE>")])
12445 (define_insn "*bswap<mode>2_1"
12446 [(set (match_operand:SWI48 0 "register_operand" "=r")
12447 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12450 [(set_attr "type" "bitmanip")
12451 (set_attr "modrm" "0")
12452 (set_attr "mode" "<MODE>")])
12454 (define_insn "*bswaphi_lowpart_1"
12455 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12456 (bswap:HI (match_dup 0)))
12457 (clobber (reg:CC FLAGS_REG))]
12458 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12460 xchg{b}\t{%h0, %b0|%b0, %h0}
12461 rol{w}\t{$8, %0|%0, 8}"
12462 [(set_attr "length" "2,4")
12463 (set_attr "mode" "QI,HI")])
12465 (define_insn "bswaphi_lowpart"
12466 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12467 (bswap:HI (match_dup 0)))
12468 (clobber (reg:CC FLAGS_REG))]
12470 "rol{w}\t{$8, %0|%0, 8}"
12471 [(set_attr "length" "4")
12472 (set_attr "mode" "HI")])
12474 (define_expand "paritydi2"
12475 [(set (match_operand:DI 0 "register_operand" "")
12476 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12479 rtx scratch = gen_reg_rtx (QImode);
12482 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12483 NULL_RTX, operands[1]));
12485 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12486 gen_rtx_REG (CCmode, FLAGS_REG),
12488 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12491 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12494 rtx tmp = gen_reg_rtx (SImode);
12496 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12497 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12502 (define_expand "paritysi2"
12503 [(set (match_operand:SI 0 "register_operand" "")
12504 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12507 rtx scratch = gen_reg_rtx (QImode);
12510 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12512 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12513 gen_rtx_REG (CCmode, FLAGS_REG),
12515 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12517 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12521 (define_insn_and_split "paritydi2_cmp"
12522 [(set (reg:CC FLAGS_REG)
12523 (parity:CC (match_operand:DI 3 "register_operand" "0")))
12524 (clobber (match_scratch:DI 0 "=r"))
12525 (clobber (match_scratch:SI 1 "=&r"))
12526 (clobber (match_scratch:HI 2 "=Q"))]
12529 "&& reload_completed"
12531 [(set (match_dup 1)
12532 (xor:SI (match_dup 1) (match_dup 4)))
12533 (clobber (reg:CC FLAGS_REG))])
12535 [(set (reg:CC FLAGS_REG)
12536 (parity:CC (match_dup 1)))
12537 (clobber (match_dup 1))
12538 (clobber (match_dup 2))])]
12540 operands[4] = gen_lowpart (SImode, operands[3]);
12544 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12545 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12548 operands[1] = gen_highpart (SImode, operands[3]);
12551 (define_insn_and_split "paritysi2_cmp"
12552 [(set (reg:CC FLAGS_REG)
12553 (parity:CC (match_operand:SI 2 "register_operand" "0")))
12554 (clobber (match_scratch:SI 0 "=r"))
12555 (clobber (match_scratch:HI 1 "=&Q"))]
12558 "&& reload_completed"
12560 [(set (match_dup 1)
12561 (xor:HI (match_dup 1) (match_dup 3)))
12562 (clobber (reg:CC FLAGS_REG))])
12564 [(set (reg:CC FLAGS_REG)
12565 (parity:CC (match_dup 1)))
12566 (clobber (match_dup 1))])]
12568 operands[3] = gen_lowpart (HImode, operands[2]);
12570 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12571 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12574 (define_insn "*parityhi2_cmp"
12575 [(set (reg:CC FLAGS_REG)
12576 (parity:CC (match_operand:HI 1 "register_operand" "0")))
12577 (clobber (match_scratch:HI 0 "=Q"))]
12579 "xor{b}\t{%h0, %b0|%b0, %h0}"
12580 [(set_attr "length" "2")
12581 (set_attr "mode" "HI")])
12583 (define_insn "*parityqi2_cmp"
12584 [(set (reg:CC FLAGS_REG)
12585 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
12588 [(set_attr "length" "2")
12589 (set_attr "mode" "QI")])
12591 ;; Thread-local storage patterns for ELF.
12593 ;; Note that these code sequences must appear exactly as shown
12594 ;; in order to allow linker relaxation.
12596 (define_insn "*tls_global_dynamic_32_gnu"
12597 [(set (match_operand:SI 0 "register_operand" "=a")
12598 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12599 (match_operand:SI 2 "tls_symbolic_operand" "")
12600 (match_operand:SI 3 "call_insn_operand" "")]
12602 (clobber (match_scratch:SI 4 "=d"))
12603 (clobber (match_scratch:SI 5 "=c"))
12604 (clobber (reg:CC FLAGS_REG))]
12605 "!TARGET_64BIT && TARGET_GNU_TLS"
12606 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12607 [(set_attr "type" "multi")
12608 (set_attr "length" "12")])
12610 (define_expand "tls_global_dynamic_32"
12611 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12614 (match_operand:SI 1 "tls_symbolic_operand" "")
12617 (clobber (match_scratch:SI 4 ""))
12618 (clobber (match_scratch:SI 5 ""))
12619 (clobber (reg:CC FLAGS_REG))])]
12623 operands[2] = pic_offset_table_rtx;
12626 operands[2] = gen_reg_rtx (Pmode);
12627 emit_insn (gen_set_got (operands[2]));
12629 if (TARGET_GNU2_TLS)
12631 emit_insn (gen_tls_dynamic_gnu2_32
12632 (operands[0], operands[1], operands[2]));
12635 operands[3] = ix86_tls_get_addr ();
12638 (define_insn "*tls_global_dynamic_64"
12639 [(set (match_operand:DI 0 "register_operand" "=a")
12640 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12641 (match_operand:DI 3 "" "")))
12642 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12645 { 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"; }
12646 [(set_attr "type" "multi")
12647 (set_attr "length" "16")])
12649 (define_expand "tls_global_dynamic_64"
12650 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12651 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12652 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12656 if (TARGET_GNU2_TLS)
12658 emit_insn (gen_tls_dynamic_gnu2_64
12659 (operands[0], operands[1]));
12662 operands[2] = ix86_tls_get_addr ();
12665 (define_insn "*tls_local_dynamic_base_32_gnu"
12666 [(set (match_operand:SI 0 "register_operand" "=a")
12667 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12668 (match_operand:SI 2 "call_insn_operand" "")]
12669 UNSPEC_TLS_LD_BASE))
12670 (clobber (match_scratch:SI 3 "=d"))
12671 (clobber (match_scratch:SI 4 "=c"))
12672 (clobber (reg:CC FLAGS_REG))]
12673 "!TARGET_64BIT && TARGET_GNU_TLS"
12674 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12675 [(set_attr "type" "multi")
12676 (set_attr "length" "11")])
12678 (define_expand "tls_local_dynamic_base_32"
12679 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12680 (unspec:SI [(match_dup 1) (match_dup 2)]
12681 UNSPEC_TLS_LD_BASE))
12682 (clobber (match_scratch:SI 3 ""))
12683 (clobber (match_scratch:SI 4 ""))
12684 (clobber (reg:CC FLAGS_REG))])]
12688 operands[1] = pic_offset_table_rtx;
12691 operands[1] = gen_reg_rtx (Pmode);
12692 emit_insn (gen_set_got (operands[1]));
12694 if (TARGET_GNU2_TLS)
12696 emit_insn (gen_tls_dynamic_gnu2_32
12697 (operands[0], ix86_tls_module_base (), operands[1]));
12700 operands[2] = ix86_tls_get_addr ();
12703 (define_insn "*tls_local_dynamic_base_64"
12704 [(set (match_operand:DI 0 "register_operand" "=a")
12705 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12706 (match_operand:DI 2 "" "")))
12707 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12709 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12710 [(set_attr "type" "multi")
12711 (set_attr "length" "12")])
12713 (define_expand "tls_local_dynamic_base_64"
12714 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12715 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12716 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12719 if (TARGET_GNU2_TLS)
12721 emit_insn (gen_tls_dynamic_gnu2_64
12722 (operands[0], ix86_tls_module_base ()));
12725 operands[1] = ix86_tls_get_addr ();
12728 ;; Local dynamic of a single variable is a lose. Show combine how
12729 ;; to convert that back to global dynamic.
12731 (define_insn_and_split "*tls_local_dynamic_32_once"
12732 [(set (match_operand:SI 0 "register_operand" "=a")
12733 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12734 (match_operand:SI 2 "call_insn_operand" "")]
12735 UNSPEC_TLS_LD_BASE)
12736 (const:SI (unspec:SI
12737 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12739 (clobber (match_scratch:SI 4 "=d"))
12740 (clobber (match_scratch:SI 5 "=c"))
12741 (clobber (reg:CC FLAGS_REG))]
12745 [(parallel [(set (match_dup 0)
12746 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12748 (clobber (match_dup 4))
12749 (clobber (match_dup 5))
12750 (clobber (reg:CC FLAGS_REG))])]
12753 ;; Load and add the thread base pointer from %gs:0.
12755 (define_insn "*load_tp_si"
12756 [(set (match_operand:SI 0 "register_operand" "=r")
12757 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12759 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12760 [(set_attr "type" "imov")
12761 (set_attr "modrm" "0")
12762 (set_attr "length" "7")
12763 (set_attr "memory" "load")
12764 (set_attr "imm_disp" "false")])
12766 (define_insn "*add_tp_si"
12767 [(set (match_operand:SI 0 "register_operand" "=r")
12768 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12769 (match_operand:SI 1 "register_operand" "0")))
12770 (clobber (reg:CC FLAGS_REG))]
12772 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12773 [(set_attr "type" "alu")
12774 (set_attr "modrm" "0")
12775 (set_attr "length" "7")
12776 (set_attr "memory" "load")
12777 (set_attr "imm_disp" "false")])
12779 (define_insn "*load_tp_di"
12780 [(set (match_operand:DI 0 "register_operand" "=r")
12781 (unspec:DI [(const_int 0)] UNSPEC_TP))]
12783 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12784 [(set_attr "type" "imov")
12785 (set_attr "modrm" "0")
12786 (set_attr "length" "7")
12787 (set_attr "memory" "load")
12788 (set_attr "imm_disp" "false")])
12790 (define_insn "*add_tp_di"
12791 [(set (match_operand:DI 0 "register_operand" "=r")
12792 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12793 (match_operand:DI 1 "register_operand" "0")))
12794 (clobber (reg:CC FLAGS_REG))]
12796 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12797 [(set_attr "type" "alu")
12798 (set_attr "modrm" "0")
12799 (set_attr "length" "7")
12800 (set_attr "memory" "load")
12801 (set_attr "imm_disp" "false")])
12803 ;; GNU2 TLS patterns can be split.
12805 (define_expand "tls_dynamic_gnu2_32"
12806 [(set (match_dup 3)
12807 (plus:SI (match_operand:SI 2 "register_operand" "")
12809 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12812 [(set (match_operand:SI 0 "register_operand" "")
12813 (unspec:SI [(match_dup 1) (match_dup 3)
12814 (match_dup 2) (reg:SI SP_REG)]
12816 (clobber (reg:CC FLAGS_REG))])]
12817 "!TARGET_64BIT && TARGET_GNU2_TLS"
12819 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12820 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12823 (define_insn "*tls_dynamic_lea_32"
12824 [(set (match_operand:SI 0 "register_operand" "=r")
12825 (plus:SI (match_operand:SI 1 "register_operand" "b")
12827 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12828 UNSPEC_TLSDESC))))]
12829 "!TARGET_64BIT && TARGET_GNU2_TLS"
12830 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12831 [(set_attr "type" "lea")
12832 (set_attr "mode" "SI")
12833 (set_attr "length" "6")
12834 (set_attr "length_address" "4")])
12836 (define_insn "*tls_dynamic_call_32"
12837 [(set (match_operand:SI 0 "register_operand" "=a")
12838 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12839 (match_operand:SI 2 "register_operand" "0")
12840 ;; we have to make sure %ebx still points to the GOT
12841 (match_operand:SI 3 "register_operand" "b")
12844 (clobber (reg:CC FLAGS_REG))]
12845 "!TARGET_64BIT && TARGET_GNU2_TLS"
12846 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12847 [(set_attr "type" "call")
12848 (set_attr "length" "2")
12849 (set_attr "length_address" "0")])
12851 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12852 [(set (match_operand:SI 0 "register_operand" "=&a")
12854 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12855 (match_operand:SI 4 "" "")
12856 (match_operand:SI 2 "register_operand" "b")
12859 (const:SI (unspec:SI
12860 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12862 (clobber (reg:CC FLAGS_REG))]
12863 "!TARGET_64BIT && TARGET_GNU2_TLS"
12866 [(set (match_dup 0) (match_dup 5))]
12868 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12869 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12872 (define_expand "tls_dynamic_gnu2_64"
12873 [(set (match_dup 2)
12874 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12877 [(set (match_operand:DI 0 "register_operand" "")
12878 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12880 (clobber (reg:CC FLAGS_REG))])]
12881 "TARGET_64BIT && TARGET_GNU2_TLS"
12883 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12884 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12887 (define_insn "*tls_dynamic_lea_64"
12888 [(set (match_operand:DI 0 "register_operand" "=r")
12889 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12891 "TARGET_64BIT && TARGET_GNU2_TLS"
12892 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12893 [(set_attr "type" "lea")
12894 (set_attr "mode" "DI")
12895 (set_attr "length" "7")
12896 (set_attr "length_address" "4")])
12898 (define_insn "*tls_dynamic_call_64"
12899 [(set (match_operand:DI 0 "register_operand" "=a")
12900 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12901 (match_operand:DI 2 "register_operand" "0")
12904 (clobber (reg:CC FLAGS_REG))]
12905 "TARGET_64BIT && TARGET_GNU2_TLS"
12906 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12907 [(set_attr "type" "call")
12908 (set_attr "length" "2")
12909 (set_attr "length_address" "0")])
12911 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12912 [(set (match_operand:DI 0 "register_operand" "=&a")
12914 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12915 (match_operand:DI 3 "" "")
12918 (const:DI (unspec:DI
12919 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12921 (clobber (reg:CC FLAGS_REG))]
12922 "TARGET_64BIT && TARGET_GNU2_TLS"
12925 [(set (match_dup 0) (match_dup 4))]
12927 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12928 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12933 ;; These patterns match the binary 387 instructions for addM3, subM3,
12934 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12935 ;; SFmode. The first is the normal insn, the second the same insn but
12936 ;; with one operand a conversion, and the third the same insn but with
12937 ;; the other operand a conversion. The conversion may be SFmode or
12938 ;; SImode if the target mode DFmode, but only SImode if the target mode
12941 ;; Gcc is slightly more smart about handling normal two address instructions
12942 ;; so use special patterns for add and mull.
12944 (define_insn "*fop_<mode>_comm_mixed_avx"
12945 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12946 (match_operator:MODEF 3 "binary_fp_operator"
12947 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12948 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12949 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12950 && COMMUTATIVE_ARITH_P (operands[3])
12951 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12952 "* return output_387_binary_op (insn, operands);"
12953 [(set (attr "type")
12954 (if_then_else (eq_attr "alternative" "1")
12955 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12956 (const_string "ssemul")
12957 (const_string "sseadd"))
12958 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12959 (const_string "fmul")
12960 (const_string "fop"))))
12961 (set_attr "prefix" "orig,maybe_vex")
12962 (set_attr "mode" "<MODE>")])
12964 (define_insn "*fop_<mode>_comm_mixed"
12965 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12966 (match_operator:MODEF 3 "binary_fp_operator"
12967 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12968 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12969 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12970 && COMMUTATIVE_ARITH_P (operands[3])
12971 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12972 "* return output_387_binary_op (insn, operands);"
12973 [(set (attr "type")
12974 (if_then_else (eq_attr "alternative" "1")
12975 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12976 (const_string "ssemul")
12977 (const_string "sseadd"))
12978 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12979 (const_string "fmul")
12980 (const_string "fop"))))
12981 (set_attr "mode" "<MODE>")])
12983 (define_insn "*fop_<mode>_comm_avx"
12984 [(set (match_operand:MODEF 0 "register_operand" "=x")
12985 (match_operator:MODEF 3 "binary_fp_operator"
12986 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12987 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12988 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12989 && COMMUTATIVE_ARITH_P (operands[3])
12990 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12991 "* return output_387_binary_op (insn, operands);"
12992 [(set (attr "type")
12993 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12994 (const_string "ssemul")
12995 (const_string "sseadd")))
12996 (set_attr "prefix" "vex")
12997 (set_attr "mode" "<MODE>")])
12999 (define_insn "*fop_<mode>_comm_sse"
13000 [(set (match_operand:MODEF 0 "register_operand" "=x")
13001 (match_operator:MODEF 3 "binary_fp_operator"
13002 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13003 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13004 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13005 && COMMUTATIVE_ARITH_P (operands[3])
13006 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13007 "* return output_387_binary_op (insn, operands);"
13008 [(set (attr "type")
13009 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13010 (const_string "ssemul")
13011 (const_string "sseadd")))
13012 (set_attr "mode" "<MODE>")])
13014 (define_insn "*fop_<mode>_comm_i387"
13015 [(set (match_operand:MODEF 0 "register_operand" "=f")
13016 (match_operator:MODEF 3 "binary_fp_operator"
13017 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13018 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13019 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13020 && COMMUTATIVE_ARITH_P (operands[3])
13021 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13022 "* return output_387_binary_op (insn, operands);"
13023 [(set (attr "type")
13024 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13025 (const_string "fmul")
13026 (const_string "fop")))
13027 (set_attr "mode" "<MODE>")])
13029 (define_insn "*fop_<mode>_1_mixed_avx"
13030 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13031 (match_operator:MODEF 3 "binary_fp_operator"
13032 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
13033 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13034 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13035 && !COMMUTATIVE_ARITH_P (operands[3])
13036 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13037 "* return output_387_binary_op (insn, operands);"
13038 [(set (attr "type")
13039 (cond [(and (eq_attr "alternative" "2")
13040 (match_operand:MODEF 3 "mult_operator" ""))
13041 (const_string "ssemul")
13042 (and (eq_attr "alternative" "2")
13043 (match_operand:MODEF 3 "div_operator" ""))
13044 (const_string "ssediv")
13045 (eq_attr "alternative" "2")
13046 (const_string "sseadd")
13047 (match_operand:MODEF 3 "mult_operator" "")
13048 (const_string "fmul")
13049 (match_operand:MODEF 3 "div_operator" "")
13050 (const_string "fdiv")
13052 (const_string "fop")))
13053 (set_attr "prefix" "orig,orig,maybe_vex")
13054 (set_attr "mode" "<MODE>")])
13056 (define_insn "*fop_<mode>_1_mixed"
13057 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13058 (match_operator:MODEF 3 "binary_fp_operator"
13059 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
13060 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13061 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13062 && !COMMUTATIVE_ARITH_P (operands[3])
13063 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13064 "* return output_387_binary_op (insn, operands);"
13065 [(set (attr "type")
13066 (cond [(and (eq_attr "alternative" "2")
13067 (match_operand:MODEF 3 "mult_operator" ""))
13068 (const_string "ssemul")
13069 (and (eq_attr "alternative" "2")
13070 (match_operand:MODEF 3 "div_operator" ""))
13071 (const_string "ssediv")
13072 (eq_attr "alternative" "2")
13073 (const_string "sseadd")
13074 (match_operand:MODEF 3 "mult_operator" "")
13075 (const_string "fmul")
13076 (match_operand:MODEF 3 "div_operator" "")
13077 (const_string "fdiv")
13079 (const_string "fop")))
13080 (set_attr "mode" "<MODE>")])
13082 (define_insn "*rcpsf2_sse"
13083 [(set (match_operand:SF 0 "register_operand" "=x")
13084 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13087 "%vrcpss\t{%1, %d0|%d0, %1}"
13088 [(set_attr "type" "sse")
13089 (set_attr "atom_sse_attr" "rcp")
13090 (set_attr "prefix" "maybe_vex")
13091 (set_attr "mode" "SF")])
13093 (define_insn "*fop_<mode>_1_avx"
13094 [(set (match_operand:MODEF 0 "register_operand" "=x")
13095 (match_operator:MODEF 3 "binary_fp_operator"
13096 [(match_operand:MODEF 1 "register_operand" "x")
13097 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13098 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13099 && !COMMUTATIVE_ARITH_P (operands[3])"
13100 "* return output_387_binary_op (insn, operands);"
13101 [(set (attr "type")
13102 (cond [(match_operand:MODEF 3 "mult_operator" "")
13103 (const_string "ssemul")
13104 (match_operand:MODEF 3 "div_operator" "")
13105 (const_string "ssediv")
13107 (const_string "sseadd")))
13108 (set_attr "prefix" "vex")
13109 (set_attr "mode" "<MODE>")])
13111 (define_insn "*fop_<mode>_1_sse"
13112 [(set (match_operand:MODEF 0 "register_operand" "=x")
13113 (match_operator:MODEF 3 "binary_fp_operator"
13114 [(match_operand:MODEF 1 "register_operand" "0")
13115 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13116 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13117 && !COMMUTATIVE_ARITH_P (operands[3])"
13118 "* return output_387_binary_op (insn, operands);"
13119 [(set (attr "type")
13120 (cond [(match_operand:MODEF 3 "mult_operator" "")
13121 (const_string "ssemul")
13122 (match_operand:MODEF 3 "div_operator" "")
13123 (const_string "ssediv")
13125 (const_string "sseadd")))
13126 (set_attr "mode" "<MODE>")])
13128 ;; This pattern is not fully shadowed by the pattern above.
13129 (define_insn "*fop_<mode>_1_i387"
13130 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13131 (match_operator:MODEF 3 "binary_fp_operator"
13132 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13133 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13134 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13135 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13136 && !COMMUTATIVE_ARITH_P (operands[3])
13137 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13138 "* return output_387_binary_op (insn, operands);"
13139 [(set (attr "type")
13140 (cond [(match_operand:MODEF 3 "mult_operator" "")
13141 (const_string "fmul")
13142 (match_operand:MODEF 3 "div_operator" "")
13143 (const_string "fdiv")
13145 (const_string "fop")))
13146 (set_attr "mode" "<MODE>")])
13148 ;; ??? Add SSE splitters for these!
13149 (define_insn "*fop_<MODEF:mode>_2_i387"
13150 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13151 (match_operator:MODEF 3 "binary_fp_operator"
13153 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13154 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13155 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13156 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13157 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13158 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13159 [(set (attr "type")
13160 (cond [(match_operand:MODEF 3 "mult_operator" "")
13161 (const_string "fmul")
13162 (match_operand:MODEF 3 "div_operator" "")
13163 (const_string "fdiv")
13165 (const_string "fop")))
13166 (set_attr "fp_int_src" "true")
13167 (set_attr "mode" "<X87MODEI12:MODE>")])
13169 (define_insn "*fop_<MODEF:mode>_3_i387"
13170 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13171 (match_operator:MODEF 3 "binary_fp_operator"
13172 [(match_operand:MODEF 1 "register_operand" "0,0")
13174 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13175 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13176 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13177 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13178 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13179 [(set (attr "type")
13180 (cond [(match_operand:MODEF 3 "mult_operator" "")
13181 (const_string "fmul")
13182 (match_operand:MODEF 3 "div_operator" "")
13183 (const_string "fdiv")
13185 (const_string "fop")))
13186 (set_attr "fp_int_src" "true")
13187 (set_attr "mode" "<MODE>")])
13189 (define_insn "*fop_df_4_i387"
13190 [(set (match_operand:DF 0 "register_operand" "=f,f")
13191 (match_operator:DF 3 "binary_fp_operator"
13193 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13194 (match_operand:DF 2 "register_operand" "0,f")]))]
13195 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13196 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13197 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13198 "* return output_387_binary_op (insn, operands);"
13199 [(set (attr "type")
13200 (cond [(match_operand:DF 3 "mult_operator" "")
13201 (const_string "fmul")
13202 (match_operand:DF 3 "div_operator" "")
13203 (const_string "fdiv")
13205 (const_string "fop")))
13206 (set_attr "mode" "SF")])
13208 (define_insn "*fop_df_5_i387"
13209 [(set (match_operand:DF 0 "register_operand" "=f,f")
13210 (match_operator:DF 3 "binary_fp_operator"
13211 [(match_operand:DF 1 "register_operand" "0,f")
13213 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13214 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13215 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13216 "* return output_387_binary_op (insn, operands);"
13217 [(set (attr "type")
13218 (cond [(match_operand:DF 3 "mult_operator" "")
13219 (const_string "fmul")
13220 (match_operand:DF 3 "div_operator" "")
13221 (const_string "fdiv")
13223 (const_string "fop")))
13224 (set_attr "mode" "SF")])
13226 (define_insn "*fop_df_6_i387"
13227 [(set (match_operand:DF 0 "register_operand" "=f,f")
13228 (match_operator:DF 3 "binary_fp_operator"
13230 (match_operand:SF 1 "register_operand" "0,f"))
13232 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13233 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13234 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13235 "* return output_387_binary_op (insn, operands);"
13236 [(set (attr "type")
13237 (cond [(match_operand:DF 3 "mult_operator" "")
13238 (const_string "fmul")
13239 (match_operand:DF 3 "div_operator" "")
13240 (const_string "fdiv")
13242 (const_string "fop")))
13243 (set_attr "mode" "SF")])
13245 (define_insn "*fop_xf_comm_i387"
13246 [(set (match_operand:XF 0 "register_operand" "=f")
13247 (match_operator:XF 3 "binary_fp_operator"
13248 [(match_operand:XF 1 "register_operand" "%0")
13249 (match_operand:XF 2 "register_operand" "f")]))]
13251 && COMMUTATIVE_ARITH_P (operands[3])"
13252 "* return output_387_binary_op (insn, operands);"
13253 [(set (attr "type")
13254 (if_then_else (match_operand:XF 3 "mult_operator" "")
13255 (const_string "fmul")
13256 (const_string "fop")))
13257 (set_attr "mode" "XF")])
13259 (define_insn "*fop_xf_1_i387"
13260 [(set (match_operand:XF 0 "register_operand" "=f,f")
13261 (match_operator:XF 3 "binary_fp_operator"
13262 [(match_operand:XF 1 "register_operand" "0,f")
13263 (match_operand:XF 2 "register_operand" "f,0")]))]
13265 && !COMMUTATIVE_ARITH_P (operands[3])"
13266 "* return output_387_binary_op (insn, operands);"
13267 [(set (attr "type")
13268 (cond [(match_operand:XF 3 "mult_operator" "")
13269 (const_string "fmul")
13270 (match_operand:XF 3 "div_operator" "")
13271 (const_string "fdiv")
13273 (const_string "fop")))
13274 (set_attr "mode" "XF")])
13276 (define_insn "*fop_xf_2_i387"
13277 [(set (match_operand:XF 0 "register_operand" "=f,f")
13278 (match_operator:XF 3 "binary_fp_operator"
13280 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13281 (match_operand:XF 2 "register_operand" "0,0")]))]
13282 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13283 "* return which_alternative ? \"#\" : 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 "fp_int_src" "true")
13292 (set_attr "mode" "<MODE>")])
13294 (define_insn "*fop_xf_3_i387"
13295 [(set (match_operand:XF 0 "register_operand" "=f,f")
13296 (match_operator:XF 3 "binary_fp_operator"
13297 [(match_operand:XF 1 "register_operand" "0,0")
13299 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13300 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13301 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13302 [(set (attr "type")
13303 (cond [(match_operand:XF 3 "mult_operator" "")
13304 (const_string "fmul")
13305 (match_operand:XF 3 "div_operator" "")
13306 (const_string "fdiv")
13308 (const_string "fop")))
13309 (set_attr "fp_int_src" "true")
13310 (set_attr "mode" "<MODE>")])
13312 (define_insn "*fop_xf_4_i387"
13313 [(set (match_operand:XF 0 "register_operand" "=f,f")
13314 (match_operator:XF 3 "binary_fp_operator"
13316 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13317 (match_operand:XF 2 "register_operand" "0,f")]))]
13319 "* return output_387_binary_op (insn, operands);"
13320 [(set (attr "type")
13321 (cond [(match_operand:XF 3 "mult_operator" "")
13322 (const_string "fmul")
13323 (match_operand:XF 3 "div_operator" "")
13324 (const_string "fdiv")
13326 (const_string "fop")))
13327 (set_attr "mode" "<MODE>")])
13329 (define_insn "*fop_xf_5_i387"
13330 [(set (match_operand:XF 0 "register_operand" "=f,f")
13331 (match_operator:XF 3 "binary_fp_operator"
13332 [(match_operand:XF 1 "register_operand" "0,f")
13334 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13336 "* return output_387_binary_op (insn, operands);"
13337 [(set (attr "type")
13338 (cond [(match_operand:XF 3 "mult_operator" "")
13339 (const_string "fmul")
13340 (match_operand:XF 3 "div_operator" "")
13341 (const_string "fdiv")
13343 (const_string "fop")))
13344 (set_attr "mode" "<MODE>")])
13346 (define_insn "*fop_xf_6_i387"
13347 [(set (match_operand:XF 0 "register_operand" "=f,f")
13348 (match_operator:XF 3 "binary_fp_operator"
13350 (match_operand:MODEF 1 "register_operand" "0,f"))
13352 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13354 "* return output_387_binary_op (insn, operands);"
13355 [(set (attr "type")
13356 (cond [(match_operand:XF 3 "mult_operator" "")
13357 (const_string "fmul")
13358 (match_operand:XF 3 "div_operator" "")
13359 (const_string "fdiv")
13361 (const_string "fop")))
13362 (set_attr "mode" "<MODE>")])
13365 [(set (match_operand 0 "register_operand" "")
13366 (match_operator 3 "binary_fp_operator"
13367 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13368 (match_operand 2 "register_operand" "")]))]
13370 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13371 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13374 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13375 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13376 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13377 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13378 GET_MODE (operands[3]),
13381 ix86_free_from_memory (GET_MODE (operands[1]));
13386 [(set (match_operand 0 "register_operand" "")
13387 (match_operator 3 "binary_fp_operator"
13388 [(match_operand 1 "register_operand" "")
13389 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13391 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13392 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13395 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13396 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13397 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13398 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13399 GET_MODE (operands[3]),
13402 ix86_free_from_memory (GET_MODE (operands[2]));
13406 ;; FPU special functions.
13408 ;; This pattern implements a no-op XFmode truncation for
13409 ;; all fancy i386 XFmode math functions.
13411 (define_insn "truncxf<mode>2_i387_noop_unspec"
13412 [(set (match_operand:MODEF 0 "register_operand" "=f")
13413 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13414 UNSPEC_TRUNC_NOOP))]
13415 "TARGET_USE_FANCY_MATH_387"
13416 "* return output_387_reg_move (insn, operands);"
13417 [(set_attr "type" "fmov")
13418 (set_attr "mode" "<MODE>")])
13420 (define_insn "sqrtxf2"
13421 [(set (match_operand:XF 0 "register_operand" "=f")
13422 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13423 "TARGET_USE_FANCY_MATH_387"
13425 [(set_attr "type" "fpspc")
13426 (set_attr "mode" "XF")
13427 (set_attr "athlon_decode" "direct")
13428 (set_attr "amdfam10_decode" "direct")])
13430 (define_insn "sqrt_extend<mode>xf2_i387"
13431 [(set (match_operand:XF 0 "register_operand" "=f")
13434 (match_operand:MODEF 1 "register_operand" "0"))))]
13435 "TARGET_USE_FANCY_MATH_387"
13437 [(set_attr "type" "fpspc")
13438 (set_attr "mode" "XF")
13439 (set_attr "athlon_decode" "direct")
13440 (set_attr "amdfam10_decode" "direct")])
13442 (define_insn "*rsqrtsf2_sse"
13443 [(set (match_operand:SF 0 "register_operand" "=x")
13444 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13447 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13448 [(set_attr "type" "sse")
13449 (set_attr "atom_sse_attr" "rcp")
13450 (set_attr "prefix" "maybe_vex")
13451 (set_attr "mode" "SF")])
13453 (define_expand "rsqrtsf2"
13454 [(set (match_operand:SF 0 "register_operand" "")
13455 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13459 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13463 (define_insn "*sqrt<mode>2_sse"
13464 [(set (match_operand:MODEF 0 "register_operand" "=x")
13466 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13467 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13468 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13469 [(set_attr "type" "sse")
13470 (set_attr "atom_sse_attr" "sqrt")
13471 (set_attr "prefix" "maybe_vex")
13472 (set_attr "mode" "<MODE>")
13473 (set_attr "athlon_decode" "*")
13474 (set_attr "amdfam10_decode" "*")])
13476 (define_expand "sqrt<mode>2"
13477 [(set (match_operand:MODEF 0 "register_operand" "")
13479 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13480 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13481 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13483 if (<MODE>mode == SFmode
13484 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13485 && flag_finite_math_only && !flag_trapping_math
13486 && flag_unsafe_math_optimizations)
13488 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13492 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13494 rtx op0 = gen_reg_rtx (XFmode);
13495 rtx op1 = force_reg (<MODE>mode, operands[1]);
13497 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13498 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13503 (define_insn "fpremxf4_i387"
13504 [(set (match_operand:XF 0 "register_operand" "=f")
13505 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13506 (match_operand:XF 3 "register_operand" "1")]
13508 (set (match_operand:XF 1 "register_operand" "=u")
13509 (unspec:XF [(match_dup 2) (match_dup 3)]
13511 (set (reg:CCFP FPSR_REG)
13512 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13514 "TARGET_USE_FANCY_MATH_387"
13516 [(set_attr "type" "fpspc")
13517 (set_attr "mode" "XF")])
13519 (define_expand "fmodxf3"
13520 [(use (match_operand:XF 0 "register_operand" ""))
13521 (use (match_operand:XF 1 "general_operand" ""))
13522 (use (match_operand:XF 2 "general_operand" ""))]
13523 "TARGET_USE_FANCY_MATH_387"
13525 rtx label = gen_label_rtx ();
13527 rtx op1 = gen_reg_rtx (XFmode);
13528 rtx op2 = gen_reg_rtx (XFmode);
13530 emit_move_insn (op2, operands[2]);
13531 emit_move_insn (op1, operands[1]);
13533 emit_label (label);
13534 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13535 ix86_emit_fp_unordered_jump (label);
13536 LABEL_NUSES (label) = 1;
13538 emit_move_insn (operands[0], op1);
13542 (define_expand "fmod<mode>3"
13543 [(use (match_operand:MODEF 0 "register_operand" ""))
13544 (use (match_operand:MODEF 1 "general_operand" ""))
13545 (use (match_operand:MODEF 2 "general_operand" ""))]
13546 "TARGET_USE_FANCY_MATH_387"
13548 rtx label = gen_label_rtx ();
13550 rtx op1 = gen_reg_rtx (XFmode);
13551 rtx op2 = gen_reg_rtx (XFmode);
13553 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13554 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13556 emit_label (label);
13557 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13558 ix86_emit_fp_unordered_jump (label);
13559 LABEL_NUSES (label) = 1;
13561 /* Truncate the result properly for strict SSE math. */
13562 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13563 && !TARGET_MIX_SSE_I387)
13564 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13566 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13571 (define_insn "fprem1xf4_i387"
13572 [(set (match_operand:XF 0 "register_operand" "=f")
13573 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13574 (match_operand:XF 3 "register_operand" "1")]
13576 (set (match_operand:XF 1 "register_operand" "=u")
13577 (unspec:XF [(match_dup 2) (match_dup 3)]
13579 (set (reg:CCFP FPSR_REG)
13580 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13582 "TARGET_USE_FANCY_MATH_387"
13584 [(set_attr "type" "fpspc")
13585 (set_attr "mode" "XF")])
13587 (define_expand "remainderxf3"
13588 [(use (match_operand:XF 0 "register_operand" ""))
13589 (use (match_operand:XF 1 "general_operand" ""))
13590 (use (match_operand:XF 2 "general_operand" ""))]
13591 "TARGET_USE_FANCY_MATH_387"
13593 rtx label = gen_label_rtx ();
13595 rtx op1 = gen_reg_rtx (XFmode);
13596 rtx op2 = gen_reg_rtx (XFmode);
13598 emit_move_insn (op2, operands[2]);
13599 emit_move_insn (op1, operands[1]);
13601 emit_label (label);
13602 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13603 ix86_emit_fp_unordered_jump (label);
13604 LABEL_NUSES (label) = 1;
13606 emit_move_insn (operands[0], op1);
13610 (define_expand "remainder<mode>3"
13611 [(use (match_operand:MODEF 0 "register_operand" ""))
13612 (use (match_operand:MODEF 1 "general_operand" ""))
13613 (use (match_operand:MODEF 2 "general_operand" ""))]
13614 "TARGET_USE_FANCY_MATH_387"
13616 rtx label = gen_label_rtx ();
13618 rtx op1 = gen_reg_rtx (XFmode);
13619 rtx op2 = gen_reg_rtx (XFmode);
13621 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13622 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13624 emit_label (label);
13626 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13627 ix86_emit_fp_unordered_jump (label);
13628 LABEL_NUSES (label) = 1;
13630 /* Truncate the result properly for strict SSE math. */
13631 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13632 && !TARGET_MIX_SSE_I387)
13633 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13635 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13640 (define_insn "*sinxf2_i387"
13641 [(set (match_operand:XF 0 "register_operand" "=f")
13642 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13643 "TARGET_USE_FANCY_MATH_387
13644 && flag_unsafe_math_optimizations"
13646 [(set_attr "type" "fpspc")
13647 (set_attr "mode" "XF")])
13649 (define_insn "*sin_extend<mode>xf2_i387"
13650 [(set (match_operand:XF 0 "register_operand" "=f")
13651 (unspec:XF [(float_extend:XF
13652 (match_operand:MODEF 1 "register_operand" "0"))]
13654 "TARGET_USE_FANCY_MATH_387
13655 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13656 || TARGET_MIX_SSE_I387)
13657 && flag_unsafe_math_optimizations"
13659 [(set_attr "type" "fpspc")
13660 (set_attr "mode" "XF")])
13662 (define_insn "*cosxf2_i387"
13663 [(set (match_operand:XF 0 "register_operand" "=f")
13664 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13665 "TARGET_USE_FANCY_MATH_387
13666 && flag_unsafe_math_optimizations"
13668 [(set_attr "type" "fpspc")
13669 (set_attr "mode" "XF")])
13671 (define_insn "*cos_extend<mode>xf2_i387"
13672 [(set (match_operand:XF 0 "register_operand" "=f")
13673 (unspec:XF [(float_extend:XF
13674 (match_operand:MODEF 1 "register_operand" "0"))]
13676 "TARGET_USE_FANCY_MATH_387
13677 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13678 || TARGET_MIX_SSE_I387)
13679 && flag_unsafe_math_optimizations"
13681 [(set_attr "type" "fpspc")
13682 (set_attr "mode" "XF")])
13684 ;; When sincos pattern is defined, sin and cos builtin functions will be
13685 ;; expanded to sincos pattern with one of its outputs left unused.
13686 ;; CSE pass will figure out if two sincos patterns can be combined,
13687 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13688 ;; depending on the unused output.
13690 (define_insn "sincosxf3"
13691 [(set (match_operand:XF 0 "register_operand" "=f")
13692 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13693 UNSPEC_SINCOS_COS))
13694 (set (match_operand:XF 1 "register_operand" "=u")
13695 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13696 "TARGET_USE_FANCY_MATH_387
13697 && flag_unsafe_math_optimizations"
13699 [(set_attr "type" "fpspc")
13700 (set_attr "mode" "XF")])
13703 [(set (match_operand:XF 0 "register_operand" "")
13704 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13705 UNSPEC_SINCOS_COS))
13706 (set (match_operand:XF 1 "register_operand" "")
13707 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13708 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13709 && !(reload_completed || reload_in_progress)"
13710 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13714 [(set (match_operand:XF 0 "register_operand" "")
13715 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13716 UNSPEC_SINCOS_COS))
13717 (set (match_operand:XF 1 "register_operand" "")
13718 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13719 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13720 && !(reload_completed || reload_in_progress)"
13721 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13724 (define_insn "sincos_extend<mode>xf3_i387"
13725 [(set (match_operand:XF 0 "register_operand" "=f")
13726 (unspec:XF [(float_extend:XF
13727 (match_operand:MODEF 2 "register_operand" "0"))]
13728 UNSPEC_SINCOS_COS))
13729 (set (match_operand:XF 1 "register_operand" "=u")
13730 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
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 [(set_attr "type" "fpspc")
13737 (set_attr "mode" "XF")])
13740 [(set (match_operand:XF 0 "register_operand" "")
13741 (unspec:XF [(float_extend:XF
13742 (match_operand:MODEF 2 "register_operand" ""))]
13743 UNSPEC_SINCOS_COS))
13744 (set (match_operand:XF 1 "register_operand" "")
13745 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13746 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13747 && !(reload_completed || reload_in_progress)"
13748 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13752 [(set (match_operand:XF 0 "register_operand" "")
13753 (unspec:XF [(float_extend:XF
13754 (match_operand:MODEF 2 "register_operand" ""))]
13755 UNSPEC_SINCOS_COS))
13756 (set (match_operand:XF 1 "register_operand" "")
13757 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13758 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13759 && !(reload_completed || reload_in_progress)"
13760 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13763 (define_expand "sincos<mode>3"
13764 [(use (match_operand:MODEF 0 "register_operand" ""))
13765 (use (match_operand:MODEF 1 "register_operand" ""))
13766 (use (match_operand:MODEF 2 "register_operand" ""))]
13767 "TARGET_USE_FANCY_MATH_387
13768 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13769 || TARGET_MIX_SSE_I387)
13770 && flag_unsafe_math_optimizations"
13772 rtx op0 = gen_reg_rtx (XFmode);
13773 rtx op1 = gen_reg_rtx (XFmode);
13775 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13776 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13777 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13781 (define_insn "fptanxf4_i387"
13782 [(set (match_operand:XF 0 "register_operand" "=f")
13783 (match_operand:XF 3 "const_double_operand" "F"))
13784 (set (match_operand:XF 1 "register_operand" "=u")
13785 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13787 "TARGET_USE_FANCY_MATH_387
13788 && flag_unsafe_math_optimizations
13789 && standard_80387_constant_p (operands[3]) == 2"
13791 [(set_attr "type" "fpspc")
13792 (set_attr "mode" "XF")])
13794 (define_insn "fptan_extend<mode>xf4_i387"
13795 [(set (match_operand:MODEF 0 "register_operand" "=f")
13796 (match_operand:MODEF 3 "const_double_operand" "F"))
13797 (set (match_operand:XF 1 "register_operand" "=u")
13798 (unspec:XF [(float_extend:XF
13799 (match_operand:MODEF 2 "register_operand" "0"))]
13801 "TARGET_USE_FANCY_MATH_387
13802 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13803 || TARGET_MIX_SSE_I387)
13804 && flag_unsafe_math_optimizations
13805 && standard_80387_constant_p (operands[3]) == 2"
13807 [(set_attr "type" "fpspc")
13808 (set_attr "mode" "XF")])
13810 (define_expand "tanxf2"
13811 [(use (match_operand:XF 0 "register_operand" ""))
13812 (use (match_operand:XF 1 "register_operand" ""))]
13813 "TARGET_USE_FANCY_MATH_387
13814 && flag_unsafe_math_optimizations"
13816 rtx one = gen_reg_rtx (XFmode);
13817 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13819 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13823 (define_expand "tan<mode>2"
13824 [(use (match_operand:MODEF 0 "register_operand" ""))
13825 (use (match_operand:MODEF 1 "register_operand" ""))]
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 rtx op0 = gen_reg_rtx (XFmode);
13833 rtx one = gen_reg_rtx (<MODE>mode);
13834 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13836 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13837 operands[1], op2));
13838 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13842 (define_insn "*fpatanxf3_i387"
13843 [(set (match_operand:XF 0 "register_operand" "=f")
13844 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13845 (match_operand:XF 2 "register_operand" "u")]
13847 (clobber (match_scratch:XF 3 "=2"))]
13848 "TARGET_USE_FANCY_MATH_387
13849 && flag_unsafe_math_optimizations"
13851 [(set_attr "type" "fpspc")
13852 (set_attr "mode" "XF")])
13854 (define_insn "fpatan_extend<mode>xf3_i387"
13855 [(set (match_operand:XF 0 "register_operand" "=f")
13856 (unspec:XF [(float_extend:XF
13857 (match_operand:MODEF 1 "register_operand" "0"))
13859 (match_operand:MODEF 2 "register_operand" "u"))]
13861 (clobber (match_scratch:XF 3 "=2"))]
13862 "TARGET_USE_FANCY_MATH_387
13863 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13864 || TARGET_MIX_SSE_I387)
13865 && flag_unsafe_math_optimizations"
13867 [(set_attr "type" "fpspc")
13868 (set_attr "mode" "XF")])
13870 (define_expand "atan2xf3"
13871 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13872 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13873 (match_operand:XF 1 "register_operand" "")]
13875 (clobber (match_scratch:XF 3 ""))])]
13876 "TARGET_USE_FANCY_MATH_387
13877 && flag_unsafe_math_optimizations"
13880 (define_expand "atan2<mode>3"
13881 [(use (match_operand:MODEF 0 "register_operand" ""))
13882 (use (match_operand:MODEF 1 "register_operand" ""))
13883 (use (match_operand:MODEF 2 "register_operand" ""))]
13884 "TARGET_USE_FANCY_MATH_387
13885 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13886 || TARGET_MIX_SSE_I387)
13887 && flag_unsafe_math_optimizations"
13889 rtx op0 = gen_reg_rtx (XFmode);
13891 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13892 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13896 (define_expand "atanxf2"
13897 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13898 (unspec:XF [(match_dup 2)
13899 (match_operand:XF 1 "register_operand" "")]
13901 (clobber (match_scratch:XF 3 ""))])]
13902 "TARGET_USE_FANCY_MATH_387
13903 && flag_unsafe_math_optimizations"
13905 operands[2] = gen_reg_rtx (XFmode);
13906 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13909 (define_expand "atan<mode>2"
13910 [(use (match_operand:MODEF 0 "register_operand" ""))
13911 (use (match_operand:MODEF 1 "register_operand" ""))]
13912 "TARGET_USE_FANCY_MATH_387
13913 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13914 || TARGET_MIX_SSE_I387)
13915 && flag_unsafe_math_optimizations"
13917 rtx op0 = gen_reg_rtx (XFmode);
13919 rtx op2 = gen_reg_rtx (<MODE>mode);
13920 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13922 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13923 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13927 (define_expand "asinxf2"
13928 [(set (match_dup 2)
13929 (mult:XF (match_operand:XF 1 "register_operand" "")
13931 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13932 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13933 (parallel [(set (match_operand:XF 0 "register_operand" "")
13934 (unspec:XF [(match_dup 5) (match_dup 1)]
13936 (clobber (match_scratch:XF 6 ""))])]
13937 "TARGET_USE_FANCY_MATH_387
13938 && flag_unsafe_math_optimizations"
13942 if (optimize_insn_for_size_p ())
13945 for (i = 2; i < 6; i++)
13946 operands[i] = gen_reg_rtx (XFmode);
13948 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13951 (define_expand "asin<mode>2"
13952 [(use (match_operand:MODEF 0 "register_operand" ""))
13953 (use (match_operand:MODEF 1 "general_operand" ""))]
13954 "TARGET_USE_FANCY_MATH_387
13955 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13956 || TARGET_MIX_SSE_I387)
13957 && flag_unsafe_math_optimizations"
13959 rtx op0 = gen_reg_rtx (XFmode);
13960 rtx op1 = gen_reg_rtx (XFmode);
13962 if (optimize_insn_for_size_p ())
13965 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13966 emit_insn (gen_asinxf2 (op0, op1));
13967 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13971 (define_expand "acosxf2"
13972 [(set (match_dup 2)
13973 (mult:XF (match_operand:XF 1 "register_operand" "")
13975 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13976 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13977 (parallel [(set (match_operand:XF 0 "register_operand" "")
13978 (unspec:XF [(match_dup 1) (match_dup 5)]
13980 (clobber (match_scratch:XF 6 ""))])]
13981 "TARGET_USE_FANCY_MATH_387
13982 && flag_unsafe_math_optimizations"
13986 if (optimize_insn_for_size_p ())
13989 for (i = 2; i < 6; i++)
13990 operands[i] = gen_reg_rtx (XFmode);
13992 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13995 (define_expand "acos<mode>2"
13996 [(use (match_operand:MODEF 0 "register_operand" ""))
13997 (use (match_operand:MODEF 1 "general_operand" ""))]
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 rtx op0 = gen_reg_rtx (XFmode);
14004 rtx op1 = gen_reg_rtx (XFmode);
14006 if (optimize_insn_for_size_p ())
14009 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14010 emit_insn (gen_acosxf2 (op0, op1));
14011 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14015 (define_insn "fyl2xxf3_i387"
14016 [(set (match_operand:XF 0 "register_operand" "=f")
14017 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14018 (match_operand:XF 2 "register_operand" "u")]
14020 (clobber (match_scratch:XF 3 "=2"))]
14021 "TARGET_USE_FANCY_MATH_387
14022 && flag_unsafe_math_optimizations"
14024 [(set_attr "type" "fpspc")
14025 (set_attr "mode" "XF")])
14027 (define_insn "fyl2x_extend<mode>xf3_i387"
14028 [(set (match_operand:XF 0 "register_operand" "=f")
14029 (unspec:XF [(float_extend:XF
14030 (match_operand:MODEF 1 "register_operand" "0"))
14031 (match_operand:XF 2 "register_operand" "u")]
14033 (clobber (match_scratch:XF 3 "=2"))]
14034 "TARGET_USE_FANCY_MATH_387
14035 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14036 || TARGET_MIX_SSE_I387)
14037 && flag_unsafe_math_optimizations"
14039 [(set_attr "type" "fpspc")
14040 (set_attr "mode" "XF")])
14042 (define_expand "logxf2"
14043 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14044 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14045 (match_dup 2)] UNSPEC_FYL2X))
14046 (clobber (match_scratch:XF 3 ""))])]
14047 "TARGET_USE_FANCY_MATH_387
14048 && flag_unsafe_math_optimizations"
14050 operands[2] = gen_reg_rtx (XFmode);
14051 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14054 (define_expand "log<mode>2"
14055 [(use (match_operand:MODEF 0 "register_operand" ""))
14056 (use (match_operand:MODEF 1 "register_operand" ""))]
14057 "TARGET_USE_FANCY_MATH_387
14058 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14059 || TARGET_MIX_SSE_I387)
14060 && flag_unsafe_math_optimizations"
14062 rtx op0 = gen_reg_rtx (XFmode);
14064 rtx op2 = gen_reg_rtx (XFmode);
14065 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14067 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14068 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14072 (define_expand "log10xf2"
14073 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14074 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14075 (match_dup 2)] UNSPEC_FYL2X))
14076 (clobber (match_scratch:XF 3 ""))])]
14077 "TARGET_USE_FANCY_MATH_387
14078 && flag_unsafe_math_optimizations"
14080 operands[2] = gen_reg_rtx (XFmode);
14081 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14084 (define_expand "log10<mode>2"
14085 [(use (match_operand:MODEF 0 "register_operand" ""))
14086 (use (match_operand:MODEF 1 "register_operand" ""))]
14087 "TARGET_USE_FANCY_MATH_387
14088 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14089 || TARGET_MIX_SSE_I387)
14090 && flag_unsafe_math_optimizations"
14092 rtx op0 = gen_reg_rtx (XFmode);
14094 rtx op2 = gen_reg_rtx (XFmode);
14095 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14097 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14098 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14102 (define_expand "log2xf2"
14103 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14104 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14105 (match_dup 2)] UNSPEC_FYL2X))
14106 (clobber (match_scratch:XF 3 ""))])]
14107 "TARGET_USE_FANCY_MATH_387
14108 && flag_unsafe_math_optimizations"
14110 operands[2] = gen_reg_rtx (XFmode);
14111 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14114 (define_expand "log2<mode>2"
14115 [(use (match_operand:MODEF 0 "register_operand" ""))
14116 (use (match_operand:MODEF 1 "register_operand" ""))]
14117 "TARGET_USE_FANCY_MATH_387
14118 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14119 || TARGET_MIX_SSE_I387)
14120 && flag_unsafe_math_optimizations"
14122 rtx op0 = gen_reg_rtx (XFmode);
14124 rtx op2 = gen_reg_rtx (XFmode);
14125 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14127 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14128 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14132 (define_insn "fyl2xp1xf3_i387"
14133 [(set (match_operand:XF 0 "register_operand" "=f")
14134 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14135 (match_operand:XF 2 "register_operand" "u")]
14137 (clobber (match_scratch:XF 3 "=2"))]
14138 "TARGET_USE_FANCY_MATH_387
14139 && flag_unsafe_math_optimizations"
14141 [(set_attr "type" "fpspc")
14142 (set_attr "mode" "XF")])
14144 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14145 [(set (match_operand:XF 0 "register_operand" "=f")
14146 (unspec:XF [(float_extend:XF
14147 (match_operand:MODEF 1 "register_operand" "0"))
14148 (match_operand:XF 2 "register_operand" "u")]
14150 (clobber (match_scratch:XF 3 "=2"))]
14151 "TARGET_USE_FANCY_MATH_387
14152 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14153 || TARGET_MIX_SSE_I387)
14154 && flag_unsafe_math_optimizations"
14156 [(set_attr "type" "fpspc")
14157 (set_attr "mode" "XF")])
14159 (define_expand "log1pxf2"
14160 [(use (match_operand:XF 0 "register_operand" ""))
14161 (use (match_operand:XF 1 "register_operand" ""))]
14162 "TARGET_USE_FANCY_MATH_387
14163 && flag_unsafe_math_optimizations"
14165 if (optimize_insn_for_size_p ())
14168 ix86_emit_i387_log1p (operands[0], operands[1]);
14172 (define_expand "log1p<mode>2"
14173 [(use (match_operand:MODEF 0 "register_operand" ""))
14174 (use (match_operand:MODEF 1 "register_operand" ""))]
14175 "TARGET_USE_FANCY_MATH_387
14176 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14177 || TARGET_MIX_SSE_I387)
14178 && flag_unsafe_math_optimizations"
14182 if (optimize_insn_for_size_p ())
14185 op0 = gen_reg_rtx (XFmode);
14187 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14189 ix86_emit_i387_log1p (op0, operands[1]);
14190 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14194 (define_insn "fxtractxf3_i387"
14195 [(set (match_operand:XF 0 "register_operand" "=f")
14196 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14197 UNSPEC_XTRACT_FRACT))
14198 (set (match_operand:XF 1 "register_operand" "=u")
14199 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14200 "TARGET_USE_FANCY_MATH_387
14201 && flag_unsafe_math_optimizations"
14203 [(set_attr "type" "fpspc")
14204 (set_attr "mode" "XF")])
14206 (define_insn "fxtract_extend<mode>xf3_i387"
14207 [(set (match_operand:XF 0 "register_operand" "=f")
14208 (unspec:XF [(float_extend:XF
14209 (match_operand:MODEF 2 "register_operand" "0"))]
14210 UNSPEC_XTRACT_FRACT))
14211 (set (match_operand:XF 1 "register_operand" "=u")
14212 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14213 "TARGET_USE_FANCY_MATH_387
14214 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14215 || TARGET_MIX_SSE_I387)
14216 && flag_unsafe_math_optimizations"
14218 [(set_attr "type" "fpspc")
14219 (set_attr "mode" "XF")])
14221 (define_expand "logbxf2"
14222 [(parallel [(set (match_dup 2)
14223 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14224 UNSPEC_XTRACT_FRACT))
14225 (set (match_operand:XF 0 "register_operand" "")
14226 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14227 "TARGET_USE_FANCY_MATH_387
14228 && flag_unsafe_math_optimizations"
14230 operands[2] = gen_reg_rtx (XFmode);
14233 (define_expand "logb<mode>2"
14234 [(use (match_operand:MODEF 0 "register_operand" ""))
14235 (use (match_operand:MODEF 1 "register_operand" ""))]
14236 "TARGET_USE_FANCY_MATH_387
14237 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14238 || TARGET_MIX_SSE_I387)
14239 && flag_unsafe_math_optimizations"
14241 rtx op0 = gen_reg_rtx (XFmode);
14242 rtx op1 = gen_reg_rtx (XFmode);
14244 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14245 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14249 (define_expand "ilogbxf2"
14250 [(use (match_operand:SI 0 "register_operand" ""))
14251 (use (match_operand:XF 1 "register_operand" ""))]
14252 "TARGET_USE_FANCY_MATH_387
14253 && flag_unsafe_math_optimizations"
14257 if (optimize_insn_for_size_p ())
14260 op0 = gen_reg_rtx (XFmode);
14261 op1 = gen_reg_rtx (XFmode);
14263 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14264 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14268 (define_expand "ilogb<mode>2"
14269 [(use (match_operand:SI 0 "register_operand" ""))
14270 (use (match_operand:MODEF 1 "register_operand" ""))]
14271 "TARGET_USE_FANCY_MATH_387
14272 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14273 || TARGET_MIX_SSE_I387)
14274 && flag_unsafe_math_optimizations"
14278 if (optimize_insn_for_size_p ())
14281 op0 = gen_reg_rtx (XFmode);
14282 op1 = gen_reg_rtx (XFmode);
14284 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14285 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14289 (define_insn "*f2xm1xf2_i387"
14290 [(set (match_operand:XF 0 "register_operand" "=f")
14291 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14293 "TARGET_USE_FANCY_MATH_387
14294 && flag_unsafe_math_optimizations"
14296 [(set_attr "type" "fpspc")
14297 (set_attr "mode" "XF")])
14299 (define_insn "*fscalexf4_i387"
14300 [(set (match_operand:XF 0 "register_operand" "=f")
14301 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14302 (match_operand:XF 3 "register_operand" "1")]
14303 UNSPEC_FSCALE_FRACT))
14304 (set (match_operand:XF 1 "register_operand" "=u")
14305 (unspec:XF [(match_dup 2) (match_dup 3)]
14306 UNSPEC_FSCALE_EXP))]
14307 "TARGET_USE_FANCY_MATH_387
14308 && flag_unsafe_math_optimizations"
14310 [(set_attr "type" "fpspc")
14311 (set_attr "mode" "XF")])
14313 (define_expand "expNcorexf3"
14314 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14315 (match_operand:XF 2 "register_operand" "")))
14316 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14317 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14318 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14319 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14320 (parallel [(set (match_operand:XF 0 "register_operand" "")
14321 (unspec:XF [(match_dup 8) (match_dup 4)]
14322 UNSPEC_FSCALE_FRACT))
14324 (unspec:XF [(match_dup 8) (match_dup 4)]
14325 UNSPEC_FSCALE_EXP))])]
14326 "TARGET_USE_FANCY_MATH_387
14327 && flag_unsafe_math_optimizations"
14331 if (optimize_insn_for_size_p ())
14334 for (i = 3; i < 10; i++)
14335 operands[i] = gen_reg_rtx (XFmode);
14337 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14340 (define_expand "expxf2"
14341 [(use (match_operand:XF 0 "register_operand" ""))
14342 (use (match_operand:XF 1 "register_operand" ""))]
14343 "TARGET_USE_FANCY_MATH_387
14344 && flag_unsafe_math_optimizations"
14348 if (optimize_insn_for_size_p ())
14351 op2 = gen_reg_rtx (XFmode);
14352 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14354 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14358 (define_expand "exp<mode>2"
14359 [(use (match_operand:MODEF 0 "register_operand" ""))
14360 (use (match_operand:MODEF 1 "general_operand" ""))]
14361 "TARGET_USE_FANCY_MATH_387
14362 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14363 || TARGET_MIX_SSE_I387)
14364 && flag_unsafe_math_optimizations"
14368 if (optimize_insn_for_size_p ())
14371 op0 = gen_reg_rtx (XFmode);
14372 op1 = gen_reg_rtx (XFmode);
14374 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14375 emit_insn (gen_expxf2 (op0, op1));
14376 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14380 (define_expand "exp10xf2"
14381 [(use (match_operand:XF 0 "register_operand" ""))
14382 (use (match_operand:XF 1 "register_operand" ""))]
14383 "TARGET_USE_FANCY_MATH_387
14384 && flag_unsafe_math_optimizations"
14388 if (optimize_insn_for_size_p ())
14391 op2 = gen_reg_rtx (XFmode);
14392 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14394 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14398 (define_expand "exp10<mode>2"
14399 [(use (match_operand:MODEF 0 "register_operand" ""))
14400 (use (match_operand:MODEF 1 "general_operand" ""))]
14401 "TARGET_USE_FANCY_MATH_387
14402 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14403 || TARGET_MIX_SSE_I387)
14404 && flag_unsafe_math_optimizations"
14408 if (optimize_insn_for_size_p ())
14411 op0 = gen_reg_rtx (XFmode);
14412 op1 = gen_reg_rtx (XFmode);
14414 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14415 emit_insn (gen_exp10xf2 (op0, op1));
14416 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14420 (define_expand "exp2xf2"
14421 [(use (match_operand:XF 0 "register_operand" ""))
14422 (use (match_operand:XF 1 "register_operand" ""))]
14423 "TARGET_USE_FANCY_MATH_387
14424 && flag_unsafe_math_optimizations"
14428 if (optimize_insn_for_size_p ())
14431 op2 = gen_reg_rtx (XFmode);
14432 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14434 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14438 (define_expand "exp2<mode>2"
14439 [(use (match_operand:MODEF 0 "register_operand" ""))
14440 (use (match_operand:MODEF 1 "general_operand" ""))]
14441 "TARGET_USE_FANCY_MATH_387
14442 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14443 || TARGET_MIX_SSE_I387)
14444 && flag_unsafe_math_optimizations"
14448 if (optimize_insn_for_size_p ())
14451 op0 = gen_reg_rtx (XFmode);
14452 op1 = gen_reg_rtx (XFmode);
14454 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14455 emit_insn (gen_exp2xf2 (op0, op1));
14456 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14460 (define_expand "expm1xf2"
14461 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14463 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14464 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14465 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14466 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14467 (parallel [(set (match_dup 7)
14468 (unspec:XF [(match_dup 6) (match_dup 4)]
14469 UNSPEC_FSCALE_FRACT))
14471 (unspec:XF [(match_dup 6) (match_dup 4)]
14472 UNSPEC_FSCALE_EXP))])
14473 (parallel [(set (match_dup 10)
14474 (unspec:XF [(match_dup 9) (match_dup 8)]
14475 UNSPEC_FSCALE_FRACT))
14476 (set (match_dup 11)
14477 (unspec:XF [(match_dup 9) (match_dup 8)]
14478 UNSPEC_FSCALE_EXP))])
14479 (set (match_dup 12) (minus:XF (match_dup 10)
14480 (float_extend:XF (match_dup 13))))
14481 (set (match_operand:XF 0 "register_operand" "")
14482 (plus:XF (match_dup 12) (match_dup 7)))]
14483 "TARGET_USE_FANCY_MATH_387
14484 && flag_unsafe_math_optimizations"
14488 if (optimize_insn_for_size_p ())
14491 for (i = 2; i < 13; i++)
14492 operands[i] = gen_reg_rtx (XFmode);
14495 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14497 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14500 (define_expand "expm1<mode>2"
14501 [(use (match_operand:MODEF 0 "register_operand" ""))
14502 (use (match_operand:MODEF 1 "general_operand" ""))]
14503 "TARGET_USE_FANCY_MATH_387
14504 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14505 || TARGET_MIX_SSE_I387)
14506 && flag_unsafe_math_optimizations"
14510 if (optimize_insn_for_size_p ())
14513 op0 = gen_reg_rtx (XFmode);
14514 op1 = gen_reg_rtx (XFmode);
14516 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14517 emit_insn (gen_expm1xf2 (op0, op1));
14518 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14522 (define_expand "ldexpxf3"
14523 [(set (match_dup 3)
14524 (float:XF (match_operand:SI 2 "register_operand" "")))
14525 (parallel [(set (match_operand:XF 0 " register_operand" "")
14526 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14528 UNSPEC_FSCALE_FRACT))
14530 (unspec:XF [(match_dup 1) (match_dup 3)]
14531 UNSPEC_FSCALE_EXP))])]
14532 "TARGET_USE_FANCY_MATH_387
14533 && flag_unsafe_math_optimizations"
14535 if (optimize_insn_for_size_p ())
14538 operands[3] = gen_reg_rtx (XFmode);
14539 operands[4] = gen_reg_rtx (XFmode);
14542 (define_expand "ldexp<mode>3"
14543 [(use (match_operand:MODEF 0 "register_operand" ""))
14544 (use (match_operand:MODEF 1 "general_operand" ""))
14545 (use (match_operand:SI 2 "register_operand" ""))]
14546 "TARGET_USE_FANCY_MATH_387
14547 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14548 || TARGET_MIX_SSE_I387)
14549 && flag_unsafe_math_optimizations"
14553 if (optimize_insn_for_size_p ())
14556 op0 = gen_reg_rtx (XFmode);
14557 op1 = gen_reg_rtx (XFmode);
14559 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14560 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14561 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14565 (define_expand "scalbxf3"
14566 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14567 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14568 (match_operand:XF 2 "register_operand" "")]
14569 UNSPEC_FSCALE_FRACT))
14571 (unspec:XF [(match_dup 1) (match_dup 2)]
14572 UNSPEC_FSCALE_EXP))])]
14573 "TARGET_USE_FANCY_MATH_387
14574 && flag_unsafe_math_optimizations"
14576 if (optimize_insn_for_size_p ())
14579 operands[3] = gen_reg_rtx (XFmode);
14582 (define_expand "scalb<mode>3"
14583 [(use (match_operand:MODEF 0 "register_operand" ""))
14584 (use (match_operand:MODEF 1 "general_operand" ""))
14585 (use (match_operand:MODEF 2 "general_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"
14593 if (optimize_insn_for_size_p ())
14596 op0 = gen_reg_rtx (XFmode);
14597 op1 = gen_reg_rtx (XFmode);
14598 op2 = gen_reg_rtx (XFmode);
14600 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14601 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14602 emit_insn (gen_scalbxf3 (op0, op1, op2));
14603 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14607 (define_expand "significandxf2"
14608 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14609 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14610 UNSPEC_XTRACT_FRACT))
14612 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14613 "TARGET_USE_FANCY_MATH_387
14614 && flag_unsafe_math_optimizations"
14616 operands[2] = gen_reg_rtx (XFmode);
14619 (define_expand "significand<mode>2"
14620 [(use (match_operand:MODEF 0 "register_operand" ""))
14621 (use (match_operand:MODEF 1 "register_operand" ""))]
14622 "TARGET_USE_FANCY_MATH_387
14623 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14624 || TARGET_MIX_SSE_I387)
14625 && flag_unsafe_math_optimizations"
14627 rtx op0 = gen_reg_rtx (XFmode);
14628 rtx op1 = gen_reg_rtx (XFmode);
14630 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14631 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14636 (define_insn "sse4_1_round<mode>2"
14637 [(set (match_operand:MODEF 0 "register_operand" "=x")
14638 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14639 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14642 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14643 [(set_attr "type" "ssecvt")
14644 (set_attr "prefix_extra" "1")
14645 (set_attr "prefix" "maybe_vex")
14646 (set_attr "mode" "<MODE>")])
14648 (define_insn "rintxf2"
14649 [(set (match_operand:XF 0 "register_operand" "=f")
14650 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14652 "TARGET_USE_FANCY_MATH_387
14653 && flag_unsafe_math_optimizations"
14655 [(set_attr "type" "fpspc")
14656 (set_attr "mode" "XF")])
14658 (define_expand "rint<mode>2"
14659 [(use (match_operand:MODEF 0 "register_operand" ""))
14660 (use (match_operand:MODEF 1 "register_operand" ""))]
14661 "(TARGET_USE_FANCY_MATH_387
14662 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14663 || TARGET_MIX_SSE_I387)
14664 && flag_unsafe_math_optimizations)
14665 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14666 && !flag_trapping_math)"
14668 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14669 && !flag_trapping_math)
14671 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14674 emit_insn (gen_sse4_1_round<mode>2
14675 (operands[0], operands[1], GEN_INT (0x04)));
14677 ix86_expand_rint (operand0, operand1);
14681 rtx op0 = gen_reg_rtx (XFmode);
14682 rtx op1 = gen_reg_rtx (XFmode);
14684 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14685 emit_insn (gen_rintxf2 (op0, op1));
14687 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14692 (define_expand "round<mode>2"
14693 [(match_operand:MODEF 0 "register_operand" "")
14694 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14695 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14696 && !flag_trapping_math && !flag_rounding_math"
14698 if (optimize_insn_for_size_p ())
14700 if (TARGET_64BIT || (<MODE>mode != DFmode))
14701 ix86_expand_round (operand0, operand1);
14703 ix86_expand_rounddf_32 (operand0, operand1);
14707 (define_insn_and_split "*fistdi2_1"
14708 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14709 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14711 "TARGET_USE_FANCY_MATH_387
14712 && can_create_pseudo_p ()"
14717 if (memory_operand (operands[0], VOIDmode))
14718 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14721 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14722 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14727 [(set_attr "type" "fpspc")
14728 (set_attr "mode" "DI")])
14730 (define_insn "fistdi2"
14731 [(set (match_operand:DI 0 "memory_operand" "=m")
14732 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14734 (clobber (match_scratch:XF 2 "=&1f"))]
14735 "TARGET_USE_FANCY_MATH_387"
14736 "* return output_fix_trunc (insn, operands, 0);"
14737 [(set_attr "type" "fpspc")
14738 (set_attr "mode" "DI")])
14740 (define_insn "fistdi2_with_temp"
14741 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14742 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14744 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14745 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14746 "TARGET_USE_FANCY_MATH_387"
14748 [(set_attr "type" "fpspc")
14749 (set_attr "mode" "DI")])
14752 [(set (match_operand:DI 0 "register_operand" "")
14753 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14755 (clobber (match_operand:DI 2 "memory_operand" ""))
14756 (clobber (match_scratch 3 ""))]
14758 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14759 (clobber (match_dup 3))])
14760 (set (match_dup 0) (match_dup 2))]
14764 [(set (match_operand:DI 0 "memory_operand" "")
14765 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14767 (clobber (match_operand:DI 2 "memory_operand" ""))
14768 (clobber (match_scratch 3 ""))]
14770 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14771 (clobber (match_dup 3))])]
14774 (define_insn_and_split "*fist<mode>2_1"
14775 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14776 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14778 "TARGET_USE_FANCY_MATH_387
14779 && can_create_pseudo_p ()"
14784 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14785 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14789 [(set_attr "type" "fpspc")
14790 (set_attr "mode" "<MODE>")])
14792 (define_insn "fist<mode>2"
14793 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14794 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14796 "TARGET_USE_FANCY_MATH_387"
14797 "* return output_fix_trunc (insn, operands, 0);"
14798 [(set_attr "type" "fpspc")
14799 (set_attr "mode" "<MODE>")])
14801 (define_insn "fist<mode>2_with_temp"
14802 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14803 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14805 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14806 "TARGET_USE_FANCY_MATH_387"
14808 [(set_attr "type" "fpspc")
14809 (set_attr "mode" "<MODE>")])
14812 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14813 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14815 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14817 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14818 (set (match_dup 0) (match_dup 2))]
14822 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14823 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14825 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14827 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14830 (define_expand "lrintxf<mode>2"
14831 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14832 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14834 "TARGET_USE_FANCY_MATH_387"
14837 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14838 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14839 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14840 UNSPEC_FIX_NOTRUNC))]
14841 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14842 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14845 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14846 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14847 (match_operand:MODEF 1 "register_operand" "")]
14848 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14849 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14850 && !flag_trapping_math && !flag_rounding_math"
14852 if (optimize_insn_for_size_p ())
14854 ix86_expand_lround (operand0, operand1);
14858 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14859 (define_insn_and_split "frndintxf2_floor"
14860 [(set (match_operand:XF 0 "register_operand" "")
14861 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14862 UNSPEC_FRNDINT_FLOOR))
14863 (clobber (reg:CC FLAGS_REG))]
14864 "TARGET_USE_FANCY_MATH_387
14865 && flag_unsafe_math_optimizations
14866 && can_create_pseudo_p ()"
14871 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14873 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14874 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14876 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14877 operands[2], operands[3]));
14880 [(set_attr "type" "frndint")
14881 (set_attr "i387_cw" "floor")
14882 (set_attr "mode" "XF")])
14884 (define_insn "frndintxf2_floor_i387"
14885 [(set (match_operand:XF 0 "register_operand" "=f")
14886 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14887 UNSPEC_FRNDINT_FLOOR))
14888 (use (match_operand:HI 2 "memory_operand" "m"))
14889 (use (match_operand:HI 3 "memory_operand" "m"))]
14890 "TARGET_USE_FANCY_MATH_387
14891 && flag_unsafe_math_optimizations"
14892 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14893 [(set_attr "type" "frndint")
14894 (set_attr "i387_cw" "floor")
14895 (set_attr "mode" "XF")])
14897 (define_expand "floorxf2"
14898 [(use (match_operand:XF 0 "register_operand" ""))
14899 (use (match_operand:XF 1 "register_operand" ""))]
14900 "TARGET_USE_FANCY_MATH_387
14901 && flag_unsafe_math_optimizations"
14903 if (optimize_insn_for_size_p ())
14905 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14909 (define_expand "floor<mode>2"
14910 [(use (match_operand:MODEF 0 "register_operand" ""))
14911 (use (match_operand:MODEF 1 "register_operand" ""))]
14912 "(TARGET_USE_FANCY_MATH_387
14913 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14914 || TARGET_MIX_SSE_I387)
14915 && flag_unsafe_math_optimizations)
14916 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14917 && !flag_trapping_math)"
14919 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14920 && !flag_trapping_math
14921 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14923 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14926 emit_insn (gen_sse4_1_round<mode>2
14927 (operands[0], operands[1], GEN_INT (0x01)));
14928 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14929 ix86_expand_floorceil (operand0, operand1, true);
14931 ix86_expand_floorceildf_32 (operand0, operand1, true);
14937 if (optimize_insn_for_size_p ())
14940 op0 = gen_reg_rtx (XFmode);
14941 op1 = gen_reg_rtx (XFmode);
14942 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14943 emit_insn (gen_frndintxf2_floor (op0, op1));
14945 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14950 (define_insn_and_split "*fist<mode>2_floor_1"
14951 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14952 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14953 UNSPEC_FIST_FLOOR))
14954 (clobber (reg:CC FLAGS_REG))]
14955 "TARGET_USE_FANCY_MATH_387
14956 && flag_unsafe_math_optimizations
14957 && can_create_pseudo_p ()"
14962 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14964 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14965 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14966 if (memory_operand (operands[0], VOIDmode))
14967 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14968 operands[2], operands[3]));
14971 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14972 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14973 operands[2], operands[3],
14978 [(set_attr "type" "fistp")
14979 (set_attr "i387_cw" "floor")
14980 (set_attr "mode" "<MODE>")])
14982 (define_insn "fistdi2_floor"
14983 [(set (match_operand:DI 0 "memory_operand" "=m")
14984 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14985 UNSPEC_FIST_FLOOR))
14986 (use (match_operand:HI 2 "memory_operand" "m"))
14987 (use (match_operand:HI 3 "memory_operand" "m"))
14988 (clobber (match_scratch:XF 4 "=&1f"))]
14989 "TARGET_USE_FANCY_MATH_387
14990 && flag_unsafe_math_optimizations"
14991 "* return output_fix_trunc (insn, operands, 0);"
14992 [(set_attr "type" "fistp")
14993 (set_attr "i387_cw" "floor")
14994 (set_attr "mode" "DI")])
14996 (define_insn "fistdi2_floor_with_temp"
14997 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14998 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14999 UNSPEC_FIST_FLOOR))
15000 (use (match_operand:HI 2 "memory_operand" "m,m"))
15001 (use (match_operand:HI 3 "memory_operand" "m,m"))
15002 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15003 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15004 "TARGET_USE_FANCY_MATH_387
15005 && flag_unsafe_math_optimizations"
15007 [(set_attr "type" "fistp")
15008 (set_attr "i387_cw" "floor")
15009 (set_attr "mode" "DI")])
15012 [(set (match_operand:DI 0 "register_operand" "")
15013 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15014 UNSPEC_FIST_FLOOR))
15015 (use (match_operand:HI 2 "memory_operand" ""))
15016 (use (match_operand:HI 3 "memory_operand" ""))
15017 (clobber (match_operand:DI 4 "memory_operand" ""))
15018 (clobber (match_scratch 5 ""))]
15020 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15021 (use (match_dup 2))
15022 (use (match_dup 3))
15023 (clobber (match_dup 5))])
15024 (set (match_dup 0) (match_dup 4))]
15028 [(set (match_operand:DI 0 "memory_operand" "")
15029 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15030 UNSPEC_FIST_FLOOR))
15031 (use (match_operand:HI 2 "memory_operand" ""))
15032 (use (match_operand:HI 3 "memory_operand" ""))
15033 (clobber (match_operand:DI 4 "memory_operand" ""))
15034 (clobber (match_scratch 5 ""))]
15036 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15037 (use (match_dup 2))
15038 (use (match_dup 3))
15039 (clobber (match_dup 5))])]
15042 (define_insn "fist<mode>2_floor"
15043 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15044 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15045 UNSPEC_FIST_FLOOR))
15046 (use (match_operand:HI 2 "memory_operand" "m"))
15047 (use (match_operand:HI 3 "memory_operand" "m"))]
15048 "TARGET_USE_FANCY_MATH_387
15049 && flag_unsafe_math_optimizations"
15050 "* return output_fix_trunc (insn, operands, 0);"
15051 [(set_attr "type" "fistp")
15052 (set_attr "i387_cw" "floor")
15053 (set_attr "mode" "<MODE>")])
15055 (define_insn "fist<mode>2_floor_with_temp"
15056 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15057 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15058 UNSPEC_FIST_FLOOR))
15059 (use (match_operand:HI 2 "memory_operand" "m,m"))
15060 (use (match_operand:HI 3 "memory_operand" "m,m"))
15061 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15062 "TARGET_USE_FANCY_MATH_387
15063 && flag_unsafe_math_optimizations"
15065 [(set_attr "type" "fistp")
15066 (set_attr "i387_cw" "floor")
15067 (set_attr "mode" "<MODE>")])
15070 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15071 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15072 UNSPEC_FIST_FLOOR))
15073 (use (match_operand:HI 2 "memory_operand" ""))
15074 (use (match_operand:HI 3 "memory_operand" ""))
15075 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15077 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15078 UNSPEC_FIST_FLOOR))
15079 (use (match_dup 2))
15080 (use (match_dup 3))])
15081 (set (match_dup 0) (match_dup 4))]
15085 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15086 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15087 UNSPEC_FIST_FLOOR))
15088 (use (match_operand:HI 2 "memory_operand" ""))
15089 (use (match_operand:HI 3 "memory_operand" ""))
15090 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15092 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15093 UNSPEC_FIST_FLOOR))
15094 (use (match_dup 2))
15095 (use (match_dup 3))])]
15098 (define_expand "lfloorxf<mode>2"
15099 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15100 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15101 UNSPEC_FIST_FLOOR))
15102 (clobber (reg:CC FLAGS_REG))])]
15103 "TARGET_USE_FANCY_MATH_387
15104 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15105 && flag_unsafe_math_optimizations"
15108 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15109 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15110 (match_operand:MODEF 1 "register_operand" "")]
15111 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15112 && !flag_trapping_math"
15114 if (TARGET_64BIT && optimize_insn_for_size_p ())
15116 ix86_expand_lfloorceil (operand0, operand1, true);
15120 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15121 (define_insn_and_split "frndintxf2_ceil"
15122 [(set (match_operand:XF 0 "register_operand" "")
15123 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15124 UNSPEC_FRNDINT_CEIL))
15125 (clobber (reg:CC FLAGS_REG))]
15126 "TARGET_USE_FANCY_MATH_387
15127 && flag_unsafe_math_optimizations
15128 && can_create_pseudo_p ()"
15133 ix86_optimize_mode_switching[I387_CEIL] = 1;
15135 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15136 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15138 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15139 operands[2], operands[3]));
15142 [(set_attr "type" "frndint")
15143 (set_attr "i387_cw" "ceil")
15144 (set_attr "mode" "XF")])
15146 (define_insn "frndintxf2_ceil_i387"
15147 [(set (match_operand:XF 0 "register_operand" "=f")
15148 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15149 UNSPEC_FRNDINT_CEIL))
15150 (use (match_operand:HI 2 "memory_operand" "m"))
15151 (use (match_operand:HI 3 "memory_operand" "m"))]
15152 "TARGET_USE_FANCY_MATH_387
15153 && flag_unsafe_math_optimizations"
15154 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15155 [(set_attr "type" "frndint")
15156 (set_attr "i387_cw" "ceil")
15157 (set_attr "mode" "XF")])
15159 (define_expand "ceilxf2"
15160 [(use (match_operand:XF 0 "register_operand" ""))
15161 (use (match_operand:XF 1 "register_operand" ""))]
15162 "TARGET_USE_FANCY_MATH_387
15163 && flag_unsafe_math_optimizations"
15165 if (optimize_insn_for_size_p ())
15167 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15171 (define_expand "ceil<mode>2"
15172 [(use (match_operand:MODEF 0 "register_operand" ""))
15173 (use (match_operand:MODEF 1 "register_operand" ""))]
15174 "(TARGET_USE_FANCY_MATH_387
15175 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15176 || TARGET_MIX_SSE_I387)
15177 && flag_unsafe_math_optimizations)
15178 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15179 && !flag_trapping_math)"
15181 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15182 && !flag_trapping_math
15183 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15186 emit_insn (gen_sse4_1_round<mode>2
15187 (operands[0], operands[1], GEN_INT (0x02)));
15188 else if (optimize_insn_for_size_p ())
15190 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15191 ix86_expand_floorceil (operand0, operand1, false);
15193 ix86_expand_floorceildf_32 (operand0, operand1, false);
15199 if (optimize_insn_for_size_p ())
15202 op0 = gen_reg_rtx (XFmode);
15203 op1 = gen_reg_rtx (XFmode);
15204 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15205 emit_insn (gen_frndintxf2_ceil (op0, op1));
15207 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15212 (define_insn_and_split "*fist<mode>2_ceil_1"
15213 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15214 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15216 (clobber (reg:CC FLAGS_REG))]
15217 "TARGET_USE_FANCY_MATH_387
15218 && flag_unsafe_math_optimizations
15219 && can_create_pseudo_p ()"
15224 ix86_optimize_mode_switching[I387_CEIL] = 1;
15226 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15227 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15228 if (memory_operand (operands[0], VOIDmode))
15229 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15230 operands[2], operands[3]));
15233 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15234 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15235 operands[2], operands[3],
15240 [(set_attr "type" "fistp")
15241 (set_attr "i387_cw" "ceil")
15242 (set_attr "mode" "<MODE>")])
15244 (define_insn "fistdi2_ceil"
15245 [(set (match_operand:DI 0 "memory_operand" "=m")
15246 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15248 (use (match_operand:HI 2 "memory_operand" "m"))
15249 (use (match_operand:HI 3 "memory_operand" "m"))
15250 (clobber (match_scratch:XF 4 "=&1f"))]
15251 "TARGET_USE_FANCY_MATH_387
15252 && flag_unsafe_math_optimizations"
15253 "* return output_fix_trunc (insn, operands, 0);"
15254 [(set_attr "type" "fistp")
15255 (set_attr "i387_cw" "ceil")
15256 (set_attr "mode" "DI")])
15258 (define_insn "fistdi2_ceil_with_temp"
15259 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15260 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15262 (use (match_operand:HI 2 "memory_operand" "m,m"))
15263 (use (match_operand:HI 3 "memory_operand" "m,m"))
15264 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15265 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15266 "TARGET_USE_FANCY_MATH_387
15267 && flag_unsafe_math_optimizations"
15269 [(set_attr "type" "fistp")
15270 (set_attr "i387_cw" "ceil")
15271 (set_attr "mode" "DI")])
15274 [(set (match_operand:DI 0 "register_operand" "")
15275 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15277 (use (match_operand:HI 2 "memory_operand" ""))
15278 (use (match_operand:HI 3 "memory_operand" ""))
15279 (clobber (match_operand:DI 4 "memory_operand" ""))
15280 (clobber (match_scratch 5 ""))]
15282 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15283 (use (match_dup 2))
15284 (use (match_dup 3))
15285 (clobber (match_dup 5))])
15286 (set (match_dup 0) (match_dup 4))]
15290 [(set (match_operand:DI 0 "memory_operand" "")
15291 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15293 (use (match_operand:HI 2 "memory_operand" ""))
15294 (use (match_operand:HI 3 "memory_operand" ""))
15295 (clobber (match_operand:DI 4 "memory_operand" ""))
15296 (clobber (match_scratch 5 ""))]
15298 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15299 (use (match_dup 2))
15300 (use (match_dup 3))
15301 (clobber (match_dup 5))])]
15304 (define_insn "fist<mode>2_ceil"
15305 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15306 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15308 (use (match_operand:HI 2 "memory_operand" "m"))
15309 (use (match_operand:HI 3 "memory_operand" "m"))]
15310 "TARGET_USE_FANCY_MATH_387
15311 && flag_unsafe_math_optimizations"
15312 "* return output_fix_trunc (insn, operands, 0);"
15313 [(set_attr "type" "fistp")
15314 (set_attr "i387_cw" "ceil")
15315 (set_attr "mode" "<MODE>")])
15317 (define_insn "fist<mode>2_ceil_with_temp"
15318 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15319 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15321 (use (match_operand:HI 2 "memory_operand" "m,m"))
15322 (use (match_operand:HI 3 "memory_operand" "m,m"))
15323 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15324 "TARGET_USE_FANCY_MATH_387
15325 && flag_unsafe_math_optimizations"
15327 [(set_attr "type" "fistp")
15328 (set_attr "i387_cw" "ceil")
15329 (set_attr "mode" "<MODE>")])
15332 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15333 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15335 (use (match_operand:HI 2 "memory_operand" ""))
15336 (use (match_operand:HI 3 "memory_operand" ""))
15337 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15339 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15341 (use (match_dup 2))
15342 (use (match_dup 3))])
15343 (set (match_dup 0) (match_dup 4))]
15347 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15348 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15350 (use (match_operand:HI 2 "memory_operand" ""))
15351 (use (match_operand:HI 3 "memory_operand" ""))
15352 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15354 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15356 (use (match_dup 2))
15357 (use (match_dup 3))])]
15360 (define_expand "lceilxf<mode>2"
15361 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15362 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15364 (clobber (reg:CC FLAGS_REG))])]
15365 "TARGET_USE_FANCY_MATH_387
15366 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15367 && flag_unsafe_math_optimizations"
15370 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15371 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15372 (match_operand:MODEF 1 "register_operand" "")]
15373 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15374 && !flag_trapping_math"
15376 ix86_expand_lfloorceil (operand0, operand1, false);
15380 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15381 (define_insn_and_split "frndintxf2_trunc"
15382 [(set (match_operand:XF 0 "register_operand" "")
15383 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15384 UNSPEC_FRNDINT_TRUNC))
15385 (clobber (reg:CC FLAGS_REG))]
15386 "TARGET_USE_FANCY_MATH_387
15387 && flag_unsafe_math_optimizations
15388 && can_create_pseudo_p ()"
15393 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15395 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15396 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15398 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15399 operands[2], operands[3]));
15402 [(set_attr "type" "frndint")
15403 (set_attr "i387_cw" "trunc")
15404 (set_attr "mode" "XF")])
15406 (define_insn "frndintxf2_trunc_i387"
15407 [(set (match_operand:XF 0 "register_operand" "=f")
15408 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15409 UNSPEC_FRNDINT_TRUNC))
15410 (use (match_operand:HI 2 "memory_operand" "m"))
15411 (use (match_operand:HI 3 "memory_operand" "m"))]
15412 "TARGET_USE_FANCY_MATH_387
15413 && flag_unsafe_math_optimizations"
15414 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15415 [(set_attr "type" "frndint")
15416 (set_attr "i387_cw" "trunc")
15417 (set_attr "mode" "XF")])
15419 (define_expand "btruncxf2"
15420 [(use (match_operand:XF 0 "register_operand" ""))
15421 (use (match_operand:XF 1 "register_operand" ""))]
15422 "TARGET_USE_FANCY_MATH_387
15423 && flag_unsafe_math_optimizations"
15425 if (optimize_insn_for_size_p ())
15427 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15431 (define_expand "btrunc<mode>2"
15432 [(use (match_operand:MODEF 0 "register_operand" ""))
15433 (use (match_operand:MODEF 1 "register_operand" ""))]
15434 "(TARGET_USE_FANCY_MATH_387
15435 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15436 || TARGET_MIX_SSE_I387)
15437 && flag_unsafe_math_optimizations)
15438 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15439 && !flag_trapping_math)"
15441 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15442 && !flag_trapping_math
15443 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15446 emit_insn (gen_sse4_1_round<mode>2
15447 (operands[0], operands[1], GEN_INT (0x03)));
15448 else if (optimize_insn_for_size_p ())
15450 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15451 ix86_expand_trunc (operand0, operand1);
15453 ix86_expand_truncdf_32 (operand0, operand1);
15459 if (optimize_insn_for_size_p ())
15462 op0 = gen_reg_rtx (XFmode);
15463 op1 = gen_reg_rtx (XFmode);
15464 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15465 emit_insn (gen_frndintxf2_trunc (op0, op1));
15467 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15472 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15473 (define_insn_and_split "frndintxf2_mask_pm"
15474 [(set (match_operand:XF 0 "register_operand" "")
15475 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15476 UNSPEC_FRNDINT_MASK_PM))
15477 (clobber (reg:CC FLAGS_REG))]
15478 "TARGET_USE_FANCY_MATH_387
15479 && flag_unsafe_math_optimizations
15480 && can_create_pseudo_p ()"
15485 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15487 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15488 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15490 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15491 operands[2], operands[3]));
15494 [(set_attr "type" "frndint")
15495 (set_attr "i387_cw" "mask_pm")
15496 (set_attr "mode" "XF")])
15498 (define_insn "frndintxf2_mask_pm_i387"
15499 [(set (match_operand:XF 0 "register_operand" "=f")
15500 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15501 UNSPEC_FRNDINT_MASK_PM))
15502 (use (match_operand:HI 2 "memory_operand" "m"))
15503 (use (match_operand:HI 3 "memory_operand" "m"))]
15504 "TARGET_USE_FANCY_MATH_387
15505 && flag_unsafe_math_optimizations"
15506 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15507 [(set_attr "type" "frndint")
15508 (set_attr "i387_cw" "mask_pm")
15509 (set_attr "mode" "XF")])
15511 (define_expand "nearbyintxf2"
15512 [(use (match_operand:XF 0 "register_operand" ""))
15513 (use (match_operand:XF 1 "register_operand" ""))]
15514 "TARGET_USE_FANCY_MATH_387
15515 && flag_unsafe_math_optimizations"
15517 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15522 (define_expand "nearbyint<mode>2"
15523 [(use (match_operand:MODEF 0 "register_operand" ""))
15524 (use (match_operand:MODEF 1 "register_operand" ""))]
15525 "TARGET_USE_FANCY_MATH_387
15526 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15527 || TARGET_MIX_SSE_I387)
15528 && flag_unsafe_math_optimizations"
15530 rtx op0 = gen_reg_rtx (XFmode);
15531 rtx op1 = gen_reg_rtx (XFmode);
15533 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15534 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15536 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15540 (define_insn "fxam<mode>2_i387"
15541 [(set (match_operand:HI 0 "register_operand" "=a")
15543 [(match_operand:X87MODEF 1 "register_operand" "f")]
15545 "TARGET_USE_FANCY_MATH_387"
15546 "fxam\n\tfnstsw\t%0"
15547 [(set_attr "type" "multi")
15548 (set_attr "length" "4")
15549 (set_attr "unit" "i387")
15550 (set_attr "mode" "<MODE>")])
15552 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15553 [(set (match_operand:HI 0 "register_operand" "")
15555 [(match_operand:MODEF 1 "memory_operand" "")]
15557 "TARGET_USE_FANCY_MATH_387
15558 && can_create_pseudo_p ()"
15561 [(set (match_dup 2)(match_dup 1))
15563 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15565 operands[2] = gen_reg_rtx (<MODE>mode);
15567 MEM_VOLATILE_P (operands[1]) = 1;
15569 [(set_attr "type" "multi")
15570 (set_attr "unit" "i387")
15571 (set_attr "mode" "<MODE>")])
15573 (define_expand "isinfxf2"
15574 [(use (match_operand:SI 0 "register_operand" ""))
15575 (use (match_operand:XF 1 "register_operand" ""))]
15576 "TARGET_USE_FANCY_MATH_387
15577 && TARGET_C99_FUNCTIONS"
15579 rtx mask = GEN_INT (0x45);
15580 rtx val = GEN_INT (0x05);
15584 rtx scratch = gen_reg_rtx (HImode);
15585 rtx res = gen_reg_rtx (QImode);
15587 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15589 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15590 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15591 cond = gen_rtx_fmt_ee (EQ, QImode,
15592 gen_rtx_REG (CCmode, FLAGS_REG),
15594 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15595 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15599 (define_expand "isinf<mode>2"
15600 [(use (match_operand:SI 0 "register_operand" ""))
15601 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15602 "TARGET_USE_FANCY_MATH_387
15603 && TARGET_C99_FUNCTIONS
15604 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15606 rtx mask = GEN_INT (0x45);
15607 rtx val = GEN_INT (0x05);
15611 rtx scratch = gen_reg_rtx (HImode);
15612 rtx res = gen_reg_rtx (QImode);
15614 /* Remove excess precision by forcing value through memory. */
15615 if (memory_operand (operands[1], VOIDmode))
15616 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15619 enum ix86_stack_slot slot = (virtuals_instantiated
15622 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15624 emit_move_insn (temp, operands[1]);
15625 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15628 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15629 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15630 cond = gen_rtx_fmt_ee (EQ, QImode,
15631 gen_rtx_REG (CCmode, FLAGS_REG),
15633 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15634 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15638 (define_expand "signbit<mode>2"
15639 [(use (match_operand:SI 0 "register_operand" ""))
15640 (use (match_operand:X87MODEF 1 "register_operand" ""))]
15641 "TARGET_USE_FANCY_MATH_387
15642 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15644 rtx mask = GEN_INT (0x0200);
15646 rtx scratch = gen_reg_rtx (HImode);
15648 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15649 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15653 ;; Block operation instructions
15656 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15659 [(set_attr "length" "1")
15660 (set_attr "length_immediate" "0")
15661 (set_attr "modrm" "0")])
15663 (define_expand "movmemsi"
15664 [(use (match_operand:BLK 0 "memory_operand" ""))
15665 (use (match_operand:BLK 1 "memory_operand" ""))
15666 (use (match_operand:SI 2 "nonmemory_operand" ""))
15667 (use (match_operand:SI 3 "const_int_operand" ""))
15668 (use (match_operand:SI 4 "const_int_operand" ""))
15669 (use (match_operand:SI 5 "const_int_operand" ""))]
15672 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15673 operands[4], operands[5]))
15679 (define_expand "movmemdi"
15680 [(use (match_operand:BLK 0 "memory_operand" ""))
15681 (use (match_operand:BLK 1 "memory_operand" ""))
15682 (use (match_operand:DI 2 "nonmemory_operand" ""))
15683 (use (match_operand:DI 3 "const_int_operand" ""))
15684 (use (match_operand:SI 4 "const_int_operand" ""))
15685 (use (match_operand:SI 5 "const_int_operand" ""))]
15688 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15689 operands[4], operands[5]))
15695 ;; Most CPUs don't like single string operations
15696 ;; Handle this case here to simplify previous expander.
15698 (define_expand "strmov"
15699 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15700 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15701 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15702 (clobber (reg:CC FLAGS_REG))])
15703 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15704 (clobber (reg:CC FLAGS_REG))])]
15707 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15709 /* If .md ever supports :P for Pmode, these can be directly
15710 in the pattern above. */
15711 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15712 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15714 /* Can't use this if the user has appropriated esi or edi. */
15715 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15716 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15718 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15719 operands[2], operands[3],
15720 operands[5], operands[6]));
15724 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15727 (define_expand "strmov_singleop"
15728 [(parallel [(set (match_operand 1 "memory_operand" "")
15729 (match_operand 3 "memory_operand" ""))
15730 (set (match_operand 0 "register_operand" "")
15731 (match_operand 4 "" ""))
15732 (set (match_operand 2 "register_operand" "")
15733 (match_operand 5 "" ""))])]
15735 "ix86_current_function_needs_cld = 1;")
15737 (define_insn "*strmovdi_rex_1"
15738 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15739 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15740 (set (match_operand:DI 0 "register_operand" "=D")
15741 (plus:DI (match_dup 2)
15743 (set (match_operand:DI 1 "register_operand" "=S")
15744 (plus:DI (match_dup 3)
15748 [(set_attr "type" "str")
15749 (set_attr "mode" "DI")
15750 (set_attr "memory" "both")])
15752 (define_insn "*strmovsi_1"
15753 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15754 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15755 (set (match_operand:SI 0 "register_operand" "=D")
15756 (plus:SI (match_dup 2)
15758 (set (match_operand:SI 1 "register_operand" "=S")
15759 (plus:SI (match_dup 3)
15763 [(set_attr "type" "str")
15764 (set_attr "mode" "SI")
15765 (set_attr "memory" "both")])
15767 (define_insn "*strmovsi_rex_1"
15768 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15769 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15770 (set (match_operand:DI 0 "register_operand" "=D")
15771 (plus:DI (match_dup 2)
15773 (set (match_operand:DI 1 "register_operand" "=S")
15774 (plus:DI (match_dup 3)
15778 [(set_attr "type" "str")
15779 (set_attr "mode" "SI")
15780 (set_attr "memory" "both")])
15782 (define_insn "*strmovhi_1"
15783 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15784 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15785 (set (match_operand:SI 0 "register_operand" "=D")
15786 (plus:SI (match_dup 2)
15788 (set (match_operand:SI 1 "register_operand" "=S")
15789 (plus:SI (match_dup 3)
15793 [(set_attr "type" "str")
15794 (set_attr "memory" "both")
15795 (set_attr "mode" "HI")])
15797 (define_insn "*strmovhi_rex_1"
15798 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15799 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15800 (set (match_operand:DI 0 "register_operand" "=D")
15801 (plus:DI (match_dup 2)
15803 (set (match_operand:DI 1 "register_operand" "=S")
15804 (plus:DI (match_dup 3)
15808 [(set_attr "type" "str")
15809 (set_attr "memory" "both")
15810 (set_attr "mode" "HI")])
15812 (define_insn "*strmovqi_1"
15813 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15814 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15815 (set (match_operand:SI 0 "register_operand" "=D")
15816 (plus:SI (match_dup 2)
15818 (set (match_operand:SI 1 "register_operand" "=S")
15819 (plus:SI (match_dup 3)
15823 [(set_attr "type" "str")
15824 (set_attr "memory" "both")
15825 (set_attr "mode" "QI")])
15827 (define_insn "*strmovqi_rex_1"
15828 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15829 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15830 (set (match_operand:DI 0 "register_operand" "=D")
15831 (plus:DI (match_dup 2)
15833 (set (match_operand:DI 1 "register_operand" "=S")
15834 (plus:DI (match_dup 3)
15838 [(set_attr "type" "str")
15839 (set_attr "memory" "both")
15840 (set_attr "prefix_rex" "0")
15841 (set_attr "mode" "QI")])
15843 (define_expand "rep_mov"
15844 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15845 (set (match_operand 0 "register_operand" "")
15846 (match_operand 5 "" ""))
15847 (set (match_operand 2 "register_operand" "")
15848 (match_operand 6 "" ""))
15849 (set (match_operand 1 "memory_operand" "")
15850 (match_operand 3 "memory_operand" ""))
15851 (use (match_dup 4))])]
15853 "ix86_current_function_needs_cld = 1;")
15855 (define_insn "*rep_movdi_rex64"
15856 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15857 (set (match_operand:DI 0 "register_operand" "=D")
15858 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15860 (match_operand:DI 3 "register_operand" "0")))
15861 (set (match_operand:DI 1 "register_operand" "=S")
15862 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15863 (match_operand:DI 4 "register_operand" "1")))
15864 (set (mem:BLK (match_dup 3))
15865 (mem:BLK (match_dup 4)))
15866 (use (match_dup 5))]
15869 [(set_attr "type" "str")
15870 (set_attr "prefix_rep" "1")
15871 (set_attr "memory" "both")
15872 (set_attr "mode" "DI")])
15874 (define_insn "*rep_movsi"
15875 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15876 (set (match_operand:SI 0 "register_operand" "=D")
15877 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15879 (match_operand:SI 3 "register_operand" "0")))
15880 (set (match_operand:SI 1 "register_operand" "=S")
15881 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15882 (match_operand:SI 4 "register_operand" "1")))
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_movsi_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 (ashift:DI (match_operand:DI 5 "register_operand" "2")
15898 (match_operand:DI 3 "register_operand" "0")))
15899 (set (match_operand:DI 1 "register_operand" "=S")
15900 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15901 (match_operand:DI 4 "register_operand" "1")))
15902 (set (mem:BLK (match_dup 3))
15903 (mem:BLK (match_dup 4)))
15904 (use (match_dup 5))]
15907 [(set_attr "type" "str")
15908 (set_attr "prefix_rep" "1")
15909 (set_attr "memory" "both")
15910 (set_attr "mode" "SI")])
15912 (define_insn "*rep_movqi"
15913 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15914 (set (match_operand:SI 0 "register_operand" "=D")
15915 (plus:SI (match_operand:SI 3 "register_operand" "0")
15916 (match_operand:SI 5 "register_operand" "2")))
15917 (set (match_operand:SI 1 "register_operand" "=S")
15918 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15919 (set (mem:BLK (match_dup 3))
15920 (mem:BLK (match_dup 4)))
15921 (use (match_dup 5))]
15924 [(set_attr "type" "str")
15925 (set_attr "prefix_rep" "1")
15926 (set_attr "memory" "both")
15927 (set_attr "mode" "SI")])
15929 (define_insn "*rep_movqi_rex64"
15930 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15931 (set (match_operand:DI 0 "register_operand" "=D")
15932 (plus:DI (match_operand:DI 3 "register_operand" "0")
15933 (match_operand:DI 5 "register_operand" "2")))
15934 (set (match_operand:DI 1 "register_operand" "=S")
15935 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15936 (set (mem:BLK (match_dup 3))
15937 (mem:BLK (match_dup 4)))
15938 (use (match_dup 5))]
15941 [(set_attr "type" "str")
15942 (set_attr "prefix_rep" "1")
15943 (set_attr "memory" "both")
15944 (set_attr "mode" "SI")])
15946 (define_expand "setmemsi"
15947 [(use (match_operand:BLK 0 "memory_operand" ""))
15948 (use (match_operand:SI 1 "nonmemory_operand" ""))
15949 (use (match_operand 2 "const_int_operand" ""))
15950 (use (match_operand 3 "const_int_operand" ""))
15951 (use (match_operand:SI 4 "const_int_operand" ""))
15952 (use (match_operand:SI 5 "const_int_operand" ""))]
15955 if (ix86_expand_setmem (operands[0], operands[1],
15956 operands[2], operands[3],
15957 operands[4], operands[5]))
15963 (define_expand "setmemdi"
15964 [(use (match_operand:BLK 0 "memory_operand" ""))
15965 (use (match_operand:DI 1 "nonmemory_operand" ""))
15966 (use (match_operand 2 "const_int_operand" ""))
15967 (use (match_operand 3 "const_int_operand" ""))
15968 (use (match_operand 4 "const_int_operand" ""))
15969 (use (match_operand 5 "const_int_operand" ""))]
15972 if (ix86_expand_setmem (operands[0], operands[1],
15973 operands[2], operands[3],
15974 operands[4], operands[5]))
15980 ;; Most CPUs don't like single string operations
15981 ;; Handle this case here to simplify previous expander.
15983 (define_expand "strset"
15984 [(set (match_operand 1 "memory_operand" "")
15985 (match_operand 2 "register_operand" ""))
15986 (parallel [(set (match_operand 0 "register_operand" "")
15988 (clobber (reg:CC FLAGS_REG))])]
15991 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15992 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15994 /* If .md ever supports :P for Pmode, this can be directly
15995 in the pattern above. */
15996 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15997 GEN_INT (GET_MODE_SIZE (GET_MODE
15999 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16001 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16007 (define_expand "strset_singleop"
16008 [(parallel [(set (match_operand 1 "memory_operand" "")
16009 (match_operand 2 "register_operand" ""))
16010 (set (match_operand 0 "register_operand" "")
16011 (match_operand 3 "" ""))])]
16013 "ix86_current_function_needs_cld = 1;")
16015 (define_insn "*strsetdi_rex_1"
16016 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16017 (match_operand:DI 2 "register_operand" "a"))
16018 (set (match_operand:DI 0 "register_operand" "=D")
16019 (plus:DI (match_dup 1)
16023 [(set_attr "type" "str")
16024 (set_attr "memory" "store")
16025 (set_attr "mode" "DI")])
16027 (define_insn "*strsetsi_1"
16028 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16029 (match_operand:SI 2 "register_operand" "a"))
16030 (set (match_operand:SI 0 "register_operand" "=D")
16031 (plus:SI (match_dup 1)
16035 [(set_attr "type" "str")
16036 (set_attr "memory" "store")
16037 (set_attr "mode" "SI")])
16039 (define_insn "*strsetsi_rex_1"
16040 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16041 (match_operand:SI 2 "register_operand" "a"))
16042 (set (match_operand:DI 0 "register_operand" "=D")
16043 (plus:DI (match_dup 1)
16047 [(set_attr "type" "str")
16048 (set_attr "memory" "store")
16049 (set_attr "mode" "SI")])
16051 (define_insn "*strsethi_1"
16052 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16053 (match_operand:HI 2 "register_operand" "a"))
16054 (set (match_operand:SI 0 "register_operand" "=D")
16055 (plus:SI (match_dup 1)
16059 [(set_attr "type" "str")
16060 (set_attr "memory" "store")
16061 (set_attr "mode" "HI")])
16063 (define_insn "*strsethi_rex_1"
16064 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16065 (match_operand:HI 2 "register_operand" "a"))
16066 (set (match_operand:DI 0 "register_operand" "=D")
16067 (plus:DI (match_dup 1)
16071 [(set_attr "type" "str")
16072 (set_attr "memory" "store")
16073 (set_attr "mode" "HI")])
16075 (define_insn "*strsetqi_1"
16076 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16077 (match_operand:QI 2 "register_operand" "a"))
16078 (set (match_operand:SI 0 "register_operand" "=D")
16079 (plus:SI (match_dup 1)
16083 [(set_attr "type" "str")
16084 (set_attr "memory" "store")
16085 (set_attr "mode" "QI")])
16087 (define_insn "*strsetqi_rex_1"
16088 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16089 (match_operand:QI 2 "register_operand" "a"))
16090 (set (match_operand:DI 0 "register_operand" "=D")
16091 (plus:DI (match_dup 1)
16095 [(set_attr "type" "str")
16096 (set_attr "memory" "store")
16097 (set_attr "prefix_rex" "0")
16098 (set_attr "mode" "QI")])
16100 (define_expand "rep_stos"
16101 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16102 (set (match_operand 0 "register_operand" "")
16103 (match_operand 4 "" ""))
16104 (set (match_operand 2 "memory_operand" "") (const_int 0))
16105 (use (match_operand 3 "register_operand" ""))
16106 (use (match_dup 1))])]
16108 "ix86_current_function_needs_cld = 1;")
16110 (define_insn "*rep_stosdi_rex64"
16111 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16112 (set (match_operand:DI 0 "register_operand" "=D")
16113 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16115 (match_operand:DI 3 "register_operand" "0")))
16116 (set (mem:BLK (match_dup 3))
16118 (use (match_operand:DI 2 "register_operand" "a"))
16119 (use (match_dup 4))]
16122 [(set_attr "type" "str")
16123 (set_attr "prefix_rep" "1")
16124 (set_attr "memory" "store")
16125 (set_attr "mode" "DI")])
16127 (define_insn "*rep_stossi"
16128 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16129 (set (match_operand:SI 0 "register_operand" "=D")
16130 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16132 (match_operand:SI 3 "register_operand" "0")))
16133 (set (mem:BLK (match_dup 3))
16135 (use (match_operand:SI 2 "register_operand" "a"))
16136 (use (match_dup 4))]
16139 [(set_attr "type" "str")
16140 (set_attr "prefix_rep" "1")
16141 (set_attr "memory" "store")
16142 (set_attr "mode" "SI")])
16144 (define_insn "*rep_stossi_rex64"
16145 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16146 (set (match_operand:DI 0 "register_operand" "=D")
16147 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16149 (match_operand:DI 3 "register_operand" "0")))
16150 (set (mem:BLK (match_dup 3))
16152 (use (match_operand:SI 2 "register_operand" "a"))
16153 (use (match_dup 4))]
16156 [(set_attr "type" "str")
16157 (set_attr "prefix_rep" "1")
16158 (set_attr "memory" "store")
16159 (set_attr "mode" "SI")])
16161 (define_insn "*rep_stosqi"
16162 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16163 (set (match_operand:SI 0 "register_operand" "=D")
16164 (plus:SI (match_operand:SI 3 "register_operand" "0")
16165 (match_operand:SI 4 "register_operand" "1")))
16166 (set (mem:BLK (match_dup 3))
16168 (use (match_operand:QI 2 "register_operand" "a"))
16169 (use (match_dup 4))]
16172 [(set_attr "type" "str")
16173 (set_attr "prefix_rep" "1")
16174 (set_attr "memory" "store")
16175 (set_attr "mode" "QI")])
16177 (define_insn "*rep_stosqi_rex64"
16178 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16179 (set (match_operand:DI 0 "register_operand" "=D")
16180 (plus:DI (match_operand:DI 3 "register_operand" "0")
16181 (match_operand:DI 4 "register_operand" "1")))
16182 (set (mem:BLK (match_dup 3))
16184 (use (match_operand:QI 2 "register_operand" "a"))
16185 (use (match_dup 4))]
16188 [(set_attr "type" "str")
16189 (set_attr "prefix_rep" "1")
16190 (set_attr "memory" "store")
16191 (set_attr "prefix_rex" "0")
16192 (set_attr "mode" "QI")])
16194 (define_expand "cmpstrnsi"
16195 [(set (match_operand:SI 0 "register_operand" "")
16196 (compare:SI (match_operand:BLK 1 "general_operand" "")
16197 (match_operand:BLK 2 "general_operand" "")))
16198 (use (match_operand 3 "general_operand" ""))
16199 (use (match_operand 4 "immediate_operand" ""))]
16202 rtx addr1, addr2, out, outlow, count, countreg, align;
16204 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16207 /* Can't use this if the user has appropriated esi or edi. */
16208 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
16213 out = gen_reg_rtx (SImode);
16215 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16216 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16217 if (addr1 != XEXP (operands[1], 0))
16218 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16219 if (addr2 != XEXP (operands[2], 0))
16220 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16222 count = operands[3];
16223 countreg = ix86_zero_extend_to_Pmode (count);
16225 /* %%% Iff we are testing strict equality, we can use known alignment
16226 to good advantage. This may be possible with combine, particularly
16227 once cc0 is dead. */
16228 align = operands[4];
16230 if (CONST_INT_P (count))
16232 if (INTVAL (count) == 0)
16234 emit_move_insn (operands[0], const0_rtx);
16237 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16238 operands[1], operands[2]));
16242 rtx (*cmp_insn)(rtx, rtx);
16245 cmp_insn = gen_cmpdi_1;
16247 cmp_insn = gen_cmpsi_1;
16248 emit_insn (cmp_insn (countreg, countreg));
16249 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16250 operands[1], operands[2]));
16253 outlow = gen_lowpart (QImode, out);
16254 emit_insn (gen_cmpintqi (outlow));
16255 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16257 if (operands[0] != out)
16258 emit_move_insn (operands[0], out);
16263 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16265 (define_expand "cmpintqi"
16266 [(set (match_dup 1)
16267 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16269 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16270 (parallel [(set (match_operand:QI 0 "register_operand" "")
16271 (minus:QI (match_dup 1)
16273 (clobber (reg:CC FLAGS_REG))])]
16275 "operands[1] = gen_reg_rtx (QImode);
16276 operands[2] = gen_reg_rtx (QImode);")
16278 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16279 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16281 (define_expand "cmpstrnqi_nz_1"
16282 [(parallel [(set (reg:CC FLAGS_REG)
16283 (compare:CC (match_operand 4 "memory_operand" "")
16284 (match_operand 5 "memory_operand" "")))
16285 (use (match_operand 2 "register_operand" ""))
16286 (use (match_operand:SI 3 "immediate_operand" ""))
16287 (clobber (match_operand 0 "register_operand" ""))
16288 (clobber (match_operand 1 "register_operand" ""))
16289 (clobber (match_dup 2))])]
16291 "ix86_current_function_needs_cld = 1;")
16293 (define_insn "*cmpstrnqi_nz_1"
16294 [(set (reg:CC FLAGS_REG)
16295 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16296 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16297 (use (match_operand:SI 6 "register_operand" "2"))
16298 (use (match_operand:SI 3 "immediate_operand" "i"))
16299 (clobber (match_operand:SI 0 "register_operand" "=S"))
16300 (clobber (match_operand:SI 1 "register_operand" "=D"))
16301 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16304 [(set_attr "type" "str")
16305 (set_attr "mode" "QI")
16306 (set_attr "prefix_rep" "1")])
16308 (define_insn "*cmpstrnqi_nz_rex_1"
16309 [(set (reg:CC FLAGS_REG)
16310 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16311 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16312 (use (match_operand:DI 6 "register_operand" "2"))
16313 (use (match_operand:SI 3 "immediate_operand" "i"))
16314 (clobber (match_operand:DI 0 "register_operand" "=S"))
16315 (clobber (match_operand:DI 1 "register_operand" "=D"))
16316 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16319 [(set_attr "type" "str")
16320 (set_attr "mode" "QI")
16321 (set_attr "prefix_rex" "0")
16322 (set_attr "prefix_rep" "1")])
16324 ;; The same, but the count is not known to not be zero.
16326 (define_expand "cmpstrnqi_1"
16327 [(parallel [(set (reg:CC FLAGS_REG)
16328 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16330 (compare:CC (match_operand 4 "memory_operand" "")
16331 (match_operand 5 "memory_operand" ""))
16333 (use (match_operand:SI 3 "immediate_operand" ""))
16334 (use (reg:CC FLAGS_REG))
16335 (clobber (match_operand 0 "register_operand" ""))
16336 (clobber (match_operand 1 "register_operand" ""))
16337 (clobber (match_dup 2))])]
16339 "ix86_current_function_needs_cld = 1;")
16341 (define_insn "*cmpstrnqi_1"
16342 [(set (reg:CC FLAGS_REG)
16343 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16345 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16346 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16348 (use (match_operand:SI 3 "immediate_operand" "i"))
16349 (use (reg:CC FLAGS_REG))
16350 (clobber (match_operand:SI 0 "register_operand" "=S"))
16351 (clobber (match_operand:SI 1 "register_operand" "=D"))
16352 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16355 [(set_attr "type" "str")
16356 (set_attr "mode" "QI")
16357 (set_attr "prefix_rep" "1")])
16359 (define_insn "*cmpstrnqi_rex_1"
16360 [(set (reg:CC FLAGS_REG)
16361 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16363 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16364 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16366 (use (match_operand:SI 3 "immediate_operand" "i"))
16367 (use (reg:CC FLAGS_REG))
16368 (clobber (match_operand:DI 0 "register_operand" "=S"))
16369 (clobber (match_operand:DI 1 "register_operand" "=D"))
16370 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16373 [(set_attr "type" "str")
16374 (set_attr "mode" "QI")
16375 (set_attr "prefix_rex" "0")
16376 (set_attr "prefix_rep" "1")])
16378 (define_expand "strlensi"
16379 [(set (match_operand:SI 0 "register_operand" "")
16380 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16381 (match_operand:QI 2 "immediate_operand" "")
16382 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16385 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16391 (define_expand "strlendi"
16392 [(set (match_operand:DI 0 "register_operand" "")
16393 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16394 (match_operand:QI 2 "immediate_operand" "")
16395 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16398 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16404 (define_expand "strlenqi_1"
16405 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16406 (clobber (match_operand 1 "register_operand" ""))
16407 (clobber (reg:CC FLAGS_REG))])]
16409 "ix86_current_function_needs_cld = 1;")
16411 (define_insn "*strlenqi_1"
16412 [(set (match_operand:SI 0 "register_operand" "=&c")
16413 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16414 (match_operand:QI 2 "register_operand" "a")
16415 (match_operand:SI 3 "immediate_operand" "i")
16416 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16417 (clobber (match_operand:SI 1 "register_operand" "=D"))
16418 (clobber (reg:CC FLAGS_REG))]
16421 [(set_attr "type" "str")
16422 (set_attr "mode" "QI")
16423 (set_attr "prefix_rep" "1")])
16425 (define_insn "*strlenqi_rex_1"
16426 [(set (match_operand:DI 0 "register_operand" "=&c")
16427 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16428 (match_operand:QI 2 "register_operand" "a")
16429 (match_operand:DI 3 "immediate_operand" "i")
16430 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16431 (clobber (match_operand:DI 1 "register_operand" "=D"))
16432 (clobber (reg:CC FLAGS_REG))]
16435 [(set_attr "type" "str")
16436 (set_attr "mode" "QI")
16437 (set_attr "prefix_rex" "0")
16438 (set_attr "prefix_rep" "1")])
16440 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16441 ;; handled in combine, but it is not currently up to the task.
16442 ;; When used for their truth value, the cmpstrn* expanders generate
16451 ;; The intermediate three instructions are unnecessary.
16453 ;; This one handles cmpstrn*_nz_1...
16456 (set (reg:CC FLAGS_REG)
16457 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16458 (mem:BLK (match_operand 5 "register_operand" ""))))
16459 (use (match_operand 6 "register_operand" ""))
16460 (use (match_operand:SI 3 "immediate_operand" ""))
16461 (clobber (match_operand 0 "register_operand" ""))
16462 (clobber (match_operand 1 "register_operand" ""))
16463 (clobber (match_operand 2 "register_operand" ""))])
16464 (set (match_operand:QI 7 "register_operand" "")
16465 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16466 (set (match_operand:QI 8 "register_operand" "")
16467 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16468 (set (reg FLAGS_REG)
16469 (compare (match_dup 7) (match_dup 8)))
16471 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16473 (set (reg:CC FLAGS_REG)
16474 (compare:CC (mem:BLK (match_dup 4))
16475 (mem:BLK (match_dup 5))))
16476 (use (match_dup 6))
16477 (use (match_dup 3))
16478 (clobber (match_dup 0))
16479 (clobber (match_dup 1))
16480 (clobber (match_dup 2))])]
16483 ;; ...and this one handles cmpstrn*_1.
16486 (set (reg:CC FLAGS_REG)
16487 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16489 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16490 (mem:BLK (match_operand 5 "register_operand" "")))
16492 (use (match_operand:SI 3 "immediate_operand" ""))
16493 (use (reg:CC FLAGS_REG))
16494 (clobber (match_operand 0 "register_operand" ""))
16495 (clobber (match_operand 1 "register_operand" ""))
16496 (clobber (match_operand 2 "register_operand" ""))])
16497 (set (match_operand:QI 7 "register_operand" "")
16498 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16499 (set (match_operand:QI 8 "register_operand" "")
16500 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16501 (set (reg FLAGS_REG)
16502 (compare (match_dup 7) (match_dup 8)))
16504 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16506 (set (reg:CC FLAGS_REG)
16507 (if_then_else:CC (ne (match_dup 6)
16509 (compare:CC (mem:BLK (match_dup 4))
16510 (mem:BLK (match_dup 5)))
16512 (use (match_dup 3))
16513 (use (reg:CC FLAGS_REG))
16514 (clobber (match_dup 0))
16515 (clobber (match_dup 1))
16516 (clobber (match_dup 2))])]
16521 ;; Conditional move instructions.
16523 (define_expand "mov<mode>cc"
16524 [(set (match_operand:SWIM 0 "register_operand" "")
16525 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16526 (match_operand:SWIM 2 "general_operand" "")
16527 (match_operand:SWIM 3 "general_operand" "")))]
16529 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16531 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16532 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16533 ;; So just document what we're doing explicitly.
16535 (define_expand "x86_mov<mode>cc_0_m1"
16537 [(set (match_operand:SWI48 0 "register_operand" "")
16538 (if_then_else:SWI48
16539 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16540 [(match_operand 1 "flags_reg_operand" "")
16544 (clobber (reg:CC FLAGS_REG))])]
16548 (define_insn "*x86_mov<mode>cc_0_m1"
16549 [(set (match_operand:SWI48 0 "register_operand" "=r")
16550 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16551 [(reg FLAGS_REG) (const_int 0)])
16554 (clobber (reg:CC FLAGS_REG))]
16556 "sbb{<imodesuffix>}\t%0, %0"
16557 ; Since we don't have the proper number of operands for an alu insn,
16558 ; fill in all the blanks.
16559 [(set_attr "type" "alu")
16560 (set_attr "use_carry" "1")
16561 (set_attr "pent_pair" "pu")
16562 (set_attr "memory" "none")
16563 (set_attr "imm_disp" "false")
16564 (set_attr "mode" "<MODE>")
16565 (set_attr "length_immediate" "0")])
16567 (define_insn "*x86_mov<mode>cc_0_m1_se"
16568 [(set (match_operand:SWI48 0 "register_operand" "=r")
16569 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16570 [(reg FLAGS_REG) (const_int 0)])
16573 (clobber (reg:CC FLAGS_REG))]
16575 "sbb{<imodesuffix>}\t%0, %0"
16576 [(set_attr "type" "alu")
16577 (set_attr "use_carry" "1")
16578 (set_attr "pent_pair" "pu")
16579 (set_attr "memory" "none")
16580 (set_attr "imm_disp" "false")
16581 (set_attr "mode" "<MODE>")
16582 (set_attr "length_immediate" "0")])
16584 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16585 [(set (match_operand:SWI48 0 "register_operand" "=r")
16586 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16587 [(reg FLAGS_REG) (const_int 0)])))]
16589 "sbb{<imodesuffix>}\t%0, %0"
16590 [(set_attr "type" "alu")
16591 (set_attr "use_carry" "1")
16592 (set_attr "pent_pair" "pu")
16593 (set_attr "memory" "none")
16594 (set_attr "imm_disp" "false")
16595 (set_attr "mode" "<MODE>")
16596 (set_attr "length_immediate" "0")])
16598 (define_insn "*mov<mode>cc_noc"
16599 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16600 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16601 [(reg FLAGS_REG) (const_int 0)])
16602 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16603 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16604 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16606 cmov%O2%C1\t{%2, %0|%0, %2}
16607 cmov%O2%c1\t{%3, %0|%0, %3}"
16608 [(set_attr "type" "icmov")
16609 (set_attr "mode" "<MODE>")])
16611 (define_insn_and_split "*movqicc_noc"
16612 [(set (match_operand:QI 0 "register_operand" "=r,r")
16613 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16614 [(match_operand 4 "flags_reg_operand" "")
16616 (match_operand:QI 2 "register_operand" "r,0")
16617 (match_operand:QI 3 "register_operand" "0,r")))]
16618 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16620 "&& reload_completed"
16621 [(set (match_dup 0)
16622 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16625 "operands[0] = gen_lowpart (SImode, operands[0]);
16626 operands[2] = gen_lowpart (SImode, operands[2]);
16627 operands[3] = gen_lowpart (SImode, operands[3]);"
16628 [(set_attr "type" "icmov")
16629 (set_attr "mode" "SI")])
16631 (define_expand "mov<mode>cc"
16632 [(set (match_operand:X87MODEF 0 "register_operand" "")
16633 (if_then_else:X87MODEF
16634 (match_operand 1 "ix86_fp_comparison_operator" "")
16635 (match_operand:X87MODEF 2 "register_operand" "")
16636 (match_operand:X87MODEF 3 "register_operand" "")))]
16637 "(TARGET_80387 && TARGET_CMOVE)
16638 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16639 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16641 (define_insn "*movsfcc_1_387"
16642 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16643 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16644 [(reg FLAGS_REG) (const_int 0)])
16645 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16646 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16647 "TARGET_80387 && TARGET_CMOVE
16648 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16650 fcmov%F1\t{%2, %0|%0, %2}
16651 fcmov%f1\t{%3, %0|%0, %3}
16652 cmov%O2%C1\t{%2, %0|%0, %2}
16653 cmov%O2%c1\t{%3, %0|%0, %3}"
16654 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16655 (set_attr "mode" "SF,SF,SI,SI")])
16657 (define_insn "*movdfcc_1"
16658 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16659 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16660 [(reg FLAGS_REG) (const_int 0)])
16661 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16662 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16663 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16664 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16666 fcmov%F1\t{%2, %0|%0, %2}
16667 fcmov%f1\t{%3, %0|%0, %3}
16670 [(set_attr "type" "fcmov,fcmov,multi,multi")
16671 (set_attr "mode" "DF")])
16673 (define_insn "*movdfcc_1_rex64"
16674 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16675 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16676 [(reg FLAGS_REG) (const_int 0)])
16677 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16678 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16679 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16680 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16682 fcmov%F1\t{%2, %0|%0, %2}
16683 fcmov%f1\t{%3, %0|%0, %3}
16684 cmov%O2%C1\t{%2, %0|%0, %2}
16685 cmov%O2%c1\t{%3, %0|%0, %3}"
16686 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16687 (set_attr "mode" "DF")])
16690 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16691 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16692 [(match_operand 4 "flags_reg_operand" "")
16694 (match_operand:DF 2 "nonimmediate_operand" "")
16695 (match_operand:DF 3 "nonimmediate_operand" "")))]
16696 "!TARGET_64BIT && reload_completed"
16697 [(set (match_dup 2)
16698 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16702 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16706 split_di (&operands[2], 2, &operands[5], &operands[7]);
16707 split_di (&operands[0], 1, &operands[2], &operands[3]);
16710 (define_insn "*movxfcc_1"
16711 [(set (match_operand:XF 0 "register_operand" "=f,f")
16712 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16713 [(reg FLAGS_REG) (const_int 0)])
16714 (match_operand:XF 2 "register_operand" "f,0")
16715 (match_operand:XF 3 "register_operand" "0,f")))]
16716 "TARGET_80387 && TARGET_CMOVE"
16718 fcmov%F1\t{%2, %0|%0, %2}
16719 fcmov%f1\t{%3, %0|%0, %3}"
16720 [(set_attr "type" "fcmov")
16721 (set_attr "mode" "XF")])
16723 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16724 ;; the scalar versions to have only XMM registers as operands.
16726 ;; XOP conditional move
16727 (define_insn "*xop_pcmov_<mode>"
16728 [(set (match_operand:MODEF 0 "register_operand" "=x")
16729 (if_then_else:MODEF
16730 (match_operand:MODEF 1 "register_operand" "x")
16731 (match_operand:MODEF 2 "register_operand" "x")
16732 (match_operand:MODEF 3 "register_operand" "x")))]
16734 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16735 [(set_attr "type" "sse4arg")])
16737 ;; These versions of the min/max patterns are intentionally ignorant of
16738 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16739 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16740 ;; are undefined in this condition, we're certain this is correct.
16742 (define_insn "*avx_<code><mode>3"
16743 [(set (match_operand:MODEF 0 "register_operand" "=x")
16745 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16746 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16747 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16748 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16749 [(set_attr "type" "sseadd")
16750 (set_attr "prefix" "vex")
16751 (set_attr "mode" "<MODE>")])
16753 (define_insn "<code><mode>3"
16754 [(set (match_operand:MODEF 0 "register_operand" "=x")
16756 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16757 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16758 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16759 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16760 [(set_attr "type" "sseadd")
16761 (set_attr "mode" "<MODE>")])
16763 ;; These versions of the min/max patterns implement exactly the operations
16764 ;; min = (op1 < op2 ? op1 : op2)
16765 ;; max = (!(op1 < op2) ? op1 : op2)
16766 ;; Their operands are not commutative, and thus they may be used in the
16767 ;; presence of -0.0 and NaN.
16769 (define_insn "*avx_ieee_smin<mode>3"
16770 [(set (match_operand:MODEF 0 "register_operand" "=x")
16772 [(match_operand:MODEF 1 "register_operand" "x")
16773 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16775 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16776 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16777 [(set_attr "type" "sseadd")
16778 (set_attr "prefix" "vex")
16779 (set_attr "mode" "<MODE>")])
16781 (define_insn "*ieee_smin<mode>3"
16782 [(set (match_operand:MODEF 0 "register_operand" "=x")
16784 [(match_operand:MODEF 1 "register_operand" "0")
16785 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16787 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16788 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16789 [(set_attr "type" "sseadd")
16790 (set_attr "mode" "<MODE>")])
16792 (define_insn "*avx_ieee_smax<mode>3"
16793 [(set (match_operand:MODEF 0 "register_operand" "=x")
16795 [(match_operand:MODEF 1 "register_operand" "0")
16796 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16798 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16799 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16800 [(set_attr "type" "sseadd")
16801 (set_attr "prefix" "vex")
16802 (set_attr "mode" "<MODE>")])
16804 (define_insn "*ieee_smax<mode>3"
16805 [(set (match_operand:MODEF 0 "register_operand" "=x")
16807 [(match_operand:MODEF 1 "register_operand" "0")
16808 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16810 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16811 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16812 [(set_attr "type" "sseadd")
16813 (set_attr "mode" "<MODE>")])
16815 ;; Make two stack loads independent:
16817 ;; fld %st(0) -> fld bb
16818 ;; fmul bb fmul %st(1), %st
16820 ;; Actually we only match the last two instructions for simplicity.
16822 [(set (match_operand 0 "fp_register_operand" "")
16823 (match_operand 1 "fp_register_operand" ""))
16825 (match_operator 2 "binary_fp_operator"
16827 (match_operand 3 "memory_operand" "")]))]
16828 "REGNO (operands[0]) != REGNO (operands[1])"
16829 [(set (match_dup 0) (match_dup 3))
16830 (set (match_dup 0) (match_dup 4))]
16832 ;; The % modifier is not operational anymore in peephole2's, so we have to
16833 ;; swap the operands manually in the case of addition and multiplication.
16834 "if (COMMUTATIVE_ARITH_P (operands[2]))
16835 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16836 operands[0], operands[1]);
16838 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16839 operands[1], operands[0]);")
16841 ;; Conditional addition patterns
16842 (define_expand "add<mode>cc"
16843 [(match_operand:SWI 0 "register_operand" "")
16844 (match_operand 1 "comparison_operator" "")
16845 (match_operand:SWI 2 "register_operand" "")
16846 (match_operand:SWI 3 "const_int_operand" "")]
16848 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16851 ;; Misc patterns (?)
16853 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16854 ;; Otherwise there will be nothing to keep
16856 ;; [(set (reg ebp) (reg esp))]
16857 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16858 ;; (clobber (eflags)]
16859 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16861 ;; in proper program order.
16862 (define_insn "pro_epilogue_adjust_stack_1"
16863 [(set (match_operand:SI 0 "register_operand" "=r,r")
16864 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16865 (match_operand:SI 2 "immediate_operand" "i,i")))
16866 (clobber (reg:CC FLAGS_REG))
16867 (clobber (mem:BLK (scratch)))]
16870 switch (get_attr_type (insn))
16873 return "mov{l}\t{%1, %0|%0, %1}";
16876 if (CONST_INT_P (operands[2])
16877 && (INTVAL (operands[2]) == 128
16878 || (INTVAL (operands[2]) < 0
16879 && INTVAL (operands[2]) != -128)))
16881 operands[2] = GEN_INT (-INTVAL (operands[2]));
16882 return "sub{l}\t{%2, %0|%0, %2}";
16884 return "add{l}\t{%2, %0|%0, %2}";
16887 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16888 return "lea{l}\t{%a2, %0|%0, %a2}";
16891 gcc_unreachable ();
16894 [(set (attr "type")
16895 (cond [(and (eq_attr "alternative" "0")
16896 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16897 (const_string "alu")
16898 (match_operand:SI 2 "const0_operand" "")
16899 (const_string "imov")
16901 (const_string "lea")))
16902 (set (attr "length_immediate")
16903 (cond [(eq_attr "type" "imov")
16905 (and (eq_attr "type" "alu")
16906 (match_operand 2 "const128_operand" ""))
16909 (const_string "*")))
16910 (set_attr "mode" "SI")])
16912 (define_insn "pro_epilogue_adjust_stack_rex64"
16913 [(set (match_operand:DI 0 "register_operand" "=r,r")
16914 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16915 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16916 (clobber (reg:CC FLAGS_REG))
16917 (clobber (mem:BLK (scratch)))]
16920 switch (get_attr_type (insn))
16923 return "mov{q}\t{%1, %0|%0, %1}";
16926 if (CONST_INT_P (operands[2])
16927 /* Avoid overflows. */
16928 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
16929 && (INTVAL (operands[2]) == 128
16930 || (INTVAL (operands[2]) < 0
16931 && INTVAL (operands[2]) != -128)))
16933 operands[2] = GEN_INT (-INTVAL (operands[2]));
16934 return "sub{q}\t{%2, %0|%0, %2}";
16936 return "add{q}\t{%2, %0|%0, %2}";
16939 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16940 return "lea{q}\t{%a2, %0|%0, %a2}";
16943 gcc_unreachable ();
16946 [(set (attr "type")
16947 (cond [(and (eq_attr "alternative" "0")
16948 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16949 (const_string "alu")
16950 (match_operand:DI 2 "const0_operand" "")
16951 (const_string "imov")
16953 (const_string "lea")))
16954 (set (attr "length_immediate")
16955 (cond [(eq_attr "type" "imov")
16957 (and (eq_attr "type" "alu")
16958 (match_operand 2 "const128_operand" ""))
16961 (const_string "*")))
16962 (set_attr "mode" "DI")])
16964 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16965 [(set (match_operand:DI 0 "register_operand" "=r,r")
16966 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16967 (match_operand:DI 3 "immediate_operand" "i,i")))
16968 (use (match_operand:DI 2 "register_operand" "r,r"))
16969 (clobber (reg:CC FLAGS_REG))
16970 (clobber (mem:BLK (scratch)))]
16973 switch (get_attr_type (insn))
16976 return "add{q}\t{%2, %0|%0, %2}";
16979 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16980 return "lea{q}\t{%a2, %0|%0, %a2}";
16983 gcc_unreachable ();
16986 [(set_attr "type" "alu,lea")
16987 (set_attr "mode" "DI")])
16989 (define_insn "allocate_stack_worker_32"
16990 [(set (match_operand:SI 0 "register_operand" "=a")
16991 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16992 UNSPECV_STACK_PROBE))
16993 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16994 (clobber (reg:CC FLAGS_REG))]
16995 "!TARGET_64BIT && TARGET_STACK_PROBE"
16997 [(set_attr "type" "multi")
16998 (set_attr "length" "5")])
17000 (define_insn "allocate_stack_worker_64"
17001 [(set (match_operand:DI 0 "register_operand" "=a")
17002 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
17003 UNSPECV_STACK_PROBE))
17004 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
17005 (clobber (reg:DI R10_REG))
17006 (clobber (reg:DI R11_REG))
17007 (clobber (reg:CC FLAGS_REG))]
17008 "TARGET_64BIT && TARGET_STACK_PROBE"
17010 [(set_attr "type" "multi")
17011 (set_attr "length" "5")])
17013 (define_expand "allocate_stack"
17014 [(match_operand 0 "register_operand" "")
17015 (match_operand 1 "general_operand" "")]
17016 "TARGET_STACK_PROBE"
17020 #ifndef CHECK_STACK_LIMIT
17021 #define CHECK_STACK_LIMIT 0
17024 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17025 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17027 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
17028 stack_pointer_rtx, 0, OPTAB_DIRECT);
17029 if (x != stack_pointer_rtx)
17030 emit_move_insn (stack_pointer_rtx, x);
17034 x = copy_to_mode_reg (Pmode, operands[1]);
17036 x = gen_allocate_stack_worker_64 (x, x);
17038 x = gen_allocate_stack_worker_32 (x, x);
17042 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17046 ;; Use IOR for stack probes, this is shorter.
17047 (define_expand "probe_stack"
17048 [(match_operand 0 "memory_operand" "")]
17051 if (GET_MODE (operands[0]) == DImode)
17052 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
17054 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
17058 (define_expand "builtin_setjmp_receiver"
17059 [(label_ref (match_operand 0 "" ""))]
17060 "!TARGET_64BIT && flag_pic"
17066 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
17067 rtx label_rtx = gen_label_rtx ();
17068 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17069 xops[0] = xops[1] = picreg;
17070 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17071 ix86_expand_binary_operator (MINUS, SImode, xops);
17075 emit_insn (gen_set_got (pic_offset_table_rtx));
17079 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17082 [(set (match_operand 0 "register_operand" "")
17083 (match_operator 3 "promotable_binary_operator"
17084 [(match_operand 1 "register_operand" "")
17085 (match_operand 2 "aligned_operand" "")]))
17086 (clobber (reg:CC FLAGS_REG))]
17087 "! TARGET_PARTIAL_REG_STALL && reload_completed
17088 && ((GET_MODE (operands[0]) == HImode
17089 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17090 /* ??? next two lines just !satisfies_constraint_K (...) */
17091 || !CONST_INT_P (operands[2])
17092 || satisfies_constraint_K (operands[2])))
17093 || (GET_MODE (operands[0]) == QImode
17094 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17095 [(parallel [(set (match_dup 0)
17096 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17097 (clobber (reg:CC FLAGS_REG))])]
17098 "operands[0] = gen_lowpart (SImode, operands[0]);
17099 operands[1] = gen_lowpart (SImode, operands[1]);
17100 if (GET_CODE (operands[3]) != ASHIFT)
17101 operands[2] = gen_lowpart (SImode, operands[2]);
17102 PUT_MODE (operands[3], SImode);")
17104 ; Promote the QImode tests, as i386 has encoding of the AND
17105 ; instruction with 32-bit sign-extended immediate and thus the
17106 ; instruction size is unchanged, except in the %eax case for
17107 ; which it is increased by one byte, hence the ! optimize_size.
17109 [(set (match_operand 0 "flags_reg_operand" "")
17110 (match_operator 2 "compare_operator"
17111 [(and (match_operand 3 "aligned_operand" "")
17112 (match_operand 4 "const_int_operand" ""))
17114 (set (match_operand 1 "register_operand" "")
17115 (and (match_dup 3) (match_dup 4)))]
17116 "! TARGET_PARTIAL_REG_STALL && reload_completed
17117 && optimize_insn_for_speed_p ()
17118 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17119 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17120 /* Ensure that the operand will remain sign-extended immediate. */
17121 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17122 [(parallel [(set (match_dup 0)
17123 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17126 (and:SI (match_dup 3) (match_dup 4)))])]
17129 = gen_int_mode (INTVAL (operands[4])
17130 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17131 operands[1] = gen_lowpart (SImode, operands[1]);
17132 operands[3] = gen_lowpart (SImode, operands[3]);
17135 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17136 ; the TEST instruction with 32-bit sign-extended immediate and thus
17137 ; the instruction size would at least double, which is not what we
17138 ; want even with ! optimize_size.
17140 [(set (match_operand 0 "flags_reg_operand" "")
17141 (match_operator 1 "compare_operator"
17142 [(and (match_operand:HI 2 "aligned_operand" "")
17143 (match_operand:HI 3 "const_int_operand" ""))
17145 "! TARGET_PARTIAL_REG_STALL && reload_completed
17146 && ! TARGET_FAST_PREFIX
17147 && optimize_insn_for_speed_p ()
17148 /* Ensure that the operand will remain sign-extended immediate. */
17149 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17150 [(set (match_dup 0)
17151 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17155 = gen_int_mode (INTVAL (operands[3])
17156 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17157 operands[2] = gen_lowpart (SImode, operands[2]);
17161 [(set (match_operand 0 "register_operand" "")
17162 (neg (match_operand 1 "register_operand" "")))
17163 (clobber (reg:CC FLAGS_REG))]
17164 "! TARGET_PARTIAL_REG_STALL && reload_completed
17165 && (GET_MODE (operands[0]) == HImode
17166 || (GET_MODE (operands[0]) == QImode
17167 && (TARGET_PROMOTE_QImode
17168 || optimize_insn_for_size_p ())))"
17169 [(parallel [(set (match_dup 0)
17170 (neg:SI (match_dup 1)))
17171 (clobber (reg:CC FLAGS_REG))])]
17172 "operands[0] = gen_lowpart (SImode, operands[0]);
17173 operands[1] = gen_lowpart (SImode, operands[1]);")
17176 [(set (match_operand 0 "register_operand" "")
17177 (not (match_operand 1 "register_operand" "")))]
17178 "! TARGET_PARTIAL_REG_STALL && reload_completed
17179 && (GET_MODE (operands[0]) == HImode
17180 || (GET_MODE (operands[0]) == QImode
17181 && (TARGET_PROMOTE_QImode
17182 || optimize_insn_for_size_p ())))"
17183 [(set (match_dup 0)
17184 (not:SI (match_dup 1)))]
17185 "operands[0] = gen_lowpart (SImode, operands[0]);
17186 operands[1] = gen_lowpart (SImode, operands[1]);")
17189 [(set (match_operand 0 "register_operand" "")
17190 (if_then_else (match_operator 1 "comparison_operator"
17191 [(reg FLAGS_REG) (const_int 0)])
17192 (match_operand 2 "register_operand" "")
17193 (match_operand 3 "register_operand" "")))]
17194 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17195 && (GET_MODE (operands[0]) == HImode
17196 || (GET_MODE (operands[0]) == QImode
17197 && (TARGET_PROMOTE_QImode
17198 || optimize_insn_for_size_p ())))"
17199 [(set (match_dup 0)
17200 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17201 "operands[0] = gen_lowpart (SImode, operands[0]);
17202 operands[2] = gen_lowpart (SImode, operands[2]);
17203 operands[3] = gen_lowpart (SImode, operands[3]);")
17206 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17207 ;; transform a complex memory operation into two memory to register operations.
17209 ;; Don't push memory operands
17211 [(set (match_operand:SI 0 "push_operand" "")
17212 (match_operand:SI 1 "memory_operand" ""))
17213 (match_scratch:SI 2 "r")]
17214 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17215 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17216 [(set (match_dup 2) (match_dup 1))
17217 (set (match_dup 0) (match_dup 2))]
17221 [(set (match_operand:DI 0 "push_operand" "")
17222 (match_operand:DI 1 "memory_operand" ""))
17223 (match_scratch:DI 2 "r")]
17224 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17225 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17226 [(set (match_dup 2) (match_dup 1))
17227 (set (match_dup 0) (match_dup 2))]
17230 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17233 [(set (match_operand:SF 0 "push_operand" "")
17234 (match_operand:SF 1 "memory_operand" ""))
17235 (match_scratch:SF 2 "r")]
17236 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17237 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17238 [(set (match_dup 2) (match_dup 1))
17239 (set (match_dup 0) (match_dup 2))]
17243 [(set (match_operand:HI 0 "push_operand" "")
17244 (match_operand:HI 1 "memory_operand" ""))
17245 (match_scratch:HI 2 "r")]
17246 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17247 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17248 [(set (match_dup 2) (match_dup 1))
17249 (set (match_dup 0) (match_dup 2))]
17253 [(set (match_operand:QI 0 "push_operand" "")
17254 (match_operand:QI 1 "memory_operand" ""))
17255 (match_scratch:QI 2 "q")]
17256 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17257 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17258 [(set (match_dup 2) (match_dup 1))
17259 (set (match_dup 0) (match_dup 2))]
17262 ;; Don't move an immediate directly to memory when the instruction
17265 [(match_scratch:SI 1 "r")
17266 (set (match_operand:SI 0 "memory_operand" "")
17268 "optimize_insn_for_speed_p ()
17269 && ! TARGET_USE_MOV0
17270 && TARGET_SPLIT_LONG_MOVES
17271 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17272 && peep2_regno_dead_p (0, FLAGS_REG)"
17273 [(parallel [(set (match_dup 1) (const_int 0))
17274 (clobber (reg:CC FLAGS_REG))])
17275 (set (match_dup 0) (match_dup 1))]
17279 [(match_scratch:HI 1 "r")
17280 (set (match_operand:HI 0 "memory_operand" "")
17282 "optimize_insn_for_speed_p ()
17283 && ! TARGET_USE_MOV0
17284 && TARGET_SPLIT_LONG_MOVES
17285 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17286 && peep2_regno_dead_p (0, FLAGS_REG)"
17287 [(parallel [(set (match_dup 2) (const_int 0))
17288 (clobber (reg:CC FLAGS_REG))])
17289 (set (match_dup 0) (match_dup 1))]
17290 "operands[2] = gen_lowpart (SImode, operands[1]);")
17293 [(match_scratch:QI 1 "q")
17294 (set (match_operand:QI 0 "memory_operand" "")
17296 "optimize_insn_for_speed_p ()
17297 && ! TARGET_USE_MOV0
17298 && TARGET_SPLIT_LONG_MOVES
17299 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17300 && peep2_regno_dead_p (0, FLAGS_REG)"
17301 [(parallel [(set (match_dup 2) (const_int 0))
17302 (clobber (reg:CC FLAGS_REG))])
17303 (set (match_dup 0) (match_dup 1))]
17304 "operands[2] = gen_lowpart (SImode, operands[1]);")
17307 [(match_scratch:SI 2 "r")
17308 (set (match_operand:SI 0 "memory_operand" "")
17309 (match_operand:SI 1 "immediate_operand" ""))]
17310 "optimize_insn_for_speed_p ()
17311 && TARGET_SPLIT_LONG_MOVES
17312 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17313 [(set (match_dup 2) (match_dup 1))
17314 (set (match_dup 0) (match_dup 2))]
17318 [(match_scratch:HI 2 "r")
17319 (set (match_operand:HI 0 "memory_operand" "")
17320 (match_operand:HI 1 "immediate_operand" ""))]
17321 "optimize_insn_for_speed_p ()
17322 && TARGET_SPLIT_LONG_MOVES
17323 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17324 [(set (match_dup 2) (match_dup 1))
17325 (set (match_dup 0) (match_dup 2))]
17329 [(match_scratch:QI 2 "q")
17330 (set (match_operand:QI 0 "memory_operand" "")
17331 (match_operand:QI 1 "immediate_operand" ""))]
17332 "optimize_insn_for_speed_p ()
17333 && TARGET_SPLIT_LONG_MOVES
17334 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17335 [(set (match_dup 2) (match_dup 1))
17336 (set (match_dup 0) (match_dup 2))]
17339 ;; Don't compare memory with zero, load and use a test instead.
17341 [(set (match_operand 0 "flags_reg_operand" "")
17342 (match_operator 1 "compare_operator"
17343 [(match_operand:SI 2 "memory_operand" "")
17345 (match_scratch:SI 3 "r")]
17346 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17347 [(set (match_dup 3) (match_dup 2))
17348 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17351 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17352 ;; Don't split NOTs with a displacement operand, because resulting XOR
17353 ;; will not be pairable anyway.
17355 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17356 ;; represented using a modRM byte. The XOR replacement is long decoded,
17357 ;; so this split helps here as well.
17359 ;; Note: Can't do this as a regular split because we can't get proper
17360 ;; lifetime information then.
17363 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17364 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17365 "optimize_insn_for_speed_p ()
17366 && ((TARGET_NOT_UNPAIRABLE
17367 && (!MEM_P (operands[0])
17368 || !memory_displacement_operand (operands[0], SImode)))
17369 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
17370 && peep2_regno_dead_p (0, FLAGS_REG)"
17371 [(parallel [(set (match_dup 0)
17372 (xor:SI (match_dup 1) (const_int -1)))
17373 (clobber (reg:CC FLAGS_REG))])]
17377 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17378 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17379 "optimize_insn_for_speed_p ()
17380 && ((TARGET_NOT_UNPAIRABLE
17381 && (!MEM_P (operands[0])
17382 || !memory_displacement_operand (operands[0], HImode)))
17383 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
17384 && peep2_regno_dead_p (0, FLAGS_REG)"
17385 [(parallel [(set (match_dup 0)
17386 (xor:HI (match_dup 1) (const_int -1)))
17387 (clobber (reg:CC FLAGS_REG))])]
17391 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17392 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17393 "optimize_insn_for_speed_p ()
17394 && ((TARGET_NOT_UNPAIRABLE
17395 && (!MEM_P (operands[0])
17396 || !memory_displacement_operand (operands[0], QImode)))
17397 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
17398 && peep2_regno_dead_p (0, FLAGS_REG)"
17399 [(parallel [(set (match_dup 0)
17400 (xor:QI (match_dup 1) (const_int -1)))
17401 (clobber (reg:CC FLAGS_REG))])]
17404 ;; Non pairable "test imm, reg" instructions can be translated to
17405 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17406 ;; byte opcode instead of two, have a short form for byte operands),
17407 ;; so do it for other CPUs as well. Given that the value was dead,
17408 ;; this should not create any new dependencies. Pass on the sub-word
17409 ;; versions if we're concerned about partial register stalls.
17412 [(set (match_operand 0 "flags_reg_operand" "")
17413 (match_operator 1 "compare_operator"
17414 [(and:SI (match_operand:SI 2 "register_operand" "")
17415 (match_operand:SI 3 "immediate_operand" ""))
17417 "ix86_match_ccmode (insn, CCNOmode)
17418 && (true_regnum (operands[2]) != AX_REG
17419 || satisfies_constraint_K (operands[3]))
17420 && peep2_reg_dead_p (1, operands[2])"
17422 [(set (match_dup 0)
17423 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17426 (and:SI (match_dup 2) (match_dup 3)))])]
17429 ;; We don't need to handle HImode case, because it will be promoted to SImode
17430 ;; on ! TARGET_PARTIAL_REG_STALL
17433 [(set (match_operand 0 "flags_reg_operand" "")
17434 (match_operator 1 "compare_operator"
17435 [(and:QI (match_operand:QI 2 "register_operand" "")
17436 (match_operand:QI 3 "immediate_operand" ""))
17438 "! TARGET_PARTIAL_REG_STALL
17439 && ix86_match_ccmode (insn, CCNOmode)
17440 && true_regnum (operands[2]) != AX_REG
17441 && peep2_reg_dead_p (1, operands[2])"
17443 [(set (match_dup 0)
17444 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17447 (and:QI (match_dup 2) (match_dup 3)))])]
17451 [(set (match_operand 0 "flags_reg_operand" "")
17452 (match_operator 1 "compare_operator"
17455 (match_operand 2 "ext_register_operand" "")
17458 (match_operand 3 "const_int_operand" ""))
17460 "! TARGET_PARTIAL_REG_STALL
17461 && ix86_match_ccmode (insn, CCNOmode)
17462 && true_regnum (operands[2]) != AX_REG
17463 && peep2_reg_dead_p (1, operands[2])"
17464 [(parallel [(set (match_dup 0)
17473 (set (zero_extract:SI (match_dup 2)
17484 ;; Don't do logical operations with memory inputs.
17486 [(match_scratch:SI 2 "r")
17487 (parallel [(set (match_operand:SI 0 "register_operand" "")
17488 (match_operator:SI 3 "arith_or_logical_operator"
17490 (match_operand:SI 1 "memory_operand" "")]))
17491 (clobber (reg:CC FLAGS_REG))])]
17492 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17493 [(set (match_dup 2) (match_dup 1))
17494 (parallel [(set (match_dup 0)
17495 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17496 (clobber (reg:CC FLAGS_REG))])]
17500 [(match_scratch:SI 2 "r")
17501 (parallel [(set (match_operand:SI 0 "register_operand" "")
17502 (match_operator:SI 3 "arith_or_logical_operator"
17503 [(match_operand:SI 1 "memory_operand" "")
17505 (clobber (reg:CC FLAGS_REG))])]
17506 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17507 [(set (match_dup 2) (match_dup 1))
17508 (parallel [(set (match_dup 0)
17509 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17510 (clobber (reg:CC FLAGS_REG))])]
17513 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17514 ;; refers to the destination of the load!
17517 [(set (match_operand:SI 0 "register_operand" "")
17518 (match_operand:SI 1 "register_operand" ""))
17519 (parallel [(set (match_dup 0)
17520 (match_operator:SI 3 "commutative_operator"
17522 (match_operand:SI 2 "memory_operand" "")]))
17523 (clobber (reg:CC FLAGS_REG))])]
17524 "REGNO (operands[0]) != REGNO (operands[1])
17525 && GENERAL_REGNO_P (REGNO (operands[0]))
17526 && GENERAL_REGNO_P (REGNO (operands[1]))"
17527 [(set (match_dup 0) (match_dup 4))
17528 (parallel [(set (match_dup 0)
17529 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17530 (clobber (reg:CC FLAGS_REG))])]
17531 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17534 [(set (match_operand 0 "register_operand" "")
17535 (match_operand 1 "register_operand" ""))
17537 (match_operator 3 "commutative_operator"
17539 (match_operand 2 "memory_operand" "")]))]
17540 "REGNO (operands[0]) != REGNO (operands[1])
17541 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17542 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17543 [(set (match_dup 0) (match_dup 2))
17545 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17548 ; Don't do logical operations with memory outputs
17550 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17551 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17552 ; the same decoder scheduling characteristics as the original.
17555 [(match_scratch:SI 2 "r")
17556 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17557 (match_operator:SI 3 "arith_or_logical_operator"
17559 (match_operand:SI 1 "nonmemory_operand" "")]))
17560 (clobber (reg:CC FLAGS_REG))])]
17561 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17562 /* Do not split stack checking probes. */
17563 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17564 [(set (match_dup 2) (match_dup 0))
17565 (parallel [(set (match_dup 2)
17566 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17567 (clobber (reg:CC FLAGS_REG))])
17568 (set (match_dup 0) (match_dup 2))]
17572 [(match_scratch:SI 2 "r")
17573 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17574 (match_operator:SI 3 "arith_or_logical_operator"
17575 [(match_operand:SI 1 "nonmemory_operand" "")
17577 (clobber (reg:CC FLAGS_REG))])]
17578 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17579 /* Do not split stack checking probes. */
17580 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17581 [(set (match_dup 2) (match_dup 0))
17582 (parallel [(set (match_dup 2)
17583 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17584 (clobber (reg:CC FLAGS_REG))])
17585 (set (match_dup 0) (match_dup 2))]
17588 ;; Attempt to always use XOR for zeroing registers.
17590 [(set (match_operand 0 "register_operand" "")
17591 (match_operand 1 "const0_operand" ""))]
17592 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17593 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17594 && GENERAL_REG_P (operands[0])
17595 && peep2_regno_dead_p (0, FLAGS_REG)"
17596 [(parallel [(set (match_dup 0) (const_int 0))
17597 (clobber (reg:CC FLAGS_REG))])]
17599 operands[0] = gen_lowpart (word_mode, operands[0]);
17603 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17605 "(GET_MODE (operands[0]) == QImode
17606 || GET_MODE (operands[0]) == HImode)
17607 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17608 && peep2_regno_dead_p (0, FLAGS_REG)"
17609 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17610 (clobber (reg:CC FLAGS_REG))])])
17612 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17614 [(set (match_operand 0 "register_operand" "")
17616 "(GET_MODE (operands[0]) == HImode
17617 || GET_MODE (operands[0]) == SImode
17618 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17619 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17620 && peep2_regno_dead_p (0, FLAGS_REG)"
17621 [(parallel [(set (match_dup 0) (const_int -1))
17622 (clobber (reg:CC FLAGS_REG))])]
17623 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17626 ;; Attempt to convert simple leas to adds. These can be created by
17629 [(set (match_operand:SI 0 "register_operand" "")
17630 (plus:SI (match_dup 0)
17631 (match_operand:SI 1 "nonmemory_operand" "")))]
17632 "peep2_regno_dead_p (0, FLAGS_REG)"
17633 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17634 (clobber (reg:CC FLAGS_REG))])]
17638 [(set (match_operand:SI 0 "register_operand" "")
17639 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17640 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17641 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17642 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17643 (clobber (reg:CC FLAGS_REG))])]
17644 "operands[2] = gen_lowpart (SImode, operands[2]);")
17647 [(set (match_operand:DI 0 "register_operand" "")
17648 (plus:DI (match_dup 0)
17649 (match_operand:DI 1 "x86_64_general_operand" "")))]
17650 "peep2_regno_dead_p (0, FLAGS_REG)"
17651 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17652 (clobber (reg:CC FLAGS_REG))])]
17656 [(set (match_operand:SI 0 "register_operand" "")
17657 (mult:SI (match_dup 0)
17658 (match_operand:SI 1 "const_int_operand" "")))]
17659 "exact_log2 (INTVAL (operands[1])) >= 0
17660 && peep2_regno_dead_p (0, FLAGS_REG)"
17661 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17662 (clobber (reg:CC FLAGS_REG))])]
17663 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17666 [(set (match_operand:DI 0 "register_operand" "")
17667 (mult:DI (match_dup 0)
17668 (match_operand:DI 1 "const_int_operand" "")))]
17669 "exact_log2 (INTVAL (operands[1])) >= 0
17670 && peep2_regno_dead_p (0, FLAGS_REG)"
17671 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17672 (clobber (reg:CC FLAGS_REG))])]
17673 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17676 [(set (match_operand:SI 0 "register_operand" "")
17677 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17678 (match_operand:DI 2 "const_int_operand" "")) 0))]
17679 "exact_log2 (INTVAL (operands[2])) >= 0
17680 && REGNO (operands[0]) == REGNO (operands[1])
17681 && peep2_regno_dead_p (0, FLAGS_REG)"
17682 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17683 (clobber (reg:CC FLAGS_REG))])]
17684 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17686 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17687 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17688 ;; many CPUs it is also faster, since special hardware to avoid esp
17689 ;; dependencies is present.
17691 ;; While some of these conversions may be done using splitters, we use peepholes
17692 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17694 ;; Convert prologue esp subtractions to push.
17695 ;; We need register to push. In order to keep verify_flow_info happy we have
17697 ;; - use scratch and clobber it in order to avoid dependencies
17698 ;; - use already live register
17699 ;; We can't use the second way right now, since there is no reliable way how to
17700 ;; verify that given register is live. First choice will also most likely in
17701 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17702 ;; call clobbered registers are dead. We may want to use base pointer as an
17703 ;; alternative when no register is available later.
17706 [(match_scratch:SI 0 "r")
17707 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17708 (clobber (reg:CC FLAGS_REG))
17709 (clobber (mem:BLK (scratch)))])]
17710 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17711 [(clobber (match_dup 0))
17712 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17713 (clobber (mem:BLK (scratch)))])])
17716 [(match_scratch:SI 0 "r")
17717 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17718 (clobber (reg:CC FLAGS_REG))
17719 (clobber (mem:BLK (scratch)))])]
17720 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17721 [(clobber (match_dup 0))
17722 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17723 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17724 (clobber (mem:BLK (scratch)))])])
17726 ;; Convert esp subtractions to push.
17728 [(match_scratch:SI 0 "r")
17729 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17730 (clobber (reg:CC FLAGS_REG))])]
17731 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17732 [(clobber (match_dup 0))
17733 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17736 [(match_scratch:SI 0 "r")
17737 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17738 (clobber (reg:CC FLAGS_REG))])]
17739 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17740 [(clobber (match_dup 0))
17741 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17742 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17744 ;; Convert epilogue deallocator to pop.
17746 [(match_scratch:SI 0 "r")
17747 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17748 (clobber (reg:CC FLAGS_REG))
17749 (clobber (mem:BLK (scratch)))])]
17750 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17751 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17752 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17753 (clobber (mem:BLK (scratch)))])]
17756 ;; Two pops case is tricky, since pop causes dependency on destination register.
17757 ;; We use two registers if available.
17759 [(match_scratch:SI 0 "r")
17760 (match_scratch:SI 1 "r")
17761 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17762 (clobber (reg:CC FLAGS_REG))
17763 (clobber (mem:BLK (scratch)))])]
17764 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17765 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17766 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17767 (clobber (mem:BLK (scratch)))])
17768 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17769 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17773 [(match_scratch:SI 0 "r")
17774 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17775 (clobber (reg:CC FLAGS_REG))
17776 (clobber (mem:BLK (scratch)))])]
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 (clobber (mem:BLK (scratch)))])
17781 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17782 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17785 ;; Convert esp additions to pop.
17787 [(match_scratch:SI 0 "r")
17788 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17789 (clobber (reg:CC FLAGS_REG))])]
17791 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17792 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17795 ;; Two pops case is tricky, since pop causes dependency on destination register.
17796 ;; We use two registers if available.
17798 [(match_scratch:SI 0 "r")
17799 (match_scratch:SI 1 "r")
17800 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17801 (clobber (reg:CC FLAGS_REG))])]
17803 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17804 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17805 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17806 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17810 [(match_scratch:SI 0 "r")
17811 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17812 (clobber (reg:CC FLAGS_REG))])]
17813 "optimize_insn_for_size_p ()"
17814 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17815 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17816 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17817 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17820 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17821 ;; required and register dies. Similarly for 128 to -128.
17823 [(set (match_operand 0 "flags_reg_operand" "")
17824 (match_operator 1 "compare_operator"
17825 [(match_operand 2 "register_operand" "")
17826 (match_operand 3 "const_int_operand" "")]))]
17827 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17828 && incdec_operand (operands[3], GET_MODE (operands[3])))
17829 || (!TARGET_FUSE_CMP_AND_BRANCH
17830 && INTVAL (operands[3]) == 128))
17831 && ix86_match_ccmode (insn, CCGCmode)
17832 && peep2_reg_dead_p (1, operands[2])"
17833 [(parallel [(set (match_dup 0)
17834 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17835 (clobber (match_dup 2))])]
17839 [(match_scratch:DI 0 "r")
17840 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17841 (clobber (reg:CC FLAGS_REG))
17842 (clobber (mem:BLK (scratch)))])]
17843 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17844 [(clobber (match_dup 0))
17845 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17846 (clobber (mem:BLK (scratch)))])])
17849 [(match_scratch:DI 0 "r")
17850 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17851 (clobber (reg:CC FLAGS_REG))
17852 (clobber (mem:BLK (scratch)))])]
17853 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17854 [(clobber (match_dup 0))
17855 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17856 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17857 (clobber (mem:BLK (scratch)))])])
17859 ;; Convert esp subtractions to push.
17861 [(match_scratch:DI 0 "r")
17862 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17863 (clobber (reg:CC FLAGS_REG))])]
17864 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17865 [(clobber (match_dup 0))
17866 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17869 [(match_scratch:DI 0 "r")
17870 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17871 (clobber (reg:CC FLAGS_REG))])]
17872 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17873 [(clobber (match_dup 0))
17874 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17875 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17877 ;; Convert epilogue deallocator to pop.
17879 [(match_scratch:DI 0 "r")
17880 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17881 (clobber (reg:CC FLAGS_REG))
17882 (clobber (mem:BLK (scratch)))])]
17883 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17884 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17885 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17886 (clobber (mem:BLK (scratch)))])]
17889 ;; Two pops case is tricky, since pop causes dependency on destination register.
17890 ;; We use two registers if available.
17892 [(match_scratch:DI 0 "r")
17893 (match_scratch:DI 1 "r")
17894 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17895 (clobber (reg:CC FLAGS_REG))
17896 (clobber (mem:BLK (scratch)))])]
17897 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17898 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17899 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17900 (clobber (mem:BLK (scratch)))])
17901 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17902 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17906 [(match_scratch:DI 0 "r")
17907 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17908 (clobber (reg:CC FLAGS_REG))
17909 (clobber (mem:BLK (scratch)))])]
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 (clobber (mem:BLK (scratch)))])
17914 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17915 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17918 ;; Convert esp additions to pop.
17920 [(match_scratch:DI 0 "r")
17921 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17922 (clobber (reg:CC FLAGS_REG))])]
17924 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17925 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17928 ;; Two pops case is tricky, since pop causes dependency on destination register.
17929 ;; We use two registers if available.
17931 [(match_scratch:DI 0 "r")
17932 (match_scratch:DI 1 "r")
17933 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17934 (clobber (reg:CC FLAGS_REG))])]
17936 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17937 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17938 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17939 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17943 [(match_scratch:DI 0 "r")
17944 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17945 (clobber (reg:CC FLAGS_REG))])]
17946 "optimize_insn_for_size_p ()"
17947 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17948 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17949 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17950 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17953 ;; Convert imul by three, five and nine into lea
17956 [(set (match_operand:SI 0 "register_operand" "")
17957 (mult:SI (match_operand:SI 1 "register_operand" "")
17958 (match_operand:SI 2 "const_int_operand" "")))
17959 (clobber (reg:CC FLAGS_REG))])]
17960 "INTVAL (operands[2]) == 3
17961 || INTVAL (operands[2]) == 5
17962 || INTVAL (operands[2]) == 9"
17963 [(set (match_dup 0)
17964 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
17966 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17970 [(set (match_operand:SI 0 "register_operand" "")
17971 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17972 (match_operand:SI 2 "const_int_operand" "")))
17973 (clobber (reg:CC FLAGS_REG))])]
17974 "optimize_insn_for_speed_p ()
17975 && (INTVAL (operands[2]) == 3
17976 || INTVAL (operands[2]) == 5
17977 || INTVAL (operands[2]) == 9)"
17978 [(set (match_dup 0) (match_dup 1))
17980 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
17982 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17986 [(set (match_operand:DI 0 "register_operand" "")
17987 (mult:DI (match_operand:DI 1 "register_operand" "")
17988 (match_operand:DI 2 "const_int_operand" "")))
17989 (clobber (reg:CC FLAGS_REG))])]
17991 && (INTVAL (operands[2]) == 3
17992 || INTVAL (operands[2]) == 5
17993 || INTVAL (operands[2]) == 9)"
17994 [(set (match_dup 0)
17995 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
17997 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18001 [(set (match_operand:DI 0 "register_operand" "")
18002 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18003 (match_operand:DI 2 "const_int_operand" "")))
18004 (clobber (reg:CC FLAGS_REG))])]
18006 && optimize_insn_for_speed_p ()
18007 && (INTVAL (operands[2]) == 3
18008 || INTVAL (operands[2]) == 5
18009 || INTVAL (operands[2]) == 9)"
18010 [(set (match_dup 0) (match_dup 1))
18012 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18014 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18016 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18017 ;; imul $32bit_imm, reg, reg is direct decoded.
18019 [(match_scratch:DI 3 "r")
18020 (parallel [(set (match_operand:DI 0 "register_operand" "")
18021 (mult:DI (match_operand:DI 1 "memory_operand" "")
18022 (match_operand:DI 2 "immediate_operand" "")))
18023 (clobber (reg:CC FLAGS_REG))])]
18024 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18025 && !satisfies_constraint_K (operands[2])"
18026 [(set (match_dup 3) (match_dup 1))
18027 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18028 (clobber (reg:CC FLAGS_REG))])]
18032 [(match_scratch:SI 3 "r")
18033 (parallel [(set (match_operand:SI 0 "register_operand" "")
18034 (mult:SI (match_operand:SI 1 "memory_operand" "")
18035 (match_operand:SI 2 "immediate_operand" "")))
18036 (clobber (reg:CC FLAGS_REG))])]
18037 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18038 && !satisfies_constraint_K (operands[2])"
18039 [(set (match_dup 3) (match_dup 1))
18040 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18041 (clobber (reg:CC FLAGS_REG))])]
18045 [(match_scratch:SI 3 "r")
18046 (parallel [(set (match_operand:DI 0 "register_operand" "")
18048 (mult:SI (match_operand:SI 1 "memory_operand" "")
18049 (match_operand:SI 2 "immediate_operand" ""))))
18050 (clobber (reg:CC FLAGS_REG))])]
18051 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18052 && !satisfies_constraint_K (operands[2])"
18053 [(set (match_dup 3) (match_dup 1))
18054 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18055 (clobber (reg:CC FLAGS_REG))])]
18058 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18059 ;; Convert it into imul reg, reg
18060 ;; It would be better to force assembler to encode instruction using long
18061 ;; immediate, but there is apparently no way to do so.
18063 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18064 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18065 (match_operand:DI 2 "const_int_operand" "")))
18066 (clobber (reg:CC FLAGS_REG))])
18067 (match_scratch:DI 3 "r")]
18068 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18069 && satisfies_constraint_K (operands[2])"
18070 [(set (match_dup 3) (match_dup 2))
18071 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18072 (clobber (reg:CC FLAGS_REG))])]
18074 if (!rtx_equal_p (operands[0], operands[1]))
18075 emit_move_insn (operands[0], operands[1]);
18079 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18080 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18081 (match_operand:SI 2 "const_int_operand" "")))
18082 (clobber (reg:CC FLAGS_REG))])
18083 (match_scratch:SI 3 "r")]
18084 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18085 && satisfies_constraint_K (operands[2])"
18086 [(set (match_dup 3) (match_dup 2))
18087 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18088 (clobber (reg:CC FLAGS_REG))])]
18090 if (!rtx_equal_p (operands[0], operands[1]))
18091 emit_move_insn (operands[0], operands[1]);
18095 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18096 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18097 (match_operand:HI 2 "immediate_operand" "")))
18098 (clobber (reg:CC FLAGS_REG))])
18099 (match_scratch:HI 3 "r")]
18100 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
18101 [(set (match_dup 3) (match_dup 2))
18102 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18103 (clobber (reg:CC FLAGS_REG))])]
18105 if (!rtx_equal_p (operands[0], operands[1]))
18106 emit_move_insn (operands[0], operands[1]);
18109 ;; After splitting up read-modify operations, array accesses with memory
18110 ;; operands might end up in form:
18112 ;; movl 4(%esp), %edx
18114 ;; instead of pre-splitting:
18116 ;; addl 4(%esp), %eax
18118 ;; movl 4(%esp), %edx
18119 ;; leal (%edx,%eax,4), %eax
18122 [(parallel [(set (match_operand 0 "register_operand" "")
18123 (ashift (match_operand 1 "register_operand" "")
18124 (match_operand 2 "const_int_operand" "")))
18125 (clobber (reg:CC FLAGS_REG))])
18126 (set (match_operand 3 "register_operand")
18127 (match_operand 4 "x86_64_general_operand" ""))
18128 (parallel [(set (match_operand 5 "register_operand" "")
18129 (plus (match_operand 6 "register_operand" "")
18130 (match_operand 7 "register_operand" "")))
18131 (clobber (reg:CC FLAGS_REG))])]
18132 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
18133 /* Validate MODE for lea. */
18134 && ((!TARGET_PARTIAL_REG_STALL
18135 && (GET_MODE (operands[0]) == QImode
18136 || GET_MODE (operands[0]) == HImode))
18137 || GET_MODE (operands[0]) == SImode
18138 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18139 /* We reorder load and the shift. */
18140 && !rtx_equal_p (operands[1], operands[3])
18141 && !reg_overlap_mentioned_p (operands[0], operands[4])
18142 /* Last PLUS must consist of operand 0 and 3. */
18143 && !rtx_equal_p (operands[0], operands[3])
18144 && (rtx_equal_p (operands[3], operands[6])
18145 || rtx_equal_p (operands[3], operands[7]))
18146 && (rtx_equal_p (operands[0], operands[6])
18147 || rtx_equal_p (operands[0], operands[7]))
18148 /* The intermediate operand 0 must die or be same as output. */
18149 && (rtx_equal_p (operands[0], operands[5])
18150 || peep2_reg_dead_p (3, operands[0]))"
18151 [(set (match_dup 3) (match_dup 4))
18152 (set (match_dup 0) (match_dup 1))]
18154 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
18155 int scale = 1 << INTVAL (operands[2]);
18156 rtx index = gen_lowpart (Pmode, operands[1]);
18157 rtx base = gen_lowpart (Pmode, operands[3]);
18158 rtx dest = gen_lowpart (mode, operands[5]);
18160 operands[1] = gen_rtx_PLUS (Pmode, base,
18161 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
18163 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18164 operands[0] = dest;
18167 ;; Call-value patterns last so that the wildcard operand does not
18168 ;; disrupt insn-recog's switch tables.
18170 (define_insn "*call_value_pop_0"
18171 [(set (match_operand 0 "" "")
18172 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18173 (match_operand:SI 2 "" "")))
18174 (set (reg:SI SP_REG)
18175 (plus:SI (reg:SI SP_REG)
18176 (match_operand:SI 3 "immediate_operand" "")))]
18179 if (SIBLING_CALL_P (insn))
18182 return "call\t%P1";
18184 [(set_attr "type" "callv")])
18186 (define_insn "*call_value_pop_1"
18187 [(set (match_operand 0 "" "")
18188 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18189 (match_operand:SI 2 "" "")))
18190 (set (reg:SI SP_REG)
18191 (plus:SI (reg:SI SP_REG)
18192 (match_operand:SI 3 "immediate_operand" "i")))]
18193 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18195 if (constant_call_address_operand (operands[1], Pmode))
18196 return "call\t%P1";
18197 return "call\t%A1";
18199 [(set_attr "type" "callv")])
18201 (define_insn "*sibcall_value_pop_1"
18202 [(set (match_operand 0 "" "")
18203 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18204 (match_operand:SI 2 "" "")))
18205 (set (reg:SI SP_REG)
18206 (plus:SI (reg:SI SP_REG)
18207 (match_operand:SI 3 "immediate_operand" "i,i")))]
18208 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18212 [(set_attr "type" "callv")])
18214 (define_insn "*call_value_0"
18215 [(set (match_operand 0 "" "")
18216 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18217 (match_operand:SI 2 "" "")))]
18220 if (SIBLING_CALL_P (insn))
18223 return "call\t%P1";
18225 [(set_attr "type" "callv")])
18227 (define_insn "*call_value_0_rex64"
18228 [(set (match_operand 0 "" "")
18229 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18230 (match_operand:DI 2 "const_int_operand" "")))]
18233 if (SIBLING_CALL_P (insn))
18236 return "call\t%P1";
18238 [(set_attr "type" "callv")])
18240 (define_insn "*call_value_0_rex64_ms_sysv"
18241 [(set (match_operand 0 "" "")
18242 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18243 (match_operand:DI 2 "const_int_operand" "")))
18244 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18245 (clobber (reg:TI XMM6_REG))
18246 (clobber (reg:TI XMM7_REG))
18247 (clobber (reg:TI XMM8_REG))
18248 (clobber (reg:TI XMM9_REG))
18249 (clobber (reg:TI XMM10_REG))
18250 (clobber (reg:TI XMM11_REG))
18251 (clobber (reg:TI XMM12_REG))
18252 (clobber (reg:TI XMM13_REG))
18253 (clobber (reg:TI XMM14_REG))
18254 (clobber (reg:TI XMM15_REG))
18255 (clobber (reg:DI SI_REG))
18256 (clobber (reg:DI DI_REG))]
18257 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18259 if (SIBLING_CALL_P (insn))
18262 return "call\t%P1";
18264 [(set_attr "type" "callv")])
18266 (define_insn "*call_value_1"
18267 [(set (match_operand 0 "" "")
18268 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18269 (match_operand:SI 2 "" "")))]
18270 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18272 if (constant_call_address_operand (operands[1], Pmode))
18273 return "call\t%P1";
18274 return "call\t%A1";
18276 [(set_attr "type" "callv")])
18278 (define_insn "*sibcall_value_1"
18279 [(set (match_operand 0 "" "")
18280 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18281 (match_operand:SI 2 "" "")))]
18282 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18286 [(set_attr "type" "callv")])
18288 (define_insn "*call_value_1_rex64"
18289 [(set (match_operand 0 "" "")
18290 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18291 (match_operand:DI 2 "" "")))]
18292 "TARGET_64BIT && !SIBLING_CALL_P (insn)
18293 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
18295 if (constant_call_address_operand (operands[1], Pmode))
18296 return "call\t%P1";
18297 return "call\t%A1";
18299 [(set_attr "type" "callv")])
18301 (define_insn "*call_value_1_rex64_ms_sysv"
18302 [(set (match_operand 0 "" "")
18303 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18304 (match_operand:DI 2 "" "")))
18305 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18306 (clobber (reg:TI XMM6_REG))
18307 (clobber (reg:TI XMM7_REG))
18308 (clobber (reg:TI XMM8_REG))
18309 (clobber (reg:TI XMM9_REG))
18310 (clobber (reg:TI XMM10_REG))
18311 (clobber (reg:TI XMM11_REG))
18312 (clobber (reg:TI XMM12_REG))
18313 (clobber (reg:TI XMM13_REG))
18314 (clobber (reg:TI XMM14_REG))
18315 (clobber (reg:TI XMM15_REG))
18316 (clobber (reg:DI SI_REG))
18317 (clobber (reg:DI DI_REG))]
18318 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18320 if (constant_call_address_operand (operands[1], Pmode))
18321 return "call\t%P1";
18322 return "call\t%A1";
18324 [(set_attr "type" "callv")])
18326 (define_insn "*call_value_1_rex64_large"
18327 [(set (match_operand 0 "" "")
18328 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
18329 (match_operand:DI 2 "" "")))]
18330 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18332 [(set_attr "type" "callv")])
18334 (define_insn "*sibcall_value_1_rex64"
18335 [(set (match_operand 0 "" "")
18336 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
18337 (match_operand:DI 2 "" "")))]
18338 "TARGET_64BIT && SIBLING_CALL_P (insn)"
18342 [(set_attr "type" "callv")])
18344 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18345 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18346 ;; caught for use by garbage collectors and the like. Using an insn that
18347 ;; maps to SIGILL makes it more likely the program will rightfully die.
18348 ;; Keeping with tradition, "6" is in honor of #UD.
18349 (define_insn "trap"
18350 [(trap_if (const_int 1) (const_int 6))]
18352 { return ASM_SHORT "0x0b0f"; }
18353 [(set_attr "length" "2")])
18355 (define_expand "sse_prologue_save"
18356 [(parallel [(set (match_operand:BLK 0 "" "")
18357 (unspec:BLK [(reg:DI XMM0_REG)
18364 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18365 (clobber (reg:CC FLAGS_REG))
18366 (clobber (match_operand:DI 1 "register_operand" ""))
18367 (use (match_operand:DI 2 "immediate_operand" ""))
18368 (use (label_ref:DI (match_operand 3 "" "")))
18369 (clobber (match_operand:DI 4 "register_operand" ""))
18370 (use (match_dup 1))])]
18374 ;; Pre-reload version of prologue save. Until after prologue generation we don't know
18375 ;; what the size of save instruction will be.
18376 ;; Operand 0+operand 6 is the memory save area
18377 ;; Operand 1 is number of registers to save (will get overwritten to operand 5)
18378 ;; Operand 2 is number of non-vaargs SSE arguments
18379 ;; Operand 3 is label starting the save block
18380 ;; Operand 4 is used for temporary computation of jump address
18381 (define_insn "*sse_prologue_save_insn1"
18382 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18383 (match_operand:DI 6 "const_int_operand" "n")))
18384 (unspec:BLK [(reg:DI XMM0_REG)
18391 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18392 (clobber (reg:CC FLAGS_REG))
18393 (clobber (match_operand:DI 1 "register_operand" "=r"))
18394 (use (match_operand:DI 2 "const_int_operand" "i"))
18395 (use (label_ref:DI (match_operand 3 "" "X")))
18396 (clobber (match_operand:DI 4 "register_operand" "=&r"))
18397 (use (match_operand:DI 5 "register_operand" "1"))]
18399 && INTVAL (operands[6]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18400 && INTVAL (operands[6]) + INTVAL (operands[2]) * 16 >= -128"
18402 [(set_attr "type" "other")
18403 (set_attr "memory" "store")
18404 (set_attr "mode" "DI")])
18406 ;; We know size of save instruction; expand the computation of jump address
18407 ;; in the jumptable.
18409 [(parallel [(set (match_operand:BLK 0 "" "")
18410 (unspec:BLK [(reg:DI XMM0_REG)
18417 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18418 (clobber (reg:CC FLAGS_REG))
18419 (clobber (match_operand:DI 1 "register_operand" ""))
18420 (use (match_operand:DI 2 "const_int_operand" ""))
18421 (use (match_operand 3 "" ""))
18422 (clobber (match_operand:DI 4 "register_operand" ""))
18423 (use (match_operand:DI 5 "register_operand" ""))])]
18425 [(parallel [(set (match_dup 0)
18426 (unspec:BLK [(reg:DI XMM0_REG)
18433 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
18434 (use (match_dup 1))
18435 (use (match_dup 2))
18436 (use (match_dup 3))
18437 (use (match_dup 5))])]
18439 /* Movaps is 4 bytes, AVX and movsd is 5 bytes. */
18440 int size = 4 + (TARGET_AVX || crtl->stack_alignment_needed < 128);
18442 /* Compute address to jump to:
18443 label - eax*size + nnamed_sse_arguments*size. */
18445 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
18448 gen_rtx_MULT (Pmode, operands[1],
18451 else if (size == 4)
18452 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
18453 gen_rtx_MULT (Pmode, operands[1],
18456 gcc_unreachable ();
18457 if (INTVAL (operands[2]))
18460 gen_rtx_CONST (DImode,
18461 gen_rtx_PLUS (DImode,
18463 GEN_INT (INTVAL (operands[2])
18466 emit_move_insn (operands[1], operands[3]);
18467 emit_insn (gen_subdi3 (operands[1], operands[1], operands[4]));
18468 operands[5] = GEN_INT (size);
18471 (define_insn "sse_prologue_save_insn"
18472 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18473 (match_operand:DI 4 "const_int_operand" "n")))
18474 (unspec:BLK [(reg:DI XMM0_REG)
18481 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
18482 (use (match_operand:DI 1 "register_operand" "r"))
18483 (use (match_operand:DI 2 "const_int_operand" "i"))
18484 (use (label_ref:DI (match_operand 3 "" "X")))
18485 (use (match_operand:DI 5 "const_int_operand" "i"))]
18487 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18488 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
18491 operands[0] = gen_rtx_MEM (Pmode,
18492 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
18493 /* VEX instruction with a REX prefix will #UD. */
18494 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
18495 gcc_unreachable ();
18497 output_asm_insn ("jmp\t%A1", operands);
18498 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
18500 operands[4] = adjust_address (operands[0], DImode, i*16);
18501 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
18502 PUT_MODE (operands[4], TImode);
18503 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
18504 output_asm_insn ("rex", operands);
18505 if (crtl->stack_alignment_needed < 128)
18506 output_asm_insn ("%vmovsd\t{%5, %4|%4, %5}", operands);
18508 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
18510 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18511 CODE_LABEL_NUMBER (operands[3]));
18514 [(set_attr "type" "other")
18515 (set_attr "length_immediate" "0")
18516 (set_attr "length_address" "0")
18517 ;; 2 bytes for jump and opernds[4] bytes for each save.
18518 (set (attr "length")
18519 (plus (const_int 2)
18520 (mult (symbol_ref ("INTVAL (operands[5])"))
18521 (symbol_ref ("X86_64_SSE_REGPARM_MAX - INTVAL (operands[2])")))))
18522 (set_attr "memory" "store")
18523 (set_attr "modrm" "0")
18524 (set_attr "prefix" "maybe_vex")
18525 (set_attr "mode" "DI")])
18527 (define_expand "prefetch"
18528 [(prefetch (match_operand 0 "address_operand" "")
18529 (match_operand:SI 1 "const_int_operand" "")
18530 (match_operand:SI 2 "const_int_operand" ""))]
18531 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
18533 int rw = INTVAL (operands[1]);
18534 int locality = INTVAL (operands[2]);
18536 gcc_assert (rw == 0 || rw == 1);
18537 gcc_assert (locality >= 0 && locality <= 3);
18538 gcc_assert (GET_MODE (operands[0]) == Pmode
18539 || GET_MODE (operands[0]) == VOIDmode);
18541 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18542 supported by SSE counterpart or the SSE prefetch is not available
18543 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18545 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
18546 operands[2] = GEN_INT (3);
18548 operands[1] = const0_rtx;
18551 (define_insn "*prefetch_sse"
18552 [(prefetch (match_operand:SI 0 "address_operand" "p")
18554 (match_operand:SI 1 "const_int_operand" ""))]
18555 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
18557 static const char * const patterns[4] = {
18558 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18561 int locality = INTVAL (operands[1]);
18562 gcc_assert (locality >= 0 && locality <= 3);
18564 return patterns[locality];
18566 [(set_attr "type" "sse")
18567 (set_attr "atom_sse_attr" "prefetch")
18568 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18569 (set_attr "memory" "none")])
18571 (define_insn "*prefetch_sse_rex"
18572 [(prefetch (match_operand:DI 0 "address_operand" "p")
18574 (match_operand:SI 1 "const_int_operand" ""))]
18575 "TARGET_PREFETCH_SSE && TARGET_64BIT"
18577 static const char * const patterns[4] = {
18578 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18581 int locality = INTVAL (operands[1]);
18582 gcc_assert (locality >= 0 && locality <= 3);
18584 return patterns[locality];
18586 [(set_attr "type" "sse")
18587 (set_attr "atom_sse_attr" "prefetch")
18588 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18589 (set_attr "memory" "none")])
18591 (define_insn "*prefetch_3dnow"
18592 [(prefetch (match_operand:SI 0 "address_operand" "p")
18593 (match_operand:SI 1 "const_int_operand" "n")
18595 "TARGET_3DNOW && !TARGET_64BIT"
18597 if (INTVAL (operands[1]) == 0)
18598 return "prefetch\t%a0";
18600 return "prefetchw\t%a0";
18602 [(set_attr "type" "mmx")
18603 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18604 (set_attr "memory" "none")])
18606 (define_insn "*prefetch_3dnow_rex"
18607 [(prefetch (match_operand:DI 0 "address_operand" "p")
18608 (match_operand:SI 1 "const_int_operand" "n")
18610 "TARGET_3DNOW && TARGET_64BIT"
18612 if (INTVAL (operands[1]) == 0)
18613 return "prefetch\t%a0";
18615 return "prefetchw\t%a0";
18617 [(set_attr "type" "mmx")
18618 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18619 (set_attr "memory" "none")])
18621 (define_expand "stack_protect_set"
18622 [(match_operand 0 "memory_operand" "")
18623 (match_operand 1 "memory_operand" "")]
18626 #ifdef TARGET_THREAD_SSP_OFFSET
18628 emit_insn (gen_stack_tls_protect_set_di (operands[0],
18629 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18631 emit_insn (gen_stack_tls_protect_set_si (operands[0],
18632 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18635 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18637 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18642 (define_insn "stack_protect_set_si"
18643 [(set (match_operand:SI 0 "memory_operand" "=m")
18644 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18645 (set (match_scratch:SI 2 "=&r") (const_int 0))
18646 (clobber (reg:CC FLAGS_REG))]
18648 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18649 [(set_attr "type" "multi")])
18651 (define_insn "stack_protect_set_di"
18652 [(set (match_operand:DI 0 "memory_operand" "=m")
18653 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18654 (set (match_scratch:DI 2 "=&r") (const_int 0))
18655 (clobber (reg:CC FLAGS_REG))]
18657 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18658 [(set_attr "type" "multi")])
18660 (define_insn "stack_tls_protect_set_si"
18661 [(set (match_operand:SI 0 "memory_operand" "=m")
18662 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18663 (set (match_scratch:SI 2 "=&r") (const_int 0))
18664 (clobber (reg:CC FLAGS_REG))]
18666 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18667 [(set_attr "type" "multi")])
18669 (define_insn "stack_tls_protect_set_di"
18670 [(set (match_operand:DI 0 "memory_operand" "=m")
18671 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18672 (set (match_scratch:DI 2 "=&r") (const_int 0))
18673 (clobber (reg:CC FLAGS_REG))]
18676 /* The kernel uses a different segment register for performance reasons; a
18677 system call would not have to trash the userspace segment register,
18678 which would be expensive */
18679 if (ix86_cmodel != CM_KERNEL)
18680 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18682 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18684 [(set_attr "type" "multi")])
18686 (define_expand "stack_protect_test"
18687 [(match_operand 0 "memory_operand" "")
18688 (match_operand 1 "memory_operand" "")
18689 (match_operand 2 "" "")]
18692 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18694 #ifdef TARGET_THREAD_SSP_OFFSET
18696 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18697 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18699 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18700 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18703 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18705 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18708 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18709 flags, const0_rtx, operands[2]));
18713 (define_insn "stack_protect_test_si"
18714 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18715 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18716 (match_operand:SI 2 "memory_operand" "m")]
18718 (clobber (match_scratch:SI 3 "=&r"))]
18720 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18721 [(set_attr "type" "multi")])
18723 (define_insn "stack_protect_test_di"
18724 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18725 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18726 (match_operand:DI 2 "memory_operand" "m")]
18728 (clobber (match_scratch:DI 3 "=&r"))]
18730 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18731 [(set_attr "type" "multi")])
18733 (define_insn "stack_tls_protect_test_si"
18734 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18735 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18736 (match_operand:SI 2 "const_int_operand" "i")]
18737 UNSPEC_SP_TLS_TEST))
18738 (clobber (match_scratch:SI 3 "=r"))]
18740 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18741 [(set_attr "type" "multi")])
18743 (define_insn "stack_tls_protect_test_di"
18744 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18745 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18746 (match_operand:DI 2 "const_int_operand" "i")]
18747 UNSPEC_SP_TLS_TEST))
18748 (clobber (match_scratch:DI 3 "=r"))]
18751 /* The kernel uses a different segment register for performance reasons; a
18752 system call would not have to trash the userspace segment register,
18753 which would be expensive */
18754 if (ix86_cmodel != CM_KERNEL)
18755 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18757 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18759 [(set_attr "type" "multi")])
18761 (define_insn "sse4_2_crc32<mode>"
18762 [(set (match_operand:SI 0 "register_operand" "=r")
18764 [(match_operand:SI 1 "register_operand" "0")
18765 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18767 "TARGET_SSE4_2 || TARGET_CRC32"
18768 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18769 [(set_attr "type" "sselog1")
18770 (set_attr "prefix_rep" "1")
18771 (set_attr "prefix_extra" "1")
18772 (set (attr "prefix_data16")
18773 (if_then_else (match_operand:HI 2 "" "")
18775 (const_string "*")))
18776 (set (attr "prefix_rex")
18777 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18779 (const_string "*")))
18780 (set_attr "mode" "SI")])
18782 (define_insn "sse4_2_crc32di"
18783 [(set (match_operand:DI 0 "register_operand" "=r")
18785 [(match_operand:DI 1 "register_operand" "0")
18786 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18788 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18789 "crc32{q}\t{%2, %0|%0, %2}"
18790 [(set_attr "type" "sselog1")
18791 (set_attr "prefix_rep" "1")
18792 (set_attr "prefix_extra" "1")
18793 (set_attr "mode" "DI")])
18795 (define_expand "rdpmc"
18796 [(match_operand:DI 0 "register_operand" "")
18797 (match_operand:SI 1 "register_operand" "")]
18800 rtx reg = gen_reg_rtx (DImode);
18803 /* Force operand 1 into ECX. */
18804 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18805 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18806 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18811 rtvec vec = rtvec_alloc (2);
18812 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18813 rtx upper = gen_reg_rtx (DImode);
18814 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18815 gen_rtvec (1, const0_rtx),
18817 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18818 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18820 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18821 NULL, 1, OPTAB_DIRECT);
18822 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18826 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18827 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18831 (define_insn "*rdpmc"
18832 [(set (match_operand:DI 0 "register_operand" "=A")
18833 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18837 [(set_attr "type" "other")
18838 (set_attr "length" "2")])
18840 (define_insn "*rdpmc_rex64"
18841 [(set (match_operand:DI 0 "register_operand" "=a")
18842 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18844 (set (match_operand:DI 1 "register_operand" "=d")
18845 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18848 [(set_attr "type" "other")
18849 (set_attr "length" "2")])
18851 (define_expand "rdtsc"
18852 [(set (match_operand:DI 0 "register_operand" "")
18853 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18858 rtvec vec = rtvec_alloc (2);
18859 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18860 rtx upper = gen_reg_rtx (DImode);
18861 rtx lower = gen_reg_rtx (DImode);
18862 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18863 gen_rtvec (1, const0_rtx),
18865 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18866 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18868 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18869 NULL, 1, OPTAB_DIRECT);
18870 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18872 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18877 (define_insn "*rdtsc"
18878 [(set (match_operand:DI 0 "register_operand" "=A")
18879 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18882 [(set_attr "type" "other")
18883 (set_attr "length" "2")])
18885 (define_insn "*rdtsc_rex64"
18886 [(set (match_operand:DI 0 "register_operand" "=a")
18887 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18888 (set (match_operand:DI 1 "register_operand" "=d")
18889 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18892 [(set_attr "type" "other")
18893 (set_attr "length" "2")])
18895 (define_expand "rdtscp"
18896 [(match_operand:DI 0 "register_operand" "")
18897 (match_operand:SI 1 "memory_operand" "")]
18900 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18901 gen_rtvec (1, const0_rtx),
18903 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18904 gen_rtvec (1, const0_rtx),
18906 rtx reg = gen_reg_rtx (DImode);
18907 rtx tmp = gen_reg_rtx (SImode);
18911 rtvec vec = rtvec_alloc (3);
18912 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18913 rtx upper = gen_reg_rtx (DImode);
18914 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18915 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18916 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18918 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18919 NULL, 1, OPTAB_DIRECT);
18920 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18925 rtvec vec = rtvec_alloc (2);
18926 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18927 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18928 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18931 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18932 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18936 (define_insn "*rdtscp"
18937 [(set (match_operand:DI 0 "register_operand" "=A")
18938 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18939 (set (match_operand:SI 1 "register_operand" "=c")
18940 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18943 [(set_attr "type" "other")
18944 (set_attr "length" "3")])
18946 (define_insn "*rdtscp_rex64"
18947 [(set (match_operand:DI 0 "register_operand" "=a")
18948 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18949 (set (match_operand:DI 1 "register_operand" "=d")
18950 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18951 (set (match_operand:SI 2 "register_operand" "=c")
18952 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18955 [(set_attr "type" "other")
18956 (set_attr "length" "3")])
18958 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18960 ;; LWP instructions
18962 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18964 (define_expand "lwp_llwpcb"
18965 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18966 UNSPECV_LLWP_INTRINSIC)]
18970 (define_insn "*lwp_llwpcb<mode>1"
18971 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18972 UNSPECV_LLWP_INTRINSIC)]
18975 [(set_attr "type" "lwp")
18976 (set_attr "mode" "<MODE>")
18977 (set_attr "length" "5")])
18979 (define_expand "lwp_slwpcb"
18980 [(set (match_operand 0 "register_operand" "=r")
18981 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18985 emit_insn (gen_lwp_slwpcbdi (operands[0]));
18987 emit_insn (gen_lwp_slwpcbsi (operands[0]));
18991 (define_insn "lwp_slwpcb<mode>"
18992 [(set (match_operand:P 0 "register_operand" "=r")
18993 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18996 [(set_attr "type" "lwp")
18997 (set_attr "mode" "<MODE>")
18998 (set_attr "length" "5")])
19000 (define_expand "lwp_lwpval<mode>3"
19001 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
19002 (match_operand:SI 2 "nonimmediate_operand" "rm")
19003 (match_operand:SI 3 "const_int_operand" "i")]
19004 UNSPECV_LWPVAL_INTRINSIC)]
19006 "/* Avoid unused variable warning. */
19009 (define_insn "*lwp_lwpval<mode>3_1"
19010 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19011 (match_operand:SI 1 "nonimmediate_operand" "rm")
19012 (match_operand:SI 2 "const_int_operand" "i")]
19013 UNSPECV_LWPVAL_INTRINSIC)]
19015 "lwpval\t{%2, %1, %0|%0, %1, %2}"
19016 [(set_attr "type" "lwp")
19017 (set_attr "mode" "<MODE>")
19018 (set (attr "length")
19019 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19021 (define_expand "lwp_lwpins<mode>3"
19022 [(set (reg:CCC FLAGS_REG)
19023 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
19024 (match_operand:SI 2 "nonimmediate_operand" "rm")
19025 (match_operand:SI 3 "const_int_operand" "i")]
19026 UNSPECV_LWPINS_INTRINSIC))
19027 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
19028 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19032 (define_insn "*lwp_lwpins<mode>3_1"
19033 [(set (reg:CCC FLAGS_REG)
19034 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19035 (match_operand:SI 1 "nonimmediate_operand" "rm")
19036 (match_operand:SI 2 "const_int_operand" "i")]
19037 UNSPECV_LWPINS_INTRINSIC))]
19039 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19040 [(set_attr "type" "lwp")
19041 (set_attr "mode" "<MODE>")
19042 (set (attr "length")
19043 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19047 (include "sync.md")