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 #ifndef HAVE_AS_IX86_SAHF
1433 return ASM_BYTE "0x9e";
1438 [(set_attr "length" "1")
1439 (set_attr "athlon_decode" "vector")
1440 (set_attr "amdfam10_decode" "direct")
1441 (set_attr "mode" "SI")])
1443 ;; Pentium Pro can do steps 1 through 3 in one go.
1444 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1445 (define_insn "*cmpfp_i_mixed"
1446 [(set (reg:CCFP FLAGS_REG)
1447 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1448 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1449 "TARGET_MIX_SSE_I387
1450 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1451 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1452 "* return output_fp_compare (insn, operands, 1, 0);"
1453 [(set_attr "type" "fcmp,ssecomi")
1454 (set_attr "prefix" "orig,maybe_vex")
1456 (if_then_else (match_operand:SF 1 "" "")
1458 (const_string "DF")))
1459 (set (attr "prefix_rep")
1460 (if_then_else (eq_attr "type" "ssecomi")
1462 (const_string "*")))
1463 (set (attr "prefix_data16")
1464 (cond [(eq_attr "type" "fcmp")
1466 (eq_attr "mode" "DF")
1469 (const_string "0")))
1470 (set_attr "athlon_decode" "vector")
1471 (set_attr "amdfam10_decode" "direct")])
1473 (define_insn "*cmpfp_i_sse"
1474 [(set (reg:CCFP FLAGS_REG)
1475 (compare:CCFP (match_operand 0 "register_operand" "x")
1476 (match_operand 1 "nonimmediate_operand" "xm")))]
1478 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1479 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1480 "* return output_fp_compare (insn, operands, 1, 0);"
1481 [(set_attr "type" "ssecomi")
1482 (set_attr "prefix" "maybe_vex")
1484 (if_then_else (match_operand:SF 1 "" "")
1486 (const_string "DF")))
1487 (set_attr "prefix_rep" "0")
1488 (set (attr "prefix_data16")
1489 (if_then_else (eq_attr "mode" "DF")
1491 (const_string "0")))
1492 (set_attr "athlon_decode" "vector")
1493 (set_attr "amdfam10_decode" "direct")])
1495 (define_insn "*cmpfp_i_i387"
1496 [(set (reg:CCFP FLAGS_REG)
1497 (compare:CCFP (match_operand 0 "register_operand" "f")
1498 (match_operand 1 "register_operand" "f")))]
1499 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1501 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1502 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503 "* return output_fp_compare (insn, operands, 1, 0);"
1504 [(set_attr "type" "fcmp")
1506 (cond [(match_operand:SF 1 "" "")
1508 (match_operand:DF 1 "" "")
1511 (const_string "XF")))
1512 (set_attr "athlon_decode" "vector")
1513 (set_attr "amdfam10_decode" "direct")])
1515 (define_insn "*cmpfp_iu_mixed"
1516 [(set (reg:CCFPU FLAGS_REG)
1517 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1518 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1519 "TARGET_MIX_SSE_I387
1520 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1521 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1522 "* return output_fp_compare (insn, operands, 1, 1);"
1523 [(set_attr "type" "fcmp,ssecomi")
1524 (set_attr "prefix" "orig,maybe_vex")
1526 (if_then_else (match_operand:SF 1 "" "")
1528 (const_string "DF")))
1529 (set (attr "prefix_rep")
1530 (if_then_else (eq_attr "type" "ssecomi")
1532 (const_string "*")))
1533 (set (attr "prefix_data16")
1534 (cond [(eq_attr "type" "fcmp")
1536 (eq_attr "mode" "DF")
1539 (const_string "0")))
1540 (set_attr "athlon_decode" "vector")
1541 (set_attr "amdfam10_decode" "direct")])
1543 (define_insn "*cmpfp_iu_sse"
1544 [(set (reg:CCFPU FLAGS_REG)
1545 (compare:CCFPU (match_operand 0 "register_operand" "x")
1546 (match_operand 1 "nonimmediate_operand" "xm")))]
1548 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1549 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1550 "* return output_fp_compare (insn, operands, 1, 1);"
1551 [(set_attr "type" "ssecomi")
1552 (set_attr "prefix" "maybe_vex")
1554 (if_then_else (match_operand:SF 1 "" "")
1556 (const_string "DF")))
1557 (set_attr "prefix_rep" "0")
1558 (set (attr "prefix_data16")
1559 (if_then_else (eq_attr "mode" "DF")
1561 (const_string "0")))
1562 (set_attr "athlon_decode" "vector")
1563 (set_attr "amdfam10_decode" "direct")])
1565 (define_insn "*cmpfp_iu_387"
1566 [(set (reg:CCFPU FLAGS_REG)
1567 (compare:CCFPU (match_operand 0 "register_operand" "f")
1568 (match_operand 1 "register_operand" "f")))]
1569 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1571 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1572 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1573 "* return output_fp_compare (insn, operands, 1, 1);"
1574 [(set_attr "type" "fcmp")
1576 (cond [(match_operand:SF 1 "" "")
1578 (match_operand:DF 1 "" "")
1581 (const_string "XF")))
1582 (set_attr "athlon_decode" "vector")
1583 (set_attr "amdfam10_decode" "direct")])
1585 ;; Move instructions.
1587 ;; General case of fullword move.
1589 (define_expand "movsi"
1590 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1591 (match_operand:SI 1 "general_operand" ""))]
1593 "ix86_expand_move (SImode, operands); DONE;")
1595 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1598 ;; %%% We don't use a post-inc memory reference because x86 is not a
1599 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1600 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1601 ;; targets without our curiosities, and it is just as easy to represent
1602 ;; this differently.
1604 (define_insn "*pushsi2"
1605 [(set (match_operand:SI 0 "push_operand" "=<")
1606 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1609 [(set_attr "type" "push")
1610 (set_attr "mode" "SI")])
1612 ;; For 64BIT abi we always round up to 8 bytes.
1613 (define_insn "*pushsi2_rex64"
1614 [(set (match_operand:SI 0 "push_operand" "=X")
1615 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1618 [(set_attr "type" "push")
1619 (set_attr "mode" "SI")])
1621 (define_insn "*pushsi2_prologue"
1622 [(set (match_operand:SI 0 "push_operand" "=<")
1623 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1624 (clobber (mem:BLK (scratch)))]
1627 [(set_attr "type" "push")
1628 (set_attr "mode" "SI")])
1630 (define_insn "*popsi1_epilogue"
1631 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1632 (mem:SI (reg:SI SP_REG)))
1633 (set (reg:SI SP_REG)
1634 (plus:SI (reg:SI SP_REG) (const_int 4)))
1635 (clobber (mem:BLK (scratch)))]
1638 [(set_attr "type" "pop")
1639 (set_attr "mode" "SI")])
1641 (define_insn "popsi1"
1642 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1643 (mem:SI (reg:SI SP_REG)))
1644 (set (reg:SI SP_REG)
1645 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1648 [(set_attr "type" "pop")
1649 (set_attr "mode" "SI")])
1651 (define_insn "*movsi_xor"
1652 [(set (match_operand:SI 0 "register_operand" "=r")
1653 (match_operand:SI 1 "const0_operand" ""))
1654 (clobber (reg:CC FLAGS_REG))]
1657 [(set_attr "type" "alu1")
1658 (set_attr "mode" "SI")
1659 (set_attr "length_immediate" "0")])
1661 (define_insn "*movsi_or"
1662 [(set (match_operand:SI 0 "register_operand" "=r")
1663 (match_operand:SI 1 "immediate_operand" "i"))
1664 (clobber (reg:CC FLAGS_REG))]
1666 && operands[1] == constm1_rtx"
1668 operands[1] = constm1_rtx;
1669 return "or{l}\t{%1, %0|%0, %1}";
1671 [(set_attr "type" "alu1")
1672 (set_attr "mode" "SI")
1673 (set_attr "length_immediate" "1")])
1675 (define_insn "*movsi_1"
1676 [(set (match_operand:SI 0 "nonimmediate_operand"
1677 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1678 (match_operand:SI 1 "general_operand"
1679 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1680 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1682 switch (get_attr_type (insn))
1685 if (get_attr_mode (insn) == MODE_TI)
1686 return "%vpxor\t%0, %d0";
1687 return "%vxorps\t%0, %d0";
1690 switch (get_attr_mode (insn))
1693 return "%vmovdqa\t{%1, %0|%0, %1}";
1695 return "%vmovaps\t{%1, %0|%0, %1}";
1697 return "%vmovd\t{%1, %0|%0, %1}";
1699 return "%vmovss\t{%1, %0|%0, %1}";
1705 return "pxor\t%0, %0";
1708 if (get_attr_mode (insn) == MODE_DI)
1709 return "movq\t{%1, %0|%0, %1}";
1710 return "movd\t{%1, %0|%0, %1}";
1713 return "lea{l}\t{%1, %0|%0, %1}";
1716 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1717 return "mov{l}\t{%1, %0|%0, %1}";
1721 (cond [(eq_attr "alternative" "2")
1722 (const_string "mmx")
1723 (eq_attr "alternative" "3,4,5")
1724 (const_string "mmxmov")
1725 (eq_attr "alternative" "6")
1726 (const_string "sselog1")
1727 (eq_attr "alternative" "7,8,9,10,11")
1728 (const_string "ssemov")
1729 (match_operand:DI 1 "pic_32bit_operand" "")
1730 (const_string "lea")
1732 (const_string "imov")))
1733 (set (attr "prefix")
1734 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1735 (const_string "orig")
1736 (const_string "maybe_vex")))
1737 (set (attr "prefix_data16")
1738 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1740 (const_string "*")))
1742 (cond [(eq_attr "alternative" "2,3")
1744 (eq_attr "alternative" "6,7")
1746 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1747 (const_string "V4SF")
1748 (const_string "TI"))
1749 (and (eq_attr "alternative" "8,9,10,11")
1750 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1753 (const_string "SI")))])
1755 ;; Stores and loads of ax to arbitrary constant address.
1756 ;; We fake an second form of instruction to force reload to load address
1757 ;; into register when rax is not available
1758 (define_insn "*movabssi_1_rex64"
1759 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1760 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1761 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1763 movabs{l}\t{%1, %P0|%P0, %1}
1764 mov{l}\t{%1, %a0|%a0, %1}"
1765 [(set_attr "type" "imov")
1766 (set_attr "modrm" "0,*")
1767 (set_attr "length_address" "8,0")
1768 (set_attr "length_immediate" "0,*")
1769 (set_attr "memory" "store")
1770 (set_attr "mode" "SI")])
1772 (define_insn "*movabssi_2_rex64"
1773 [(set (match_operand:SI 0 "register_operand" "=a,r")
1774 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1775 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1777 movabs{l}\t{%P1, %0|%0, %P1}
1778 mov{l}\t{%a1, %0|%0, %a1}"
1779 [(set_attr "type" "imov")
1780 (set_attr "modrm" "0,*")
1781 (set_attr "length_address" "8,0")
1782 (set_attr "length_immediate" "0")
1783 (set_attr "memory" "load")
1784 (set_attr "mode" "SI")])
1786 (define_insn "*swapsi"
1787 [(set (match_operand:SI 0 "register_operand" "+r")
1788 (match_operand:SI 1 "register_operand" "+r"))
1793 [(set_attr "type" "imov")
1794 (set_attr "mode" "SI")
1795 (set_attr "pent_pair" "np")
1796 (set_attr "athlon_decode" "vector")
1797 (set_attr "amdfam10_decode" "double")])
1799 (define_expand "movhi"
1800 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1801 (match_operand:HI 1 "general_operand" ""))]
1803 "ix86_expand_move (HImode, operands); DONE;")
1805 (define_insn "*pushhi2"
1806 [(set (match_operand:HI 0 "push_operand" "=X")
1807 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1810 [(set_attr "type" "push")
1811 (set_attr "mode" "SI")])
1813 ;; For 64BIT abi we always round up to 8 bytes.
1814 (define_insn "*pushhi2_rex64"
1815 [(set (match_operand:HI 0 "push_operand" "=X")
1816 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1819 [(set_attr "type" "push")
1820 (set_attr "mode" "DI")])
1822 (define_insn "*movhi_1"
1823 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1824 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1825 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1827 switch (get_attr_type (insn))
1830 /* movzwl is faster than movw on p2 due to partial word stalls,
1831 though not as fast as an aligned movl. */
1832 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1834 if (get_attr_mode (insn) == MODE_SI)
1835 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1837 return "mov{w}\t{%1, %0|%0, %1}";
1841 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1842 (const_string "imov")
1843 (and (eq_attr "alternative" "0")
1844 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1846 (eq (symbol_ref "TARGET_HIMODE_MATH")
1848 (const_string "imov")
1849 (and (eq_attr "alternative" "1,2")
1850 (match_operand:HI 1 "aligned_operand" ""))
1851 (const_string "imov")
1852 (and (ne (symbol_ref "TARGET_MOVX")
1854 (eq_attr "alternative" "0,2"))
1855 (const_string "imovx")
1857 (const_string "imov")))
1859 (cond [(eq_attr "type" "imovx")
1861 (and (eq_attr "alternative" "1,2")
1862 (match_operand:HI 1 "aligned_operand" ""))
1864 (and (eq_attr "alternative" "0")
1865 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1867 (eq (symbol_ref "TARGET_HIMODE_MATH")
1871 (const_string "HI")))])
1873 ;; Stores and loads of ax to arbitrary constant address.
1874 ;; We fake an second form of instruction to force reload to load address
1875 ;; into register when rax is not available
1876 (define_insn "*movabshi_1_rex64"
1877 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1878 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1879 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1881 movabs{w}\t{%1, %P0|%P0, %1}
1882 mov{w}\t{%1, %a0|%a0, %1}"
1883 [(set_attr "type" "imov")
1884 (set_attr "modrm" "0,*")
1885 (set_attr "length_address" "8,0")
1886 (set_attr "length_immediate" "0,*")
1887 (set_attr "memory" "store")
1888 (set_attr "mode" "HI")])
1890 (define_insn "*movabshi_2_rex64"
1891 [(set (match_operand:HI 0 "register_operand" "=a,r")
1892 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1893 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1895 movabs{w}\t{%P1, %0|%0, %P1}
1896 mov{w}\t{%a1, %0|%0, %a1}"
1897 [(set_attr "type" "imov")
1898 (set_attr "modrm" "0,*")
1899 (set_attr "length_address" "8,0")
1900 (set_attr "length_immediate" "0")
1901 (set_attr "memory" "load")
1902 (set_attr "mode" "HI")])
1904 (define_insn "*swaphi_1"
1905 [(set (match_operand:HI 0 "register_operand" "+r")
1906 (match_operand:HI 1 "register_operand" "+r"))
1909 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1911 [(set_attr "type" "imov")
1912 (set_attr "mode" "SI")
1913 (set_attr "pent_pair" "np")
1914 (set_attr "athlon_decode" "vector")
1915 (set_attr "amdfam10_decode" "double")])
1917 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1918 (define_insn "*swaphi_2"
1919 [(set (match_operand:HI 0 "register_operand" "+r")
1920 (match_operand:HI 1 "register_operand" "+r"))
1923 "TARGET_PARTIAL_REG_STALL"
1925 [(set_attr "type" "imov")
1926 (set_attr "mode" "HI")
1927 (set_attr "pent_pair" "np")
1928 (set_attr "athlon_decode" "vector")])
1930 (define_expand "movstricthi"
1931 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1932 (match_operand:HI 1 "general_operand" ""))]
1935 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1937 /* Don't generate memory->memory moves, go through a register */
1938 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1939 operands[1] = force_reg (HImode, operands[1]);
1942 (define_insn "*movstricthi_1"
1943 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1944 (match_operand:HI 1 "general_operand" "rn,m"))]
1945 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1946 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1947 "mov{w}\t{%1, %0|%0, %1}"
1948 [(set_attr "type" "imov")
1949 (set_attr "mode" "HI")])
1951 (define_insn "*movstricthi_xor"
1952 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1953 (match_operand:HI 1 "const0_operand" ""))
1954 (clobber (reg:CC FLAGS_REG))]
1957 [(set_attr "type" "alu1")
1958 (set_attr "mode" "HI")
1959 (set_attr "length_immediate" "0")])
1961 (define_expand "movqi"
1962 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1963 (match_operand:QI 1 "general_operand" ""))]
1965 "ix86_expand_move (QImode, operands); DONE;")
1967 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1968 ;; "push a byte". But actually we use pushl, which has the effect
1969 ;; of rounding the amount pushed up to a word.
1971 (define_insn "*pushqi2"
1972 [(set (match_operand:QI 0 "push_operand" "=X")
1973 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1976 [(set_attr "type" "push")
1977 (set_attr "mode" "SI")])
1979 ;; For 64BIT abi we always round up to 8 bytes.
1980 (define_insn "*pushqi2_rex64"
1981 [(set (match_operand:QI 0 "push_operand" "=X")
1982 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1985 [(set_attr "type" "push")
1986 (set_attr "mode" "DI")])
1988 ;; Situation is quite tricky about when to choose full sized (SImode) move
1989 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1990 ;; partial register dependency machines (such as AMD Athlon), where QImode
1991 ;; moves issue extra dependency and for partial register stalls machines
1992 ;; that don't use QImode patterns (and QImode move cause stall on the next
1995 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1996 ;; register stall machines with, where we use QImode instructions, since
1997 ;; partial register stall can be caused there. Then we use movzx.
1998 (define_insn "*movqi_1"
1999 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2000 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2001 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2003 switch (get_attr_type (insn))
2006 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2007 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2009 if (get_attr_mode (insn) == MODE_SI)
2010 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2012 return "mov{b}\t{%1, %0|%0, %1}";
2016 (cond [(and (eq_attr "alternative" "5")
2017 (not (match_operand:QI 1 "aligned_operand" "")))
2018 (const_string "imovx")
2019 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2020 (const_string "imov")
2021 (and (eq_attr "alternative" "3")
2022 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2024 (eq (symbol_ref "TARGET_QIMODE_MATH")
2026 (const_string "imov")
2027 (eq_attr "alternative" "3,5")
2028 (const_string "imovx")
2029 (and (ne (symbol_ref "TARGET_MOVX")
2031 (eq_attr "alternative" "2"))
2032 (const_string "imovx")
2034 (const_string "imov")))
2036 (cond [(eq_attr "alternative" "3,4,5")
2038 (eq_attr "alternative" "6")
2040 (eq_attr "type" "imovx")
2042 (and (eq_attr "type" "imov")
2043 (and (eq_attr "alternative" "0,1")
2044 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2046 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2048 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2051 ;; Avoid partial register stalls when not using QImode arithmetic
2052 (and (eq_attr "type" "imov")
2053 (and (eq_attr "alternative" "0,1")
2054 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2056 (eq (symbol_ref "TARGET_QIMODE_MATH")
2060 (const_string "QI")))])
2062 (define_insn "*swapqi_1"
2063 [(set (match_operand:QI 0 "register_operand" "+r")
2064 (match_operand:QI 1 "register_operand" "+r"))
2067 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2069 [(set_attr "type" "imov")
2070 (set_attr "mode" "SI")
2071 (set_attr "pent_pair" "np")
2072 (set_attr "athlon_decode" "vector")
2073 (set_attr "amdfam10_decode" "vector")])
2075 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2076 (define_insn "*swapqi_2"
2077 [(set (match_operand:QI 0 "register_operand" "+q")
2078 (match_operand:QI 1 "register_operand" "+q"))
2081 "TARGET_PARTIAL_REG_STALL"
2083 [(set_attr "type" "imov")
2084 (set_attr "mode" "QI")
2085 (set_attr "pent_pair" "np")
2086 (set_attr "athlon_decode" "vector")])
2088 (define_expand "movstrictqi"
2089 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2090 (match_operand:QI 1 "general_operand" ""))]
2093 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2095 /* Don't generate memory->memory moves, go through a register. */
2096 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2097 operands[1] = force_reg (QImode, operands[1]);
2100 (define_insn "*movstrictqi_1"
2101 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2102 (match_operand:QI 1 "general_operand" "*qn,m"))]
2103 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2104 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2105 "mov{b}\t{%1, %0|%0, %1}"
2106 [(set_attr "type" "imov")
2107 (set_attr "mode" "QI")])
2109 (define_insn "*movstrictqi_xor"
2110 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2111 (match_operand:QI 1 "const0_operand" ""))
2112 (clobber (reg:CC FLAGS_REG))]
2115 [(set_attr "type" "alu1")
2116 (set_attr "mode" "QI")
2117 (set_attr "length_immediate" "0")])
2119 (define_insn "*movsi_extv_1"
2120 [(set (match_operand:SI 0 "register_operand" "=R")
2121 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2125 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2126 [(set_attr "type" "imovx")
2127 (set_attr "mode" "SI")])
2129 (define_insn "*movhi_extv_1"
2130 [(set (match_operand:HI 0 "register_operand" "=R")
2131 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2135 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2136 [(set_attr "type" "imovx")
2137 (set_attr "mode" "SI")])
2139 (define_insn "*movqi_extv_1"
2140 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2141 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2146 switch (get_attr_type (insn))
2149 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2151 return "mov{b}\t{%h1, %0|%0, %h1}";
2155 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2156 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2157 (ne (symbol_ref "TARGET_MOVX")
2159 (const_string "imovx")
2160 (const_string "imov")))
2162 (if_then_else (eq_attr "type" "imovx")
2164 (const_string "QI")))])
2166 (define_insn "*movqi_extv_1_rex64"
2167 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2168 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2173 switch (get_attr_type (insn))
2176 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2178 return "mov{b}\t{%h1, %0|%0, %h1}";
2182 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2183 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2184 (ne (symbol_ref "TARGET_MOVX")
2186 (const_string "imovx")
2187 (const_string "imov")))
2189 (if_then_else (eq_attr "type" "imovx")
2191 (const_string "QI")))])
2193 ;; Stores and loads of ax to arbitrary constant address.
2194 ;; We fake an second form of instruction to force reload to load address
2195 ;; into register when rax is not available
2196 (define_insn "*movabsqi_1_rex64"
2197 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2198 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2199 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2201 movabs{b}\t{%1, %P0|%P0, %1}
2202 mov{b}\t{%1, %a0|%a0, %1}"
2203 [(set_attr "type" "imov")
2204 (set_attr "modrm" "0,*")
2205 (set_attr "length_address" "8,0")
2206 (set_attr "length_immediate" "0,*")
2207 (set_attr "memory" "store")
2208 (set_attr "mode" "QI")])
2210 (define_insn "*movabsqi_2_rex64"
2211 [(set (match_operand:QI 0 "register_operand" "=a,r")
2212 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2213 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2215 movabs{b}\t{%P1, %0|%0, %P1}
2216 mov{b}\t{%a1, %0|%0, %a1}"
2217 [(set_attr "type" "imov")
2218 (set_attr "modrm" "0,*")
2219 (set_attr "length_address" "8,0")
2220 (set_attr "length_immediate" "0")
2221 (set_attr "memory" "load")
2222 (set_attr "mode" "QI")])
2224 (define_insn "*movdi_extzv_1"
2225 [(set (match_operand:DI 0 "register_operand" "=R")
2226 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2230 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2231 [(set_attr "type" "imovx")
2232 (set_attr "mode" "SI")])
2234 (define_insn "*movsi_extzv_1"
2235 [(set (match_operand:SI 0 "register_operand" "=R")
2236 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2240 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2241 [(set_attr "type" "imovx")
2242 (set_attr "mode" "SI")])
2244 (define_insn "*movqi_extzv_2"
2245 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2246 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2251 switch (get_attr_type (insn))
2254 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2256 return "mov{b}\t{%h1, %0|%0, %h1}";
2260 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2261 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2262 (ne (symbol_ref "TARGET_MOVX")
2264 (const_string "imovx")
2265 (const_string "imov")))
2267 (if_then_else (eq_attr "type" "imovx")
2269 (const_string "QI")))])
2271 (define_insn "*movqi_extzv_2_rex64"
2272 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2273 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2278 switch (get_attr_type (insn))
2281 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2283 return "mov{b}\t{%h1, %0|%0, %h1}";
2287 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2288 (ne (symbol_ref "TARGET_MOVX")
2290 (const_string "imovx")
2291 (const_string "imov")))
2293 (if_then_else (eq_attr "type" "imovx")
2295 (const_string "QI")))])
2297 (define_insn "movsi_insv_1"
2298 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2301 (match_operand:SI 1 "general_operand" "Qmn"))]
2303 "mov{b}\t{%b1, %h0|%h0, %b1}"
2304 [(set_attr "type" "imov")
2305 (set_attr "mode" "QI")])
2307 (define_insn "*movsi_insv_1_rex64"
2308 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2311 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2313 "mov{b}\t{%b1, %h0|%h0, %b1}"
2314 [(set_attr "type" "imov")
2315 (set_attr "mode" "QI")])
2317 (define_insn "movdi_insv_1_rex64"
2318 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2321 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2323 "mov{b}\t{%b1, %h0|%h0, %b1}"
2324 [(set_attr "type" "imov")
2325 (set_attr "mode" "QI")])
2327 (define_insn "*movqi_insv_2"
2328 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2331 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2334 "mov{b}\t{%h1, %h0|%h0, %h1}"
2335 [(set_attr "type" "imov")
2336 (set_attr "mode" "QI")])
2338 (define_expand "movdi"
2339 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2340 (match_operand:DI 1 "general_operand" ""))]
2342 "ix86_expand_move (DImode, operands); DONE;")
2344 (define_insn "*pushdi"
2345 [(set (match_operand:DI 0 "push_operand" "=<")
2346 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2350 (define_insn "*pushdi2_rex64"
2351 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2352 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2357 [(set_attr "type" "push,multi")
2358 (set_attr "mode" "DI")])
2360 ;; Convert impossible pushes of immediate to existing instructions.
2361 ;; First try to get scratch register and go through it. In case this
2362 ;; fails, push sign extended lower part first and then overwrite
2363 ;; upper part by 32bit move.
2365 [(match_scratch:DI 2 "r")
2366 (set (match_operand:DI 0 "push_operand" "")
2367 (match_operand:DI 1 "immediate_operand" ""))]
2368 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2369 && !x86_64_immediate_operand (operands[1], DImode)"
2370 [(set (match_dup 2) (match_dup 1))
2371 (set (match_dup 0) (match_dup 2))]
2374 ;; We need to define this as both peepholer and splitter for case
2375 ;; peephole2 pass is not run.
2376 ;; "&& 1" is needed to keep it from matching the previous pattern.
2378 [(set (match_operand:DI 0 "push_operand" "")
2379 (match_operand:DI 1 "immediate_operand" ""))]
2380 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2381 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2382 [(set (match_dup 0) (match_dup 1))
2383 (set (match_dup 2) (match_dup 3))]
2385 split_di (&operands[1], 1, &operands[2], &operands[3]);
2387 operands[1] = gen_lowpart (DImode, operands[2]);
2388 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2393 [(set (match_operand:DI 0 "push_operand" "")
2394 (match_operand:DI 1 "immediate_operand" ""))]
2395 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2396 ? epilogue_completed : reload_completed)
2397 && !symbolic_operand (operands[1], DImode)
2398 && !x86_64_immediate_operand (operands[1], DImode)"
2399 [(set (match_dup 0) (match_dup 1))
2400 (set (match_dup 2) (match_dup 3))]
2402 split_di (&operands[1], 1, &operands[2], &operands[3]);
2404 operands[1] = gen_lowpart (DImode, operands[2]);
2405 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2409 (define_insn "*pushdi2_prologue_rex64"
2410 [(set (match_operand:DI 0 "push_operand" "=<")
2411 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2412 (clobber (mem:BLK (scratch)))]
2415 [(set_attr "type" "push")
2416 (set_attr "mode" "DI")])
2418 (define_insn "*popdi1_epilogue_rex64"
2419 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2420 (mem:DI (reg:DI SP_REG)))
2421 (set (reg:DI SP_REG)
2422 (plus:DI (reg:DI SP_REG) (const_int 8)))
2423 (clobber (mem:BLK (scratch)))]
2426 [(set_attr "type" "pop")
2427 (set_attr "mode" "DI")])
2429 (define_insn "popdi1"
2430 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2431 (mem:DI (reg:DI SP_REG)))
2432 (set (reg:DI SP_REG)
2433 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2436 [(set_attr "type" "pop")
2437 (set_attr "mode" "DI")])
2439 (define_insn "*movdi_xor_rex64"
2440 [(set (match_operand:DI 0 "register_operand" "=r")
2441 (match_operand:DI 1 "const0_operand" ""))
2442 (clobber (reg:CC FLAGS_REG))]
2444 && reload_completed"
2446 [(set_attr "type" "alu1")
2447 (set_attr "mode" "SI")
2448 (set_attr "length_immediate" "0")])
2450 (define_insn "*movdi_or_rex64"
2451 [(set (match_operand:DI 0 "register_operand" "=r")
2452 (match_operand:DI 1 "const_int_operand" "i"))
2453 (clobber (reg:CC FLAGS_REG))]
2456 && operands[1] == constm1_rtx"
2458 operands[1] = constm1_rtx;
2459 return "or{q}\t{%1, %0|%0, %1}";
2461 [(set_attr "type" "alu1")
2462 (set_attr "mode" "DI")
2463 (set_attr "length_immediate" "1")])
2465 (define_insn "*movdi_2"
2466 [(set (match_operand:DI 0 "nonimmediate_operand"
2467 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2468 (match_operand:DI 1 "general_operand"
2469 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2470 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2475 movq\t{%1, %0|%0, %1}
2476 movq\t{%1, %0|%0, %1}
2478 %vmovq\t{%1, %0|%0, %1}
2479 %vmovdqa\t{%1, %0|%0, %1}
2480 %vmovq\t{%1, %0|%0, %1}
2482 movlps\t{%1, %0|%0, %1}
2483 movaps\t{%1, %0|%0, %1}
2484 movlps\t{%1, %0|%0, %1}"
2485 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2486 (set (attr "prefix")
2487 (if_then_else (eq_attr "alternative" "5,6,7,8")
2488 (const_string "vex")
2489 (const_string "orig")))
2490 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2493 [(set (match_operand:DI 0 "push_operand" "")
2494 (match_operand:DI 1 "general_operand" ""))]
2495 "!TARGET_64BIT && reload_completed
2496 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2498 "ix86_split_long_move (operands); DONE;")
2500 ;; %%% This multiword shite has got to go.
2502 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2503 (match_operand:DI 1 "general_operand" ""))]
2504 "!TARGET_64BIT && reload_completed
2505 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2506 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2508 "ix86_split_long_move (operands); DONE;")
2510 (define_insn "*movdi_1_rex64"
2511 [(set (match_operand:DI 0 "nonimmediate_operand"
2512 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2513 (match_operand:DI 1 "general_operand"
2514 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2515 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2517 switch (get_attr_type (insn))
2520 if (SSE_REG_P (operands[0]))
2521 return "movq2dq\t{%1, %0|%0, %1}";
2523 return "movdq2q\t{%1, %0|%0, %1}";
2528 if (get_attr_mode (insn) == MODE_TI)
2529 return "vmovdqa\t{%1, %0|%0, %1}";
2531 return "vmovq\t{%1, %0|%0, %1}";
2534 if (get_attr_mode (insn) == MODE_TI)
2535 return "movdqa\t{%1, %0|%0, %1}";
2539 /* Moves from and into integer register is done using movd
2540 opcode with REX prefix. */
2541 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2542 return "movd\t{%1, %0|%0, %1}";
2543 return "movq\t{%1, %0|%0, %1}";
2546 return "%vpxor\t%0, %d0";
2549 return "pxor\t%0, %0";
2555 return "lea{q}\t{%a1, %0|%0, %a1}";
2558 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2559 if (get_attr_mode (insn) == MODE_SI)
2560 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2561 else if (which_alternative == 2)
2562 return "movabs{q}\t{%1, %0|%0, %1}";
2564 return "mov{q}\t{%1, %0|%0, %1}";
2568 (cond [(eq_attr "alternative" "5")
2569 (const_string "mmx")
2570 (eq_attr "alternative" "6,7,8,9,10")
2571 (const_string "mmxmov")
2572 (eq_attr "alternative" "11")
2573 (const_string "sselog1")
2574 (eq_attr "alternative" "12,13,14,15,16")
2575 (const_string "ssemov")
2576 (eq_attr "alternative" "17,18")
2577 (const_string "ssecvt")
2578 (eq_attr "alternative" "4")
2579 (const_string "multi")
2580 (match_operand:DI 1 "pic_32bit_operand" "")
2581 (const_string "lea")
2583 (const_string "imov")))
2586 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2588 (const_string "*")))
2589 (set (attr "length_immediate")
2591 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2593 (const_string "*")))
2594 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2595 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2596 (set (attr "prefix")
2597 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2598 (const_string "maybe_vex")
2599 (const_string "orig")))
2600 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2602 ;; Stores and loads of ax to arbitrary constant address.
2603 ;; We fake an second form of instruction to force reload to load address
2604 ;; into register when rax is not available
2605 (define_insn "*movabsdi_1_rex64"
2606 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2607 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2608 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2610 movabs{q}\t{%1, %P0|%P0, %1}
2611 mov{q}\t{%1, %a0|%a0, %1}"
2612 [(set_attr "type" "imov")
2613 (set_attr "modrm" "0,*")
2614 (set_attr "length_address" "8,0")
2615 (set_attr "length_immediate" "0,*")
2616 (set_attr "memory" "store")
2617 (set_attr "mode" "DI")])
2619 (define_insn "*movabsdi_2_rex64"
2620 [(set (match_operand:DI 0 "register_operand" "=a,r")
2621 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2622 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2624 movabs{q}\t{%P1, %0|%0, %P1}
2625 mov{q}\t{%a1, %0|%0, %a1}"
2626 [(set_attr "type" "imov")
2627 (set_attr "modrm" "0,*")
2628 (set_attr "length_address" "8,0")
2629 (set_attr "length_immediate" "0")
2630 (set_attr "memory" "load")
2631 (set_attr "mode" "DI")])
2633 ;; Convert impossible stores of immediate to existing instructions.
2634 ;; First try to get scratch register and go through it. In case this
2635 ;; fails, move by 32bit parts.
2637 [(match_scratch:DI 2 "r")
2638 (set (match_operand:DI 0 "memory_operand" "")
2639 (match_operand:DI 1 "immediate_operand" ""))]
2640 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2641 && !x86_64_immediate_operand (operands[1], DImode)"
2642 [(set (match_dup 2) (match_dup 1))
2643 (set (match_dup 0) (match_dup 2))]
2646 ;; We need to define this as both peepholer and splitter for case
2647 ;; peephole2 pass is not run.
2648 ;; "&& 1" is needed to keep it from matching the previous pattern.
2650 [(set (match_operand:DI 0 "memory_operand" "")
2651 (match_operand:DI 1 "immediate_operand" ""))]
2652 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2653 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2654 [(set (match_dup 2) (match_dup 3))
2655 (set (match_dup 4) (match_dup 5))]
2656 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2659 [(set (match_operand:DI 0 "memory_operand" "")
2660 (match_operand:DI 1 "immediate_operand" ""))]
2661 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2662 ? epilogue_completed : reload_completed)
2663 && !symbolic_operand (operands[1], DImode)
2664 && !x86_64_immediate_operand (operands[1], DImode)"
2665 [(set (match_dup 2) (match_dup 3))
2666 (set (match_dup 4) (match_dup 5))]
2667 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2669 (define_insn "*swapdi_rex64"
2670 [(set (match_operand:DI 0 "register_operand" "+r")
2671 (match_operand:DI 1 "register_operand" "+r"))
2676 [(set_attr "type" "imov")
2677 (set_attr "mode" "DI")
2678 (set_attr "pent_pair" "np")
2679 (set_attr "athlon_decode" "vector")
2680 (set_attr "amdfam10_decode" "double")])
2682 (define_expand "movoi"
2683 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2684 (match_operand:OI 1 "general_operand" ""))]
2686 "ix86_expand_move (OImode, operands); DONE;")
2688 (define_insn "*movoi_internal"
2689 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2690 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2692 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2694 switch (which_alternative)
2697 return "vxorps\t%0, %0, %0";
2700 if (misaligned_operand (operands[0], OImode)
2701 || misaligned_operand (operands[1], OImode))
2702 return "vmovdqu\t{%1, %0|%0, %1}";
2704 return "vmovdqa\t{%1, %0|%0, %1}";
2709 [(set_attr "type" "sselog1,ssemov,ssemov")
2710 (set_attr "prefix" "vex")
2711 (set_attr "mode" "OI")])
2713 (define_expand "movti"
2714 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2715 (match_operand:TI 1 "nonimmediate_operand" ""))]
2716 "TARGET_SSE || TARGET_64BIT"
2719 ix86_expand_move (TImode, operands);
2720 else if (push_operand (operands[0], TImode))
2721 ix86_expand_push (TImode, operands[1]);
2723 ix86_expand_vector_move (TImode, operands);
2727 (define_insn "*movti_internal"
2728 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2729 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2730 "TARGET_SSE && !TARGET_64BIT
2731 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2733 switch (which_alternative)
2736 if (get_attr_mode (insn) == MODE_V4SF)
2737 return "%vxorps\t%0, %d0";
2739 return "%vpxor\t%0, %d0";
2742 /* TDmode values are passed as TImode on the stack. Moving them
2743 to stack may result in unaligned memory access. */
2744 if (misaligned_operand (operands[0], TImode)
2745 || misaligned_operand (operands[1], TImode))
2747 if (get_attr_mode (insn) == MODE_V4SF)
2748 return "%vmovups\t{%1, %0|%0, %1}";
2750 return "%vmovdqu\t{%1, %0|%0, %1}";
2754 if (get_attr_mode (insn) == MODE_V4SF)
2755 return "%vmovaps\t{%1, %0|%0, %1}";
2757 return "%vmovdqa\t{%1, %0|%0, %1}";
2763 [(set_attr "type" "sselog1,ssemov,ssemov")
2764 (set_attr "prefix" "maybe_vex")
2766 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2767 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2768 (const_string "V4SF")
2769 (and (eq_attr "alternative" "2")
2770 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2772 (const_string "V4SF")]
2773 (const_string "TI")))])
2775 (define_insn "*movti_rex64"
2776 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2777 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2779 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2781 switch (which_alternative)
2787 if (get_attr_mode (insn) == MODE_V4SF)
2788 return "%vxorps\t%0, %d0";
2790 return "%vpxor\t%0, %d0";
2793 /* TDmode values are passed as TImode on the stack. Moving them
2794 to stack may result in unaligned memory access. */
2795 if (misaligned_operand (operands[0], TImode)
2796 || misaligned_operand (operands[1], TImode))
2798 if (get_attr_mode (insn) == MODE_V4SF)
2799 return "%vmovups\t{%1, %0|%0, %1}";
2801 return "%vmovdqu\t{%1, %0|%0, %1}";
2805 if (get_attr_mode (insn) == MODE_V4SF)
2806 return "%vmovaps\t{%1, %0|%0, %1}";
2808 return "%vmovdqa\t{%1, %0|%0, %1}";
2814 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2815 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2817 (cond [(eq_attr "alternative" "2,3")
2819 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2821 (const_string "V4SF")
2822 (const_string "TI"))
2823 (eq_attr "alternative" "4")
2825 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2827 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2829 (const_string "V4SF")
2830 (const_string "TI"))]
2831 (const_string "DI")))])
2834 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2835 (match_operand:TI 1 "general_operand" ""))]
2836 "reload_completed && !SSE_REG_P (operands[0])
2837 && !SSE_REG_P (operands[1])"
2839 "ix86_split_long_move (operands); DONE;")
2841 ;; This expands to what emit_move_complex would generate if we didn't
2842 ;; have a movti pattern. Having this avoids problems with reload on
2843 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2844 ;; to have around all the time.
2845 (define_expand "movcdi"
2846 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2847 (match_operand:CDI 1 "general_operand" ""))]
2850 if (push_operand (operands[0], CDImode))
2851 emit_move_complex_push (CDImode, operands[0], operands[1]);
2853 emit_move_complex_parts (operands[0], operands[1]);
2857 (define_expand "movsf"
2858 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2859 (match_operand:SF 1 "general_operand" ""))]
2861 "ix86_expand_move (SFmode, operands); DONE;")
2863 (define_insn "*pushsf"
2864 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2865 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2868 /* Anything else should be already split before reg-stack. */
2869 gcc_assert (which_alternative == 1);
2870 return "push{l}\t%1";
2872 [(set_attr "type" "multi,push,multi")
2873 (set_attr "unit" "i387,*,*")
2874 (set_attr "mode" "SF,SI,SF")])
2876 (define_insn "*pushsf_rex64"
2877 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2878 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2881 /* Anything else should be already split before reg-stack. */
2882 gcc_assert (which_alternative == 1);
2883 return "push{q}\t%q1";
2885 [(set_attr "type" "multi,push,multi")
2886 (set_attr "unit" "i387,*,*")
2887 (set_attr "mode" "SF,DI,SF")])
2890 [(set (match_operand:SF 0 "push_operand" "")
2891 (match_operand:SF 1 "memory_operand" ""))]
2893 && MEM_P (operands[1])
2894 && (operands[2] = find_constant_src (insn))"
2898 ;; %%% Kill this when call knows how to work this out.
2900 [(set (match_operand:SF 0 "push_operand" "")
2901 (match_operand:SF 1 "any_fp_register_operand" ""))]
2903 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2904 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2907 [(set (match_operand:SF 0 "push_operand" "")
2908 (match_operand:SF 1 "any_fp_register_operand" ""))]
2910 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2911 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2913 (define_insn "*movsf_1"
2914 [(set (match_operand:SF 0 "nonimmediate_operand"
2915 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2916 (match_operand:SF 1 "general_operand"
2917 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2918 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2919 && (reload_in_progress || reload_completed
2920 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2921 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2922 && standard_80387_constant_p (operands[1]))
2923 || GET_CODE (operands[1]) != CONST_DOUBLE
2924 || memory_operand (operands[0], SFmode))"
2926 switch (which_alternative)
2930 return output_387_reg_move (insn, operands);
2933 return standard_80387_constant_opcode (operands[1]);
2937 return "mov{l}\t{%1, %0|%0, %1}";
2939 if (get_attr_mode (insn) == MODE_TI)
2940 return "%vpxor\t%0, %d0";
2942 return "%vxorps\t%0, %d0";
2944 if (get_attr_mode (insn) == MODE_V4SF)
2945 return "%vmovaps\t{%1, %0|%0, %1}";
2947 return "%vmovss\t{%1, %d0|%d0, %1}";
2950 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2951 : "vmovss\t{%1, %0|%0, %1}";
2953 return "movss\t{%1, %0|%0, %1}";
2955 return "%vmovss\t{%1, %0|%0, %1}";
2957 case 9: case 10: case 14: case 15:
2958 return "movd\t{%1, %0|%0, %1}";
2960 return "%vmovd\t{%1, %0|%0, %1}";
2963 return "movq\t{%1, %0|%0, %1}";
2969 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2970 (set (attr "prefix")
2971 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2972 (const_string "maybe_vex")
2973 (const_string "orig")))
2975 (cond [(eq_attr "alternative" "3,4,9,10")
2977 (eq_attr "alternative" "5")
2979 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2981 (ne (symbol_ref "TARGET_SSE2")
2983 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2986 (const_string "V4SF"))
2987 /* For architectures resolving dependencies on
2988 whole SSE registers use APS move to break dependency
2989 chains, otherwise use short move to avoid extra work.
2991 Do the same for architectures resolving dependencies on
2992 the parts. While in DF mode it is better to always handle
2993 just register parts, the SF mode is different due to lack
2994 of instructions to load just part of the register. It is
2995 better to maintain the whole registers in single format
2996 to avoid problems on using packed logical operations. */
2997 (eq_attr "alternative" "6")
2999 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3001 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3003 (const_string "V4SF")
3004 (const_string "SF"))
3005 (eq_attr "alternative" "11")
3006 (const_string "DI")]
3007 (const_string "SF")))])
3009 (define_insn "*swapsf"
3010 [(set (match_operand:SF 0 "fp_register_operand" "+f")
3011 (match_operand:SF 1 "fp_register_operand" "+f"))
3014 "reload_completed || TARGET_80387"
3016 if (STACK_TOP_P (operands[0]))
3021 [(set_attr "type" "fxch")
3022 (set_attr "mode" "SF")])
3024 (define_expand "movdf"
3025 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3026 (match_operand:DF 1 "general_operand" ""))]
3028 "ix86_expand_move (DFmode, operands); DONE;")
3030 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3031 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3032 ;; On the average, pushdf using integers can be still shorter. Allow this
3033 ;; pattern for optimize_size too.
3035 (define_insn "*pushdf_nointeger"
3036 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3037 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3038 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3040 /* This insn should be already split before reg-stack. */
3043 [(set_attr "type" "multi")
3044 (set_attr "unit" "i387,*,*,*")
3045 (set_attr "mode" "DF,SI,SI,DF")])
3047 (define_insn "*pushdf_integer"
3048 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3049 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3050 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3052 /* This insn should be already split before reg-stack. */
3055 [(set_attr "type" "multi")
3056 (set_attr "unit" "i387,*,*")
3057 (set_attr "mode" "DF,SI,DF")])
3059 ;; %%% Kill this when call knows how to work this out.
3061 [(set (match_operand:DF 0 "push_operand" "")
3062 (match_operand:DF 1 "any_fp_register_operand" ""))]
3064 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3065 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3069 [(set (match_operand:DF 0 "push_operand" "")
3070 (match_operand:DF 1 "general_operand" ""))]
3073 "ix86_split_long_move (operands); DONE;")
3075 ;; Moving is usually shorter when only FP registers are used. This separate
3076 ;; movdf pattern avoids the use of integer registers for FP operations
3077 ;; when optimizing for size.
3079 (define_insn "*movdf_nointeger"
3080 [(set (match_operand:DF 0 "nonimmediate_operand"
3081 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3082 (match_operand:DF 1 "general_operand"
3083 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3084 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3085 && ((optimize_function_for_size_p (cfun)
3086 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3087 && (reload_in_progress || reload_completed
3088 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3089 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3090 && optimize_function_for_size_p (cfun)
3091 && !memory_operand (operands[0], DFmode)
3092 && standard_80387_constant_p (operands[1]))
3093 || GET_CODE (operands[1]) != CONST_DOUBLE
3094 || ((optimize_function_for_size_p (cfun)
3095 || !TARGET_MEMORY_MISMATCH_STALL
3096 || reload_in_progress || reload_completed)
3097 && memory_operand (operands[0], DFmode)))"
3099 switch (which_alternative)
3103 return output_387_reg_move (insn, operands);
3106 return standard_80387_constant_opcode (operands[1]);
3112 switch (get_attr_mode (insn))
3115 return "%vxorps\t%0, %d0";
3117 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3118 return "%vxorps\t%0, %d0";
3120 return "%vxorpd\t%0, %d0";
3122 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3123 return "%vxorps\t%0, %d0";
3125 return "%vpxor\t%0, %d0";
3132 switch (get_attr_mode (insn))
3135 return "%vmovaps\t{%1, %0|%0, %1}";
3137 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3138 return "%vmovaps\t{%1, %0|%0, %1}";
3140 return "%vmovapd\t{%1, %0|%0, %1}";
3142 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3143 return "%vmovaps\t{%1, %0|%0, %1}";
3145 return "%vmovdqa\t{%1, %0|%0, %1}";
3147 return "%vmovq\t{%1, %0|%0, %1}";
3151 if (REG_P (operands[0]) && REG_P (operands[1]))
3152 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3154 return "vmovsd\t{%1, %0|%0, %1}";
3157 return "movsd\t{%1, %0|%0, %1}";
3161 if (REG_P (operands[0]))
3162 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3164 return "vmovlpd\t{%1, %0|%0, %1}";
3167 return "movlpd\t{%1, %0|%0, %1}";
3171 if (REG_P (operands[0]))
3172 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3174 return "vmovlps\t{%1, %0|%0, %1}";
3177 return "movlps\t{%1, %0|%0, %1}";
3186 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3187 (set (attr "prefix")
3188 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3189 (const_string "orig")
3190 (const_string "maybe_vex")))
3191 (set (attr "prefix_data16")
3192 (if_then_else (eq_attr "mode" "V1DF")
3194 (const_string "*")))
3196 (cond [(eq_attr "alternative" "0,1,2")
3198 (eq_attr "alternative" "3,4")
3201 /* For SSE1, we have many fewer alternatives. */
3202 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3203 (cond [(eq_attr "alternative" "5,6")
3204 (const_string "V4SF")
3206 (const_string "V2SF"))
3208 /* xorps is one byte shorter. */
3209 (eq_attr "alternative" "5")
3210 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3212 (const_string "V4SF")
3213 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3217 (const_string "V2DF"))
3219 /* For architectures resolving dependencies on
3220 whole SSE registers use APD move to break dependency
3221 chains, otherwise use short move to avoid extra work.
3223 movaps encodes one byte shorter. */
3224 (eq_attr "alternative" "6")
3226 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3228 (const_string "V4SF")
3229 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3231 (const_string "V2DF")
3233 (const_string "DF"))
3234 /* For architectures resolving dependencies on register
3235 parts we may avoid extra work to zero out upper part
3237 (eq_attr "alternative" "7")
3239 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3241 (const_string "V1DF")
3242 (const_string "DF"))
3244 (const_string "DF")))])
3246 (define_insn "*movdf_integer_rex64"
3247 [(set (match_operand:DF 0 "nonimmediate_operand"
3248 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3249 (match_operand:DF 1 "general_operand"
3250 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3251 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3252 && (reload_in_progress || reload_completed
3253 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3254 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3255 && optimize_function_for_size_p (cfun)
3256 && standard_80387_constant_p (operands[1]))
3257 || GET_CODE (operands[1]) != CONST_DOUBLE
3258 || memory_operand (operands[0], DFmode))"
3260 switch (which_alternative)
3264 return output_387_reg_move (insn, operands);
3267 return standard_80387_constant_opcode (operands[1]);
3274 switch (get_attr_mode (insn))
3277 return "%vxorps\t%0, %d0";
3279 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3280 return "%vxorps\t%0, %d0";
3282 return "%vxorpd\t%0, %d0";
3284 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3285 return "%vxorps\t%0, %d0";
3287 return "%vpxor\t%0, %d0";
3294 switch (get_attr_mode (insn))
3297 return "%vmovaps\t{%1, %0|%0, %1}";
3299 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3300 return "%vmovaps\t{%1, %0|%0, %1}";
3302 return "%vmovapd\t{%1, %0|%0, %1}";
3304 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3305 return "%vmovaps\t{%1, %0|%0, %1}";
3307 return "%vmovdqa\t{%1, %0|%0, %1}";
3309 return "%vmovq\t{%1, %0|%0, %1}";
3313 if (REG_P (operands[0]) && REG_P (operands[1]))
3314 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3316 return "vmovsd\t{%1, %0|%0, %1}";
3319 return "movsd\t{%1, %0|%0, %1}";
3321 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3323 return "%vmovlps\t{%1, %d0|%d0, %1}";
3330 return "%vmovd\t{%1, %0|%0, %1}";
3336 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3337 (set (attr "prefix")
3338 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3339 (const_string "orig")
3340 (const_string "maybe_vex")))
3341 (set (attr "prefix_data16")
3342 (if_then_else (eq_attr "mode" "V1DF")
3344 (const_string "*")))
3346 (cond [(eq_attr "alternative" "0,1,2")
3348 (eq_attr "alternative" "3,4,9,10")
3351 /* For SSE1, we have many fewer alternatives. */
3352 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3353 (cond [(eq_attr "alternative" "5,6")
3354 (const_string "V4SF")
3356 (const_string "V2SF"))
3358 /* xorps is one byte shorter. */
3359 (eq_attr "alternative" "5")
3360 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3362 (const_string "V4SF")
3363 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3367 (const_string "V2DF"))
3369 /* For architectures resolving dependencies on
3370 whole SSE registers use APD move to break dependency
3371 chains, otherwise use short move to avoid extra work.
3373 movaps encodes one byte shorter. */
3374 (eq_attr "alternative" "6")
3376 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3378 (const_string "V4SF")
3379 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3381 (const_string "V2DF")
3383 (const_string "DF"))
3384 /* For architectures resolving dependencies on register
3385 parts we may avoid extra work to zero out upper part
3387 (eq_attr "alternative" "7")
3389 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3391 (const_string "V1DF")
3392 (const_string "DF"))
3394 (const_string "DF")))])
3396 (define_insn "*movdf_integer"
3397 [(set (match_operand:DF 0 "nonimmediate_operand"
3398 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3399 (match_operand:DF 1 "general_operand"
3400 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3401 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3402 && optimize_function_for_speed_p (cfun)
3403 && TARGET_INTEGER_DFMODE_MOVES
3404 && (reload_in_progress || reload_completed
3405 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3406 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3407 && optimize_function_for_size_p (cfun)
3408 && standard_80387_constant_p (operands[1]))
3409 || GET_CODE (operands[1]) != CONST_DOUBLE
3410 || memory_operand (operands[0], DFmode))"
3412 switch (which_alternative)
3416 return output_387_reg_move (insn, operands);
3419 return standard_80387_constant_opcode (operands[1]);
3426 switch (get_attr_mode (insn))
3429 return "xorps\t%0, %0";
3431 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3432 return "xorps\t%0, %0";
3434 return "xorpd\t%0, %0";
3436 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3437 return "xorps\t%0, %0";
3439 return "pxor\t%0, %0";
3446 switch (get_attr_mode (insn))
3449 return "movaps\t{%1, %0|%0, %1}";
3451 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3452 return "movaps\t{%1, %0|%0, %1}";
3454 return "movapd\t{%1, %0|%0, %1}";
3456 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3457 return "movaps\t{%1, %0|%0, %1}";
3459 return "movdqa\t{%1, %0|%0, %1}";
3461 return "movq\t{%1, %0|%0, %1}";
3463 return "movsd\t{%1, %0|%0, %1}";
3465 return "movlpd\t{%1, %0|%0, %1}";
3467 return "movlps\t{%1, %0|%0, %1}";
3476 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3477 (set (attr "prefix_data16")
3478 (if_then_else (eq_attr "mode" "V1DF")
3480 (const_string "*")))
3482 (cond [(eq_attr "alternative" "0,1,2")
3484 (eq_attr "alternative" "3,4")
3487 /* For SSE1, we have many fewer alternatives. */
3488 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3489 (cond [(eq_attr "alternative" "5,6")
3490 (const_string "V4SF")
3492 (const_string "V2SF"))
3494 /* xorps is one byte shorter. */
3495 (eq_attr "alternative" "5")
3496 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3498 (const_string "V4SF")
3499 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3503 (const_string "V2DF"))
3505 /* For architectures resolving dependencies on
3506 whole SSE registers use APD move to break dependency
3507 chains, otherwise use short move to avoid extra work.
3509 movaps encodes one byte shorter. */
3510 (eq_attr "alternative" "6")
3512 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3514 (const_string "V4SF")
3515 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3517 (const_string "V2DF")
3519 (const_string "DF"))
3520 /* For architectures resolving dependencies on register
3521 parts we may avoid extra work to zero out upper part
3523 (eq_attr "alternative" "7")
3525 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3527 (const_string "V1DF")
3528 (const_string "DF"))
3530 (const_string "DF")))])
3533 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3534 (match_operand:DF 1 "general_operand" ""))]
3536 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3537 && ! (ANY_FP_REG_P (operands[0]) ||
3538 (GET_CODE (operands[0]) == SUBREG
3539 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3540 && ! (ANY_FP_REG_P (operands[1]) ||
3541 (GET_CODE (operands[1]) == SUBREG
3542 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3544 "ix86_split_long_move (operands); DONE;")
3546 (define_insn "*swapdf"
3547 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3548 (match_operand:DF 1 "fp_register_operand" "+f"))
3551 "reload_completed || TARGET_80387"
3553 if (STACK_TOP_P (operands[0]))
3558 [(set_attr "type" "fxch")
3559 (set_attr "mode" "DF")])
3561 (define_expand "movxf"
3562 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3563 (match_operand:XF 1 "general_operand" ""))]
3565 "ix86_expand_move (XFmode, operands); DONE;")
3567 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3568 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3569 ;; Pushing using integer instructions is longer except for constants
3570 ;; and direct memory references.
3571 ;; (assuming that any given constant is pushed only once, but this ought to be
3572 ;; handled elsewhere).
3574 (define_insn "*pushxf_nointeger"
3575 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3576 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3577 "optimize_function_for_size_p (cfun)"
3579 /* This insn should be already split before reg-stack. */
3582 [(set_attr "type" "multi")
3583 (set_attr "unit" "i387,*,*")
3584 (set_attr "mode" "XF,SI,SI")])
3586 (define_insn "*pushxf_integer"
3587 [(set (match_operand:XF 0 "push_operand" "=<,<")
3588 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3589 "optimize_function_for_speed_p (cfun)"
3591 /* This insn should be already split before reg-stack. */
3594 [(set_attr "type" "multi")
3595 (set_attr "unit" "i387,*")
3596 (set_attr "mode" "XF,SI")])
3599 [(set (match_operand 0 "push_operand" "")
3600 (match_operand 1 "general_operand" ""))]
3602 && (GET_MODE (operands[0]) == XFmode
3603 || GET_MODE (operands[0]) == DFmode)
3604 && !ANY_FP_REG_P (operands[1])"
3606 "ix86_split_long_move (operands); DONE;")
3609 [(set (match_operand:XF 0 "push_operand" "")
3610 (match_operand:XF 1 "any_fp_register_operand" ""))]
3612 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3613 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3614 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3616 ;; Do not use integer registers when optimizing for size
3617 (define_insn "*movxf_nointeger"
3618 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3619 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3620 "optimize_function_for_size_p (cfun)
3621 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3622 && (reload_in_progress || reload_completed
3623 || standard_80387_constant_p (operands[1])
3624 || GET_CODE (operands[1]) != CONST_DOUBLE
3625 || memory_operand (operands[0], XFmode))"
3627 switch (which_alternative)
3631 return output_387_reg_move (insn, operands);
3634 return standard_80387_constant_opcode (operands[1]);
3642 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3643 (set_attr "mode" "XF,XF,XF,SI,SI")])
3645 (define_insn "*movxf_integer"
3646 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3647 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3648 "optimize_function_for_speed_p (cfun)
3649 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3650 && (reload_in_progress || reload_completed
3651 || GET_CODE (operands[1]) != CONST_DOUBLE
3652 || memory_operand (operands[0], XFmode))"
3654 switch (which_alternative)
3658 return output_387_reg_move (insn, operands);
3661 return standard_80387_constant_opcode (operands[1]);
3670 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3671 (set_attr "mode" "XF,XF,XF,SI,SI")])
3673 (define_expand "movtf"
3674 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3675 (match_operand:TF 1 "nonimmediate_operand" ""))]
3678 ix86_expand_move (TFmode, operands);
3682 (define_insn "*movtf_internal"
3683 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3684 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3686 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3688 switch (which_alternative)
3692 if (get_attr_mode (insn) == MODE_V4SF)
3693 return "%vmovaps\t{%1, %0|%0, %1}";
3695 return "%vmovdqa\t{%1, %0|%0, %1}";
3697 if (get_attr_mode (insn) == MODE_V4SF)
3698 return "%vxorps\t%0, %d0";
3700 return "%vpxor\t%0, %d0";
3708 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3709 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3711 (cond [(eq_attr "alternative" "0,2")
3713 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3715 (const_string "V4SF")
3716 (const_string "TI"))
3717 (eq_attr "alternative" "1")
3719 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3721 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3723 (const_string "V4SF")
3724 (const_string "TI"))]
3725 (const_string "DI")))])
3727 (define_insn "*pushtf_sse"
3728 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3729 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3732 /* This insn should be already split before reg-stack. */
3735 [(set_attr "type" "multi")
3736 (set_attr "unit" "sse,*,*")
3737 (set_attr "mode" "TF,SI,SI")])
3740 [(set (match_operand:TF 0 "push_operand" "")
3741 (match_operand:TF 1 "general_operand" ""))]
3742 "TARGET_SSE2 && reload_completed
3743 && !SSE_REG_P (operands[1])"
3745 "ix86_split_long_move (operands); DONE;")
3748 [(set (match_operand:TF 0 "push_operand" "")
3749 (match_operand:TF 1 "any_fp_register_operand" ""))]
3751 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3752 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3756 [(set (match_operand 0 "nonimmediate_operand" "")
3757 (match_operand 1 "general_operand" ""))]
3759 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3760 && GET_MODE (operands[0]) == XFmode
3761 && ! (ANY_FP_REG_P (operands[0]) ||
3762 (GET_CODE (operands[0]) == SUBREG
3763 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3764 && ! (ANY_FP_REG_P (operands[1]) ||
3765 (GET_CODE (operands[1]) == SUBREG
3766 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3768 "ix86_split_long_move (operands); DONE;")
3771 [(set (match_operand 0 "register_operand" "")
3772 (match_operand 1 "memory_operand" ""))]
3774 && MEM_P (operands[1])
3775 && (GET_MODE (operands[0]) == TFmode
3776 || GET_MODE (operands[0]) == XFmode
3777 || GET_MODE (operands[0]) == SFmode
3778 || GET_MODE (operands[0]) == DFmode)
3779 && (operands[2] = find_constant_src (insn))"
3780 [(set (match_dup 0) (match_dup 2))]
3782 rtx c = operands[2];
3783 rtx r = operands[0];
3785 if (GET_CODE (r) == SUBREG)
3790 if (!standard_sse_constant_p (c))
3793 else if (FP_REG_P (r))
3795 if (!standard_80387_constant_p (c))
3798 else if (MMX_REG_P (r))
3803 [(set (match_operand 0 "register_operand" "")
3804 (float_extend (match_operand 1 "memory_operand" "")))]
3806 && MEM_P (operands[1])
3807 && (GET_MODE (operands[0]) == TFmode
3808 || GET_MODE (operands[0]) == XFmode
3809 || GET_MODE (operands[0]) == SFmode
3810 || GET_MODE (operands[0]) == DFmode)
3811 && (operands[2] = find_constant_src (insn))"
3812 [(set (match_dup 0) (match_dup 2))]
3814 rtx c = operands[2];
3815 rtx r = operands[0];
3817 if (GET_CODE (r) == SUBREG)
3822 if (!standard_sse_constant_p (c))
3825 else if (FP_REG_P (r))
3827 if (!standard_80387_constant_p (c))
3830 else if (MMX_REG_P (r))
3834 (define_insn "swapxf"
3835 [(set (match_operand:XF 0 "register_operand" "+f")
3836 (match_operand:XF 1 "register_operand" "+f"))
3841 if (STACK_TOP_P (operands[0]))
3846 [(set_attr "type" "fxch")
3847 (set_attr "mode" "XF")])
3849 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3851 [(set (match_operand:X87MODEF 0 "register_operand" "")
3852 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3853 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3854 && (standard_80387_constant_p (operands[1]) == 8
3855 || standard_80387_constant_p (operands[1]) == 9)"
3856 [(set (match_dup 0)(match_dup 1))
3858 (neg:X87MODEF (match_dup 0)))]
3862 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3863 if (real_isnegzero (&r))
3864 operands[1] = CONST0_RTX (<MODE>mode);
3866 operands[1] = CONST1_RTX (<MODE>mode);
3870 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3871 (match_operand:TF 1 "general_operand" ""))]
3873 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3875 "ix86_split_long_move (operands); DONE;")
3877 ;; Zero extension instructions
3879 (define_expand "zero_extendhisi2"
3880 [(set (match_operand:SI 0 "register_operand" "")
3881 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3884 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3886 operands[1] = force_reg (HImode, operands[1]);
3887 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3892 (define_insn "zero_extendhisi2_and"
3893 [(set (match_operand:SI 0 "register_operand" "=r")
3894 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3895 (clobber (reg:CC FLAGS_REG))]
3896 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3898 [(set_attr "type" "alu1")
3899 (set_attr "mode" "SI")])
3902 [(set (match_operand:SI 0 "register_operand" "")
3903 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3904 (clobber (reg:CC FLAGS_REG))]
3905 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3906 && optimize_function_for_speed_p (cfun)"
3907 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3908 (clobber (reg:CC FLAGS_REG))])]
3911 (define_insn "*zero_extendhisi2_movzwl"
3912 [(set (match_operand:SI 0 "register_operand" "=r")
3913 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3914 "!TARGET_ZERO_EXTEND_WITH_AND
3915 || optimize_function_for_size_p (cfun)"
3916 "movz{wl|x}\t{%1, %0|%0, %1}"
3917 [(set_attr "type" "imovx")
3918 (set_attr "mode" "SI")])
3920 (define_expand "zero_extendqihi2"
3922 [(set (match_operand:HI 0 "register_operand" "")
3923 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3924 (clobber (reg:CC FLAGS_REG))])]
3928 (define_insn "*zero_extendqihi2_and"
3929 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3930 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3931 (clobber (reg:CC FLAGS_REG))]
3932 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3934 [(set_attr "type" "alu1")
3935 (set_attr "mode" "HI")])
3937 (define_insn "*zero_extendqihi2_movzbw_and"
3938 [(set (match_operand:HI 0 "register_operand" "=r,r")
3939 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3940 (clobber (reg:CC FLAGS_REG))]
3941 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3943 [(set_attr "type" "imovx,alu1")
3944 (set_attr "mode" "HI")])
3946 ; zero extend to SImode here to avoid partial register stalls
3947 (define_insn "*zero_extendqihi2_movzbl"
3948 [(set (match_operand:HI 0 "register_operand" "=r")
3949 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3950 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3951 && reload_completed"
3952 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3953 [(set_attr "type" "imovx")
3954 (set_attr "mode" "SI")])
3956 ;; For the movzbw case strip only the clobber
3958 [(set (match_operand:HI 0 "register_operand" "")
3959 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3960 (clobber (reg:CC FLAGS_REG))]
3962 && (!TARGET_ZERO_EXTEND_WITH_AND
3963 || optimize_function_for_size_p (cfun))
3964 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3965 [(set (match_operand:HI 0 "register_operand" "")
3966 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3968 ;; When source and destination does not overlap, clear destination
3969 ;; first and then do the movb
3971 [(set (match_operand:HI 0 "register_operand" "")
3972 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3973 (clobber (reg:CC FLAGS_REG))]
3975 && ANY_QI_REG_P (operands[0])
3976 && (TARGET_ZERO_EXTEND_WITH_AND
3977 && optimize_function_for_speed_p (cfun))
3978 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3979 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3981 operands[2] = gen_lowpart (QImode, operands[0]);
3982 ix86_expand_clear (operands[0]);
3985 ;; Rest is handled by single and.
3987 [(set (match_operand:HI 0 "register_operand" "")
3988 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3989 (clobber (reg:CC FLAGS_REG))]
3991 && true_regnum (operands[0]) == true_regnum (operands[1])"
3992 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3993 (clobber (reg:CC FLAGS_REG))])]
3996 (define_expand "zero_extendqisi2"
3998 [(set (match_operand:SI 0 "register_operand" "")
3999 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4000 (clobber (reg:CC FLAGS_REG))])]
4004 (define_insn "*zero_extendqisi2_and"
4005 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
4006 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4007 (clobber (reg:CC FLAGS_REG))]
4008 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4010 [(set_attr "type" "alu1")
4011 (set_attr "mode" "SI")])
4013 (define_insn "*zero_extendqisi2_movzbl_and"
4014 [(set (match_operand:SI 0 "register_operand" "=r,r")
4015 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4016 (clobber (reg:CC FLAGS_REG))]
4017 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4019 [(set_attr "type" "imovx,alu1")
4020 (set_attr "mode" "SI")])
4022 (define_insn "*zero_extendqisi2_movzbl"
4023 [(set (match_operand:SI 0 "register_operand" "=r")
4024 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4025 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4026 && reload_completed"
4027 "movz{bl|x}\t{%1, %0|%0, %1}"
4028 [(set_attr "type" "imovx")
4029 (set_attr "mode" "SI")])
4031 ;; For the movzbl case strip only the clobber
4033 [(set (match_operand:SI 0 "register_operand" "")
4034 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4035 (clobber (reg:CC FLAGS_REG))]
4037 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4038 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4040 (zero_extend:SI (match_dup 1)))])
4042 ;; When source and destination does not overlap, clear destination
4043 ;; first and then do the movb
4045 [(set (match_operand:SI 0 "register_operand" "")
4046 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4047 (clobber (reg:CC FLAGS_REG))]
4049 && ANY_QI_REG_P (operands[0])
4050 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4051 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4052 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4053 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
4055 operands[2] = gen_lowpart (QImode, operands[0]);
4056 ix86_expand_clear (operands[0]);
4059 ;; Rest is handled by single and.
4061 [(set (match_operand:SI 0 "register_operand" "")
4062 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4063 (clobber (reg:CC FLAGS_REG))]
4065 && true_regnum (operands[0]) == true_regnum (operands[1])"
4066 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4067 (clobber (reg:CC FLAGS_REG))])]
4070 ;; %%% Kill me once multi-word ops are sane.
4071 (define_expand "zero_extendsidi2"
4072 [(set (match_operand:DI 0 "register_operand" "")
4073 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4078 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4083 (define_insn "zero_extendsidi2_32"
4084 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4086 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
4087 (clobber (reg:CC FLAGS_REG))]
4093 movd\t{%1, %0|%0, %1}
4094 movd\t{%1, %0|%0, %1}
4095 %vmovd\t{%1, %0|%0, %1}
4096 %vmovd\t{%1, %0|%0, %1}"
4097 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4098 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4099 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4101 (define_insn "zero_extendsidi2_rex64"
4102 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4104 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4107 mov\t{%k1, %k0|%k0, %k1}
4109 movd\t{%1, %0|%0, %1}
4110 movd\t{%1, %0|%0, %1}
4111 %vmovd\t{%1, %0|%0, %1}
4112 %vmovd\t{%1, %0|%0, %1}"
4113 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4114 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4115 (set_attr "prefix_0f" "0,*,*,*,*,*")
4116 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4119 [(set (match_operand:DI 0 "memory_operand" "")
4120 (zero_extend:DI (match_dup 0)))]
4122 [(set (match_dup 4) (const_int 0))]
4123 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4126 [(set (match_operand:DI 0 "register_operand" "")
4127 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4128 (clobber (reg:CC FLAGS_REG))]
4129 "!TARGET_64BIT && reload_completed
4130 && true_regnum (operands[0]) == true_regnum (operands[1])"
4131 [(set (match_dup 4) (const_int 0))]
4132 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4135 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4136 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4137 (clobber (reg:CC FLAGS_REG))]
4138 "!TARGET_64BIT && reload_completed
4139 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4140 [(set (match_dup 3) (match_dup 1))
4141 (set (match_dup 4) (const_int 0))]
4142 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4144 (define_insn "zero_extendhidi2"
4145 [(set (match_operand:DI 0 "register_operand" "=r")
4146 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4148 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4149 [(set_attr "type" "imovx")
4150 (set_attr "mode" "SI")])
4152 (define_insn "zero_extendqidi2"
4153 [(set (match_operand:DI 0 "register_operand" "=r")
4154 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4156 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4157 [(set_attr "type" "imovx")
4158 (set_attr "mode" "SI")])
4160 ;; Sign extension instructions
4162 (define_expand "extendsidi2"
4163 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4164 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4165 (clobber (reg:CC FLAGS_REG))
4166 (clobber (match_scratch:SI 2 ""))])]
4171 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4176 (define_insn "*extendsidi2_1"
4177 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4178 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4179 (clobber (reg:CC FLAGS_REG))
4180 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4184 (define_insn "extendsidi2_rex64"
4185 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4186 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4190 movs{lq|x}\t{%1, %0|%0, %1}"
4191 [(set_attr "type" "imovx")
4192 (set_attr "mode" "DI")
4193 (set_attr "prefix_0f" "0")
4194 (set_attr "modrm" "0,1")])
4196 (define_insn "extendhidi2"
4197 [(set (match_operand:DI 0 "register_operand" "=r")
4198 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4200 "movs{wq|x}\t{%1, %0|%0, %1}"
4201 [(set_attr "type" "imovx")
4202 (set_attr "mode" "DI")])
4204 (define_insn "extendqidi2"
4205 [(set (match_operand:DI 0 "register_operand" "=r")
4206 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4208 "movs{bq|x}\t{%1, %0|%0, %1}"
4209 [(set_attr "type" "imovx")
4210 (set_attr "mode" "DI")])
4212 ;; Extend to memory case when source register does die.
4214 [(set (match_operand:DI 0 "memory_operand" "")
4215 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4216 (clobber (reg:CC FLAGS_REG))
4217 (clobber (match_operand:SI 2 "register_operand" ""))]
4219 && dead_or_set_p (insn, operands[1])
4220 && !reg_mentioned_p (operands[1], operands[0]))"
4221 [(set (match_dup 3) (match_dup 1))
4222 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4223 (clobber (reg:CC FLAGS_REG))])
4224 (set (match_dup 4) (match_dup 1))]
4225 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4227 ;; Extend to memory case when source register does not die.
4229 [(set (match_operand:DI 0 "memory_operand" "")
4230 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4231 (clobber (reg:CC FLAGS_REG))
4232 (clobber (match_operand:SI 2 "register_operand" ""))]
4236 split_di (&operands[0], 1, &operands[3], &operands[4]);
4238 emit_move_insn (operands[3], operands[1]);
4240 /* Generate a cltd if possible and doing so it profitable. */
4241 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4242 && true_regnum (operands[1]) == AX_REG
4243 && true_regnum (operands[2]) == DX_REG)
4245 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4249 emit_move_insn (operands[2], operands[1]);
4250 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4252 emit_move_insn (operands[4], operands[2]);
4256 ;; Extend to register case. Optimize case where source and destination
4257 ;; registers match and cases where we can use cltd.
4259 [(set (match_operand:DI 0 "register_operand" "")
4260 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4261 (clobber (reg:CC FLAGS_REG))
4262 (clobber (match_scratch:SI 2 ""))]
4266 split_di (&operands[0], 1, &operands[3], &operands[4]);
4268 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4269 emit_move_insn (operands[3], operands[1]);
4271 /* Generate a cltd if possible and doing so it profitable. */
4272 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4273 && true_regnum (operands[3]) == AX_REG
4274 && true_regnum (operands[4]) == DX_REG)
4276 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4280 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4281 emit_move_insn (operands[4], operands[1]);
4283 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4287 (define_insn "extendhisi2"
4288 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4289 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4292 switch (get_attr_prefix_0f (insn))
4295 return "{cwtl|cwde}";
4297 return "movs{wl|x}\t{%1, %0|%0, %1}";
4300 [(set_attr "type" "imovx")
4301 (set_attr "mode" "SI")
4302 (set (attr "prefix_0f")
4303 ;; movsx is short decodable while cwtl is vector decoded.
4304 (if_then_else (and (eq_attr "cpu" "!k6")
4305 (eq_attr "alternative" "0"))
4307 (const_string "1")))
4309 (if_then_else (eq_attr "prefix_0f" "0")
4311 (const_string "1")))])
4313 (define_insn "*extendhisi2_zext"
4314 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4316 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4319 switch (get_attr_prefix_0f (insn))
4322 return "{cwtl|cwde}";
4324 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4327 [(set_attr "type" "imovx")
4328 (set_attr "mode" "SI")
4329 (set (attr "prefix_0f")
4330 ;; movsx is short decodable while cwtl is vector decoded.
4331 (if_then_else (and (eq_attr "cpu" "!k6")
4332 (eq_attr "alternative" "0"))
4334 (const_string "1")))
4336 (if_then_else (eq_attr "prefix_0f" "0")
4338 (const_string "1")))])
4340 (define_insn "extendqihi2"
4341 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4342 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4345 switch (get_attr_prefix_0f (insn))
4348 return "{cbtw|cbw}";
4350 return "movs{bw|x}\t{%1, %0|%0, %1}";
4353 [(set_attr "type" "imovx")
4354 (set_attr "mode" "HI")
4355 (set (attr "prefix_0f")
4356 ;; movsx is short decodable while cwtl is vector decoded.
4357 (if_then_else (and (eq_attr "cpu" "!k6")
4358 (eq_attr "alternative" "0"))
4360 (const_string "1")))
4362 (if_then_else (eq_attr "prefix_0f" "0")
4364 (const_string "1")))])
4366 (define_insn "extendqisi2"
4367 [(set (match_operand:SI 0 "register_operand" "=r")
4368 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4370 "movs{bl|x}\t{%1, %0|%0, %1}"
4371 [(set_attr "type" "imovx")
4372 (set_attr "mode" "SI")])
4374 (define_insn "*extendqisi2_zext"
4375 [(set (match_operand:DI 0 "register_operand" "=r")
4377 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4379 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4380 [(set_attr "type" "imovx")
4381 (set_attr "mode" "SI")])
4383 ;; Conversions between float and double.
4385 ;; These are all no-ops in the model used for the 80387. So just
4388 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4389 (define_insn "*dummy_extendsfdf2"
4390 [(set (match_operand:DF 0 "push_operand" "=<")
4391 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4396 [(set (match_operand:DF 0 "push_operand" "")
4397 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4399 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4400 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4402 (define_insn "*dummy_extendsfxf2"
4403 [(set (match_operand:XF 0 "push_operand" "=<")
4404 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4409 [(set (match_operand:XF 0 "push_operand" "")
4410 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4412 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4413 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4414 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4417 [(set (match_operand:XF 0 "push_operand" "")
4418 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4420 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4421 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4422 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4424 (define_expand "extendsfdf2"
4425 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4426 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4427 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4429 /* ??? Needed for compress_float_constant since all fp constants
4430 are LEGITIMATE_CONSTANT_P. */
4431 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4433 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4434 && standard_80387_constant_p (operands[1]) > 0)
4436 operands[1] = simplify_const_unary_operation
4437 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4438 emit_move_insn_1 (operands[0], operands[1]);
4441 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4445 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4447 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4449 We do the conversion post reload to avoid producing of 128bit spills
4450 that might lead to ICE on 32bit target. The sequence unlikely combine
4453 [(set (match_operand:DF 0 "register_operand" "")
4455 (match_operand:SF 1 "nonimmediate_operand" "")))]
4456 "TARGET_USE_VECTOR_FP_CONVERTS
4457 && optimize_insn_for_speed_p ()
4458 && reload_completed && SSE_REG_P (operands[0])"
4463 (parallel [(const_int 0) (const_int 1)]))))]
4465 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4466 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4467 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4468 Try to avoid move when unpacking can be done in source. */
4469 if (REG_P (operands[1]))
4471 /* If it is unsafe to overwrite upper half of source, we need
4472 to move to destination and unpack there. */
4473 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4474 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4475 && true_regnum (operands[0]) != true_regnum (operands[1]))
4477 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4478 emit_move_insn (tmp, operands[1]);
4481 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4482 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4486 emit_insn (gen_vec_setv4sf_0 (operands[3],
4487 CONST0_RTX (V4SFmode), operands[1]));
4490 (define_insn "*extendsfdf2_mixed"
4491 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4493 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4494 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4496 switch (which_alternative)
4500 return output_387_reg_move (insn, operands);
4503 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4509 [(set_attr "type" "fmov,fmov,ssecvt")
4510 (set_attr "prefix" "orig,orig,maybe_vex")
4511 (set_attr "mode" "SF,XF,DF")])
4513 (define_insn "*extendsfdf2_sse"
4514 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4515 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4516 "TARGET_SSE2 && TARGET_SSE_MATH"
4517 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4518 [(set_attr "type" "ssecvt")
4519 (set_attr "prefix" "maybe_vex")
4520 (set_attr "mode" "DF")])
4522 (define_insn "*extendsfdf2_i387"
4523 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4524 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4526 "* return output_387_reg_move (insn, operands);"
4527 [(set_attr "type" "fmov")
4528 (set_attr "mode" "SF,XF")])
4530 (define_expand "extend<mode>xf2"
4531 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4532 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4535 /* ??? Needed for compress_float_constant since all fp constants
4536 are LEGITIMATE_CONSTANT_P. */
4537 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4539 if (standard_80387_constant_p (operands[1]) > 0)
4541 operands[1] = simplify_const_unary_operation
4542 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4543 emit_move_insn_1 (operands[0], operands[1]);
4546 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4550 (define_insn "*extend<mode>xf2_i387"
4551 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4553 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4555 "* return output_387_reg_move (insn, operands);"
4556 [(set_attr "type" "fmov")
4557 (set_attr "mode" "<MODE>,XF")])
4559 ;; %%% This seems bad bad news.
4560 ;; This cannot output into an f-reg because there is no way to be sure
4561 ;; of truncating in that case. Otherwise this is just like a simple move
4562 ;; insn. So we pretend we can output to a reg in order to get better
4563 ;; register preferencing, but we really use a stack slot.
4565 ;; Conversion from DFmode to SFmode.
4567 (define_expand "truncdfsf2"
4568 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4570 (match_operand:DF 1 "nonimmediate_operand" "")))]
4571 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4573 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4575 else if (flag_unsafe_math_optimizations)
4579 enum ix86_stack_slot slot = (virtuals_instantiated
4582 rtx temp = assign_386_stack_local (SFmode, slot);
4583 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4588 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4590 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4592 We do the conversion post reload to avoid producing of 128bit spills
4593 that might lead to ICE on 32bit target. The sequence unlikely combine
4596 [(set (match_operand:SF 0 "register_operand" "")
4598 (match_operand:DF 1 "nonimmediate_operand" "")))]
4599 "TARGET_USE_VECTOR_FP_CONVERTS
4600 && optimize_insn_for_speed_p ()
4601 && reload_completed && SSE_REG_P (operands[0])"
4604 (float_truncate:V2SF
4608 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4609 operands[3] = CONST0_RTX (V2SFmode);
4610 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4611 /* Use movsd for loading from memory, unpcklpd for registers.
4612 Try to avoid move when unpacking can be done in source, or SSE3
4613 movddup is available. */
4614 if (REG_P (operands[1]))
4617 && true_regnum (operands[0]) != true_regnum (operands[1])
4618 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4619 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4621 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4622 emit_move_insn (tmp, operands[1]);
4625 else if (!TARGET_SSE3)
4626 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4627 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4630 emit_insn (gen_sse2_loadlpd (operands[4],
4631 CONST0_RTX (V2DFmode), operands[1]));
4634 (define_expand "truncdfsf2_with_temp"
4635 [(parallel [(set (match_operand:SF 0 "" "")
4636 (float_truncate:SF (match_operand:DF 1 "" "")))
4637 (clobber (match_operand:SF 2 "" ""))])]
4640 (define_insn "*truncdfsf_fast_mixed"
4641 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4643 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4644 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4646 switch (which_alternative)
4649 return output_387_reg_move (insn, operands);
4651 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4656 [(set_attr "type" "fmov,ssecvt")
4657 (set_attr "prefix" "orig,maybe_vex")
4658 (set_attr "mode" "SF")])
4660 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4661 ;; because nothing we do here is unsafe.
4662 (define_insn "*truncdfsf_fast_sse"
4663 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4665 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4666 "TARGET_SSE2 && TARGET_SSE_MATH"
4667 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4668 [(set_attr "type" "ssecvt")
4669 (set_attr "prefix" "maybe_vex")
4670 (set_attr "mode" "SF")])
4672 (define_insn "*truncdfsf_fast_i387"
4673 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4675 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4676 "TARGET_80387 && flag_unsafe_math_optimizations"
4677 "* return output_387_reg_move (insn, operands);"
4678 [(set_attr "type" "fmov")
4679 (set_attr "mode" "SF")])
4681 (define_insn "*truncdfsf_mixed"
4682 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4684 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4685 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4686 "TARGET_MIX_SSE_I387"
4688 switch (which_alternative)
4691 return output_387_reg_move (insn, operands);
4693 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4699 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4700 (set_attr "unit" "*,*,i387,i387,i387")
4701 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4702 (set_attr "mode" "SF")])
4704 (define_insn "*truncdfsf_i387"
4705 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4707 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4708 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4711 switch (which_alternative)
4714 return output_387_reg_move (insn, operands);
4720 [(set_attr "type" "fmov,multi,multi,multi")
4721 (set_attr "unit" "*,i387,i387,i387")
4722 (set_attr "mode" "SF")])
4724 (define_insn "*truncdfsf2_i387_1"
4725 [(set (match_operand:SF 0 "memory_operand" "=m")
4727 (match_operand:DF 1 "register_operand" "f")))]
4729 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4730 && !TARGET_MIX_SSE_I387"
4731 "* return output_387_reg_move (insn, operands);"
4732 [(set_attr "type" "fmov")
4733 (set_attr "mode" "SF")])
4736 [(set (match_operand:SF 0 "register_operand" "")
4738 (match_operand:DF 1 "fp_register_operand" "")))
4739 (clobber (match_operand 2 "" ""))]
4741 [(set (match_dup 2) (match_dup 1))
4742 (set (match_dup 0) (match_dup 2))]
4744 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4747 ;; Conversion from XFmode to {SF,DF}mode
4749 (define_expand "truncxf<mode>2"
4750 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4751 (float_truncate:MODEF
4752 (match_operand:XF 1 "register_operand" "")))
4753 (clobber (match_dup 2))])]
4756 if (flag_unsafe_math_optimizations)
4758 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4759 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4760 if (reg != operands[0])
4761 emit_move_insn (operands[0], reg);
4766 enum ix86_stack_slot slot = (virtuals_instantiated
4769 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4773 (define_insn "*truncxfsf2_mixed"
4774 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4776 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4777 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4780 gcc_assert (!which_alternative);
4781 return output_387_reg_move (insn, operands);
4783 [(set_attr "type" "fmov,multi,multi,multi")
4784 (set_attr "unit" "*,i387,i387,i387")
4785 (set_attr "mode" "SF")])
4787 (define_insn "*truncxfdf2_mixed"
4788 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4790 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4791 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4794 gcc_assert (!which_alternative);
4795 return output_387_reg_move (insn, operands);
4797 [(set_attr "type" "fmov,multi,multi,multi")
4798 (set_attr "unit" "*,i387,i387,i387")
4799 (set_attr "mode" "DF")])
4801 (define_insn "truncxf<mode>2_i387_noop"
4802 [(set (match_operand:MODEF 0 "register_operand" "=f")
4803 (float_truncate:MODEF
4804 (match_operand:XF 1 "register_operand" "f")))]
4805 "TARGET_80387 && flag_unsafe_math_optimizations"
4806 "* return output_387_reg_move (insn, operands);"
4807 [(set_attr "type" "fmov")
4808 (set_attr "mode" "<MODE>")])
4810 (define_insn "*truncxf<mode>2_i387"
4811 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4812 (float_truncate:MODEF
4813 (match_operand:XF 1 "register_operand" "f")))]
4815 "* return output_387_reg_move (insn, operands);"
4816 [(set_attr "type" "fmov")
4817 (set_attr "mode" "<MODE>")])
4820 [(set (match_operand:MODEF 0 "register_operand" "")
4821 (float_truncate:MODEF
4822 (match_operand:XF 1 "register_operand" "")))
4823 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4824 "TARGET_80387 && reload_completed"
4825 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4826 (set (match_dup 0) (match_dup 2))]
4830 [(set (match_operand:MODEF 0 "memory_operand" "")
4831 (float_truncate:MODEF
4832 (match_operand:XF 1 "register_operand" "")))
4833 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4835 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4838 ;; Signed conversion to DImode.
4840 (define_expand "fix_truncxfdi2"
4841 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4842 (fix:DI (match_operand:XF 1 "register_operand" "")))
4843 (clobber (reg:CC FLAGS_REG))])]
4848 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4853 (define_expand "fix_trunc<mode>di2"
4854 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4855 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4856 (clobber (reg:CC FLAGS_REG))])]
4857 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4860 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4862 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4865 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4867 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4868 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4869 if (out != operands[0])
4870 emit_move_insn (operands[0], out);
4875 ;; Signed conversion to SImode.
4877 (define_expand "fix_truncxfsi2"
4878 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4879 (fix:SI (match_operand:XF 1 "register_operand" "")))
4880 (clobber (reg:CC FLAGS_REG))])]
4885 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4890 (define_expand "fix_trunc<mode>si2"
4891 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4892 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4893 (clobber (reg:CC FLAGS_REG))])]
4894 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4897 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4899 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4902 if (SSE_FLOAT_MODE_P (<MODE>mode))
4904 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4905 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4906 if (out != operands[0])
4907 emit_move_insn (operands[0], out);
4912 ;; Signed conversion to HImode.
4914 (define_expand "fix_trunc<mode>hi2"
4915 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4916 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4917 (clobber (reg:CC FLAGS_REG))])]
4919 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4923 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4928 ;; Unsigned conversion to SImode.
4930 (define_expand "fixuns_trunc<mode>si2"
4932 [(set (match_operand:SI 0 "register_operand" "")
4934 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4936 (clobber (match_scratch:<ssevecmode> 3 ""))
4937 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4938 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4940 enum machine_mode mode = <MODE>mode;
4941 enum machine_mode vecmode = <ssevecmode>mode;
4942 REAL_VALUE_TYPE TWO31r;
4945 if (optimize_insn_for_size_p ())
4948 real_ldexp (&TWO31r, &dconst1, 31);
4949 two31 = const_double_from_real_value (TWO31r, mode);
4950 two31 = ix86_build_const_vector (mode, true, two31);
4951 operands[2] = force_reg (vecmode, two31);
4954 (define_insn_and_split "*fixuns_trunc<mode>_1"
4955 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4957 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4958 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4959 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4960 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4961 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4962 && optimize_function_for_speed_p (cfun)"
4964 "&& reload_completed"
4967 ix86_split_convert_uns_si_sse (operands);
4971 ;; Unsigned conversion to HImode.
4972 ;; Without these patterns, we'll try the unsigned SI conversion which
4973 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4975 (define_expand "fixuns_trunc<mode>hi2"
4977 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4978 (set (match_operand:HI 0 "nonimmediate_operand" "")
4979 (subreg:HI (match_dup 2) 0))]
4980 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4981 "operands[2] = gen_reg_rtx (SImode);")
4983 ;; When SSE is available, it is always faster to use it!
4984 (define_insn "fix_trunc<mode>di_sse"
4985 [(set (match_operand:DI 0 "register_operand" "=r,r")
4986 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4987 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4988 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4989 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4990 [(set_attr "type" "sseicvt")
4991 (set_attr "prefix" "maybe_vex")
4992 (set_attr "prefix_rex" "1")
4993 (set_attr "mode" "<MODE>")
4994 (set_attr "athlon_decode" "double,vector")
4995 (set_attr "amdfam10_decode" "double,double")])
4997 (define_insn "fix_trunc<mode>si_sse"
4998 [(set (match_operand:SI 0 "register_operand" "=r,r")
4999 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5000 "SSE_FLOAT_MODE_P (<MODE>mode)
5001 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5002 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
5003 [(set_attr "type" "sseicvt")
5004 (set_attr "prefix" "maybe_vex")
5005 (set_attr "mode" "<MODE>")
5006 (set_attr "athlon_decode" "double,vector")
5007 (set_attr "amdfam10_decode" "double,double")])
5009 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
5011 [(set (match_operand:MODEF 0 "register_operand" "")
5012 (match_operand:MODEF 1 "memory_operand" ""))
5013 (set (match_operand:SSEMODEI24 2 "register_operand" "")
5014 (fix:SSEMODEI24 (match_dup 0)))]
5015 "TARGET_SHORTEN_X87_SSE
5016 && peep2_reg_dead_p (2, operands[0])"
5017 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
5020 ;; Avoid vector decoded forms of the instruction.
5022 [(match_scratch:DF 2 "Y2")
5023 (set (match_operand:SSEMODEI24 0 "register_operand" "")
5024 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
5025 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5026 [(set (match_dup 2) (match_dup 1))
5027 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5031 [(match_scratch:SF 2 "x")
5032 (set (match_operand:SSEMODEI24 0 "register_operand" "")
5033 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
5034 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5035 [(set (match_dup 2) (match_dup 1))
5036 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5039 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5040 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5041 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5042 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5044 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5045 && (TARGET_64BIT || <MODE>mode != DImode))
5047 && can_create_pseudo_p ()"
5052 if (memory_operand (operands[0], VOIDmode))
5053 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5056 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5057 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5063 [(set_attr "type" "fisttp")
5064 (set_attr "mode" "<MODE>")])
5066 (define_insn "fix_trunc<mode>_i387_fisttp"
5067 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5068 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5069 (clobber (match_scratch:XF 2 "=&1f"))]
5070 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5072 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5073 && (TARGET_64BIT || <MODE>mode != DImode))
5074 && TARGET_SSE_MATH)"
5075 "* return output_fix_trunc (insn, operands, 1);"
5076 [(set_attr "type" "fisttp")
5077 (set_attr "mode" "<MODE>")])
5079 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5080 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5081 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5082 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5083 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5084 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5086 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5087 && (TARGET_64BIT || <MODE>mode != DImode))
5088 && TARGET_SSE_MATH)"
5090 [(set_attr "type" "fisttp")
5091 (set_attr "mode" "<MODE>")])
5094 [(set (match_operand:X87MODEI 0 "register_operand" "")
5095 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5096 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5097 (clobber (match_scratch 3 ""))]
5099 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5100 (clobber (match_dup 3))])
5101 (set (match_dup 0) (match_dup 2))]
5105 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5106 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5107 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5108 (clobber (match_scratch 3 ""))]
5110 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5111 (clobber (match_dup 3))])]
5114 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5115 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5116 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5117 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5118 ;; function in i386.c.
5119 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5120 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5121 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5122 (clobber (reg:CC FLAGS_REG))]
5123 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5125 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5126 && (TARGET_64BIT || <MODE>mode != DImode))
5127 && can_create_pseudo_p ()"
5132 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5134 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5135 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5136 if (memory_operand (operands[0], VOIDmode))
5137 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5138 operands[2], operands[3]));
5141 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5142 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5143 operands[2], operands[3],
5148 [(set_attr "type" "fistp")
5149 (set_attr "i387_cw" "trunc")
5150 (set_attr "mode" "<MODE>")])
5152 (define_insn "fix_truncdi_i387"
5153 [(set (match_operand:DI 0 "memory_operand" "=m")
5154 (fix:DI (match_operand 1 "register_operand" "f")))
5155 (use (match_operand:HI 2 "memory_operand" "m"))
5156 (use (match_operand:HI 3 "memory_operand" "m"))
5157 (clobber (match_scratch:XF 4 "=&1f"))]
5158 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5160 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5161 "* return output_fix_trunc (insn, operands, 0);"
5162 [(set_attr "type" "fistp")
5163 (set_attr "i387_cw" "trunc")
5164 (set_attr "mode" "DI")])
5166 (define_insn "fix_truncdi_i387_with_temp"
5167 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5168 (fix:DI (match_operand 1 "register_operand" "f,f")))
5169 (use (match_operand:HI 2 "memory_operand" "m,m"))
5170 (use (match_operand:HI 3 "memory_operand" "m,m"))
5171 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5172 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5173 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5175 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5177 [(set_attr "type" "fistp")
5178 (set_attr "i387_cw" "trunc")
5179 (set_attr "mode" "DI")])
5182 [(set (match_operand:DI 0 "register_operand" "")
5183 (fix:DI (match_operand 1 "register_operand" "")))
5184 (use (match_operand:HI 2 "memory_operand" ""))
5185 (use (match_operand:HI 3 "memory_operand" ""))
5186 (clobber (match_operand:DI 4 "memory_operand" ""))
5187 (clobber (match_scratch 5 ""))]
5189 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5192 (clobber (match_dup 5))])
5193 (set (match_dup 0) (match_dup 4))]
5197 [(set (match_operand:DI 0 "memory_operand" "")
5198 (fix:DI (match_operand 1 "register_operand" "")))
5199 (use (match_operand:HI 2 "memory_operand" ""))
5200 (use (match_operand:HI 3 "memory_operand" ""))
5201 (clobber (match_operand:DI 4 "memory_operand" ""))
5202 (clobber (match_scratch 5 ""))]
5204 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5207 (clobber (match_dup 5))])]
5210 (define_insn "fix_trunc<mode>_i387"
5211 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5212 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5213 (use (match_operand:HI 2 "memory_operand" "m"))
5214 (use (match_operand:HI 3 "memory_operand" "m"))]
5215 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5217 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5218 "* return output_fix_trunc (insn, operands, 0);"
5219 [(set_attr "type" "fistp")
5220 (set_attr "i387_cw" "trunc")
5221 (set_attr "mode" "<MODE>")])
5223 (define_insn "fix_trunc<mode>_i387_with_temp"
5224 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5225 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5226 (use (match_operand:HI 2 "memory_operand" "m,m"))
5227 (use (match_operand:HI 3 "memory_operand" "m,m"))
5228 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5229 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5231 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5233 [(set_attr "type" "fistp")
5234 (set_attr "i387_cw" "trunc")
5235 (set_attr "mode" "<MODE>")])
5238 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5239 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5240 (use (match_operand:HI 2 "memory_operand" ""))
5241 (use (match_operand:HI 3 "memory_operand" ""))
5242 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5244 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5246 (use (match_dup 3))])
5247 (set (match_dup 0) (match_dup 4))]
5251 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5252 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5253 (use (match_operand:HI 2 "memory_operand" ""))
5254 (use (match_operand:HI 3 "memory_operand" ""))
5255 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5257 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5259 (use (match_dup 3))])]
5262 (define_insn "x86_fnstcw_1"
5263 [(set (match_operand:HI 0 "memory_operand" "=m")
5264 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5267 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5268 (set_attr "mode" "HI")
5269 (set_attr "unit" "i387")])
5271 (define_insn "x86_fldcw_1"
5272 [(set (reg:HI FPCR_REG)
5273 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5276 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5277 (set_attr "mode" "HI")
5278 (set_attr "unit" "i387")
5279 (set_attr "athlon_decode" "vector")
5280 (set_attr "amdfam10_decode" "vector")])
5282 ;; Conversion between fixed point and floating point.
5284 ;; Even though we only accept memory inputs, the backend _really_
5285 ;; wants to be able to do this between registers.
5287 (define_expand "floathi<mode>2"
5288 [(set (match_operand:X87MODEF 0 "register_operand" "")
5289 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5291 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5292 || TARGET_MIX_SSE_I387)"
5295 ;; Pre-reload splitter to add memory clobber to the pattern.
5296 (define_insn_and_split "*floathi<mode>2_1"
5297 [(set (match_operand:X87MODEF 0 "register_operand" "")
5298 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5300 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5301 || TARGET_MIX_SSE_I387)
5302 && can_create_pseudo_p ()"
5305 [(parallel [(set (match_dup 0)
5306 (float:X87MODEF (match_dup 1)))
5307 (clobber (match_dup 2))])]
5308 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5310 (define_insn "*floathi<mode>2_i387_with_temp"
5311 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5312 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5313 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5315 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5316 || TARGET_MIX_SSE_I387)"
5318 [(set_attr "type" "fmov,multi")
5319 (set_attr "mode" "<MODE>")
5320 (set_attr "unit" "*,i387")
5321 (set_attr "fp_int_src" "true")])
5323 (define_insn "*floathi<mode>2_i387"
5324 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5325 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5327 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5328 || TARGET_MIX_SSE_I387)"
5330 [(set_attr "type" "fmov")
5331 (set_attr "mode" "<MODE>")
5332 (set_attr "fp_int_src" "true")])
5335 [(set (match_operand:X87MODEF 0 "register_operand" "")
5336 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5337 (clobber (match_operand:HI 2 "memory_operand" ""))]
5339 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5340 || TARGET_MIX_SSE_I387)
5341 && reload_completed"
5342 [(set (match_dup 2) (match_dup 1))
5343 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5347 [(set (match_operand:X87MODEF 0 "register_operand" "")
5348 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5349 (clobber (match_operand:HI 2 "memory_operand" ""))]
5351 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5352 || TARGET_MIX_SSE_I387)
5353 && reload_completed"
5354 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5357 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5358 [(set (match_operand:X87MODEF 0 "register_operand" "")
5360 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5362 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5363 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5365 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5366 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5367 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5369 rtx reg = gen_reg_rtx (XFmode);
5372 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5374 if (<X87MODEF:MODE>mode == SFmode)
5375 insn = gen_truncxfsf2 (operands[0], reg);
5376 else if (<X87MODEF:MODE>mode == DFmode)
5377 insn = gen_truncxfdf2 (operands[0], reg);
5386 ;; Pre-reload splitter to add memory clobber to the pattern.
5387 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5388 [(set (match_operand:X87MODEF 0 "register_operand" "")
5389 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5391 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5392 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5393 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5394 || TARGET_MIX_SSE_I387))
5395 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5396 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5397 && ((<SSEMODEI24:MODE>mode == SImode
5398 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5399 && optimize_function_for_speed_p (cfun)
5400 && flag_trapping_math)
5401 || !(TARGET_INTER_UNIT_CONVERSIONS
5402 || optimize_function_for_size_p (cfun)))))
5403 && can_create_pseudo_p ()"
5406 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5407 (clobber (match_dup 2))])]
5409 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5411 /* Avoid store forwarding (partial memory) stall penalty
5412 by passing DImode value through XMM registers. */
5413 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5414 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5415 && optimize_function_for_speed_p (cfun))
5417 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5424 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5425 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5427 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5428 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5429 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5430 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5432 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5433 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5434 (set_attr "unit" "*,i387,*,*,*")
5435 (set_attr "athlon_decode" "*,*,double,direct,double")
5436 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5437 (set_attr "fp_int_src" "true")])
5439 (define_insn "*floatsi<mode>2_vector_mixed"
5440 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5441 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5442 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5443 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5447 [(set_attr "type" "fmov,sseicvt")
5448 (set_attr "mode" "<MODE>,<ssevecmode>")
5449 (set_attr "unit" "i387,*")
5450 (set_attr "athlon_decode" "*,direct")
5451 (set_attr "amdfam10_decode" "*,double")
5452 (set_attr "fp_int_src" "true")])
5454 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5455 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5457 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5458 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5459 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5460 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5462 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5463 (set_attr "mode" "<MODEF:MODE>")
5464 (set_attr "unit" "*,i387,*,*")
5465 (set_attr "athlon_decode" "*,*,double,direct")
5466 (set_attr "amdfam10_decode" "*,*,vector,double")
5467 (set_attr "fp_int_src" "true")])
5470 [(set (match_operand:MODEF 0 "register_operand" "")
5471 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5472 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5473 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5474 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5475 && TARGET_INTER_UNIT_CONVERSIONS
5477 && (SSE_REG_P (operands[0])
5478 || (GET_CODE (operands[0]) == SUBREG
5479 && SSE_REG_P (operands[0])))"
5480 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5484 [(set (match_operand:MODEF 0 "register_operand" "")
5485 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5486 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5487 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5488 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5489 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5491 && (SSE_REG_P (operands[0])
5492 || (GET_CODE (operands[0]) == SUBREG
5493 && SSE_REG_P (operands[0])))"
5494 [(set (match_dup 2) (match_dup 1))
5495 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5498 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5499 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5501 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5502 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5503 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5504 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5507 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5508 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5509 [(set_attr "type" "fmov,sseicvt,sseicvt")
5510 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5511 (set_attr "mode" "<MODEF:MODE>")
5512 (set (attr "prefix_rex")
5514 (and (eq_attr "prefix" "maybe_vex")
5515 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5517 (const_string "*")))
5518 (set_attr "unit" "i387,*,*")
5519 (set_attr "athlon_decode" "*,double,direct")
5520 (set_attr "amdfam10_decode" "*,vector,double")
5521 (set_attr "fp_int_src" "true")])
5523 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5524 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5526 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5527 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5528 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5529 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5532 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5533 [(set_attr "type" "fmov,sseicvt")
5534 (set_attr "prefix" "orig,maybe_vex")
5535 (set_attr "mode" "<MODEF:MODE>")
5536 (set (attr "prefix_rex")
5538 (and (eq_attr "prefix" "maybe_vex")
5539 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5541 (const_string "*")))
5542 (set_attr "athlon_decode" "*,direct")
5543 (set_attr "amdfam10_decode" "*,double")
5544 (set_attr "fp_int_src" "true")])
5546 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5547 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5549 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5550 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5551 "TARGET_SSE2 && TARGET_SSE_MATH
5552 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5554 [(set_attr "type" "sseicvt")
5555 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5556 (set_attr "athlon_decode" "double,direct,double")
5557 (set_attr "amdfam10_decode" "vector,double,double")
5558 (set_attr "fp_int_src" "true")])
5560 (define_insn "*floatsi<mode>2_vector_sse"
5561 [(set (match_operand:MODEF 0 "register_operand" "=x")
5562 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5563 "TARGET_SSE2 && TARGET_SSE_MATH
5564 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5566 [(set_attr "type" "sseicvt")
5567 (set_attr "mode" "<MODE>")
5568 (set_attr "athlon_decode" "direct")
5569 (set_attr "amdfam10_decode" "double")
5570 (set_attr "fp_int_src" "true")])
5573 [(set (match_operand:MODEF 0 "register_operand" "")
5574 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5575 (clobber (match_operand:SI 2 "memory_operand" ""))]
5576 "TARGET_SSE2 && TARGET_SSE_MATH
5577 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5579 && (SSE_REG_P (operands[0])
5580 || (GET_CODE (operands[0]) == SUBREG
5581 && SSE_REG_P (operands[0])))"
5584 rtx op1 = operands[1];
5586 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5588 if (GET_CODE (op1) == SUBREG)
5589 op1 = SUBREG_REG (op1);
5591 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5593 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5594 emit_insn (gen_sse2_loadld (operands[4],
5595 CONST0_RTX (V4SImode), operands[1]));
5597 /* We can ignore possible trapping value in the
5598 high part of SSE register for non-trapping math. */
5599 else if (SSE_REG_P (op1) && !flag_trapping_math)
5600 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5603 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5604 emit_move_insn (operands[2], operands[1]);
5605 emit_insn (gen_sse2_loadld (operands[4],
5606 CONST0_RTX (V4SImode), operands[2]));
5609 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5614 [(set (match_operand:MODEF 0 "register_operand" "")
5615 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5616 (clobber (match_operand:SI 2 "memory_operand" ""))]
5617 "TARGET_SSE2 && TARGET_SSE_MATH
5618 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5620 && (SSE_REG_P (operands[0])
5621 || (GET_CODE (operands[0]) == SUBREG
5622 && SSE_REG_P (operands[0])))"
5625 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5627 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5629 emit_insn (gen_sse2_loadld (operands[4],
5630 CONST0_RTX (V4SImode), operands[1]));
5632 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5637 [(set (match_operand:MODEF 0 "register_operand" "")
5638 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5639 "TARGET_SSE2 && TARGET_SSE_MATH
5640 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5642 && (SSE_REG_P (operands[0])
5643 || (GET_CODE (operands[0]) == SUBREG
5644 && SSE_REG_P (operands[0])))"
5647 rtx op1 = operands[1];
5649 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5651 if (GET_CODE (op1) == SUBREG)
5652 op1 = SUBREG_REG (op1);
5654 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5656 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5657 emit_insn (gen_sse2_loadld (operands[4],
5658 CONST0_RTX (V4SImode), operands[1]));
5660 /* We can ignore possible trapping value in the
5661 high part of SSE register for non-trapping math. */
5662 else if (SSE_REG_P (op1) && !flag_trapping_math)
5663 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5667 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5672 [(set (match_operand:MODEF 0 "register_operand" "")
5673 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5674 "TARGET_SSE2 && TARGET_SSE_MATH
5675 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5677 && (SSE_REG_P (operands[0])
5678 || (GET_CODE (operands[0]) == SUBREG
5679 && SSE_REG_P (operands[0])))"
5682 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5684 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5686 emit_insn (gen_sse2_loadld (operands[4],
5687 CONST0_RTX (V4SImode), operands[1]));
5689 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5693 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5694 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5696 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5697 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5698 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5699 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5701 [(set_attr "type" "sseicvt")
5702 (set_attr "mode" "<MODEF:MODE>")
5703 (set_attr "athlon_decode" "double,direct")
5704 (set_attr "amdfam10_decode" "vector,double")
5705 (set_attr "fp_int_src" "true")])
5707 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5708 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5710 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5711 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5712 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5713 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5714 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5715 [(set_attr "type" "sseicvt")
5716 (set_attr "prefix" "maybe_vex")
5717 (set_attr "mode" "<MODEF:MODE>")
5718 (set (attr "prefix_rex")
5720 (and (eq_attr "prefix" "maybe_vex")
5721 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5723 (const_string "*")))
5724 (set_attr "athlon_decode" "double,direct")
5725 (set_attr "amdfam10_decode" "vector,double")
5726 (set_attr "fp_int_src" "true")])
5729 [(set (match_operand:MODEF 0 "register_operand" "")
5730 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5731 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5732 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5733 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5734 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5736 && (SSE_REG_P (operands[0])
5737 || (GET_CODE (operands[0]) == SUBREG
5738 && SSE_REG_P (operands[0])))"
5739 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5742 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5743 [(set (match_operand:MODEF 0 "register_operand" "=x")
5745 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5746 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5747 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5748 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5749 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5750 [(set_attr "type" "sseicvt")
5751 (set_attr "prefix" "maybe_vex")
5752 (set_attr "mode" "<MODEF:MODE>")
5753 (set (attr "prefix_rex")
5755 (and (eq_attr "prefix" "maybe_vex")
5756 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5758 (const_string "*")))
5759 (set_attr "athlon_decode" "direct")
5760 (set_attr "amdfam10_decode" "double")
5761 (set_attr "fp_int_src" "true")])
5764 [(set (match_operand:MODEF 0 "register_operand" "")
5765 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5766 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5767 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5768 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5769 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5771 && (SSE_REG_P (operands[0])
5772 || (GET_CODE (operands[0]) == SUBREG
5773 && SSE_REG_P (operands[0])))"
5774 [(set (match_dup 2) (match_dup 1))
5775 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5779 [(set (match_operand:MODEF 0 "register_operand" "")
5780 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5781 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5782 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5783 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5785 && (SSE_REG_P (operands[0])
5786 || (GET_CODE (operands[0]) == SUBREG
5787 && SSE_REG_P (operands[0])))"
5788 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5791 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5792 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5794 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5795 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5797 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5801 [(set_attr "type" "fmov,multi")
5802 (set_attr "mode" "<X87MODEF:MODE>")
5803 (set_attr "unit" "*,i387")
5804 (set_attr "fp_int_src" "true")])
5806 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5807 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5809 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5811 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5813 [(set_attr "type" "fmov")
5814 (set_attr "mode" "<X87MODEF:MODE>")
5815 (set_attr "fp_int_src" "true")])
5818 [(set (match_operand:X87MODEF 0 "register_operand" "")
5819 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5820 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5822 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5824 && FP_REG_P (operands[0])"
5825 [(set (match_dup 2) (match_dup 1))
5826 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5830 [(set (match_operand:X87MODEF 0 "register_operand" "")
5831 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5832 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5834 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5836 && FP_REG_P (operands[0])"
5837 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5840 ;; Avoid store forwarding (partial memory) stall penalty
5841 ;; by passing DImode value through XMM registers. */
5843 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5844 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5846 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5847 (clobber (match_scratch:V4SI 3 "=X,x"))
5848 (clobber (match_scratch:V4SI 4 "=X,x"))
5849 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5850 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5851 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5852 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5854 [(set_attr "type" "multi")
5855 (set_attr "mode" "<X87MODEF:MODE>")
5856 (set_attr "unit" "i387")
5857 (set_attr "fp_int_src" "true")])
5860 [(set (match_operand:X87MODEF 0 "register_operand" "")
5861 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5862 (clobber (match_scratch:V4SI 3 ""))
5863 (clobber (match_scratch:V4SI 4 ""))
5864 (clobber (match_operand:DI 2 "memory_operand" ""))]
5865 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5866 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5867 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5869 && FP_REG_P (operands[0])"
5870 [(set (match_dup 2) (match_dup 3))
5871 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5873 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5874 Assemble the 64-bit DImode value in an xmm register. */
5875 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5876 gen_rtx_SUBREG (SImode, operands[1], 0)));
5877 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5878 gen_rtx_SUBREG (SImode, operands[1], 4)));
5879 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5882 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5886 [(set (match_operand:X87MODEF 0 "register_operand" "")
5887 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5888 (clobber (match_scratch:V4SI 3 ""))
5889 (clobber (match_scratch:V4SI 4 ""))
5890 (clobber (match_operand:DI 2 "memory_operand" ""))]
5891 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5892 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5893 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5895 && FP_REG_P (operands[0])"
5896 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5899 ;; Avoid store forwarding (partial memory) stall penalty by extending
5900 ;; SImode value to DImode through XMM register instead of pushing two
5901 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5902 ;; targets benefit from this optimization. Also note that fild
5903 ;; loads from memory only.
5905 (define_insn "*floatunssi<mode>2_1"
5906 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5907 (unsigned_float:X87MODEF
5908 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5909 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5910 (clobber (match_scratch:SI 3 "=X,x"))]
5912 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5915 [(set_attr "type" "multi")
5916 (set_attr "mode" "<MODE>")])
5919 [(set (match_operand:X87MODEF 0 "register_operand" "")
5920 (unsigned_float:X87MODEF
5921 (match_operand:SI 1 "register_operand" "")))
5922 (clobber (match_operand:DI 2 "memory_operand" ""))
5923 (clobber (match_scratch:SI 3 ""))]
5925 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5927 && reload_completed"
5928 [(set (match_dup 2) (match_dup 1))
5930 (float:X87MODEF (match_dup 2)))]
5931 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5934 [(set (match_operand:X87MODEF 0 "register_operand" "")
5935 (unsigned_float:X87MODEF
5936 (match_operand:SI 1 "memory_operand" "")))
5937 (clobber (match_operand:DI 2 "memory_operand" ""))
5938 (clobber (match_scratch:SI 3 ""))]
5940 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5942 && reload_completed"
5943 [(set (match_dup 2) (match_dup 3))
5945 (float:X87MODEF (match_dup 2)))]
5947 emit_move_insn (operands[3], operands[1]);
5948 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5951 (define_expand "floatunssi<mode>2"
5953 [(set (match_operand:X87MODEF 0 "register_operand" "")
5954 (unsigned_float:X87MODEF
5955 (match_operand:SI 1 "nonimmediate_operand" "")))
5956 (clobber (match_dup 2))
5957 (clobber (match_scratch:SI 3 ""))])]
5959 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5961 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5963 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5965 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5970 enum ix86_stack_slot slot = (virtuals_instantiated
5973 operands[2] = assign_386_stack_local (DImode, slot);
5977 (define_expand "floatunsdisf2"
5978 [(use (match_operand:SF 0 "register_operand" ""))
5979 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5980 "TARGET_64BIT && TARGET_SSE_MATH"
5981 "x86_emit_floatuns (operands); DONE;")
5983 (define_expand "floatunsdidf2"
5984 [(use (match_operand:DF 0 "register_operand" ""))
5985 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5986 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5987 && TARGET_SSE2 && TARGET_SSE_MATH"
5990 x86_emit_floatuns (operands);
5992 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5998 (define_expand "add<mode>3"
5999 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6000 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6001 (match_operand:SDWIM 2 "<general_operand>" "")))]
6003 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6005 (define_insn_and_split "*add<dwi>3_doubleword"
6006 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6008 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6009 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6010 (clobber (reg:CC FLAGS_REG))]
6011 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6014 [(parallel [(set (reg:CC FLAGS_REG)
6015 (unspec:CC [(match_dup 1) (match_dup 2)]
6018 (plus:DWIH (match_dup 1) (match_dup 2)))])
6019 (parallel [(set (match_dup 3)
6023 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6025 (clobber (reg:CC FLAGS_REG))])]
6026 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6028 (define_insn "*add<mode>3_cc"
6029 [(set (reg:CC FLAGS_REG)
6031 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6032 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
6034 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
6035 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6036 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6037 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6038 [(set_attr "type" "alu")
6039 (set_attr "mode" "<MODE>")])
6041 (define_insn "addqi3_cc"
6042 [(set (reg:CC FLAGS_REG)
6044 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6045 (match_operand:QI 2 "general_operand" "qn,qm")]
6047 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6048 (plus:QI (match_dup 1) (match_dup 2)))]
6049 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6050 "add{b}\t{%2, %0|%0, %2}"
6051 [(set_attr "type" "alu")
6052 (set_attr "mode" "QI")])
6054 (define_insn "*lea_1"
6055 [(set (match_operand:DWIH 0 "register_operand" "=r")
6056 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
6058 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
6059 [(set_attr "type" "lea")
6060 (set_attr "mode" "<MODE>")])
6062 (define_insn "*lea_2"
6063 [(set (match_operand:SI 0 "register_operand" "=r")
6064 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6066 "lea{l}\t{%a1, %0|%0, %a1}"
6067 [(set_attr "type" "lea")
6068 (set_attr "mode" "SI")])
6070 (define_insn "*lea_2_zext"
6071 [(set (match_operand:DI 0 "register_operand" "=r")
6073 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6075 "lea{l}\t{%a1, %k0|%k0, %a1}"
6076 [(set_attr "type" "lea")
6077 (set_attr "mode" "SI")])
6079 (define_insn "*add<mode>_1"
6080 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6082 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6083 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6084 (clobber (reg:CC FLAGS_REG))]
6085 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6087 switch (get_attr_type (insn))
6090 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6091 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6094 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6095 if (operands[2] == const1_rtx)
6096 return "inc{<imodesuffix>}\t%0";
6099 gcc_assert (operands[2] == constm1_rtx);
6100 return "dec{<imodesuffix>}\t%0";
6104 /* Use add as much as possible to replace lea for AGU optimization. */
6105 if (which_alternative == 2 && TARGET_OPT_AGU)
6106 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6108 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6109 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6110 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6112 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6116 (cond [(and (eq_attr "alternative" "2")
6117 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6118 (const_string "lea")
6119 (eq_attr "alternative" "3")
6120 (const_string "lea")
6121 (match_operand:SWI48 2 "incdec_operand" "")
6122 (const_string "incdec")
6124 (const_string "alu")))
6125 (set (attr "length_immediate")
6127 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6129 (const_string "*")))
6130 (set_attr "mode" "<MODE>")])
6132 ;; It may seem that nonimmediate operand is proper one for operand 1.
6133 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6134 ;; we take care in ix86_binary_operator_ok to not allow two memory
6135 ;; operands so proper swapping will be done in reload. This allow
6136 ;; patterns constructed from addsi_1 to match.
6138 (define_insn "*addsi_1_zext"
6139 [(set (match_operand:DI 0 "register_operand" "=r,r")
6141 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6142 (match_operand:SI 2 "general_operand" "g,li"))))
6143 (clobber (reg:CC FLAGS_REG))]
6144 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6146 switch (get_attr_type (insn))
6149 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6150 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6153 if (operands[2] == const1_rtx)
6154 return "inc{l}\t%k0";
6157 gcc_assert (operands[2] == constm1_rtx);
6158 return "dec{l}\t%k0";
6162 if (x86_maybe_negate_const_int (&operands[2], SImode))
6163 return "sub{l}\t{%2, %k0|%k0, %2}";
6165 return "add{l}\t{%2, %k0|%k0, %2}";
6169 (cond [(eq_attr "alternative" "1")
6170 (const_string "lea")
6171 (match_operand:SI 2 "incdec_operand" "")
6172 (const_string "incdec")
6174 (const_string "alu")))
6175 (set (attr "length_immediate")
6177 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6179 (const_string "*")))
6180 (set_attr "mode" "SI")])
6182 (define_insn "*addhi_1"
6183 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6184 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6185 (match_operand:HI 2 "general_operand" "rn,rm")))
6186 (clobber (reg:CC FLAGS_REG))]
6187 "TARGET_PARTIAL_REG_STALL
6188 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6190 switch (get_attr_type (insn))
6193 if (operands[2] == const1_rtx)
6194 return "inc{w}\t%0";
6197 gcc_assert (operands[2] == constm1_rtx);
6198 return "dec{w}\t%0";
6202 if (x86_maybe_negate_const_int (&operands[2], HImode))
6203 return "sub{w}\t{%2, %0|%0, %2}";
6205 return "add{w}\t{%2, %0|%0, %2}";
6209 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6210 (const_string "incdec")
6211 (const_string "alu")))
6212 (set (attr "length_immediate")
6214 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6216 (const_string "*")))
6217 (set_attr "mode" "HI")])
6219 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6220 ;; type optimizations enabled by define-splits. This is not important
6221 ;; for PII, and in fact harmful because of partial register stalls.
6223 (define_insn "*addhi_1_lea"
6224 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6225 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6226 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6227 (clobber (reg:CC FLAGS_REG))]
6228 "!TARGET_PARTIAL_REG_STALL
6229 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6231 switch (get_attr_type (insn))
6236 if (operands[2] == const1_rtx)
6237 return "inc{w}\t%0";
6240 gcc_assert (operands[2] == constm1_rtx);
6241 return "dec{w}\t%0";
6245 if (x86_maybe_negate_const_int (&operands[2], HImode))
6246 return "sub{w}\t{%2, %0|%0, %2}";
6248 return "add{w}\t{%2, %0|%0, %2}";
6252 (if_then_else (eq_attr "alternative" "2")
6253 (const_string "lea")
6254 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6255 (const_string "incdec")
6256 (const_string "alu"))))
6257 (set (attr "length_immediate")
6259 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6261 (const_string "*")))
6262 (set_attr "mode" "HI,HI,SI")])
6264 (define_insn "*addqi_1"
6265 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6266 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6267 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6268 (clobber (reg:CC FLAGS_REG))]
6269 "TARGET_PARTIAL_REG_STALL
6270 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6272 int widen = (which_alternative == 2);
6273 switch (get_attr_type (insn))
6276 if (operands[2] == const1_rtx)
6277 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6280 gcc_assert (operands[2] == constm1_rtx);
6281 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6285 if (x86_maybe_negate_const_int (&operands[2], QImode))
6288 return "sub{l}\t{%2, %k0|%k0, %2}";
6290 return "sub{b}\t{%2, %0|%0, %2}";
6293 return "add{l}\t{%k2, %k0|%k0, %k2}";
6295 return "add{b}\t{%2, %0|%0, %2}";
6299 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6300 (const_string "incdec")
6301 (const_string "alu")))
6302 (set (attr "length_immediate")
6304 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6306 (const_string "*")))
6307 (set_attr "mode" "QI,QI,SI")])
6309 ;; %%% Potential partial reg stall on alternative 2. What to do?
6310 (define_insn "*addqi_1_lea"
6311 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6312 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6313 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6314 (clobber (reg:CC FLAGS_REG))]
6315 "!TARGET_PARTIAL_REG_STALL
6316 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6318 int widen = (which_alternative == 2);
6319 switch (get_attr_type (insn))
6324 if (operands[2] == const1_rtx)
6325 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6328 gcc_assert (operands[2] == constm1_rtx);
6329 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6333 if (x86_maybe_negate_const_int (&operands[2], QImode))
6336 return "sub{l}\t{%2, %k0|%k0, %2}";
6338 return "sub{b}\t{%2, %0|%0, %2}";
6341 return "add{l}\t{%k2, %k0|%k0, %k2}";
6343 return "add{b}\t{%2, %0|%0, %2}";
6347 (if_then_else (eq_attr "alternative" "3")
6348 (const_string "lea")
6349 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6350 (const_string "incdec")
6351 (const_string "alu"))))
6352 (set (attr "length_immediate")
6354 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6356 (const_string "*")))
6357 (set_attr "mode" "QI,QI,SI,SI")])
6359 (define_insn "*addqi_1_slp"
6360 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6361 (plus:QI (match_dup 0)
6362 (match_operand:QI 1 "general_operand" "qn,qnm")))
6363 (clobber (reg:CC FLAGS_REG))]
6364 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6365 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6367 switch (get_attr_type (insn))
6370 if (operands[1] == const1_rtx)
6371 return "inc{b}\t%0";
6374 gcc_assert (operands[1] == constm1_rtx);
6375 return "dec{b}\t%0";
6379 if (x86_maybe_negate_const_int (&operands[1], QImode))
6380 return "sub{b}\t{%1, %0|%0, %1}";
6382 return "add{b}\t{%1, %0|%0, %1}";
6386 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6387 (const_string "incdec")
6388 (const_string "alu1")))
6389 (set (attr "memory")
6390 (if_then_else (match_operand 1 "memory_operand" "")
6391 (const_string "load")
6392 (const_string "none")))
6393 (set_attr "mode" "QI")])
6395 (define_insn "*add<mode>_2"
6396 [(set (reg FLAGS_REG)
6399 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6400 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6402 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6403 (plus:SWI (match_dup 1) (match_dup 2)))]
6404 "ix86_match_ccmode (insn, CCGOCmode)
6405 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6407 switch (get_attr_type (insn))
6410 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6411 if (operands[2] == const1_rtx)
6412 return "inc{<imodesuffix>}\t%0";
6415 gcc_assert (operands[2] == constm1_rtx);
6416 return "dec{<imodesuffix>}\t%0";
6420 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6421 /* ???? In DImode, we ought to handle there the 32bit case too
6422 - do we need new constraint? */
6423 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6424 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6426 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6430 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6431 (const_string "incdec")
6432 (const_string "alu")))
6433 (set (attr "length_immediate")
6435 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6437 (const_string "*")))
6438 (set_attr "mode" "<MODE>")])
6440 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6441 (define_insn "*addsi_2_zext"
6442 [(set (reg FLAGS_REG)
6444 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6445 (match_operand:SI 2 "general_operand" "g"))
6447 (set (match_operand:DI 0 "register_operand" "=r")
6448 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6449 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6450 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6452 switch (get_attr_type (insn))
6455 if (operands[2] == const1_rtx)
6456 return "inc{l}\t%k0";
6459 gcc_assert (operands[2] == constm1_rtx);
6460 return "dec{l}\t%k0";
6464 if (x86_maybe_negate_const_int (&operands[2], SImode))
6465 return "sub{l}\t{%2, %k0|%k0, %2}";
6467 return "add{l}\t{%2, %k0|%k0, %2}";
6471 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6472 (const_string "incdec")
6473 (const_string "alu")))
6474 (set (attr "length_immediate")
6476 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6478 (const_string "*")))
6479 (set_attr "mode" "SI")])
6481 (define_insn "*add<mode>_3"
6482 [(set (reg FLAGS_REG)
6484 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6485 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6486 (clobber (match_scratch:SWI 0 "=<r>"))]
6487 "ix86_match_ccmode (insn, CCZmode)
6488 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6490 switch (get_attr_type (insn))
6493 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6494 if (operands[2] == const1_rtx)
6495 return "inc{<imodesuffix>}\t%0";
6498 gcc_assert (operands[2] == constm1_rtx);
6499 return "dec{<imodesuffix>}\t%0";
6503 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6504 /* ???? In DImode, we ought to handle there the 32bit case too
6505 - do we need new constraint? */
6506 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6507 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6509 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6513 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6514 (const_string "incdec")
6515 (const_string "alu")))
6516 (set (attr "length_immediate")
6518 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6520 (const_string "*")))
6521 (set_attr "mode" "<MODE>")])
6523 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6524 (define_insn "*addsi_3_zext"
6525 [(set (reg FLAGS_REG)
6527 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6528 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6529 (set (match_operand:DI 0 "register_operand" "=r")
6530 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6531 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6532 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6534 switch (get_attr_type (insn))
6537 if (operands[2] == const1_rtx)
6538 return "inc{l}\t%k0";
6541 gcc_assert (operands[2] == constm1_rtx);
6542 return "dec{l}\t%k0";
6546 if (x86_maybe_negate_const_int (&operands[2], SImode))
6547 return "sub{l}\t{%2, %k0|%k0, %2}";
6549 return "add{l}\t{%2, %k0|%k0, %2}";
6553 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6554 (const_string "incdec")
6555 (const_string "alu")))
6556 (set (attr "length_immediate")
6558 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6560 (const_string "*")))
6561 (set_attr "mode" "SI")])
6563 ; For comparisons against 1, -1 and 128, we may generate better code
6564 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6565 ; is matched then. We can't accept general immediate, because for
6566 ; case of overflows, the result is messed up.
6567 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6568 ; only for comparisons not depending on it.
6570 (define_insn "*adddi_4"
6571 [(set (reg FLAGS_REG)
6573 (match_operand:DI 1 "nonimmediate_operand" "0")
6574 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6575 (clobber (match_scratch:DI 0 "=rm"))]
6577 && ix86_match_ccmode (insn, CCGCmode)"
6579 switch (get_attr_type (insn))
6582 if (operands[2] == constm1_rtx)
6583 return "inc{q}\t%0";
6586 gcc_assert (operands[2] == const1_rtx);
6587 return "dec{q}\t%0";
6591 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6592 if (x86_maybe_negate_const_int (&operands[2], DImode))
6593 return "add{q}\t{%2, %0|%0, %2}";
6595 return "sub{q}\t{%2, %0|%0, %2}";
6599 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6600 (const_string "incdec")
6601 (const_string "alu")))
6602 (set (attr "length_immediate")
6604 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6606 (const_string "*")))
6607 (set_attr "mode" "DI")])
6609 ; For comparisons against 1, -1 and 128, we may generate better code
6610 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6611 ; is matched then. We can't accept general immediate, because for
6612 ; case of overflows, the result is messed up.
6613 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6614 ; only for comparisons not depending on it.
6616 (define_insn "*add<mode>_4"
6617 [(set (reg FLAGS_REG)
6619 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6620 (match_operand:SWI124 2 "const_int_operand" "n")))
6621 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6622 "ix86_match_ccmode (insn, CCGCmode)"
6624 switch (get_attr_type (insn))
6627 if (operands[2] == constm1_rtx)
6628 return "inc{<imodesuffix>}\t%0";
6631 gcc_assert (operands[2] == const1_rtx);
6632 return "dec{<imodesuffix>}\t%0";
6636 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6637 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6638 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6640 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6644 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6645 (const_string "incdec")
6646 (const_string "alu")))
6647 (set (attr "length_immediate")
6649 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6651 (const_string "*")))
6652 (set_attr "mode" "<MODE>")])
6654 (define_insn "*add<mode>_5"
6655 [(set (reg FLAGS_REG)
6658 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6659 (match_operand:SWI 2 "<general_operand>" "<g>"))
6661 (clobber (match_scratch:SWI 0 "=<r>"))]
6662 "ix86_match_ccmode (insn, CCGOCmode)
6663 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6665 switch (get_attr_type (insn))
6668 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6669 if (operands[2] == const1_rtx)
6670 return "inc{<imodesuffix>}\t%0";
6673 gcc_assert (operands[2] == constm1_rtx);
6674 return "dec{<imodesuffix>}\t%0";
6678 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6679 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6680 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6682 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6686 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6687 (const_string "incdec")
6688 (const_string "alu")))
6689 (set (attr "length_immediate")
6691 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6693 (const_string "*")))
6694 (set_attr "mode" "<MODE>")])
6696 (define_insn "*addqi_ext_1_rex64"
6697 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6702 (match_operand 1 "ext_register_operand" "0")
6705 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6706 (clobber (reg:CC FLAGS_REG))]
6709 switch (get_attr_type (insn))
6712 if (operands[2] == const1_rtx)
6713 return "inc{b}\t%h0";
6716 gcc_assert (operands[2] == constm1_rtx);
6717 return "dec{b}\t%h0";
6721 return "add{b}\t{%2, %h0|%h0, %2}";
6725 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6726 (const_string "incdec")
6727 (const_string "alu")))
6728 (set_attr "modrm" "1")
6729 (set_attr "mode" "QI")])
6731 (define_insn "addqi_ext_1"
6732 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6737 (match_operand 1 "ext_register_operand" "0")
6740 (match_operand:QI 2 "general_operand" "Qmn")))
6741 (clobber (reg:CC FLAGS_REG))]
6744 switch (get_attr_type (insn))
6747 if (operands[2] == const1_rtx)
6748 return "inc{b}\t%h0";
6751 gcc_assert (operands[2] == constm1_rtx);
6752 return "dec{b}\t%h0";
6756 return "add{b}\t{%2, %h0|%h0, %2}";
6760 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6761 (const_string "incdec")
6762 (const_string "alu")))
6763 (set_attr "modrm" "1")
6764 (set_attr "mode" "QI")])
6766 (define_insn "*addqi_ext_2"
6767 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6772 (match_operand 1 "ext_register_operand" "%0")
6776 (match_operand 2 "ext_register_operand" "Q")
6779 (clobber (reg:CC FLAGS_REG))]
6781 "add{b}\t{%h2, %h0|%h0, %h2}"
6782 [(set_attr "type" "alu")
6783 (set_attr "mode" "QI")])
6785 ;; The lea patterns for non-Pmodes needs to be matched by
6786 ;; several insns converted to real lea by splitters.
6788 (define_insn_and_split "*lea_general_1"
6789 [(set (match_operand 0 "register_operand" "=r")
6790 (plus (plus (match_operand 1 "index_register_operand" "l")
6791 (match_operand 2 "register_operand" "r"))
6792 (match_operand 3 "immediate_operand" "i")))]
6793 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6794 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6795 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6796 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6797 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6798 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6799 || GET_MODE (operands[3]) == VOIDmode)"
6801 "&& reload_completed"
6805 operands[0] = gen_lowpart (SImode, operands[0]);
6806 operands[1] = gen_lowpart (Pmode, operands[1]);
6807 operands[2] = gen_lowpart (Pmode, operands[2]);
6808 operands[3] = gen_lowpart (Pmode, operands[3]);
6809 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6811 if (Pmode != SImode)
6812 pat = gen_rtx_SUBREG (SImode, pat, 0);
6813 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6816 [(set_attr "type" "lea")
6817 (set_attr "mode" "SI")])
6819 (define_insn_and_split "*lea_general_1_zext"
6820 [(set (match_operand:DI 0 "register_operand" "=r")
6823 (match_operand:SI 1 "index_register_operand" "l")
6824 (match_operand:SI 2 "register_operand" "r"))
6825 (match_operand:SI 3 "immediate_operand" "i"))))]
6828 "&& reload_completed"
6830 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6832 (match_dup 3)) 0)))]
6834 operands[1] = gen_lowpart (Pmode, operands[1]);
6835 operands[2] = gen_lowpart (Pmode, operands[2]);
6836 operands[3] = gen_lowpart (Pmode, operands[3]);
6838 [(set_attr "type" "lea")
6839 (set_attr "mode" "SI")])
6841 (define_insn_and_split "*lea_general_2"
6842 [(set (match_operand 0 "register_operand" "=r")
6843 (plus (mult (match_operand 1 "index_register_operand" "l")
6844 (match_operand 2 "const248_operand" "i"))
6845 (match_operand 3 "nonmemory_operand" "ri")))]
6846 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6847 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6848 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6849 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6850 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6851 || GET_MODE (operands[3]) == VOIDmode)"
6853 "&& reload_completed"
6857 operands[0] = gen_lowpart (SImode, operands[0]);
6858 operands[1] = gen_lowpart (Pmode, operands[1]);
6859 operands[3] = gen_lowpart (Pmode, operands[3]);
6860 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6862 if (Pmode != SImode)
6863 pat = gen_rtx_SUBREG (SImode, pat, 0);
6864 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6867 [(set_attr "type" "lea")
6868 (set_attr "mode" "SI")])
6870 (define_insn_and_split "*lea_general_2_zext"
6871 [(set (match_operand:DI 0 "register_operand" "=r")
6874 (match_operand:SI 1 "index_register_operand" "l")
6875 (match_operand:SI 2 "const248_operand" "n"))
6876 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6879 "&& reload_completed"
6881 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6883 (match_dup 3)) 0)))]
6885 operands[1] = gen_lowpart (Pmode, operands[1]);
6886 operands[3] = gen_lowpart (Pmode, operands[3]);
6888 [(set_attr "type" "lea")
6889 (set_attr "mode" "SI")])
6891 (define_insn_and_split "*lea_general_3"
6892 [(set (match_operand 0 "register_operand" "=r")
6893 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6894 (match_operand 2 "const248_operand" "i"))
6895 (match_operand 3 "register_operand" "r"))
6896 (match_operand 4 "immediate_operand" "i")))]
6897 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6898 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6899 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6900 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6901 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6903 "&& reload_completed"
6907 operands[0] = gen_lowpart (SImode, operands[0]);
6908 operands[1] = gen_lowpart (Pmode, operands[1]);
6909 operands[3] = gen_lowpart (Pmode, operands[3]);
6910 operands[4] = gen_lowpart (Pmode, operands[4]);
6911 pat = gen_rtx_PLUS (Pmode,
6912 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6916 if (Pmode != SImode)
6917 pat = gen_rtx_SUBREG (SImode, pat, 0);
6918 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6921 [(set_attr "type" "lea")
6922 (set_attr "mode" "SI")])
6924 (define_insn_and_split "*lea_general_3_zext"
6925 [(set (match_operand:DI 0 "register_operand" "=r")
6929 (match_operand:SI 1 "index_register_operand" "l")
6930 (match_operand:SI 2 "const248_operand" "n"))
6931 (match_operand:SI 3 "register_operand" "r"))
6932 (match_operand:SI 4 "immediate_operand" "i"))))]
6935 "&& reload_completed"
6937 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6940 (match_dup 4)) 0)))]
6942 operands[1] = gen_lowpart (Pmode, operands[1]);
6943 operands[3] = gen_lowpart (Pmode, operands[3]);
6944 operands[4] = gen_lowpart (Pmode, operands[4]);
6946 [(set_attr "type" "lea")
6947 (set_attr "mode" "SI")])
6949 ;; Convert lea to the lea pattern to avoid flags dependency.
6951 [(set (match_operand:DI 0 "register_operand" "")
6952 (plus:DI (match_operand:DI 1 "register_operand" "")
6953 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6954 (clobber (reg:CC FLAGS_REG))]
6955 "TARGET_64BIT && reload_completed
6956 && ix86_lea_for_add_ok (PLUS, insn, operands)"
6958 (plus:DI (match_dup 1)
6962 ;; Convert lea to the lea pattern to avoid flags dependency.
6964 [(set (match_operand 0 "register_operand" "")
6965 (plus (match_operand 1 "register_operand" "")
6966 (match_operand 2 "nonmemory_operand" "")))
6967 (clobber (reg:CC FLAGS_REG))]
6968 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
6972 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6973 may confuse gen_lowpart. */
6974 if (GET_MODE (operands[0]) != Pmode)
6976 operands[1] = gen_lowpart (Pmode, operands[1]);
6977 operands[2] = gen_lowpart (Pmode, operands[2]);
6979 operands[0] = gen_lowpart (SImode, operands[0]);
6980 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6981 if (Pmode != SImode)
6982 pat = gen_rtx_SUBREG (SImode, pat, 0);
6983 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6987 ;; Convert lea to the lea pattern to avoid flags dependency.
6989 [(set (match_operand:DI 0 "register_operand" "")
6991 (plus:SI (match_operand:SI 1 "register_operand" "")
6992 (match_operand:SI 2 "nonmemory_operand" ""))))
6993 (clobber (reg:CC FLAGS_REG))]
6994 "TARGET_64BIT && reload_completed
6995 && true_regnum (operands[0]) != true_regnum (operands[1])"
6997 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6999 operands[1] = gen_lowpart (Pmode, operands[1]);
7000 operands[2] = gen_lowpart (Pmode, operands[2]);
7003 ;; Subtract instructions
7005 (define_expand "sub<mode>3"
7006 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7007 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7008 (match_operand:SDWIM 2 "<general_operand>" "")))]
7010 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7012 (define_insn_and_split "*sub<dwi>3_doubleword"
7013 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7015 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7016 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7017 (clobber (reg:CC FLAGS_REG))]
7018 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7021 [(parallel [(set (reg:CC FLAGS_REG)
7022 (compare:CC (match_dup 1) (match_dup 2)))
7024 (minus:DWIH (match_dup 1) (match_dup 2)))])
7025 (parallel [(set (match_dup 3)
7029 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7031 (clobber (reg:CC FLAGS_REG))])]
7032 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7034 (define_insn "*sub<mode>_1"
7035 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7037 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7038 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7039 (clobber (reg:CC FLAGS_REG))]
7040 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7041 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7042 [(set_attr "type" "alu")
7043 (set_attr "mode" "<MODE>")])
7045 (define_insn "*subsi_1_zext"
7046 [(set (match_operand:DI 0 "register_operand" "=r")
7048 (minus:SI (match_operand:SI 1 "register_operand" "0")
7049 (match_operand:SI 2 "general_operand" "g"))))
7050 (clobber (reg:CC FLAGS_REG))]
7051 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7052 "sub{l}\t{%2, %k0|%k0, %2}"
7053 [(set_attr "type" "alu")
7054 (set_attr "mode" "SI")])
7056 (define_insn "*subqi_1_slp"
7057 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7058 (minus:QI (match_dup 0)
7059 (match_operand:QI 1 "general_operand" "qn,qm")))
7060 (clobber (reg:CC FLAGS_REG))]
7061 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7062 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7063 "sub{b}\t{%1, %0|%0, %1}"
7064 [(set_attr "type" "alu1")
7065 (set_attr "mode" "QI")])
7067 (define_insn "*sub<mode>_2"
7068 [(set (reg FLAGS_REG)
7071 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7072 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7074 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7075 (minus:SWI (match_dup 1) (match_dup 2)))]
7076 "ix86_match_ccmode (insn, CCGOCmode)
7077 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7078 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7079 [(set_attr "type" "alu")
7080 (set_attr "mode" "<MODE>")])
7082 (define_insn "*subsi_2_zext"
7083 [(set (reg FLAGS_REG)
7085 (minus:SI (match_operand:SI 1 "register_operand" "0")
7086 (match_operand:SI 2 "general_operand" "g"))
7088 (set (match_operand:DI 0 "register_operand" "=r")
7090 (minus:SI (match_dup 1)
7092 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7093 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7094 "sub{l}\t{%2, %k0|%k0, %2}"
7095 [(set_attr "type" "alu")
7096 (set_attr "mode" "SI")])
7098 (define_insn "*sub<mode>_3"
7099 [(set (reg FLAGS_REG)
7100 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7101 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7102 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7103 (minus:SWI (match_dup 1) (match_dup 2)))]
7104 "ix86_match_ccmode (insn, CCmode)
7105 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7106 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7107 [(set_attr "type" "alu")
7108 (set_attr "mode" "<MODE>")])
7110 (define_insn "*subsi_3_zext"
7111 [(set (reg FLAGS_REG)
7112 (compare (match_operand:SI 1 "register_operand" "0")
7113 (match_operand:SI 2 "general_operand" "g")))
7114 (set (match_operand:DI 0 "register_operand" "=r")
7116 (minus:SI (match_dup 1)
7118 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7119 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7120 "sub{l}\t{%2, %1|%1, %2}"
7121 [(set_attr "type" "alu")
7122 (set_attr "mode" "SI")])
7124 ;; Add with carry and subtract with borrow
7126 (define_expand "<plusminus_insn><mode>3_carry"
7128 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7130 (match_operand:SWI 1 "nonimmediate_operand" "")
7131 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7132 [(match_operand 3 "flags_reg_operand" "")
7134 (match_operand:SWI 2 "<general_operand>" ""))))
7135 (clobber (reg:CC FLAGS_REG))])]
7136 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7139 (define_insn "*<plusminus_insn><mode>3_carry"
7140 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7142 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7144 (match_operator 3 "ix86_carry_flag_operator"
7145 [(reg FLAGS_REG) (const_int 0)])
7146 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7147 (clobber (reg:CC FLAGS_REG))]
7148 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7149 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7150 [(set_attr "type" "alu")
7151 (set_attr "use_carry" "1")
7152 (set_attr "pent_pair" "pu")
7153 (set_attr "mode" "<MODE>")])
7155 (define_insn "*addsi3_carry_zext"
7156 [(set (match_operand:DI 0 "register_operand" "=r")
7158 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7159 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7160 [(reg FLAGS_REG) (const_int 0)])
7161 (match_operand:SI 2 "general_operand" "g")))))
7162 (clobber (reg:CC FLAGS_REG))]
7163 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7164 "adc{l}\t{%2, %k0|%k0, %2}"
7165 [(set_attr "type" "alu")
7166 (set_attr "use_carry" "1")
7167 (set_attr "pent_pair" "pu")
7168 (set_attr "mode" "SI")])
7170 (define_insn "*subsi3_carry_zext"
7171 [(set (match_operand:DI 0 "register_operand" "=r")
7173 (minus:SI (match_operand:SI 1 "register_operand" "0")
7174 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7175 [(reg FLAGS_REG) (const_int 0)])
7176 (match_operand:SI 2 "general_operand" "g")))))
7177 (clobber (reg:CC FLAGS_REG))]
7178 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7179 "sbb{l}\t{%2, %k0|%k0, %2}"
7180 [(set_attr "type" "alu")
7181 (set_attr "pent_pair" "pu")
7182 (set_attr "mode" "SI")])
7184 ;; Overflow setting add and subtract instructions
7186 (define_insn "*add<mode>3_cconly_overflow"
7187 [(set (reg:CCC FLAGS_REG)
7190 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7191 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7193 (clobber (match_scratch:SWI 0 "=<r>"))]
7194 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7195 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7196 [(set_attr "type" "alu")
7197 (set_attr "mode" "<MODE>")])
7199 (define_insn "*sub<mode>3_cconly_overflow"
7200 [(set (reg:CCC FLAGS_REG)
7203 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7204 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7207 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7208 [(set_attr "type" "icmp")
7209 (set_attr "mode" "<MODE>")])
7211 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7212 [(set (reg:CCC FLAGS_REG)
7215 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7216 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7218 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7219 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7220 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7221 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7222 [(set_attr "type" "alu")
7223 (set_attr "mode" "<MODE>")])
7225 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7226 [(set (reg:CCC FLAGS_REG)
7229 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7230 (match_operand:SI 2 "general_operand" "g"))
7232 (set (match_operand:DI 0 "register_operand" "=r")
7233 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7234 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7235 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7236 [(set_attr "type" "alu")
7237 (set_attr "mode" "SI")])
7239 ;; The patterns that match these are at the end of this file.
7241 (define_expand "<plusminus_insn>xf3"
7242 [(set (match_operand:XF 0 "register_operand" "")
7244 (match_operand:XF 1 "register_operand" "")
7245 (match_operand:XF 2 "register_operand" "")))]
7249 (define_expand "<plusminus_insn><mode>3"
7250 [(set (match_operand:MODEF 0 "register_operand" "")
7252 (match_operand:MODEF 1 "register_operand" "")
7253 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7254 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7255 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7258 ;; Multiply instructions
7260 (define_expand "mul<mode>3"
7261 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7263 (match_operand:SWIM248 1 "register_operand" "")
7264 (match_operand:SWIM248 2 "<general_operand>" "")))
7265 (clobber (reg:CC FLAGS_REG))])]
7269 (define_expand "mulqi3"
7270 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7272 (match_operand:QI 1 "register_operand" "")
7273 (match_operand:QI 2 "nonimmediate_operand" "")))
7274 (clobber (reg:CC FLAGS_REG))])]
7275 "TARGET_QIMODE_MATH"
7279 ;; IMUL reg32/64, reg32/64, imm8 Direct
7280 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7281 ;; IMUL reg32/64, reg32/64, imm32 Direct
7282 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7283 ;; IMUL reg32/64, reg32/64 Direct
7284 ;; IMUL reg32/64, mem32/64 Direct
7286 (define_insn "*mul<mode>3_1"
7287 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7289 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7290 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7291 (clobber (reg:CC FLAGS_REG))]
7292 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7294 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7295 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7296 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7297 [(set_attr "type" "imul")
7298 (set_attr "prefix_0f" "0,0,1")
7299 (set (attr "athlon_decode")
7300 (cond [(eq_attr "cpu" "athlon")
7301 (const_string "vector")
7302 (eq_attr "alternative" "1")
7303 (const_string "vector")
7304 (and (eq_attr "alternative" "2")
7305 (match_operand 1 "memory_operand" ""))
7306 (const_string "vector")]
7307 (const_string "direct")))
7308 (set (attr "amdfam10_decode")
7309 (cond [(and (eq_attr "alternative" "0,1")
7310 (match_operand 1 "memory_operand" ""))
7311 (const_string "vector")]
7312 (const_string "direct")))
7313 (set_attr "mode" "<MODE>")])
7315 (define_insn "*mulsi3_1_zext"
7316 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7318 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7319 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7320 (clobber (reg:CC FLAGS_REG))]
7322 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7324 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7325 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7326 imul{l}\t{%2, %k0|%k0, %2}"
7327 [(set_attr "type" "imul")
7328 (set_attr "prefix_0f" "0,0,1")
7329 (set (attr "athlon_decode")
7330 (cond [(eq_attr "cpu" "athlon")
7331 (const_string "vector")
7332 (eq_attr "alternative" "1")
7333 (const_string "vector")
7334 (and (eq_attr "alternative" "2")
7335 (match_operand 1 "memory_operand" ""))
7336 (const_string "vector")]
7337 (const_string "direct")))
7338 (set (attr "amdfam10_decode")
7339 (cond [(and (eq_attr "alternative" "0,1")
7340 (match_operand 1 "memory_operand" ""))
7341 (const_string "vector")]
7342 (const_string "direct")))
7343 (set_attr "mode" "SI")])
7346 ;; IMUL reg16, reg16, imm8 VectorPath
7347 ;; IMUL reg16, mem16, imm8 VectorPath
7348 ;; IMUL reg16, reg16, imm16 VectorPath
7349 ;; IMUL reg16, mem16, imm16 VectorPath
7350 ;; IMUL reg16, reg16 Direct
7351 ;; IMUL reg16, mem16 Direct
7353 (define_insn "*mulhi3_1"
7354 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7355 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7356 (match_operand:HI 2 "general_operand" "K,n,mr")))
7357 (clobber (reg:CC FLAGS_REG))]
7359 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7361 imul{w}\t{%2, %1, %0|%0, %1, %2}
7362 imul{w}\t{%2, %1, %0|%0, %1, %2}
7363 imul{w}\t{%2, %0|%0, %2}"
7364 [(set_attr "type" "imul")
7365 (set_attr "prefix_0f" "0,0,1")
7366 (set (attr "athlon_decode")
7367 (cond [(eq_attr "cpu" "athlon")
7368 (const_string "vector")
7369 (eq_attr "alternative" "1,2")
7370 (const_string "vector")]
7371 (const_string "direct")))
7372 (set (attr "amdfam10_decode")
7373 (cond [(eq_attr "alternative" "0,1")
7374 (const_string "vector")]
7375 (const_string "direct")))
7376 (set_attr "mode" "HI")])
7382 (define_insn "*mulqi3_1"
7383 [(set (match_operand:QI 0 "register_operand" "=a")
7384 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7385 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7386 (clobber (reg:CC FLAGS_REG))]
7388 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7390 [(set_attr "type" "imul")
7391 (set_attr "length_immediate" "0")
7392 (set (attr "athlon_decode")
7393 (if_then_else (eq_attr "cpu" "athlon")
7394 (const_string "vector")
7395 (const_string "direct")))
7396 (set_attr "amdfam10_decode" "direct")
7397 (set_attr "mode" "QI")])
7399 (define_expand "<u>mul<mode><dwi>3"
7400 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7403 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7405 (match_operand:DWIH 2 "register_operand" ""))))
7406 (clobber (reg:CC FLAGS_REG))])]
7410 (define_expand "<u>mulqihi3"
7411 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7414 (match_operand:QI 1 "nonimmediate_operand" ""))
7416 (match_operand:QI 2 "register_operand" ""))))
7417 (clobber (reg:CC FLAGS_REG))])]
7418 "TARGET_QIMODE_MATH"
7421 (define_insn "*<u>mul<mode><dwi>3_1"
7422 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7425 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7427 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7428 (clobber (reg:CC FLAGS_REG))]
7429 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7430 "<sgnprefix>mul{<imodesuffix>}\t%2"
7431 [(set_attr "type" "imul")
7432 (set_attr "length_immediate" "0")
7433 (set (attr "athlon_decode")
7434 (if_then_else (eq_attr "cpu" "athlon")
7435 (const_string "vector")
7436 (const_string "double")))
7437 (set_attr "amdfam10_decode" "double")
7438 (set_attr "mode" "<MODE>")])
7440 (define_insn "*<u>mulqihi3_1"
7441 [(set (match_operand:HI 0 "register_operand" "=a")
7444 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7446 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7447 (clobber (reg:CC FLAGS_REG))]
7449 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7450 "<sgnprefix>mul{b}\t%2"
7451 [(set_attr "type" "imul")
7452 (set_attr "length_immediate" "0")
7453 (set (attr "athlon_decode")
7454 (if_then_else (eq_attr "cpu" "athlon")
7455 (const_string "vector")
7456 (const_string "direct")))
7457 (set_attr "amdfam10_decode" "direct")
7458 (set_attr "mode" "QI")])
7460 (define_expand "<s>mul<mode>3_highpart"
7461 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7466 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7468 (match_operand:SWI48 2 "register_operand" "")))
7470 (clobber (match_scratch:SWI48 3 ""))
7471 (clobber (reg:CC FLAGS_REG))])]
7473 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7475 (define_insn "*<s>muldi3_highpart_1"
7476 [(set (match_operand:DI 0 "register_operand" "=d")
7481 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7483 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7485 (clobber (match_scratch:DI 3 "=1"))
7486 (clobber (reg:CC FLAGS_REG))]
7488 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7489 "<sgnprefix>mul{q}\t%2"
7490 [(set_attr "type" "imul")
7491 (set_attr "length_immediate" "0")
7492 (set (attr "athlon_decode")
7493 (if_then_else (eq_attr "cpu" "athlon")
7494 (const_string "vector")
7495 (const_string "double")))
7496 (set_attr "amdfam10_decode" "double")
7497 (set_attr "mode" "DI")])
7499 (define_insn "*<s>mulsi3_highpart_1"
7500 [(set (match_operand:SI 0 "register_operand" "=d")
7505 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7507 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7509 (clobber (match_scratch:SI 3 "=1"))
7510 (clobber (reg:CC FLAGS_REG))]
7511 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7512 "<sgnprefix>mul{l}\t%2"
7513 [(set_attr "type" "imul")
7514 (set_attr "length_immediate" "0")
7515 (set (attr "athlon_decode")
7516 (if_then_else (eq_attr "cpu" "athlon")
7517 (const_string "vector")
7518 (const_string "double")))
7519 (set_attr "amdfam10_decode" "double")
7520 (set_attr "mode" "SI")])
7522 (define_insn "*<s>mulsi3_highpart_zext"
7523 [(set (match_operand:DI 0 "register_operand" "=d")
7524 (zero_extend:DI (truncate:SI
7526 (mult:DI (any_extend:DI
7527 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7529 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7531 (clobber (match_scratch:SI 3 "=1"))
7532 (clobber (reg:CC FLAGS_REG))]
7534 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7535 "<sgnprefix>mul{l}\t%2"
7536 [(set_attr "type" "imul")
7537 (set_attr "length_immediate" "0")
7538 (set (attr "athlon_decode")
7539 (if_then_else (eq_attr "cpu" "athlon")
7540 (const_string "vector")
7541 (const_string "double")))
7542 (set_attr "amdfam10_decode" "double")
7543 (set_attr "mode" "SI")])
7545 ;; The patterns that match these are at the end of this file.
7547 (define_expand "mulxf3"
7548 [(set (match_operand:XF 0 "register_operand" "")
7549 (mult:XF (match_operand:XF 1 "register_operand" "")
7550 (match_operand:XF 2 "register_operand" "")))]
7554 (define_expand "mul<mode>3"
7555 [(set (match_operand:MODEF 0 "register_operand" "")
7556 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7557 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7558 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7559 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7562 ;; Divide instructions
7564 (define_insn "<u>divqi3"
7565 [(set (match_operand:QI 0 "register_operand" "=a")
7567 (match_operand:HI 1 "register_operand" "0")
7568 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7569 (clobber (reg:CC FLAGS_REG))]
7570 "TARGET_QIMODE_MATH"
7571 "<sgnprefix>div{b}\t%2"
7572 [(set_attr "type" "idiv")
7573 (set_attr "mode" "QI")])
7575 ;; The patterns that match these are at the end of this file.
7577 (define_expand "divxf3"
7578 [(set (match_operand:XF 0 "register_operand" "")
7579 (div:XF (match_operand:XF 1 "register_operand" "")
7580 (match_operand:XF 2 "register_operand" "")))]
7584 (define_expand "divdf3"
7585 [(set (match_operand:DF 0 "register_operand" "")
7586 (div:DF (match_operand:DF 1 "register_operand" "")
7587 (match_operand:DF 2 "nonimmediate_operand" "")))]
7588 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7589 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7592 (define_expand "divsf3"
7593 [(set (match_operand:SF 0 "register_operand" "")
7594 (div:SF (match_operand:SF 1 "register_operand" "")
7595 (match_operand:SF 2 "nonimmediate_operand" "")))]
7596 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7599 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7600 && flag_finite_math_only && !flag_trapping_math
7601 && flag_unsafe_math_optimizations)
7603 ix86_emit_swdivsf (operands[0], operands[1],
7604 operands[2], SFmode);
7609 ;; Divmod instructions.
7611 (define_expand "divmod<mode>4"
7612 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7614 (match_operand:SWIM248 1 "register_operand" "")
7615 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7616 (set (match_operand:SWIM248 3 "register_operand" "")
7617 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7618 (clobber (reg:CC FLAGS_REG))])]
7622 (define_insn_and_split "*divmod<mode>4"
7623 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7624 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7625 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7626 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7627 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7628 (clobber (reg:CC FLAGS_REG))]
7632 [(parallel [(set (match_dup 1)
7633 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7634 (clobber (reg:CC FLAGS_REG))])
7635 (parallel [(set (match_dup 0)
7636 (div:SWIM248 (match_dup 2) (match_dup 3)))
7638 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7640 (clobber (reg:CC FLAGS_REG))])]
7642 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7644 if (<MODE>mode != HImode
7645 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7646 operands[4] = operands[2];
7649 /* Avoid use of cltd in favor of a mov+shift. */
7650 emit_move_insn (operands[1], operands[2]);
7651 operands[4] = operands[1];
7654 [(set_attr "type" "multi")
7655 (set_attr "mode" "<MODE>")])
7657 (define_insn "*divmod<mode>4_noext"
7658 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7659 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7660 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7661 (set (match_operand:SWIM248 1 "register_operand" "=d")
7662 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7663 (use (match_operand:SWIM248 4 "register_operand" "1"))
7664 (clobber (reg:CC FLAGS_REG))]
7666 "idiv{<imodesuffix>}\t%3"
7667 [(set_attr "type" "idiv")
7668 (set_attr "mode" "<MODE>")])
7670 (define_expand "udivmod<mode>4"
7671 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7673 (match_operand:SWIM248 1 "register_operand" "")
7674 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7675 (set (match_operand:SWIM248 3 "register_operand" "")
7676 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7677 (clobber (reg:CC FLAGS_REG))])]
7681 (define_insn_and_split "*udivmod<mode>4"
7682 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7683 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7684 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7685 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7686 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7687 (clobber (reg:CC FLAGS_REG))]
7691 [(set (match_dup 1) (const_int 0))
7692 (parallel [(set (match_dup 0)
7693 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7695 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7697 (clobber (reg:CC FLAGS_REG))])]
7699 [(set_attr "type" "multi")
7700 (set_attr "mode" "<MODE>")])
7702 (define_insn "*udivmod<mode>4_noext"
7703 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7704 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7705 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7706 (set (match_operand:SWIM248 1 "register_operand" "=d")
7707 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7708 (use (match_operand:SWIM248 4 "register_operand" "1"))
7709 (clobber (reg:CC FLAGS_REG))]
7711 "div{<imodesuffix>}\t%3"
7712 [(set_attr "type" "idiv")
7713 (set_attr "mode" "<MODE>")])
7715 ;; We cannot use div/idiv for double division, because it causes
7716 ;; "division by zero" on the overflow and that's not what we expect
7717 ;; from truncate. Because true (non truncating) double division is
7718 ;; never generated, we can't create this insn anyway.
7721 ; [(set (match_operand:SI 0 "register_operand" "=a")
7723 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7725 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7726 ; (set (match_operand:SI 3 "register_operand" "=d")
7728 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7729 ; (clobber (reg:CC FLAGS_REG))]
7731 ; "div{l}\t{%2, %0|%0, %2}"
7732 ; [(set_attr "type" "idiv")])
7734 ;;- Logical AND instructions
7736 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7737 ;; Note that this excludes ah.
7739 (define_expand "testsi_ccno_1"
7740 [(set (reg:CCNO FLAGS_REG)
7742 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7743 (match_operand:SI 1 "nonmemory_operand" ""))
7748 (define_expand "testqi_ccz_1"
7749 [(set (reg:CCZ FLAGS_REG)
7750 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7751 (match_operand:QI 1 "nonmemory_operand" ""))
7756 (define_insn "*testdi_1"
7757 [(set (reg FLAGS_REG)
7760 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7761 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7763 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7764 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7766 test{l}\t{%k1, %k0|%k0, %k1}
7767 test{l}\t{%k1, %k0|%k0, %k1}
7768 test{q}\t{%1, %0|%0, %1}
7769 test{q}\t{%1, %0|%0, %1}
7770 test{q}\t{%1, %0|%0, %1}"
7771 [(set_attr "type" "test")
7772 (set_attr "modrm" "0,1,0,1,1")
7773 (set_attr "mode" "SI,SI,DI,DI,DI")])
7775 (define_insn "*testqi_1_maybe_si"
7776 [(set (reg FLAGS_REG)
7779 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7780 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7782 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7783 && ix86_match_ccmode (insn,
7784 CONST_INT_P (operands[1])
7785 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7787 if (which_alternative == 3)
7789 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7790 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7791 return "test{l}\t{%1, %k0|%k0, %1}";
7793 return "test{b}\t{%1, %0|%0, %1}";
7795 [(set_attr "type" "test")
7796 (set_attr "modrm" "0,1,1,1")
7797 (set_attr "mode" "QI,QI,QI,SI")
7798 (set_attr "pent_pair" "uv,np,uv,np")])
7800 (define_insn "*test<mode>_1"
7801 [(set (reg FLAGS_REG)
7804 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7805 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7807 "ix86_match_ccmode (insn, CCNOmode)
7808 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7809 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7810 [(set_attr "type" "test")
7811 (set_attr "modrm" "0,1,1")
7812 (set_attr "mode" "<MODE>")
7813 (set_attr "pent_pair" "uv,np,uv")])
7815 (define_expand "testqi_ext_ccno_0"
7816 [(set (reg:CCNO FLAGS_REG)
7820 (match_operand 0 "ext_register_operand" "")
7823 (match_operand 1 "const_int_operand" ""))
7828 (define_insn "*testqi_ext_0"
7829 [(set (reg FLAGS_REG)
7833 (match_operand 0 "ext_register_operand" "Q")
7836 (match_operand 1 "const_int_operand" "n"))
7838 "ix86_match_ccmode (insn, CCNOmode)"
7839 "test{b}\t{%1, %h0|%h0, %1}"
7840 [(set_attr "type" "test")
7841 (set_attr "mode" "QI")
7842 (set_attr "length_immediate" "1")
7843 (set_attr "modrm" "1")
7844 (set_attr "pent_pair" "np")])
7846 (define_insn "*testqi_ext_1_rex64"
7847 [(set (reg FLAGS_REG)
7851 (match_operand 0 "ext_register_operand" "Q")
7855 (match_operand:QI 1 "register_operand" "Q")))
7857 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7858 "test{b}\t{%1, %h0|%h0, %1}"
7859 [(set_attr "type" "test")
7860 (set_attr "mode" "QI")])
7862 (define_insn "*testqi_ext_1"
7863 [(set (reg FLAGS_REG)
7867 (match_operand 0 "ext_register_operand" "Q")
7871 (match_operand:QI 1 "general_operand" "Qm")))
7873 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7874 "test{b}\t{%1, %h0|%h0, %1}"
7875 [(set_attr "type" "test")
7876 (set_attr "mode" "QI")])
7878 (define_insn "*testqi_ext_2"
7879 [(set (reg FLAGS_REG)
7883 (match_operand 0 "ext_register_operand" "Q")
7887 (match_operand 1 "ext_register_operand" "Q")
7891 "ix86_match_ccmode (insn, CCNOmode)"
7892 "test{b}\t{%h1, %h0|%h0, %h1}"
7893 [(set_attr "type" "test")
7894 (set_attr "mode" "QI")])
7896 (define_insn "*testqi_ext_3_rex64"
7897 [(set (reg FLAGS_REG)
7898 (compare (zero_extract:DI
7899 (match_operand 0 "nonimmediate_operand" "rm")
7900 (match_operand:DI 1 "const_int_operand" "")
7901 (match_operand:DI 2 "const_int_operand" ""))
7904 && ix86_match_ccmode (insn, CCNOmode)
7905 && INTVAL (operands[1]) > 0
7906 && INTVAL (operands[2]) >= 0
7907 /* Ensure that resulting mask is zero or sign extended operand. */
7908 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7909 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7910 && INTVAL (operands[1]) > 32))
7911 && (GET_MODE (operands[0]) == SImode
7912 || GET_MODE (operands[0]) == DImode
7913 || GET_MODE (operands[0]) == HImode
7914 || GET_MODE (operands[0]) == QImode)"
7917 ;; Combine likes to form bit extractions for some tests. Humor it.
7918 (define_insn "*testqi_ext_3"
7919 [(set (reg FLAGS_REG)
7920 (compare (zero_extract:SI
7921 (match_operand 0 "nonimmediate_operand" "rm")
7922 (match_operand:SI 1 "const_int_operand" "")
7923 (match_operand:SI 2 "const_int_operand" ""))
7925 "ix86_match_ccmode (insn, CCNOmode)
7926 && INTVAL (operands[1]) > 0
7927 && INTVAL (operands[2]) >= 0
7928 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7929 && (GET_MODE (operands[0]) == SImode
7930 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7931 || GET_MODE (operands[0]) == HImode
7932 || GET_MODE (operands[0]) == QImode)"
7936 [(set (match_operand 0 "flags_reg_operand" "")
7937 (match_operator 1 "compare_operator"
7939 (match_operand 2 "nonimmediate_operand" "")
7940 (match_operand 3 "const_int_operand" "")
7941 (match_operand 4 "const_int_operand" ""))
7943 "ix86_match_ccmode (insn, CCNOmode)"
7944 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7946 rtx val = operands[2];
7947 HOST_WIDE_INT len = INTVAL (operands[3]);
7948 HOST_WIDE_INT pos = INTVAL (operands[4]);
7950 enum machine_mode mode, submode;
7952 mode = GET_MODE (val);
7955 /* ??? Combine likes to put non-volatile mem extractions in QImode
7956 no matter the size of the test. So find a mode that works. */
7957 if (! MEM_VOLATILE_P (val))
7959 mode = smallest_mode_for_size (pos + len, MODE_INT);
7960 val = adjust_address (val, mode, 0);
7963 else if (GET_CODE (val) == SUBREG
7964 && (submode = GET_MODE (SUBREG_REG (val)),
7965 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7966 && pos + len <= GET_MODE_BITSIZE (submode)
7967 && GET_MODE_CLASS (submode) == MODE_INT)
7969 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7971 val = SUBREG_REG (val);
7973 else if (mode == HImode && pos + len <= 8)
7975 /* Small HImode tests can be converted to QImode. */
7977 val = gen_lowpart (QImode, val);
7980 if (len == HOST_BITS_PER_WIDE_INT)
7983 mask = ((HOST_WIDE_INT)1 << len) - 1;
7986 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7989 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7990 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7991 ;; this is relatively important trick.
7992 ;; Do the conversion only post-reload to avoid limiting of the register class
7995 [(set (match_operand 0 "flags_reg_operand" "")
7996 (match_operator 1 "compare_operator"
7997 [(and (match_operand 2 "register_operand" "")
7998 (match_operand 3 "const_int_operand" ""))
8001 && QI_REG_P (operands[2])
8002 && GET_MODE (operands[2]) != QImode
8003 && ((ix86_match_ccmode (insn, CCZmode)
8004 && !(INTVAL (operands[3]) & ~(255 << 8)))
8005 || (ix86_match_ccmode (insn, CCNOmode)
8006 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8009 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8012 "operands[2] = gen_lowpart (SImode, operands[2]);
8013 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8016 [(set (match_operand 0 "flags_reg_operand" "")
8017 (match_operator 1 "compare_operator"
8018 [(and (match_operand 2 "nonimmediate_operand" "")
8019 (match_operand 3 "const_int_operand" ""))
8022 && GET_MODE (operands[2]) != QImode
8023 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8024 && ((ix86_match_ccmode (insn, CCZmode)
8025 && !(INTVAL (operands[3]) & ~255))
8026 || (ix86_match_ccmode (insn, CCNOmode)
8027 && !(INTVAL (operands[3]) & ~127)))"
8029 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8031 "operands[2] = gen_lowpart (QImode, operands[2]);
8032 operands[3] = gen_lowpart (QImode, operands[3]);")
8034 ;; %%% This used to optimize known byte-wide and operations to memory,
8035 ;; and sometimes to QImode registers. If this is considered useful,
8036 ;; it should be done with splitters.
8038 (define_expand "and<mode>3"
8039 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8040 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8041 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8043 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8045 (define_insn "*anddi_1"
8046 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8048 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8049 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8050 (clobber (reg:CC FLAGS_REG))]
8051 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8053 switch (get_attr_type (insn))
8057 enum machine_mode mode;
8059 gcc_assert (CONST_INT_P (operands[2]));
8060 if (INTVAL (operands[2]) == 0xff)
8064 gcc_assert (INTVAL (operands[2]) == 0xffff);
8068 operands[1] = gen_lowpart (mode, operands[1]);
8070 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8072 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8076 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8077 if (get_attr_mode (insn) == MODE_SI)
8078 return "and{l}\t{%k2, %k0|%k0, %k2}";
8080 return "and{q}\t{%2, %0|%0, %2}";
8083 [(set_attr "type" "alu,alu,alu,imovx")
8084 (set_attr "length_immediate" "*,*,*,0")
8085 (set (attr "prefix_rex")
8087 (and (eq_attr "type" "imovx")
8088 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8089 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8091 (const_string "*")))
8092 (set_attr "mode" "SI,DI,DI,SI")])
8094 (define_insn "*andsi_1"
8095 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8096 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8097 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8098 (clobber (reg:CC FLAGS_REG))]
8099 "ix86_binary_operator_ok (AND, SImode, operands)"
8101 switch (get_attr_type (insn))
8105 enum machine_mode mode;
8107 gcc_assert (CONST_INT_P (operands[2]));
8108 if (INTVAL (operands[2]) == 0xff)
8112 gcc_assert (INTVAL (operands[2]) == 0xffff);
8116 operands[1] = gen_lowpart (mode, operands[1]);
8118 return "movz{bl|x}\t{%1, %0|%0, %1}";
8120 return "movz{wl|x}\t{%1, %0|%0, %1}";
8124 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8125 return "and{l}\t{%2, %0|%0, %2}";
8128 [(set_attr "type" "alu,alu,imovx")
8129 (set (attr "prefix_rex")
8131 (and (eq_attr "type" "imovx")
8132 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8133 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8135 (const_string "*")))
8136 (set_attr "length_immediate" "*,*,0")
8137 (set_attr "mode" "SI")])
8139 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8140 (define_insn "*andsi_1_zext"
8141 [(set (match_operand:DI 0 "register_operand" "=r")
8143 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8144 (match_operand:SI 2 "general_operand" "g"))))
8145 (clobber (reg:CC FLAGS_REG))]
8146 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8147 "and{l}\t{%2, %k0|%k0, %2}"
8148 [(set_attr "type" "alu")
8149 (set_attr "mode" "SI")])
8151 (define_insn "*andhi_1"
8152 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8153 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8154 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8155 (clobber (reg:CC FLAGS_REG))]
8156 "ix86_binary_operator_ok (AND, HImode, operands)"
8158 switch (get_attr_type (insn))
8161 gcc_assert (CONST_INT_P (operands[2]));
8162 gcc_assert (INTVAL (operands[2]) == 0xff);
8163 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8166 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8168 return "and{w}\t{%2, %0|%0, %2}";
8171 [(set_attr "type" "alu,alu,imovx")
8172 (set_attr "length_immediate" "*,*,0")
8173 (set (attr "prefix_rex")
8175 (and (eq_attr "type" "imovx")
8176 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8178 (const_string "*")))
8179 (set_attr "mode" "HI,HI,SI")])
8181 ;; %%% Potential partial reg stall on alternative 2. What to do?
8182 (define_insn "*andqi_1"
8183 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8184 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8185 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8186 (clobber (reg:CC FLAGS_REG))]
8187 "ix86_binary_operator_ok (AND, QImode, operands)"
8189 and{b}\t{%2, %0|%0, %2}
8190 and{b}\t{%2, %0|%0, %2}
8191 and{l}\t{%k2, %k0|%k0, %k2}"
8192 [(set_attr "type" "alu")
8193 (set_attr "mode" "QI,QI,SI")])
8195 (define_insn "*andqi_1_slp"
8196 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8197 (and:QI (match_dup 0)
8198 (match_operand:QI 1 "general_operand" "qn,qmn")))
8199 (clobber (reg:CC FLAGS_REG))]
8200 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8201 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8202 "and{b}\t{%1, %0|%0, %1}"
8203 [(set_attr "type" "alu1")
8204 (set_attr "mode" "QI")])
8207 [(set (match_operand 0 "register_operand" "")
8209 (const_int -65536)))
8210 (clobber (reg:CC FLAGS_REG))]
8211 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8212 || optimize_function_for_size_p (cfun)"
8213 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8214 "operands[1] = gen_lowpart (HImode, operands[0]);")
8217 [(set (match_operand 0 "ext_register_operand" "")
8220 (clobber (reg:CC FLAGS_REG))]
8221 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8222 && reload_completed"
8223 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8224 "operands[1] = gen_lowpart (QImode, operands[0]);")
8227 [(set (match_operand 0 "ext_register_operand" "")
8229 (const_int -65281)))
8230 (clobber (reg:CC FLAGS_REG))]
8231 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8232 && reload_completed"
8233 [(parallel [(set (zero_extract:SI (match_dup 0)
8237 (zero_extract:SI (match_dup 0)
8240 (zero_extract:SI (match_dup 0)
8243 (clobber (reg:CC FLAGS_REG))])]
8244 "operands[0] = gen_lowpart (SImode, operands[0]);")
8246 (define_insn "*anddi_2"
8247 [(set (reg FLAGS_REG)
8250 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8251 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8253 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8254 (and:DI (match_dup 1) (match_dup 2)))]
8255 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8256 && ix86_binary_operator_ok (AND, DImode, operands)"
8258 and{l}\t{%k2, %k0|%k0, %k2}
8259 and{q}\t{%2, %0|%0, %2}
8260 and{q}\t{%2, %0|%0, %2}"
8261 [(set_attr "type" "alu")
8262 (set_attr "mode" "SI,DI,DI")])
8264 (define_insn "*andqi_2_maybe_si"
8265 [(set (reg FLAGS_REG)
8267 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8268 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8270 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8271 (and:QI (match_dup 1) (match_dup 2)))]
8272 "ix86_binary_operator_ok (AND, QImode, operands)
8273 && ix86_match_ccmode (insn,
8274 CONST_INT_P (operands[2])
8275 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8277 if (which_alternative == 2)
8279 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8280 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8281 return "and{l}\t{%2, %k0|%k0, %2}";
8283 return "and{b}\t{%2, %0|%0, %2}";
8285 [(set_attr "type" "alu")
8286 (set_attr "mode" "QI,QI,SI")])
8288 (define_insn "*and<mode>_2"
8289 [(set (reg FLAGS_REG)
8290 (compare (and:SWI124
8291 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8292 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8294 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8295 (and:SWI124 (match_dup 1) (match_dup 2)))]
8296 "ix86_match_ccmode (insn, CCNOmode)
8297 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8298 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8299 [(set_attr "type" "alu")
8300 (set_attr "mode" "<MODE>")])
8302 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8303 (define_insn "*andsi_2_zext"
8304 [(set (reg FLAGS_REG)
8306 (match_operand:SI 1 "nonimmediate_operand" "%0")
8307 (match_operand:SI 2 "general_operand" "g"))
8309 (set (match_operand:DI 0 "register_operand" "=r")
8310 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8311 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8312 && ix86_binary_operator_ok (AND, SImode, operands)"
8313 "and{l}\t{%2, %k0|%k0, %2}"
8314 [(set_attr "type" "alu")
8315 (set_attr "mode" "SI")])
8317 (define_insn "*andqi_2_slp"
8318 [(set (reg FLAGS_REG)
8320 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8321 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8323 (set (strict_low_part (match_dup 0))
8324 (and:QI (match_dup 0) (match_dup 1)))]
8325 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8326 && ix86_match_ccmode (insn, CCNOmode)
8327 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8328 "and{b}\t{%1, %0|%0, %1}"
8329 [(set_attr "type" "alu1")
8330 (set_attr "mode" "QI")])
8332 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8333 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8334 ;; for a QImode operand, which of course failed.
8335 (define_insn "andqi_ext_0"
8336 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8341 (match_operand 1 "ext_register_operand" "0")
8344 (match_operand 2 "const_int_operand" "n")))
8345 (clobber (reg:CC FLAGS_REG))]
8347 "and{b}\t{%2, %h0|%h0, %2}"
8348 [(set_attr "type" "alu")
8349 (set_attr "length_immediate" "1")
8350 (set_attr "modrm" "1")
8351 (set_attr "mode" "QI")])
8353 ;; Generated by peephole translating test to and. This shows up
8354 ;; often in fp comparisons.
8355 (define_insn "*andqi_ext_0_cc"
8356 [(set (reg FLAGS_REG)
8360 (match_operand 1 "ext_register_operand" "0")
8363 (match_operand 2 "const_int_operand" "n"))
8365 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8374 "ix86_match_ccmode (insn, CCNOmode)"
8375 "and{b}\t{%2, %h0|%h0, %2}"
8376 [(set_attr "type" "alu")
8377 (set_attr "length_immediate" "1")
8378 (set_attr "modrm" "1")
8379 (set_attr "mode" "QI")])
8381 (define_insn "*andqi_ext_1_rex64"
8382 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8387 (match_operand 1 "ext_register_operand" "0")
8391 (match_operand 2 "ext_register_operand" "Q"))))
8392 (clobber (reg:CC FLAGS_REG))]
8394 "and{b}\t{%2, %h0|%h0, %2}"
8395 [(set_attr "type" "alu")
8396 (set_attr "length_immediate" "0")
8397 (set_attr "mode" "QI")])
8399 (define_insn "*andqi_ext_1"
8400 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8405 (match_operand 1 "ext_register_operand" "0")
8409 (match_operand:QI 2 "general_operand" "Qm"))))
8410 (clobber (reg:CC FLAGS_REG))]
8412 "and{b}\t{%2, %h0|%h0, %2}"
8413 [(set_attr "type" "alu")
8414 (set_attr "length_immediate" "0")
8415 (set_attr "mode" "QI")])
8417 (define_insn "*andqi_ext_2"
8418 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8423 (match_operand 1 "ext_register_operand" "%0")
8427 (match_operand 2 "ext_register_operand" "Q")
8430 (clobber (reg:CC FLAGS_REG))]
8432 "and{b}\t{%h2, %h0|%h0, %h2}"
8433 [(set_attr "type" "alu")
8434 (set_attr "length_immediate" "0")
8435 (set_attr "mode" "QI")])
8437 ;; Convert wide AND instructions with immediate operand to shorter QImode
8438 ;; equivalents when possible.
8439 ;; Don't do the splitting with memory operands, since it introduces risk
8440 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8441 ;; for size, but that can (should?) be handled by generic code instead.
8443 [(set (match_operand 0 "register_operand" "")
8444 (and (match_operand 1 "register_operand" "")
8445 (match_operand 2 "const_int_operand" "")))
8446 (clobber (reg:CC FLAGS_REG))]
8448 && QI_REG_P (operands[0])
8449 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8450 && !(~INTVAL (operands[2]) & ~(255 << 8))
8451 && GET_MODE (operands[0]) != QImode"
8452 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8453 (and:SI (zero_extract:SI (match_dup 1)
8454 (const_int 8) (const_int 8))
8456 (clobber (reg:CC FLAGS_REG))])]
8457 "operands[0] = gen_lowpart (SImode, operands[0]);
8458 operands[1] = gen_lowpart (SImode, operands[1]);
8459 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8461 ;; Since AND can be encoded with sign extended immediate, this is only
8462 ;; profitable when 7th bit is not set.
8464 [(set (match_operand 0 "register_operand" "")
8465 (and (match_operand 1 "general_operand" "")
8466 (match_operand 2 "const_int_operand" "")))
8467 (clobber (reg:CC FLAGS_REG))]
8469 && ANY_QI_REG_P (operands[0])
8470 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8471 && !(~INTVAL (operands[2]) & ~255)
8472 && !(INTVAL (operands[2]) & 128)
8473 && GET_MODE (operands[0]) != QImode"
8474 [(parallel [(set (strict_low_part (match_dup 0))
8475 (and:QI (match_dup 1)
8477 (clobber (reg:CC FLAGS_REG))])]
8478 "operands[0] = gen_lowpart (QImode, operands[0]);
8479 operands[1] = gen_lowpart (QImode, operands[1]);
8480 operands[2] = gen_lowpart (QImode, operands[2]);")
8482 ;; Logical inclusive and exclusive OR instructions
8484 ;; %%% This used to optimize known byte-wide and operations to memory.
8485 ;; If this is considered useful, it should be done with splitters.
8487 (define_expand "<code><mode>3"
8488 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8489 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8490 (match_operand:SWIM 2 "<general_operand>" "")))]
8492 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8494 (define_insn "*<code><mode>_1"
8495 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8497 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8498 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8499 (clobber (reg:CC FLAGS_REG))]
8500 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8501 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8502 [(set_attr "type" "alu")
8503 (set_attr "mode" "<MODE>")])
8505 ;; %%% Potential partial reg stall on alternative 2. What to do?
8506 (define_insn "*<code>qi_1"
8507 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8508 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8509 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8510 (clobber (reg:CC FLAGS_REG))]
8511 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8513 <logic>{b}\t{%2, %0|%0, %2}
8514 <logic>{b}\t{%2, %0|%0, %2}
8515 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8516 [(set_attr "type" "alu")
8517 (set_attr "mode" "QI,QI,SI")])
8519 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8520 (define_insn "*<code>si_1_zext"
8521 [(set (match_operand:DI 0 "register_operand" "=r")
8523 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8524 (match_operand:SI 2 "general_operand" "g"))))
8525 (clobber (reg:CC FLAGS_REG))]
8526 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8527 "<logic>{l}\t{%2, %k0|%k0, %2}"
8528 [(set_attr "type" "alu")
8529 (set_attr "mode" "SI")])
8531 (define_insn "*<code>si_1_zext_imm"
8532 [(set (match_operand:DI 0 "register_operand" "=r")
8534 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8535 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8536 (clobber (reg:CC FLAGS_REG))]
8537 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8538 "<logic>{l}\t{%2, %k0|%k0, %2}"
8539 [(set_attr "type" "alu")
8540 (set_attr "mode" "SI")])
8542 (define_insn "*<code>qi_1_slp"
8543 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8544 (any_or:QI (match_dup 0)
8545 (match_operand:QI 1 "general_operand" "qmn,qn")))
8546 (clobber (reg:CC FLAGS_REG))]
8547 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8548 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8549 "<logic>{b}\t{%1, %0|%0, %1}"
8550 [(set_attr "type" "alu1")
8551 (set_attr "mode" "QI")])
8553 (define_insn "*<code><mode>_2"
8554 [(set (reg FLAGS_REG)
8555 (compare (any_or:SWI
8556 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8557 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8559 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8560 (any_or:SWI (match_dup 1) (match_dup 2)))]
8561 "ix86_match_ccmode (insn, CCNOmode)
8562 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8563 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8564 [(set_attr "type" "alu")
8565 (set_attr "mode" "<MODE>")])
8567 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8568 ;; ??? Special case for immediate operand is missing - it is tricky.
8569 (define_insn "*<code>si_2_zext"
8570 [(set (reg FLAGS_REG)
8571 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8572 (match_operand:SI 2 "general_operand" "g"))
8574 (set (match_operand:DI 0 "register_operand" "=r")
8575 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8576 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8577 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8578 "<logic>{l}\t{%2, %k0|%k0, %2}"
8579 [(set_attr "type" "alu")
8580 (set_attr "mode" "SI")])
8582 (define_insn "*<code>si_2_zext_imm"
8583 [(set (reg FLAGS_REG)
8585 (match_operand:SI 1 "nonimmediate_operand" "%0")
8586 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8588 (set (match_operand:DI 0 "register_operand" "=r")
8589 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8590 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8591 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8592 "<logic>{l}\t{%2, %k0|%k0, %2}"
8593 [(set_attr "type" "alu")
8594 (set_attr "mode" "SI")])
8596 (define_insn "*<code>qi_2_slp"
8597 [(set (reg FLAGS_REG)
8598 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8599 (match_operand:QI 1 "general_operand" "qmn,qn"))
8601 (set (strict_low_part (match_dup 0))
8602 (any_or:QI (match_dup 0) (match_dup 1)))]
8603 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8604 && ix86_match_ccmode (insn, CCNOmode)
8605 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8606 "<logic>{b}\t{%1, %0|%0, %1}"
8607 [(set_attr "type" "alu1")
8608 (set_attr "mode" "QI")])
8610 (define_insn "*<code><mode>_3"
8611 [(set (reg FLAGS_REG)
8612 (compare (any_or:SWI
8613 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8614 (match_operand:SWI 2 "<general_operand>" "<g>"))
8616 (clobber (match_scratch:SWI 0 "=<r>"))]
8617 "ix86_match_ccmode (insn, CCNOmode)
8618 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8619 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8620 [(set_attr "type" "alu")
8621 (set_attr "mode" "<MODE>")])
8623 (define_insn "*<code>qi_ext_0"
8624 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8629 (match_operand 1 "ext_register_operand" "0")
8632 (match_operand 2 "const_int_operand" "n")))
8633 (clobber (reg:CC FLAGS_REG))]
8634 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8635 "<logic>{b}\t{%2, %h0|%h0, %2}"
8636 [(set_attr "type" "alu")
8637 (set_attr "length_immediate" "1")
8638 (set_attr "modrm" "1")
8639 (set_attr "mode" "QI")])
8641 (define_insn "*<code>qi_ext_1_rex64"
8642 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8647 (match_operand 1 "ext_register_operand" "0")
8651 (match_operand 2 "ext_register_operand" "Q"))))
8652 (clobber (reg:CC FLAGS_REG))]
8654 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8655 "<logic>{b}\t{%2, %h0|%h0, %2}"
8656 [(set_attr "type" "alu")
8657 (set_attr "length_immediate" "0")
8658 (set_attr "mode" "QI")])
8660 (define_insn "*<code>qi_ext_1"
8661 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8666 (match_operand 1 "ext_register_operand" "0")
8670 (match_operand:QI 2 "general_operand" "Qm"))))
8671 (clobber (reg:CC FLAGS_REG))]
8673 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8674 "<logic>{b}\t{%2, %h0|%h0, %2}"
8675 [(set_attr "type" "alu")
8676 (set_attr "length_immediate" "0")
8677 (set_attr "mode" "QI")])
8679 (define_insn "*<code>qi_ext_2"
8680 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8684 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8687 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8690 (clobber (reg:CC FLAGS_REG))]
8691 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8692 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8693 [(set_attr "type" "alu")
8694 (set_attr "length_immediate" "0")
8695 (set_attr "mode" "QI")])
8698 [(set (match_operand 0 "register_operand" "")
8699 (any_or (match_operand 1 "register_operand" "")
8700 (match_operand 2 "const_int_operand" "")))
8701 (clobber (reg:CC FLAGS_REG))]
8703 && QI_REG_P (operands[0])
8704 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8705 && !(INTVAL (operands[2]) & ~(255 << 8))
8706 && GET_MODE (operands[0]) != QImode"
8707 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8708 (any_or:SI (zero_extract:SI (match_dup 1)
8709 (const_int 8) (const_int 8))
8711 (clobber (reg:CC FLAGS_REG))])]
8712 "operands[0] = gen_lowpart (SImode, operands[0]);
8713 operands[1] = gen_lowpart (SImode, operands[1]);
8714 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8716 ;; Since OR can be encoded with sign extended immediate, this is only
8717 ;; profitable when 7th bit is set.
8719 [(set (match_operand 0 "register_operand" "")
8720 (any_or (match_operand 1 "general_operand" "")
8721 (match_operand 2 "const_int_operand" "")))
8722 (clobber (reg:CC FLAGS_REG))]
8724 && ANY_QI_REG_P (operands[0])
8725 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8726 && !(INTVAL (operands[2]) & ~255)
8727 && (INTVAL (operands[2]) & 128)
8728 && GET_MODE (operands[0]) != QImode"
8729 [(parallel [(set (strict_low_part (match_dup 0))
8730 (any_or:QI (match_dup 1)
8732 (clobber (reg:CC FLAGS_REG))])]
8733 "operands[0] = gen_lowpart (QImode, operands[0]);
8734 operands[1] = gen_lowpart (QImode, operands[1]);
8735 operands[2] = gen_lowpart (QImode, operands[2]);")
8737 (define_expand "xorqi_cc_ext_1"
8739 (set (reg:CCNO FLAGS_REG)
8743 (match_operand 1 "ext_register_operand" "")
8746 (match_operand:QI 2 "general_operand" ""))
8748 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8760 (define_insn "*xorqi_cc_ext_1_rex64"
8761 [(set (reg FLAGS_REG)
8765 (match_operand 1 "ext_register_operand" "0")
8768 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8770 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8779 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8780 "xor{b}\t{%2, %h0|%h0, %2}"
8781 [(set_attr "type" "alu")
8782 (set_attr "modrm" "1")
8783 (set_attr "mode" "QI")])
8785 (define_insn "*xorqi_cc_ext_1"
8786 [(set (reg FLAGS_REG)
8790 (match_operand 1 "ext_register_operand" "0")
8793 (match_operand:QI 2 "general_operand" "qmn"))
8795 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8804 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8805 "xor{b}\t{%2, %h0|%h0, %2}"
8806 [(set_attr "type" "alu")
8807 (set_attr "modrm" "1")
8808 (set_attr "mode" "QI")])
8810 ;; Negation instructions
8812 (define_expand "neg<mode>2"
8813 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8814 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8816 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8818 (define_insn_and_split "*neg<dwi>2_doubleword"
8819 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8820 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8821 (clobber (reg:CC FLAGS_REG))]
8822 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8826 [(set (reg:CCZ FLAGS_REG)
8827 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8828 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8831 (plus:DWIH (match_dup 3)
8832 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8834 (clobber (reg:CC FLAGS_REG))])
8837 (neg:DWIH (match_dup 2)))
8838 (clobber (reg:CC FLAGS_REG))])]
8839 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8841 (define_insn "*neg<mode>2_1"
8842 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8843 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8844 (clobber (reg:CC FLAGS_REG))]
8845 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8846 "neg{<imodesuffix>}\t%0"
8847 [(set_attr "type" "negnot")
8848 (set_attr "mode" "<MODE>")])
8850 ;; Combine is quite creative about this pattern.
8851 (define_insn "*negsi2_1_zext"
8852 [(set (match_operand:DI 0 "register_operand" "=r")
8854 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8857 (clobber (reg:CC FLAGS_REG))]
8858 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8860 [(set_attr "type" "negnot")
8861 (set_attr "mode" "SI")])
8863 ;; The problem with neg is that it does not perform (compare x 0),
8864 ;; it really performs (compare 0 x), which leaves us with the zero
8865 ;; flag being the only useful item.
8867 (define_insn "*neg<mode>2_cmpz"
8868 [(set (reg:CCZ FLAGS_REG)
8870 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8872 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8873 (neg:SWI (match_dup 1)))]
8874 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8875 "neg{<imodesuffix>}\t%0"
8876 [(set_attr "type" "negnot")
8877 (set_attr "mode" "<MODE>")])
8879 (define_insn "*negsi2_cmpz_zext"
8880 [(set (reg:CCZ FLAGS_REG)
8884 (match_operand:DI 1 "register_operand" "0")
8888 (set (match_operand:DI 0 "register_operand" "=r")
8889 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8892 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8894 [(set_attr "type" "negnot")
8895 (set_attr "mode" "SI")])
8897 ;; Changing of sign for FP values is doable using integer unit too.
8899 (define_expand "<code><mode>2"
8900 [(set (match_operand:X87MODEF 0 "register_operand" "")
8901 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8902 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8903 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8905 (define_insn "*absneg<mode>2_mixed"
8906 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8907 (match_operator:MODEF 3 "absneg_operator"
8908 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8909 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8910 (clobber (reg:CC FLAGS_REG))]
8911 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8914 (define_insn "*absneg<mode>2_sse"
8915 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8916 (match_operator:MODEF 3 "absneg_operator"
8917 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8918 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8919 (clobber (reg:CC FLAGS_REG))]
8920 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8923 (define_insn "*absneg<mode>2_i387"
8924 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8925 (match_operator:X87MODEF 3 "absneg_operator"
8926 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8927 (use (match_operand 2 "" ""))
8928 (clobber (reg:CC FLAGS_REG))]
8929 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8932 (define_expand "<code>tf2"
8933 [(set (match_operand:TF 0 "register_operand" "")
8934 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8936 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8938 (define_insn "*absnegtf2_sse"
8939 [(set (match_operand:TF 0 "register_operand" "=x,x")
8940 (match_operator:TF 3 "absneg_operator"
8941 [(match_operand:TF 1 "register_operand" "0,x")]))
8942 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8943 (clobber (reg:CC FLAGS_REG))]
8947 ;; Splitters for fp abs and neg.
8950 [(set (match_operand 0 "fp_register_operand" "")
8951 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8952 (use (match_operand 2 "" ""))
8953 (clobber (reg:CC FLAGS_REG))]
8955 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8958 [(set (match_operand 0 "register_operand" "")
8959 (match_operator 3 "absneg_operator"
8960 [(match_operand 1 "register_operand" "")]))
8961 (use (match_operand 2 "nonimmediate_operand" ""))
8962 (clobber (reg:CC FLAGS_REG))]
8963 "reload_completed && SSE_REG_P (operands[0])"
8964 [(set (match_dup 0) (match_dup 3))]
8966 enum machine_mode mode = GET_MODE (operands[0]);
8967 enum machine_mode vmode = GET_MODE (operands[2]);
8970 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8971 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8972 if (operands_match_p (operands[0], operands[2]))
8975 operands[1] = operands[2];
8978 if (GET_CODE (operands[3]) == ABS)
8979 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8981 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8986 [(set (match_operand:SF 0 "register_operand" "")
8987 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8988 (use (match_operand:V4SF 2 "" ""))
8989 (clobber (reg:CC FLAGS_REG))]
8991 [(parallel [(set (match_dup 0) (match_dup 1))
8992 (clobber (reg:CC FLAGS_REG))])]
8995 operands[0] = gen_lowpart (SImode, operands[0]);
8996 if (GET_CODE (operands[1]) == ABS)
8998 tmp = gen_int_mode (0x7fffffff, SImode);
8999 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9003 tmp = gen_int_mode (0x80000000, SImode);
9004 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9010 [(set (match_operand:DF 0 "register_operand" "")
9011 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9012 (use (match_operand 2 "" ""))
9013 (clobber (reg:CC FLAGS_REG))]
9015 [(parallel [(set (match_dup 0) (match_dup 1))
9016 (clobber (reg:CC FLAGS_REG))])]
9021 tmp = gen_lowpart (DImode, operands[0]);
9022 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9025 if (GET_CODE (operands[1]) == ABS)
9028 tmp = gen_rtx_NOT (DImode, tmp);
9032 operands[0] = gen_highpart (SImode, operands[0]);
9033 if (GET_CODE (operands[1]) == ABS)
9035 tmp = gen_int_mode (0x7fffffff, SImode);
9036 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9040 tmp = gen_int_mode (0x80000000, SImode);
9041 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9048 [(set (match_operand:XF 0 "register_operand" "")
9049 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9050 (use (match_operand 2 "" ""))
9051 (clobber (reg:CC FLAGS_REG))]
9053 [(parallel [(set (match_dup 0) (match_dup 1))
9054 (clobber (reg:CC FLAGS_REG))])]
9057 operands[0] = gen_rtx_REG (SImode,
9058 true_regnum (operands[0])
9059 + (TARGET_64BIT ? 1 : 2));
9060 if (GET_CODE (operands[1]) == ABS)
9062 tmp = GEN_INT (0x7fff);
9063 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9067 tmp = GEN_INT (0x8000);
9068 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9073 ;; Conditionalize these after reload. If they match before reload, we
9074 ;; lose the clobber and ability to use integer instructions.
9076 (define_insn "*<code><mode>2_1"
9077 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9078 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9080 && (reload_completed
9081 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9082 "f<absneg_mnemonic>"
9083 [(set_attr "type" "fsgn")
9084 (set_attr "mode" "<MODE>")])
9086 (define_insn "*<code>extendsfdf2"
9087 [(set (match_operand:DF 0 "register_operand" "=f")
9088 (absneg:DF (float_extend:DF
9089 (match_operand:SF 1 "register_operand" "0"))))]
9090 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9091 "f<absneg_mnemonic>"
9092 [(set_attr "type" "fsgn")
9093 (set_attr "mode" "DF")])
9095 (define_insn "*<code>extendsfxf2"
9096 [(set (match_operand:XF 0 "register_operand" "=f")
9097 (absneg:XF (float_extend:XF
9098 (match_operand:SF 1 "register_operand" "0"))))]
9100 "f<absneg_mnemonic>"
9101 [(set_attr "type" "fsgn")
9102 (set_attr "mode" "XF")])
9104 (define_insn "*<code>extenddfxf2"
9105 [(set (match_operand:XF 0 "register_operand" "=f")
9106 (absneg:XF (float_extend:XF
9107 (match_operand:DF 1 "register_operand" "0"))))]
9109 "f<absneg_mnemonic>"
9110 [(set_attr "type" "fsgn")
9111 (set_attr "mode" "XF")])
9113 ;; Copysign instructions
9115 (define_mode_iterator CSGNMODE [SF DF TF])
9116 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9118 (define_expand "copysign<mode>3"
9119 [(match_operand:CSGNMODE 0 "register_operand" "")
9120 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9121 (match_operand:CSGNMODE 2 "register_operand" "")]
9122 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9123 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9125 ix86_expand_copysign (operands);
9129 (define_insn_and_split "copysign<mode>3_const"
9130 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9132 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9133 (match_operand:CSGNMODE 2 "register_operand" "0")
9134 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9136 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9137 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9139 "&& reload_completed"
9142 ix86_split_copysign_const (operands);
9146 (define_insn "copysign<mode>3_var"
9147 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9149 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9150 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9151 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9152 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9154 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9155 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9156 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9160 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9162 [(match_operand:CSGNMODE 2 "register_operand" "")
9163 (match_operand:CSGNMODE 3 "register_operand" "")
9164 (match_operand:<CSGNVMODE> 4 "" "")
9165 (match_operand:<CSGNVMODE> 5 "" "")]
9167 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9168 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9169 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9170 && reload_completed"
9173 ix86_split_copysign_var (operands);
9177 ;; One complement instructions
9179 (define_expand "one_cmpl<mode>2"
9180 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9181 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9183 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9185 (define_insn "*one_cmpl<mode>2_1"
9186 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9187 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9188 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9189 "not{<imodesuffix>}\t%0"
9190 [(set_attr "type" "negnot")
9191 (set_attr "mode" "<MODE>")])
9193 ;; %%% Potential partial reg stall on alternative 1. What to do?
9194 (define_insn "*one_cmplqi2_1"
9195 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9196 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9197 "ix86_unary_operator_ok (NOT, QImode, operands)"
9201 [(set_attr "type" "negnot")
9202 (set_attr "mode" "QI,SI")])
9204 ;; ??? Currently never generated - xor is used instead.
9205 (define_insn "*one_cmplsi2_1_zext"
9206 [(set (match_operand:DI 0 "register_operand" "=r")
9208 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9209 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9211 [(set_attr "type" "negnot")
9212 (set_attr "mode" "SI")])
9214 (define_insn "*one_cmpl<mode>2_2"
9215 [(set (reg FLAGS_REG)
9216 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9218 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9219 (not:SWI (match_dup 1)))]
9220 "ix86_match_ccmode (insn, CCNOmode)
9221 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9223 [(set_attr "type" "alu1")
9224 (set_attr "mode" "<MODE>")])
9227 [(set (match_operand 0 "flags_reg_operand" "")
9228 (match_operator 2 "compare_operator"
9229 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9231 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9232 (not:SWI (match_dup 3)))]
9233 "ix86_match_ccmode (insn, CCNOmode)"
9234 [(parallel [(set (match_dup 0)
9235 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9238 (xor:SWI (match_dup 3) (const_int -1)))])]
9241 ;; ??? Currently never generated - xor is used instead.
9242 (define_insn "*one_cmplsi2_2_zext"
9243 [(set (reg FLAGS_REG)
9244 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9246 (set (match_operand:DI 0 "register_operand" "=r")
9247 (zero_extend:DI (not:SI (match_dup 1))))]
9248 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9249 && ix86_unary_operator_ok (NOT, SImode, operands)"
9251 [(set_attr "type" "alu1")
9252 (set_attr "mode" "SI")])
9255 [(set (match_operand 0 "flags_reg_operand" "")
9256 (match_operator 2 "compare_operator"
9257 [(not:SI (match_operand:SI 3 "register_operand" ""))
9259 (set (match_operand:DI 1 "register_operand" "")
9260 (zero_extend:DI (not:SI (match_dup 3))))]
9261 "ix86_match_ccmode (insn, CCNOmode)"
9262 [(parallel [(set (match_dup 0)
9263 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9266 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9269 ;; Shift instructions
9271 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9272 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9273 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9274 ;; from the assembler input.
9276 ;; This instruction shifts the target reg/mem as usual, but instead of
9277 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9278 ;; is a left shift double, bits are taken from the high order bits of
9279 ;; reg, else if the insn is a shift right double, bits are taken from the
9280 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9281 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9283 ;; Since sh[lr]d does not change the `reg' operand, that is done
9284 ;; separately, making all shifts emit pairs of shift double and normal
9285 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9286 ;; support a 63 bit shift, each shift where the count is in a reg expands
9287 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9289 ;; If the shift count is a constant, we need never emit more than one
9290 ;; shift pair, instead using moves and sign extension for counts greater
9293 (define_expand "ashl<mode>3"
9294 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9295 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9296 (match_operand:QI 2 "nonmemory_operand" "")))]
9298 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9300 (define_insn "*ashl<mode>3_doubleword"
9301 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9302 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9303 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9304 (clobber (reg:CC FLAGS_REG))]
9307 [(set_attr "type" "multi")])
9310 [(set (match_operand:DWI 0 "register_operand" "")
9311 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9312 (match_operand:QI 2 "nonmemory_operand" "")))
9313 (clobber (reg:CC FLAGS_REG))]
9314 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9316 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9318 ;; By default we don't ask for a scratch register, because when DWImode
9319 ;; values are manipulated, registers are already at a premium. But if
9320 ;; we have one handy, we won't turn it away.
9323 [(match_scratch:DWIH 3 "r")
9324 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9326 (match_operand:<DWI> 1 "nonmemory_operand" "")
9327 (match_operand:QI 2 "nonmemory_operand" "")))
9328 (clobber (reg:CC FLAGS_REG))])
9332 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9334 (define_insn "x86_64_shld"
9335 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9336 (ior:DI (ashift:DI (match_dup 0)
9337 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9338 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9339 (minus:QI (const_int 64) (match_dup 2)))))
9340 (clobber (reg:CC FLAGS_REG))]
9342 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9343 [(set_attr "type" "ishift")
9344 (set_attr "prefix_0f" "1")
9345 (set_attr "mode" "DI")
9346 (set_attr "athlon_decode" "vector")
9347 (set_attr "amdfam10_decode" "vector")])
9349 (define_insn "x86_shld"
9350 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9351 (ior:SI (ashift:SI (match_dup 0)
9352 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9353 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9354 (minus:QI (const_int 32) (match_dup 2)))))
9355 (clobber (reg:CC FLAGS_REG))]
9357 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9358 [(set_attr "type" "ishift")
9359 (set_attr "prefix_0f" "1")
9360 (set_attr "mode" "SI")
9361 (set_attr "pent_pair" "np")
9362 (set_attr "athlon_decode" "vector")
9363 (set_attr "amdfam10_decode" "vector")])
9365 (define_expand "x86_shift<mode>_adj_1"
9366 [(set (reg:CCZ FLAGS_REG)
9367 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9370 (set (match_operand:SWI48 0 "register_operand" "")
9371 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9372 (match_operand:SWI48 1 "register_operand" "")
9375 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9376 (match_operand:SWI48 3 "register_operand" "r")
9379 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9381 (define_expand "x86_shift<mode>_adj_2"
9382 [(use (match_operand:SWI48 0 "register_operand" ""))
9383 (use (match_operand:SWI48 1 "register_operand" ""))
9384 (use (match_operand:QI 2 "register_operand" ""))]
9387 rtx label = gen_label_rtx ();
9390 emit_insn (gen_testqi_ccz_1 (operands[2],
9391 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9393 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9394 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9395 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9396 gen_rtx_LABEL_REF (VOIDmode, label),
9398 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9399 JUMP_LABEL (tmp) = label;
9401 emit_move_insn (operands[0], operands[1]);
9402 ix86_expand_clear (operands[1]);
9405 LABEL_NUSES (label) = 1;
9410 (define_insn "*ashl<mode>3_1"
9411 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9412 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9413 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9414 (clobber (reg:CC FLAGS_REG))]
9415 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9417 switch (get_attr_type (insn))
9423 gcc_assert (operands[2] == const1_rtx);
9424 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9425 return "add{<imodesuffix>}\t%0, %0";
9428 if (operands[2] == const1_rtx
9429 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9430 return "sal{<imodesuffix>}\t%0";
9432 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9436 (cond [(eq_attr "alternative" "1")
9437 (const_string "lea")
9438 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9440 (match_operand 0 "register_operand" ""))
9441 (match_operand 2 "const1_operand" ""))
9442 (const_string "alu")
9444 (const_string "ishift")))
9445 (set (attr "length_immediate")
9447 (ior (eq_attr "type" "alu")
9448 (and (eq_attr "type" "ishift")
9449 (and (match_operand 2 "const1_operand" "")
9450 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9453 (const_string "*")))
9454 (set_attr "mode" "<MODE>")])
9456 (define_insn "*ashlsi3_1_zext"
9457 [(set (match_operand:DI 0 "register_operand" "=r,r")
9459 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9460 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9461 (clobber (reg:CC FLAGS_REG))]
9462 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9464 switch (get_attr_type (insn))
9470 gcc_assert (operands[2] == const1_rtx);
9471 return "add{l}\t%k0, %k0";
9474 if (operands[2] == const1_rtx
9475 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9476 return "sal{l}\t%k0";
9478 return "sal{l}\t{%2, %k0|%k0, %2}";
9482 (cond [(eq_attr "alternative" "1")
9483 (const_string "lea")
9484 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9486 (match_operand 2 "const1_operand" ""))
9487 (const_string "alu")
9489 (const_string "ishift")))
9490 (set (attr "length_immediate")
9492 (ior (eq_attr "type" "alu")
9493 (and (eq_attr "type" "ishift")
9494 (and (match_operand 2 "const1_operand" "")
9495 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9498 (const_string "*")))
9499 (set_attr "mode" "SI")])
9501 (define_insn "*ashlhi3_1"
9502 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9503 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9504 (match_operand:QI 2 "nonmemory_operand" "cI")))
9505 (clobber (reg:CC FLAGS_REG))]
9506 "TARGET_PARTIAL_REG_STALL
9507 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9509 switch (get_attr_type (insn))
9512 gcc_assert (operands[2] == const1_rtx);
9513 return "add{w}\t%0, %0";
9516 if (operands[2] == const1_rtx
9517 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9518 return "sal{w}\t%0";
9520 return "sal{w}\t{%2, %0|%0, %2}";
9524 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9526 (match_operand 0 "register_operand" ""))
9527 (match_operand 2 "const1_operand" ""))
9528 (const_string "alu")
9530 (const_string "ishift")))
9531 (set (attr "length_immediate")
9533 (ior (eq_attr "type" "alu")
9534 (and (eq_attr "type" "ishift")
9535 (and (match_operand 2 "const1_operand" "")
9536 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9539 (const_string "*")))
9540 (set_attr "mode" "HI")])
9542 (define_insn "*ashlhi3_1_lea"
9543 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9544 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9545 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9546 (clobber (reg:CC FLAGS_REG))]
9547 "!TARGET_PARTIAL_REG_STALL
9548 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9550 switch (get_attr_type (insn))
9556 gcc_assert (operands[2] == const1_rtx);
9557 return "add{w}\t%0, %0";
9560 if (operands[2] == const1_rtx
9561 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9562 return "sal{w}\t%0";
9564 return "sal{w}\t{%2, %0|%0, %2}";
9568 (cond [(eq_attr "alternative" "1")
9569 (const_string "lea")
9570 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9572 (match_operand 0 "register_operand" ""))
9573 (match_operand 2 "const1_operand" ""))
9574 (const_string "alu")
9576 (const_string "ishift")))
9577 (set (attr "length_immediate")
9579 (ior (eq_attr "type" "alu")
9580 (and (eq_attr "type" "ishift")
9581 (and (match_operand 2 "const1_operand" "")
9582 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9585 (const_string "*")))
9586 (set_attr "mode" "HI,SI")])
9588 (define_insn "*ashlqi3_1"
9589 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9590 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9591 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9592 (clobber (reg:CC FLAGS_REG))]
9593 "TARGET_PARTIAL_REG_STALL
9594 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9596 switch (get_attr_type (insn))
9599 gcc_assert (operands[2] == const1_rtx);
9600 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9601 return "add{l}\t%k0, %k0";
9603 return "add{b}\t%0, %0";
9606 if (operands[2] == const1_rtx
9607 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9609 if (get_attr_mode (insn) == MODE_SI)
9610 return "sal{l}\t%k0";
9612 return "sal{b}\t%0";
9616 if (get_attr_mode (insn) == MODE_SI)
9617 return "sal{l}\t{%2, %k0|%k0, %2}";
9619 return "sal{b}\t{%2, %0|%0, %2}";
9624 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9626 (match_operand 0 "register_operand" ""))
9627 (match_operand 2 "const1_operand" ""))
9628 (const_string "alu")
9630 (const_string "ishift")))
9631 (set (attr "length_immediate")
9633 (ior (eq_attr "type" "alu")
9634 (and (eq_attr "type" "ishift")
9635 (and (match_operand 2 "const1_operand" "")
9636 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9639 (const_string "*")))
9640 (set_attr "mode" "QI,SI")])
9642 ;; %%% Potential partial reg stall on alternative 2. What to do?
9643 (define_insn "*ashlqi3_1_lea"
9644 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9645 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9646 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9647 (clobber (reg:CC FLAGS_REG))]
9648 "!TARGET_PARTIAL_REG_STALL
9649 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9651 switch (get_attr_type (insn))
9657 gcc_assert (operands[2] == const1_rtx);
9658 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9659 return "add{l}\t%k0, %k0";
9661 return "add{b}\t%0, %0";
9664 if (operands[2] == const1_rtx
9665 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9667 if (get_attr_mode (insn) == MODE_SI)
9668 return "sal{l}\t%k0";
9670 return "sal{b}\t%0";
9674 if (get_attr_mode (insn) == MODE_SI)
9675 return "sal{l}\t{%2, %k0|%k0, %2}";
9677 return "sal{b}\t{%2, %0|%0, %2}";
9682 (cond [(eq_attr "alternative" "2")
9683 (const_string "lea")
9684 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9686 (match_operand 0 "register_operand" ""))
9687 (match_operand 2 "const1_operand" ""))
9688 (const_string "alu")
9690 (const_string "ishift")))
9691 (set (attr "length_immediate")
9693 (ior (eq_attr "type" "alu")
9694 (and (eq_attr "type" "ishift")
9695 (and (match_operand 2 "const1_operand" "")
9696 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9699 (const_string "*")))
9700 (set_attr "mode" "QI,SI,SI")])
9702 (define_insn "*ashlqi3_1_slp"
9703 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9704 (ashift:QI (match_dup 0)
9705 (match_operand:QI 1 "nonmemory_operand" "cI")))
9706 (clobber (reg:CC FLAGS_REG))]
9707 "(optimize_function_for_size_p (cfun)
9708 || !TARGET_PARTIAL_FLAG_REG_STALL
9709 || (operands[1] == const1_rtx
9711 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9713 switch (get_attr_type (insn))
9716 gcc_assert (operands[1] == const1_rtx);
9717 return "add{b}\t%0, %0";
9720 if (operands[1] == const1_rtx
9721 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9722 return "sal{b}\t%0";
9724 return "sal{b}\t{%1, %0|%0, %1}";
9728 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9730 (match_operand 0 "register_operand" ""))
9731 (match_operand 1 "const1_operand" ""))
9732 (const_string "alu")
9734 (const_string "ishift1")))
9735 (set (attr "length_immediate")
9737 (ior (eq_attr "type" "alu")
9738 (and (eq_attr "type" "ishift1")
9739 (and (match_operand 1 "const1_operand" "")
9740 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9743 (const_string "*")))
9744 (set_attr "mode" "QI")])
9746 ;; Convert lea to the lea pattern to avoid flags dependency.
9748 [(set (match_operand:DI 0 "register_operand" "")
9749 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9750 (match_operand:QI 2 "const_int_operand" "")))
9751 (clobber (reg:CC FLAGS_REG))]
9752 "TARGET_64BIT && reload_completed
9753 && true_regnum (operands[0]) != true_regnum (operands[1])"
9755 (mult:DI (match_dup 1)
9757 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9759 ;; Convert lea to the lea pattern to avoid flags dependency.
9761 [(set (match_operand 0 "register_operand" "")
9762 (ashift (match_operand 1 "index_register_operand" "")
9763 (match_operand:QI 2 "const_int_operand" "")))
9764 (clobber (reg:CC FLAGS_REG))]
9766 && true_regnum (operands[0]) != true_regnum (operands[1])
9767 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
9771 enum machine_mode mode = GET_MODE (operands[0]);
9773 if (GET_MODE_SIZE (mode) < 4)
9774 operands[0] = gen_lowpart (SImode, operands[0]);
9776 operands[1] = gen_lowpart (Pmode, operands[1]);
9777 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9779 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9780 if (Pmode != SImode)
9781 pat = gen_rtx_SUBREG (SImode, pat, 0);
9782 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9786 ;; Rare case of shifting RSP is handled by generating move and shift
9788 [(set (match_operand 0 "register_operand" "")
9789 (ashift (match_operand 1 "register_operand" "")
9790 (match_operand:QI 2 "const_int_operand" "")))
9791 (clobber (reg:CC FLAGS_REG))]
9793 && true_regnum (operands[0]) != true_regnum (operands[1])"
9797 emit_move_insn (operands[0], operands[1]);
9798 pat = gen_rtx_SET (VOIDmode, operands[0],
9799 gen_rtx_ASHIFT (GET_MODE (operands[0]),
9800 operands[0], operands[2]));
9801 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
9802 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
9806 ;; Convert lea to the lea pattern to avoid flags dependency.
9808 [(set (match_operand:DI 0 "register_operand" "")
9810 (ashift:SI (match_operand:SI 1 "register_operand" "")
9811 (match_operand:QI 2 "const_int_operand" ""))))
9812 (clobber (reg:CC FLAGS_REG))]
9813 "TARGET_64BIT && reload_completed
9814 && true_regnum (operands[0]) != true_regnum (operands[1])"
9816 (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
9818 operands[1] = gen_lowpart (Pmode, operands[1]);
9819 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9822 ;; This pattern can't accept a variable shift count, since shifts by
9823 ;; zero don't affect the flags. We assume that shifts by constant
9824 ;; zero are optimized away.
9825 (define_insn "*ashl<mode>3_cmp"
9826 [(set (reg FLAGS_REG)
9828 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9829 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9831 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9832 (ashift:SWI (match_dup 1) (match_dup 2)))]
9833 "(optimize_function_for_size_p (cfun)
9834 || !TARGET_PARTIAL_FLAG_REG_STALL
9835 || (operands[2] == const1_rtx
9837 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9838 && ix86_match_ccmode (insn, CCGOCmode)
9839 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9841 switch (get_attr_type (insn))
9844 gcc_assert (operands[2] == const1_rtx);
9845 return "add{<imodesuffix>}\t%0, %0";
9848 if (operands[2] == const1_rtx
9849 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9850 return "sal{<imodesuffix>}\t%0";
9852 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9856 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9858 (match_operand 0 "register_operand" ""))
9859 (match_operand 2 "const1_operand" ""))
9860 (const_string "alu")
9862 (const_string "ishift")))
9863 (set (attr "length_immediate")
9865 (ior (eq_attr "type" "alu")
9866 (and (eq_attr "type" "ishift")
9867 (and (match_operand 2 "const1_operand" "")
9868 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9871 (const_string "*")))
9872 (set_attr "mode" "<MODE>")])
9874 (define_insn "*ashlsi3_cmp_zext"
9875 [(set (reg FLAGS_REG)
9877 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9878 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9880 (set (match_operand:DI 0 "register_operand" "=r")
9881 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9883 && (optimize_function_for_size_p (cfun)
9884 || !TARGET_PARTIAL_FLAG_REG_STALL
9885 || (operands[2] == const1_rtx
9887 || TARGET_DOUBLE_WITH_ADD)))
9888 && ix86_match_ccmode (insn, CCGOCmode)
9889 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9891 switch (get_attr_type (insn))
9894 gcc_assert (operands[2] == const1_rtx);
9895 return "add{l}\t%k0, %k0";
9898 if (operands[2] == const1_rtx
9899 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9900 return "sal{l}\t%k0";
9902 return "sal{l}\t{%2, %k0|%k0, %2}";
9906 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9908 (match_operand 2 "const1_operand" ""))
9909 (const_string "alu")
9911 (const_string "ishift")))
9912 (set (attr "length_immediate")
9914 (ior (eq_attr "type" "alu")
9915 (and (eq_attr "type" "ishift")
9916 (and (match_operand 2 "const1_operand" "")
9917 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9920 (const_string "*")))
9921 (set_attr "mode" "SI")])
9923 (define_insn "*ashl<mode>3_cconly"
9924 [(set (reg FLAGS_REG)
9926 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9927 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9929 (clobber (match_scratch:SWI 0 "=<r>"))]
9930 "(optimize_function_for_size_p (cfun)
9931 || !TARGET_PARTIAL_FLAG_REG_STALL
9932 || (operands[2] == const1_rtx
9934 || TARGET_DOUBLE_WITH_ADD)))
9935 && ix86_match_ccmode (insn, CCGOCmode)
9936 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9938 switch (get_attr_type (insn))
9941 gcc_assert (operands[2] == const1_rtx);
9942 return "add{<imodesuffix>}\t%0, %0";
9945 if (operands[2] == const1_rtx
9946 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9947 return "sal{<imodesuffix>}\t%0";
9949 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9953 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9955 (match_operand 0 "register_operand" ""))
9956 (match_operand 2 "const1_operand" ""))
9957 (const_string "alu")
9959 (const_string "ishift")))
9960 (set (attr "length_immediate")
9962 (ior (eq_attr "type" "alu")
9963 (and (eq_attr "type" "ishift")
9964 (and (match_operand 2 "const1_operand" "")
9965 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9968 (const_string "*")))
9969 (set_attr "mode" "<MODE>")])
9971 ;; See comment above `ashl<mode>3' about how this works.
9973 (define_expand "<shiftrt_insn><mode>3"
9974 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9975 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9976 (match_operand:QI 2 "nonmemory_operand" "")))]
9978 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9980 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9981 [(set (match_operand:DWI 0 "register_operand" "=r")
9982 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9983 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9984 (clobber (reg:CC FLAGS_REG))]
9987 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9989 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9990 [(set_attr "type" "multi")])
9992 ;; By default we don't ask for a scratch register, because when DWImode
9993 ;; values are manipulated, registers are already at a premium. But if
9994 ;; we have one handy, we won't turn it away.
9997 [(match_scratch:DWIH 3 "r")
9998 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
10000 (match_operand:<DWI> 1 "register_operand" "")
10001 (match_operand:QI 2 "nonmemory_operand" "")))
10002 (clobber (reg:CC FLAGS_REG))])
10006 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
10008 (define_insn "x86_64_shrd"
10009 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10010 (ior:DI (ashiftrt:DI (match_dup 0)
10011 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10012 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10013 (minus:QI (const_int 64) (match_dup 2)))))
10014 (clobber (reg:CC FLAGS_REG))]
10016 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10017 [(set_attr "type" "ishift")
10018 (set_attr "prefix_0f" "1")
10019 (set_attr "mode" "DI")
10020 (set_attr "athlon_decode" "vector")
10021 (set_attr "amdfam10_decode" "vector")])
10023 (define_insn "x86_shrd"
10024 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10025 (ior:SI (ashiftrt:SI (match_dup 0)
10026 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10027 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10028 (minus:QI (const_int 32) (match_dup 2)))))
10029 (clobber (reg:CC FLAGS_REG))]
10031 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10032 [(set_attr "type" "ishift")
10033 (set_attr "prefix_0f" "1")
10034 (set_attr "mode" "SI")
10035 (set_attr "pent_pair" "np")
10036 (set_attr "athlon_decode" "vector")
10037 (set_attr "amdfam10_decode" "vector")])
10039 (define_insn "ashrdi3_cvt"
10040 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10041 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10042 (match_operand:QI 2 "const_int_operand" "")))
10043 (clobber (reg:CC FLAGS_REG))]
10044 "TARGET_64BIT && INTVAL (operands[2]) == 63
10045 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10046 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10049 sar{q}\t{%2, %0|%0, %2}"
10050 [(set_attr "type" "imovx,ishift")
10051 (set_attr "prefix_0f" "0,*")
10052 (set_attr "length_immediate" "0,*")
10053 (set_attr "modrm" "0,1")
10054 (set_attr "mode" "DI")])
10056 (define_insn "ashrsi3_cvt"
10057 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10058 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10059 (match_operand:QI 2 "const_int_operand" "")))
10060 (clobber (reg:CC FLAGS_REG))]
10061 "INTVAL (operands[2]) == 31
10062 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10063 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10066 sar{l}\t{%2, %0|%0, %2}"
10067 [(set_attr "type" "imovx,ishift")
10068 (set_attr "prefix_0f" "0,*")
10069 (set_attr "length_immediate" "0,*")
10070 (set_attr "modrm" "0,1")
10071 (set_attr "mode" "SI")])
10073 (define_insn "*ashrsi3_cvt_zext"
10074 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10076 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10077 (match_operand:QI 2 "const_int_operand" ""))))
10078 (clobber (reg:CC FLAGS_REG))]
10079 "TARGET_64BIT && INTVAL (operands[2]) == 31
10080 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10081 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10084 sar{l}\t{%2, %k0|%k0, %2}"
10085 [(set_attr "type" "imovx,ishift")
10086 (set_attr "prefix_0f" "0,*")
10087 (set_attr "length_immediate" "0,*")
10088 (set_attr "modrm" "0,1")
10089 (set_attr "mode" "SI")])
10091 (define_expand "x86_shift<mode>_adj_3"
10092 [(use (match_operand:SWI48 0 "register_operand" ""))
10093 (use (match_operand:SWI48 1 "register_operand" ""))
10094 (use (match_operand:QI 2 "register_operand" ""))]
10097 rtx label = gen_label_rtx ();
10100 emit_insn (gen_testqi_ccz_1 (operands[2],
10101 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10103 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10104 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10105 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10106 gen_rtx_LABEL_REF (VOIDmode, label),
10108 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10109 JUMP_LABEL (tmp) = label;
10111 emit_move_insn (operands[0], operands[1]);
10112 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10113 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10114 emit_label (label);
10115 LABEL_NUSES (label) = 1;
10120 (define_insn "*<shiftrt_insn><mode>3_1"
10121 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10122 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10123 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10124 (clobber (reg:CC FLAGS_REG))]
10125 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10127 if (operands[2] == const1_rtx
10128 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10129 return "<shiftrt>{<imodesuffix>}\t%0";
10131 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10133 [(set_attr "type" "ishift")
10134 (set (attr "length_immediate")
10136 (and (match_operand 2 "const1_operand" "")
10137 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10140 (const_string "*")))
10141 (set_attr "mode" "<MODE>")])
10143 (define_insn "*<shiftrt_insn>si3_1_zext"
10144 [(set (match_operand:DI 0 "register_operand" "=r")
10146 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10147 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10148 (clobber (reg:CC FLAGS_REG))]
10149 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10151 if (operands[2] == const1_rtx
10152 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10153 return "<shiftrt>{l}\t%k0";
10155 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10157 [(set_attr "type" "ishift")
10158 (set (attr "length_immediate")
10160 (and (match_operand 2 "const1_operand" "")
10161 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10164 (const_string "*")))
10165 (set_attr "mode" "SI")])
10167 (define_insn "*<shiftrt_insn>qi3_1_slp"
10168 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10169 (any_shiftrt:QI (match_dup 0)
10170 (match_operand:QI 1 "nonmemory_operand" "cI")))
10171 (clobber (reg:CC FLAGS_REG))]
10172 "(optimize_function_for_size_p (cfun)
10173 || !TARGET_PARTIAL_REG_STALL
10174 || (operands[1] == const1_rtx
10175 && TARGET_SHIFT1))"
10177 if (operands[1] == const1_rtx
10178 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10179 return "<shiftrt>{b}\t%0";
10181 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10183 [(set_attr "type" "ishift1")
10184 (set (attr "length_immediate")
10186 (and (match_operand 1 "const1_operand" "")
10187 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10190 (const_string "*")))
10191 (set_attr "mode" "QI")])
10193 ;; This pattern can't accept a variable shift count, since shifts by
10194 ;; zero don't affect the flags. We assume that shifts by constant
10195 ;; zero are optimized away.
10196 (define_insn "*<shiftrt_insn><mode>3_cmp"
10197 [(set (reg FLAGS_REG)
10200 (match_operand:SWI 1 "nonimmediate_operand" "0")
10201 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10203 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10204 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10205 "(optimize_function_for_size_p (cfun)
10206 || !TARGET_PARTIAL_FLAG_REG_STALL
10207 || (operands[2] == const1_rtx
10209 && ix86_match_ccmode (insn, CCGOCmode)
10210 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10212 if (operands[2] == const1_rtx
10213 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10214 return "<shiftrt>{<imodesuffix>}\t%0";
10216 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10218 [(set_attr "type" "ishift")
10219 (set (attr "length_immediate")
10221 (and (match_operand 2 "const1_operand" "")
10222 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10225 (const_string "*")))
10226 (set_attr "mode" "<MODE>")])
10228 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10229 [(set (reg FLAGS_REG)
10231 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10232 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10234 (set (match_operand:DI 0 "register_operand" "=r")
10235 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10237 && (optimize_function_for_size_p (cfun)
10238 || !TARGET_PARTIAL_FLAG_REG_STALL
10239 || (operands[2] == const1_rtx
10241 && ix86_match_ccmode (insn, CCGOCmode)
10242 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10244 if (operands[2] == const1_rtx
10245 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10246 return "<shiftrt>{l}\t%k0";
10248 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10250 [(set_attr "type" "ishift")
10251 (set (attr "length_immediate")
10253 (and (match_operand 2 "const1_operand" "")
10254 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10257 (const_string "*")))
10258 (set_attr "mode" "SI")])
10260 (define_insn "*<shiftrt_insn><mode>3_cconly"
10261 [(set (reg FLAGS_REG)
10264 (match_operand:SWI 1 "nonimmediate_operand" "0")
10265 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10267 (clobber (match_scratch:SWI 0 "=<r>"))]
10268 "(optimize_function_for_size_p (cfun)
10269 || !TARGET_PARTIAL_FLAG_REG_STALL
10270 || (operands[2] == const1_rtx
10272 && ix86_match_ccmode (insn, CCGOCmode)
10273 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10275 if (operands[2] == const1_rtx
10276 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10277 return "<shiftrt>{<imodesuffix>}\t%0";
10279 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10281 [(set_attr "type" "ishift")
10282 (set (attr "length_immediate")
10284 (and (match_operand 2 "const1_operand" "")
10285 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10288 (const_string "*")))
10289 (set_attr "mode" "<MODE>")])
10291 ;; Rotate instructions
10293 (define_expand "<rotate_insn>ti3"
10294 [(set (match_operand:TI 0 "register_operand" "")
10295 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10296 (match_operand:QI 2 "nonmemory_operand" "")))]
10299 if (const_1_to_63_operand (operands[2], VOIDmode))
10300 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10301 (operands[0], operands[1], operands[2]));
10308 (define_expand "<rotate_insn>di3"
10309 [(set (match_operand:DI 0 "shiftdi_operand" "")
10310 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10311 (match_operand:QI 2 "nonmemory_operand" "")))]
10315 ix86_expand_binary_operator (<CODE>, DImode, operands);
10316 else if (const_1_to_31_operand (operands[2], VOIDmode))
10317 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10318 (operands[0], operands[1], operands[2]));
10325 (define_expand "<rotate_insn><mode>3"
10326 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10327 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10328 (match_operand:QI 2 "nonmemory_operand" "")))]
10330 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10332 ;; Implement rotation using two double-precision
10333 ;; shift instructions and a scratch register.
10335 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10336 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10337 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10338 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10339 (clobber (reg:CC FLAGS_REG))
10340 (clobber (match_scratch:DWIH 3 "=&r"))]
10344 [(set (match_dup 3) (match_dup 4))
10346 [(set (match_dup 4)
10347 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10348 (lshiftrt:DWIH (match_dup 5)
10349 (minus:QI (match_dup 6) (match_dup 2)))))
10350 (clobber (reg:CC FLAGS_REG))])
10352 [(set (match_dup 5)
10353 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10354 (lshiftrt:DWIH (match_dup 3)
10355 (minus:QI (match_dup 6) (match_dup 2)))))
10356 (clobber (reg:CC FLAGS_REG))])]
10358 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10360 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10363 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10364 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10365 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10366 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10367 (clobber (reg:CC FLAGS_REG))
10368 (clobber (match_scratch:DWIH 3 "=&r"))]
10372 [(set (match_dup 3) (match_dup 4))
10374 [(set (match_dup 4)
10375 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10376 (ashift:DWIH (match_dup 5)
10377 (minus:QI (match_dup 6) (match_dup 2)))))
10378 (clobber (reg:CC FLAGS_REG))])
10380 [(set (match_dup 5)
10381 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10382 (ashift:DWIH (match_dup 3)
10383 (minus:QI (match_dup 6) (match_dup 2)))))
10384 (clobber (reg:CC FLAGS_REG))])]
10386 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10388 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10391 (define_insn "*<rotate_insn><mode>3_1"
10392 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10393 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10394 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10395 (clobber (reg:CC FLAGS_REG))]
10396 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10398 if (operands[2] == const1_rtx
10399 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10400 return "<rotate>{<imodesuffix>}\t%0";
10402 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10404 [(set_attr "type" "rotate")
10405 (set (attr "length_immediate")
10407 (and (match_operand 2 "const1_operand" "")
10408 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10411 (const_string "*")))
10412 (set_attr "mode" "<MODE>")])
10414 (define_insn "*<rotate_insn>si3_1_zext"
10415 [(set (match_operand:DI 0 "register_operand" "=r")
10417 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10418 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10419 (clobber (reg:CC FLAGS_REG))]
10420 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10422 if (operands[2] == const1_rtx
10423 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10424 return "<rotate>{l}\t%k0";
10426 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10428 [(set_attr "type" "rotate")
10429 (set (attr "length_immediate")
10431 (and (match_operand 2 "const1_operand" "")
10432 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10435 (const_string "*")))
10436 (set_attr "mode" "SI")])
10438 (define_insn "*<rotate_insn>qi3_1_slp"
10439 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10440 (any_rotate:QI (match_dup 0)
10441 (match_operand:QI 1 "nonmemory_operand" "cI")))
10442 (clobber (reg:CC FLAGS_REG))]
10443 "(optimize_function_for_size_p (cfun)
10444 || !TARGET_PARTIAL_REG_STALL
10445 || (operands[1] == const1_rtx
10446 && TARGET_SHIFT1))"
10448 if (operands[1] == const1_rtx
10449 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10450 return "<rotate>{b}\t%0";
10452 return "<rotate>{b}\t{%1, %0|%0, %1}";
10454 [(set_attr "type" "rotate1")
10455 (set (attr "length_immediate")
10457 (and (match_operand 1 "const1_operand" "")
10458 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10461 (const_string "*")))
10462 (set_attr "mode" "QI")])
10465 [(set (match_operand:HI 0 "register_operand" "")
10466 (any_rotate:HI (match_dup 0) (const_int 8)))
10467 (clobber (reg:CC FLAGS_REG))]
10469 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10470 [(parallel [(set (strict_low_part (match_dup 0))
10471 (bswap:HI (match_dup 0)))
10472 (clobber (reg:CC FLAGS_REG))])]
10475 ;; Bit set / bit test instructions
10477 (define_expand "extv"
10478 [(set (match_operand:SI 0 "register_operand" "")
10479 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10480 (match_operand:SI 2 "const8_operand" "")
10481 (match_operand:SI 3 "const8_operand" "")))]
10484 /* Handle extractions from %ah et al. */
10485 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10488 /* From mips.md: extract_bit_field doesn't verify that our source
10489 matches the predicate, so check it again here. */
10490 if (! ext_register_operand (operands[1], VOIDmode))
10494 (define_expand "extzv"
10495 [(set (match_operand:SI 0 "register_operand" "")
10496 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10497 (match_operand:SI 2 "const8_operand" "")
10498 (match_operand:SI 3 "const8_operand" "")))]
10501 /* Handle extractions from %ah et al. */
10502 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10505 /* From mips.md: extract_bit_field doesn't verify that our source
10506 matches the predicate, so check it again here. */
10507 if (! ext_register_operand (operands[1], VOIDmode))
10511 (define_expand "insv"
10512 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10513 (match_operand 1 "const8_operand" "")
10514 (match_operand 2 "const8_operand" ""))
10515 (match_operand 3 "register_operand" ""))]
10518 /* Handle insertions to %ah et al. */
10519 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10522 /* From mips.md: insert_bit_field doesn't verify that our source
10523 matches the predicate, so check it again here. */
10524 if (! ext_register_operand (operands[0], VOIDmode))
10528 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
10530 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10535 ;; %%% bts, btr, btc, bt.
10536 ;; In general these instructions are *slow* when applied to memory,
10537 ;; since they enforce atomic operation. When applied to registers,
10538 ;; it depends on the cpu implementation. They're never faster than
10539 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10540 ;; no point. But in 64-bit, we can't hold the relevant immediates
10541 ;; within the instruction itself, so operating on bits in the high
10542 ;; 32-bits of a register becomes easier.
10544 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10545 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10546 ;; negdf respectively, so they can never be disabled entirely.
10548 (define_insn "*btsq"
10549 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10551 (match_operand:DI 1 "const_0_to_63_operand" ""))
10553 (clobber (reg:CC FLAGS_REG))]
10554 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10555 "bts{q}\t{%1, %0|%0, %1}"
10556 [(set_attr "type" "alu1")
10557 (set_attr "prefix_0f" "1")
10558 (set_attr "mode" "DI")])
10560 (define_insn "*btrq"
10561 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10563 (match_operand:DI 1 "const_0_to_63_operand" ""))
10565 (clobber (reg:CC FLAGS_REG))]
10566 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10567 "btr{q}\t{%1, %0|%0, %1}"
10568 [(set_attr "type" "alu1")
10569 (set_attr "prefix_0f" "1")
10570 (set_attr "mode" "DI")])
10572 (define_insn "*btcq"
10573 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10575 (match_operand:DI 1 "const_0_to_63_operand" ""))
10576 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10577 (clobber (reg:CC FLAGS_REG))]
10578 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10579 "btc{q}\t{%1, %0|%0, %1}"
10580 [(set_attr "type" "alu1")
10581 (set_attr "prefix_0f" "1")
10582 (set_attr "mode" "DI")])
10584 ;; Allow Nocona to avoid these instructions if a register is available.
10587 [(match_scratch:DI 2 "r")
10588 (parallel [(set (zero_extract:DI
10589 (match_operand:DI 0 "register_operand" "")
10591 (match_operand:DI 1 "const_0_to_63_operand" ""))
10593 (clobber (reg:CC FLAGS_REG))])]
10594 "TARGET_64BIT && !TARGET_USE_BT"
10597 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10600 if (HOST_BITS_PER_WIDE_INT >= 64)
10601 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10602 else if (i < HOST_BITS_PER_WIDE_INT)
10603 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10605 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10607 op1 = immed_double_const (lo, hi, DImode);
10610 emit_move_insn (operands[2], op1);
10614 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10619 [(match_scratch:DI 2 "r")
10620 (parallel [(set (zero_extract:DI
10621 (match_operand:DI 0 "register_operand" "")
10623 (match_operand:DI 1 "const_0_to_63_operand" ""))
10625 (clobber (reg:CC FLAGS_REG))])]
10626 "TARGET_64BIT && !TARGET_USE_BT"
10629 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10632 if (HOST_BITS_PER_WIDE_INT >= 64)
10633 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10634 else if (i < HOST_BITS_PER_WIDE_INT)
10635 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10637 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10639 op1 = immed_double_const (~lo, ~hi, DImode);
10642 emit_move_insn (operands[2], op1);
10646 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10651 [(match_scratch:DI 2 "r")
10652 (parallel [(set (zero_extract:DI
10653 (match_operand:DI 0 "register_operand" "")
10655 (match_operand:DI 1 "const_0_to_63_operand" ""))
10656 (not:DI (zero_extract:DI
10657 (match_dup 0) (const_int 1) (match_dup 1))))
10658 (clobber (reg:CC FLAGS_REG))])]
10659 "TARGET_64BIT && !TARGET_USE_BT"
10662 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10665 if (HOST_BITS_PER_WIDE_INT >= 64)
10666 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10667 else if (i < HOST_BITS_PER_WIDE_INT)
10668 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10670 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10672 op1 = immed_double_const (lo, hi, DImode);
10675 emit_move_insn (operands[2], op1);
10679 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10683 (define_insn "*bt<mode>"
10684 [(set (reg:CCC FLAGS_REG)
10686 (zero_extract:SWI48
10687 (match_operand:SWI48 0 "register_operand" "r")
10689 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10691 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10692 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10693 [(set_attr "type" "alu1")
10694 (set_attr "prefix_0f" "1")
10695 (set_attr "mode" "<MODE>")])
10697 ;; Store-flag instructions.
10699 ;; For all sCOND expanders, also expand the compare or test insn that
10700 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10702 (define_insn_and_split "*setcc_di_1"
10703 [(set (match_operand:DI 0 "register_operand" "=q")
10704 (match_operator:DI 1 "ix86_comparison_operator"
10705 [(reg FLAGS_REG) (const_int 0)]))]
10706 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10708 "&& reload_completed"
10709 [(set (match_dup 2) (match_dup 1))
10710 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10712 PUT_MODE (operands[1], QImode);
10713 operands[2] = gen_lowpart (QImode, operands[0]);
10716 (define_insn_and_split "*setcc_si_1_and"
10717 [(set (match_operand:SI 0 "register_operand" "=q")
10718 (match_operator:SI 1 "ix86_comparison_operator"
10719 [(reg FLAGS_REG) (const_int 0)]))
10720 (clobber (reg:CC FLAGS_REG))]
10721 "!TARGET_PARTIAL_REG_STALL
10722 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10724 "&& reload_completed"
10725 [(set (match_dup 2) (match_dup 1))
10726 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10727 (clobber (reg:CC FLAGS_REG))])]
10729 PUT_MODE (operands[1], QImode);
10730 operands[2] = gen_lowpart (QImode, operands[0]);
10733 (define_insn_and_split "*setcc_si_1_movzbl"
10734 [(set (match_operand:SI 0 "register_operand" "=q")
10735 (match_operator:SI 1 "ix86_comparison_operator"
10736 [(reg FLAGS_REG) (const_int 0)]))]
10737 "!TARGET_PARTIAL_REG_STALL
10738 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10740 "&& reload_completed"
10741 [(set (match_dup 2) (match_dup 1))
10742 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10744 PUT_MODE (operands[1], QImode);
10745 operands[2] = gen_lowpart (QImode, operands[0]);
10748 (define_insn "*setcc_qi"
10749 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10750 (match_operator:QI 1 "ix86_comparison_operator"
10751 [(reg FLAGS_REG) (const_int 0)]))]
10754 [(set_attr "type" "setcc")
10755 (set_attr "mode" "QI")])
10757 (define_insn "*setcc_qi_slp"
10758 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10759 (match_operator:QI 1 "ix86_comparison_operator"
10760 [(reg FLAGS_REG) (const_int 0)]))]
10763 [(set_attr "type" "setcc")
10764 (set_attr "mode" "QI")])
10766 ;; In general it is not safe to assume too much about CCmode registers,
10767 ;; so simplify-rtx stops when it sees a second one. Under certain
10768 ;; conditions this is safe on x86, so help combine not create
10775 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10776 (ne:QI (match_operator 1 "ix86_comparison_operator"
10777 [(reg FLAGS_REG) (const_int 0)])
10780 [(set (match_dup 0) (match_dup 1))]
10782 PUT_MODE (operands[1], QImode);
10786 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10787 (ne:QI (match_operator 1 "ix86_comparison_operator"
10788 [(reg FLAGS_REG) (const_int 0)])
10791 [(set (match_dup 0) (match_dup 1))]
10793 PUT_MODE (operands[1], QImode);
10797 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10798 (eq:QI (match_operator 1 "ix86_comparison_operator"
10799 [(reg FLAGS_REG) (const_int 0)])
10802 [(set (match_dup 0) (match_dup 1))]
10804 rtx new_op1 = copy_rtx (operands[1]);
10805 operands[1] = new_op1;
10806 PUT_MODE (new_op1, QImode);
10807 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10808 GET_MODE (XEXP (new_op1, 0))));
10810 /* Make sure that (a) the CCmode we have for the flags is strong
10811 enough for the reversed compare or (b) we have a valid FP compare. */
10812 if (! ix86_comparison_operator (new_op1, VOIDmode))
10817 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10818 (eq:QI (match_operator 1 "ix86_comparison_operator"
10819 [(reg FLAGS_REG) (const_int 0)])
10822 [(set (match_dup 0) (match_dup 1))]
10824 rtx new_op1 = copy_rtx (operands[1]);
10825 operands[1] = new_op1;
10826 PUT_MODE (new_op1, QImode);
10827 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10828 GET_MODE (XEXP (new_op1, 0))));
10830 /* Make sure that (a) the CCmode we have for the flags is strong
10831 enough for the reversed compare or (b) we have a valid FP compare. */
10832 if (! ix86_comparison_operator (new_op1, VOIDmode))
10836 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10837 ;; subsequent logical operations are used to imitate conditional moves.
10838 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10841 (define_insn "*avx_setcc<mode>"
10842 [(set (match_operand:MODEF 0 "register_operand" "=x")
10843 (match_operator:MODEF 1 "avx_comparison_float_operator"
10844 [(match_operand:MODEF 2 "register_operand" "x")
10845 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10847 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10848 [(set_attr "type" "ssecmp")
10849 (set_attr "prefix" "vex")
10850 (set_attr "length_immediate" "1")
10851 (set_attr "mode" "<MODE>")])
10853 (define_insn "*sse_setcc<mode>"
10854 [(set (match_operand:MODEF 0 "register_operand" "=x")
10855 (match_operator:MODEF 1 "sse_comparison_operator"
10856 [(match_operand:MODEF 2 "register_operand" "0")
10857 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10858 "SSE_FLOAT_MODE_P (<MODE>mode)"
10859 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10860 [(set_attr "type" "ssecmp")
10861 (set_attr "length_immediate" "1")
10862 (set_attr "mode" "<MODE>")])
10864 ;; Basic conditional jump instructions.
10865 ;; We ignore the overflow flag for signed branch instructions.
10867 (define_insn "*jcc_1"
10869 (if_then_else (match_operator 1 "ix86_comparison_operator"
10870 [(reg FLAGS_REG) (const_int 0)])
10871 (label_ref (match_operand 0 "" ""))
10875 [(set_attr "type" "ibr")
10876 (set_attr "modrm" "0")
10877 (set (attr "length")
10878 (if_then_else (and (ge (minus (match_dup 0) (pc))
10880 (lt (minus (match_dup 0) (pc))
10885 (define_insn "*jcc_2"
10887 (if_then_else (match_operator 1 "ix86_comparison_operator"
10888 [(reg FLAGS_REG) (const_int 0)])
10890 (label_ref (match_operand 0 "" ""))))]
10893 [(set_attr "type" "ibr")
10894 (set_attr "modrm" "0")
10895 (set (attr "length")
10896 (if_then_else (and (ge (minus (match_dup 0) (pc))
10898 (lt (minus (match_dup 0) (pc))
10903 ;; In general it is not safe to assume too much about CCmode registers,
10904 ;; so simplify-rtx stops when it sees a second one. Under certain
10905 ;; conditions this is safe on x86, so help combine not create
10913 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10914 [(reg FLAGS_REG) (const_int 0)])
10916 (label_ref (match_operand 1 "" ""))
10920 (if_then_else (match_dup 0)
10921 (label_ref (match_dup 1))
10924 PUT_MODE (operands[0], VOIDmode);
10929 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10930 [(reg FLAGS_REG) (const_int 0)])
10932 (label_ref (match_operand 1 "" ""))
10936 (if_then_else (match_dup 0)
10937 (label_ref (match_dup 1))
10940 rtx new_op0 = copy_rtx (operands[0]);
10941 operands[0] = new_op0;
10942 PUT_MODE (new_op0, VOIDmode);
10943 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10944 GET_MODE (XEXP (new_op0, 0))));
10946 /* Make sure that (a) the CCmode we have for the flags is strong
10947 enough for the reversed compare or (b) we have a valid FP compare. */
10948 if (! ix86_comparison_operator (new_op0, VOIDmode))
10952 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10953 ;; pass generates from shift insn with QImode operand. Actually, the mode
10954 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10955 ;; appropriate modulo of the bit offset value.
10957 (define_insn_and_split "*jcc_bt<mode>"
10959 (if_then_else (match_operator 0 "bt_comparison_operator"
10960 [(zero_extract:SWI48
10961 (match_operand:SWI48 1 "register_operand" "r")
10964 (match_operand:QI 2 "register_operand" "r")))
10966 (label_ref (match_operand 3 "" ""))
10968 (clobber (reg:CC FLAGS_REG))]
10969 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10972 [(set (reg:CCC FLAGS_REG)
10974 (zero_extract:SWI48
10980 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10981 (label_ref (match_dup 3))
10984 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10986 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10989 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10990 ;; also for DImode, this is what combine produces.
10991 (define_insn_and_split "*jcc_bt<mode>_mask"
10993 (if_then_else (match_operator 0 "bt_comparison_operator"
10994 [(zero_extract:SWI48
10995 (match_operand:SWI48 1 "register_operand" "r")
10998 (match_operand:SI 2 "register_operand" "r")
10999 (match_operand:SI 3 "const_int_operand" "n")))])
11000 (label_ref (match_operand 4 "" ""))
11002 (clobber (reg:CC FLAGS_REG))]
11003 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11004 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11005 == GET_MODE_BITSIZE (<MODE>mode)-1"
11008 [(set (reg:CCC FLAGS_REG)
11010 (zero_extract:SWI48
11016 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11017 (label_ref (match_dup 4))
11020 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11022 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11025 (define_insn_and_split "*jcc_btsi_1"
11027 (if_then_else (match_operator 0 "bt_comparison_operator"
11030 (match_operand:SI 1 "register_operand" "r")
11031 (match_operand:QI 2 "register_operand" "r"))
11034 (label_ref (match_operand 3 "" ""))
11036 (clobber (reg:CC FLAGS_REG))]
11037 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11040 [(set (reg:CCC FLAGS_REG)
11048 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11049 (label_ref (match_dup 3))
11052 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11054 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11057 ;; avoid useless masking of bit offset operand
11058 (define_insn_and_split "*jcc_btsi_mask_1"
11061 (match_operator 0 "bt_comparison_operator"
11064 (match_operand:SI 1 "register_operand" "r")
11067 (match_operand:SI 2 "register_operand" "r")
11068 (match_operand:SI 3 "const_int_operand" "n")) 0))
11071 (label_ref (match_operand 4 "" ""))
11073 (clobber (reg:CC FLAGS_REG))]
11074 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11075 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11078 [(set (reg:CCC FLAGS_REG)
11086 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11087 (label_ref (match_dup 4))
11089 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11091 ;; Define combination compare-and-branch fp compare instructions to help
11094 (define_insn "*fp_jcc_3_387"
11096 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11097 [(match_operand 1 "register_operand" "f")
11098 (match_operand 2 "nonimmediate_operand" "fm")])
11099 (label_ref (match_operand 3 "" ""))
11101 (clobber (reg:CCFP FPSR_REG))
11102 (clobber (reg:CCFP FLAGS_REG))
11103 (clobber (match_scratch:HI 4 "=a"))]
11105 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11106 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11107 && SELECT_CC_MODE (GET_CODE (operands[0]),
11108 operands[1], operands[2]) == CCFPmode
11112 (define_insn "*fp_jcc_4_387"
11114 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11115 [(match_operand 1 "register_operand" "f")
11116 (match_operand 2 "nonimmediate_operand" "fm")])
11118 (label_ref (match_operand 3 "" ""))))
11119 (clobber (reg:CCFP FPSR_REG))
11120 (clobber (reg:CCFP FLAGS_REG))
11121 (clobber (match_scratch:HI 4 "=a"))]
11123 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11124 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11125 && SELECT_CC_MODE (GET_CODE (operands[0]),
11126 operands[1], operands[2]) == CCFPmode
11130 (define_insn "*fp_jcc_5_387"
11132 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11133 [(match_operand 1 "register_operand" "f")
11134 (match_operand 2 "register_operand" "f")])
11135 (label_ref (match_operand 3 "" ""))
11137 (clobber (reg:CCFP FPSR_REG))
11138 (clobber (reg:CCFP FLAGS_REG))
11139 (clobber (match_scratch:HI 4 "=a"))]
11140 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11141 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11145 (define_insn "*fp_jcc_6_387"
11147 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11148 [(match_operand 1 "register_operand" "f")
11149 (match_operand 2 "register_operand" "f")])
11151 (label_ref (match_operand 3 "" ""))))
11152 (clobber (reg:CCFP FPSR_REG))
11153 (clobber (reg:CCFP FLAGS_REG))
11154 (clobber (match_scratch:HI 4 "=a"))]
11155 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11156 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11160 (define_insn "*fp_jcc_7_387"
11162 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11163 [(match_operand 1 "register_operand" "f")
11164 (match_operand 2 "const0_operand" "")])
11165 (label_ref (match_operand 3 "" ""))
11167 (clobber (reg:CCFP FPSR_REG))
11168 (clobber (reg:CCFP FLAGS_REG))
11169 (clobber (match_scratch:HI 4 "=a"))]
11170 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11171 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11172 && SELECT_CC_MODE (GET_CODE (operands[0]),
11173 operands[1], operands[2]) == CCFPmode
11177 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
11178 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11179 ;; with a precedence over other operators and is always put in the first
11180 ;; place. Swap condition and operands to match ficom instruction.
11182 (define_insn "*fp_jcc_8<mode>_387"
11184 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11185 [(match_operator 1 "float_operator"
11186 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11187 (match_operand 3 "register_operand" "f,f")])
11188 (label_ref (match_operand 4 "" ""))
11190 (clobber (reg:CCFP FPSR_REG))
11191 (clobber (reg:CCFP FLAGS_REG))
11192 (clobber (match_scratch:HI 5 "=a,a"))]
11193 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11194 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11195 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11196 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11202 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11203 [(match_operand 1 "register_operand" "")
11204 (match_operand 2 "nonimmediate_operand" "")])
11205 (match_operand 3 "" "")
11206 (match_operand 4 "" "")))
11207 (clobber (reg:CCFP FPSR_REG))
11208 (clobber (reg:CCFP FLAGS_REG))]
11212 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11213 operands[3], operands[4], NULL_RTX, NULL_RTX);
11219 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11220 [(match_operand 1 "register_operand" "")
11221 (match_operand 2 "general_operand" "")])
11222 (match_operand 3 "" "")
11223 (match_operand 4 "" "")))
11224 (clobber (reg:CCFP FPSR_REG))
11225 (clobber (reg:CCFP FLAGS_REG))
11226 (clobber (match_scratch:HI 5 "=a"))]
11230 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11231 operands[3], operands[4], operands[5], NULL_RTX);
11237 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11238 [(match_operator 1 "float_operator"
11239 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11240 (match_operand 3 "register_operand" "")])
11241 (match_operand 4 "" "")
11242 (match_operand 5 "" "")))
11243 (clobber (reg:CCFP FPSR_REG))
11244 (clobber (reg:CCFP FLAGS_REG))
11245 (clobber (match_scratch:HI 6 "=a"))]
11249 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11251 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11252 operands[3], operands[7],
11253 operands[4], operands[5], operands[6], NULL_RTX);
11257 ;; %%% Kill this when reload knows how to do it.
11260 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11261 [(match_operator 1 "float_operator"
11262 [(match_operand:X87MODEI12 2 "register_operand" "")])
11263 (match_operand 3 "register_operand" "")])
11264 (match_operand 4 "" "")
11265 (match_operand 5 "" "")))
11266 (clobber (reg:CCFP FPSR_REG))
11267 (clobber (reg:CCFP FLAGS_REG))
11268 (clobber (match_scratch:HI 6 "=a"))]
11272 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11273 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11275 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11276 operands[3], operands[7],
11277 operands[4], operands[5], operands[6], operands[2]);
11281 ;; Unconditional and other jump instructions
11283 (define_insn "jump"
11285 (label_ref (match_operand 0 "" "")))]
11288 [(set_attr "type" "ibr")
11289 (set (attr "length")
11290 (if_then_else (and (ge (minus (match_dup 0) (pc))
11292 (lt (minus (match_dup 0) (pc))
11296 (set_attr "modrm" "0")])
11298 (define_expand "indirect_jump"
11299 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11303 (define_insn "*indirect_jump"
11304 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11307 [(set_attr "type" "ibr")
11308 (set_attr "length_immediate" "0")])
11310 (define_expand "tablejump"
11311 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11312 (use (label_ref (match_operand 1 "" "")))])]
11315 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11316 relative. Convert the relative address to an absolute address. */
11320 enum rtx_code code;
11322 /* We can't use @GOTOFF for text labels on VxWorks;
11323 see gotoff_operand. */
11324 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11328 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11330 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11334 op1 = pic_offset_table_rtx;
11339 op0 = pic_offset_table_rtx;
11343 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11348 (define_insn "*tablejump_1"
11349 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11350 (use (label_ref (match_operand 1 "" "")))]
11353 [(set_attr "type" "ibr")
11354 (set_attr "length_immediate" "0")])
11356 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11359 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11360 (set (match_operand:QI 1 "register_operand" "")
11361 (match_operator:QI 2 "ix86_comparison_operator"
11362 [(reg FLAGS_REG) (const_int 0)]))
11363 (set (match_operand 3 "q_regs_operand" "")
11364 (zero_extend (match_dup 1)))]
11365 "(peep2_reg_dead_p (3, operands[1])
11366 || operands_match_p (operands[1], operands[3]))
11367 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11368 [(set (match_dup 4) (match_dup 0))
11369 (set (strict_low_part (match_dup 5))
11372 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11373 operands[5] = gen_lowpart (QImode, operands[3]);
11374 ix86_expand_clear (operands[3]);
11377 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11380 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11381 (set (match_operand:QI 1 "register_operand" "")
11382 (match_operator:QI 2 "ix86_comparison_operator"
11383 [(reg FLAGS_REG) (const_int 0)]))
11384 (parallel [(set (match_operand 3 "q_regs_operand" "")
11385 (zero_extend (match_dup 1)))
11386 (clobber (reg:CC FLAGS_REG))])]
11387 "(peep2_reg_dead_p (3, operands[1])
11388 || operands_match_p (operands[1], operands[3]))
11389 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11390 [(set (match_dup 4) (match_dup 0))
11391 (set (strict_low_part (match_dup 5))
11394 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11395 operands[5] = gen_lowpart (QImode, operands[3]);
11396 ix86_expand_clear (operands[3]);
11399 ;; Call instructions.
11401 ;; The predicates normally associated with named expanders are not properly
11402 ;; checked for calls. This is a bug in the generic code, but it isn't that
11403 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11405 ;; P6 processors will jump to the address after the decrement when %esp
11406 ;; is used as a call operand, so they will execute return address as a code.
11407 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11409 ;; Call subroutine returning no value.
11411 (define_expand "call_pop"
11412 [(parallel [(call (match_operand:QI 0 "" "")
11413 (match_operand:SI 1 "" ""))
11414 (set (reg:SI SP_REG)
11415 (plus:SI (reg:SI SP_REG)
11416 (match_operand:SI 3 "" "")))])]
11419 ix86_expand_call (NULL, operands[0], operands[1],
11420 operands[2], operands[3], 0);
11424 (define_insn "*call_pop_0"
11425 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11426 (match_operand:SI 1 "" ""))
11427 (set (reg:SI SP_REG)
11428 (plus:SI (reg:SI SP_REG)
11429 (match_operand:SI 2 "immediate_operand" "")))]
11432 if (SIBLING_CALL_P (insn))
11435 return "call\t%P0";
11437 [(set_attr "type" "call")])
11439 (define_insn "*call_pop_1"
11440 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11441 (match_operand:SI 1 "" ""))
11442 (set (reg:SI SP_REG)
11443 (plus:SI (reg:SI SP_REG)
11444 (match_operand:SI 2 "immediate_operand" "i")))]
11445 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11447 if (constant_call_address_operand (operands[0], Pmode))
11448 return "call\t%P0";
11449 return "call\t%A0";
11451 [(set_attr "type" "call")])
11453 (define_insn "*sibcall_pop_1"
11454 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11455 (match_operand:SI 1 "" ""))
11456 (set (reg:SI SP_REG)
11457 (plus:SI (reg:SI SP_REG)
11458 (match_operand:SI 2 "immediate_operand" "i,i")))]
11459 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11463 [(set_attr "type" "call")])
11465 (define_expand "call"
11466 [(call (match_operand:QI 0 "" "")
11467 (match_operand 1 "" ""))
11468 (use (match_operand 2 "" ""))]
11471 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11475 (define_expand "sibcall"
11476 [(call (match_operand:QI 0 "" "")
11477 (match_operand 1 "" ""))
11478 (use (match_operand 2 "" ""))]
11481 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11485 (define_insn "*call_0"
11486 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11487 (match_operand 1 "" ""))]
11490 if (SIBLING_CALL_P (insn))
11493 return "call\t%P0";
11495 [(set_attr "type" "call")])
11497 (define_insn "*call_1"
11498 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11499 (match_operand 1 "" ""))]
11500 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11502 if (constant_call_address_operand (operands[0], Pmode))
11503 return "call\t%P0";
11504 return "call\t%A0";
11506 [(set_attr "type" "call")])
11508 (define_insn "*sibcall_1"
11509 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11510 (match_operand 1 "" ""))]
11511 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11515 [(set_attr "type" "call")])
11517 (define_insn "*call_1_rex64"
11518 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11519 (match_operand 1 "" ""))]
11520 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11521 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11523 if (constant_call_address_operand (operands[0], Pmode))
11524 return "call\t%P0";
11525 return "call\t%A0";
11527 [(set_attr "type" "call")])
11529 (define_insn "*call_1_rex64_ms_sysv"
11530 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11531 (match_operand 1 "" ""))
11532 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11533 (clobber (reg:TI XMM6_REG))
11534 (clobber (reg:TI XMM7_REG))
11535 (clobber (reg:TI XMM8_REG))
11536 (clobber (reg:TI XMM9_REG))
11537 (clobber (reg:TI XMM10_REG))
11538 (clobber (reg:TI XMM11_REG))
11539 (clobber (reg:TI XMM12_REG))
11540 (clobber (reg:TI XMM13_REG))
11541 (clobber (reg:TI XMM14_REG))
11542 (clobber (reg:TI XMM15_REG))
11543 (clobber (reg:DI SI_REG))
11544 (clobber (reg:DI DI_REG))]
11545 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11547 if (constant_call_address_operand (operands[0], Pmode))
11548 return "call\t%P0";
11549 return "call\t%A0";
11551 [(set_attr "type" "call")])
11553 (define_insn "*call_1_rex64_large"
11554 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11555 (match_operand 1 "" ""))]
11556 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11558 [(set_attr "type" "call")])
11560 (define_insn "*sibcall_1_rex64"
11561 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11562 (match_operand 1 "" ""))]
11563 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11567 [(set_attr "type" "call")])
11569 ;; Call subroutine, returning value in operand 0
11570 (define_expand "call_value_pop"
11571 [(parallel [(set (match_operand 0 "" "")
11572 (call (match_operand:QI 1 "" "")
11573 (match_operand:SI 2 "" "")))
11574 (set (reg:SI SP_REG)
11575 (plus:SI (reg:SI SP_REG)
11576 (match_operand:SI 4 "" "")))])]
11579 ix86_expand_call (operands[0], operands[1], operands[2],
11580 operands[3], operands[4], 0);
11584 (define_expand "call_value"
11585 [(set (match_operand 0 "" "")
11586 (call (match_operand:QI 1 "" "")
11587 (match_operand:SI 2 "" "")))
11588 (use (match_operand:SI 3 "" ""))]
11589 ;; Operand 3 is not used on the i386.
11592 ix86_expand_call (operands[0], operands[1], operands[2],
11593 operands[3], NULL, 0);
11597 (define_expand "sibcall_value"
11598 [(set (match_operand 0 "" "")
11599 (call (match_operand:QI 1 "" "")
11600 (match_operand:SI 2 "" "")))
11601 (use (match_operand:SI 3 "" ""))]
11602 ;; Operand 3 is not used on the i386.
11605 ix86_expand_call (operands[0], operands[1], operands[2],
11606 operands[3], NULL, 1);
11610 ;; Call subroutine returning any type.
11612 (define_expand "untyped_call"
11613 [(parallel [(call (match_operand 0 "" "")
11615 (match_operand 1 "" "")
11616 (match_operand 2 "" "")])]
11621 /* In order to give reg-stack an easier job in validating two
11622 coprocessor registers as containing a possible return value,
11623 simply pretend the untyped call returns a complex long double
11626 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11627 and should have the default ABI. */
11629 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11630 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11631 operands[0], const0_rtx,
11632 GEN_INT ((TARGET_64BIT
11633 ? (ix86_abi == SYSV_ABI
11634 ? X86_64_SSE_REGPARM_MAX
11635 : X86_64_MS_SSE_REGPARM_MAX)
11636 : X86_32_SSE_REGPARM_MAX)
11640 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11642 rtx set = XVECEXP (operands[2], 0, i);
11643 emit_move_insn (SET_DEST (set), SET_SRC (set));
11646 /* The optimizer does not know that the call sets the function value
11647 registers we stored in the result block. We avoid problems by
11648 claiming that all hard registers are used and clobbered at this
11650 emit_insn (gen_blockage ());
11655 ;; Prologue and epilogue instructions
11657 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11658 ;; all of memory. This blocks insns from being moved across this point.
11660 (define_insn "blockage"
11661 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11664 [(set_attr "length" "0")])
11666 ;; Do not schedule instructions accessing memory across this point.
11668 (define_expand "memory_blockage"
11669 [(set (match_dup 0)
11670 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11673 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11674 MEM_VOLATILE_P (operands[0]) = 1;
11677 (define_insn "*memory_blockage"
11678 [(set (match_operand:BLK 0 "" "")
11679 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11682 [(set_attr "length" "0")])
11684 ;; As USE insns aren't meaningful after reload, this is used instead
11685 ;; to prevent deleting instructions setting registers for PIC code
11686 (define_insn "prologue_use"
11687 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11690 [(set_attr "length" "0")])
11692 ;; Insn emitted into the body of a function to return from a function.
11693 ;; This is only done if the function's epilogue is known to be simple.
11694 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11696 (define_expand "return"
11698 "ix86_can_use_return_insn_p ()"
11700 if (crtl->args.pops_args)
11702 rtx popc = GEN_INT (crtl->args.pops_args);
11703 emit_jump_insn (gen_return_pop_internal (popc));
11708 (define_insn "return_internal"
11712 [(set_attr "length" "1")
11713 (set_attr "atom_unit" "jeu")
11714 (set_attr "length_immediate" "0")
11715 (set_attr "modrm" "0")])
11717 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11718 ;; instruction Athlon and K8 have.
11720 (define_insn "return_internal_long"
11722 (unspec [(const_int 0)] UNSPEC_REP)]
11725 [(set_attr "length" "2")
11726 (set_attr "atom_unit" "jeu")
11727 (set_attr "length_immediate" "0")
11728 (set_attr "prefix_rep" "1")
11729 (set_attr "modrm" "0")])
11731 (define_insn "return_pop_internal"
11733 (use (match_operand:SI 0 "const_int_operand" ""))]
11736 [(set_attr "length" "3")
11737 (set_attr "atom_unit" "jeu")
11738 (set_attr "length_immediate" "2")
11739 (set_attr "modrm" "0")])
11741 (define_insn "return_indirect_internal"
11743 (use (match_operand:SI 0 "register_operand" "r"))]
11746 [(set_attr "type" "ibr")
11747 (set_attr "length_immediate" "0")])
11753 [(set_attr "length" "1")
11754 (set_attr "length_immediate" "0")
11755 (set_attr "modrm" "0")])
11757 (define_insn "vswapmov"
11758 [(set (match_operand:SI 0 "register_operand" "=r")
11759 (match_operand:SI 1 "register_operand" "r"))
11760 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
11762 "movl.s\t{%1, %0|%0, %1}"
11763 [(set_attr "length" "2")
11764 (set_attr "length_immediate" "0")
11765 (set_attr "modrm" "0")])
11767 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11768 ;; branch prediction penalty for the third jump in a 16-byte
11772 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11775 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11776 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11778 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11779 The align insn is used to avoid 3 jump instructions in the row to improve
11780 branch prediction and the benefits hardly outweigh the cost of extra 8
11781 nops on the average inserted by full alignment pseudo operation. */
11785 [(set_attr "length" "16")])
11787 (define_expand "prologue"
11790 "ix86_expand_prologue (); DONE;")
11792 (define_insn "set_got"
11793 [(set (match_operand:SI 0 "register_operand" "=r")
11794 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11795 (clobber (reg:CC FLAGS_REG))]
11797 { return output_set_got (operands[0], NULL_RTX); }
11798 [(set_attr "type" "multi")
11799 (set_attr "length" "12")])
11801 (define_insn "set_got_labelled"
11802 [(set (match_operand:SI 0 "register_operand" "=r")
11803 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11805 (clobber (reg:CC FLAGS_REG))]
11807 { return output_set_got (operands[0], operands[1]); }
11808 [(set_attr "type" "multi")
11809 (set_attr "length" "12")])
11811 (define_insn "set_got_rex64"
11812 [(set (match_operand:DI 0 "register_operand" "=r")
11813 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11815 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11816 [(set_attr "type" "lea")
11817 (set_attr "length_address" "4")
11818 (set_attr "mode" "DI")])
11820 (define_insn "set_rip_rex64"
11821 [(set (match_operand:DI 0 "register_operand" "=r")
11822 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11824 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11825 [(set_attr "type" "lea")
11826 (set_attr "length_address" "4")
11827 (set_attr "mode" "DI")])
11829 (define_insn "set_got_offset_rex64"
11830 [(set (match_operand:DI 0 "register_operand" "=r")
11832 [(label_ref (match_operand 1 "" ""))]
11833 UNSPEC_SET_GOT_OFFSET))]
11835 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11836 [(set_attr "type" "imov")
11837 (set_attr "length_immediate" "0")
11838 (set_attr "length_address" "8")
11839 (set_attr "mode" "DI")])
11841 (define_expand "epilogue"
11844 "ix86_expand_epilogue (1); DONE;")
11846 (define_expand "sibcall_epilogue"
11849 "ix86_expand_epilogue (0); DONE;")
11851 (define_expand "eh_return"
11852 [(use (match_operand 0 "register_operand" ""))]
11855 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11857 /* Tricky bit: we write the address of the handler to which we will
11858 be returning into someone else's stack frame, one word below the
11859 stack address we wish to restore. */
11860 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11861 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11862 tmp = gen_rtx_MEM (Pmode, tmp);
11863 emit_move_insn (tmp, ra);
11865 emit_jump_insn (gen_eh_return_internal ());
11870 (define_insn_and_split "eh_return_internal"
11874 "epilogue_completed"
11876 "ix86_expand_epilogue (2); DONE;")
11878 (define_insn "leave"
11879 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11880 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11881 (clobber (mem:BLK (scratch)))]
11884 [(set_attr "type" "leave")])
11886 (define_insn "leave_rex64"
11887 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11888 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11889 (clobber (mem:BLK (scratch)))]
11892 [(set_attr "type" "leave")])
11894 ;; Bit manipulation instructions.
11896 (define_expand "ffs<mode>2"
11897 [(set (match_dup 2) (const_int -1))
11898 (parallel [(set (reg:CCZ FLAGS_REG)
11900 (match_operand:SWI48 1 "nonimmediate_operand" "")
11902 (set (match_operand:SWI48 0 "register_operand" "")
11903 (ctz:SWI48 (match_dup 1)))])
11904 (set (match_dup 0) (if_then_else:SWI48
11905 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11908 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11909 (clobber (reg:CC FLAGS_REG))])]
11912 if (<MODE>mode == SImode && !TARGET_CMOVE)
11914 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11917 operands[2] = gen_reg_rtx (<MODE>mode);
11920 (define_insn_and_split "ffssi2_no_cmove"
11921 [(set (match_operand:SI 0 "register_operand" "=r")
11922 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11923 (clobber (match_scratch:SI 2 "=&q"))
11924 (clobber (reg:CC FLAGS_REG))]
11927 "&& reload_completed"
11928 [(parallel [(set (reg:CCZ FLAGS_REG)
11929 (compare:CCZ (match_dup 1) (const_int 0)))
11930 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11931 (set (strict_low_part (match_dup 3))
11932 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11933 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11934 (clobber (reg:CC FLAGS_REG))])
11935 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11936 (clobber (reg:CC FLAGS_REG))])
11937 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11938 (clobber (reg:CC FLAGS_REG))])]
11940 operands[3] = gen_lowpart (QImode, operands[2]);
11941 ix86_expand_clear (operands[2]);
11944 (define_insn "*ffs<mode>_1"
11945 [(set (reg:CCZ FLAGS_REG)
11946 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11948 (set (match_operand:SWI48 0 "register_operand" "=r")
11949 (ctz:SWI48 (match_dup 1)))]
11951 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11952 [(set_attr "type" "alu1")
11953 (set_attr "prefix_0f" "1")
11954 (set_attr "mode" "<MODE>")])
11956 (define_insn "ctz<mode>2"
11957 [(set (match_operand:SWI48 0 "register_operand" "=r")
11958 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11959 (clobber (reg:CC FLAGS_REG))]
11961 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11962 [(set_attr "type" "alu1")
11963 (set_attr "prefix_0f" "1")
11964 (set_attr "mode" "<MODE>")])
11966 (define_expand "clz<mode>2"
11968 [(set (match_operand:SWI248 0 "register_operand" "")
11971 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11972 (clobber (reg:CC FLAGS_REG))])
11974 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11975 (clobber (reg:CC FLAGS_REG))])]
11980 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11983 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11986 (define_insn "clz<mode>2_abm"
11987 [(set (match_operand:SWI248 0 "register_operand" "=r")
11988 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11989 (clobber (reg:CC FLAGS_REG))]
11991 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11992 [(set_attr "prefix_rep" "1")
11993 (set_attr "type" "bitmanip")
11994 (set_attr "mode" "<MODE>")])
11996 (define_insn "bsr_rex64"
11997 [(set (match_operand:DI 0 "register_operand" "=r")
11998 (minus:DI (const_int 63)
11999 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12000 (clobber (reg:CC FLAGS_REG))]
12002 "bsr{q}\t{%1, %0|%0, %1}"
12003 [(set_attr "type" "alu1")
12004 (set_attr "prefix_0f" "1")
12005 (set_attr "mode" "DI")])
12008 [(set (match_operand:SI 0 "register_operand" "=r")
12009 (minus:SI (const_int 31)
12010 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12011 (clobber (reg:CC FLAGS_REG))]
12013 "bsr{l}\t{%1, %0|%0, %1}"
12014 [(set_attr "type" "alu1")
12015 (set_attr "prefix_0f" "1")
12016 (set_attr "mode" "SI")])
12018 (define_insn "*bsrhi"
12019 [(set (match_operand:HI 0 "register_operand" "=r")
12020 (minus:HI (const_int 15)
12021 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12022 (clobber (reg:CC FLAGS_REG))]
12024 "bsr{w}\t{%1, %0|%0, %1}"
12025 [(set_attr "type" "alu1")
12026 (set_attr "prefix_0f" "1")
12027 (set_attr "mode" "HI")])
12029 (define_insn "popcount<mode>2"
12030 [(set (match_operand:SWI248 0 "register_operand" "=r")
12032 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12033 (clobber (reg:CC FLAGS_REG))]
12037 return "popcnt\t{%1, %0|%0, %1}";
12039 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12042 [(set_attr "prefix_rep" "1")
12043 (set_attr "type" "bitmanip")
12044 (set_attr "mode" "<MODE>")])
12046 (define_insn "*popcount<mode>2_cmp"
12047 [(set (reg FLAGS_REG)
12050 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12052 (set (match_operand:SWI248 0 "register_operand" "=r")
12053 (popcount:SWI248 (match_dup 1)))]
12054 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12057 return "popcnt\t{%1, %0|%0, %1}";
12059 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12062 [(set_attr "prefix_rep" "1")
12063 (set_attr "type" "bitmanip")
12064 (set_attr "mode" "<MODE>")])
12066 (define_insn "*popcountsi2_cmp_zext"
12067 [(set (reg FLAGS_REG)
12069 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12071 (set (match_operand:DI 0 "register_operand" "=r")
12072 (zero_extend:DI(popcount:SI (match_dup 1))))]
12073 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12076 return "popcnt\t{%1, %0|%0, %1}";
12078 return "popcnt{l}\t{%1, %0|%0, %1}";
12081 [(set_attr "prefix_rep" "1")
12082 (set_attr "type" "bitmanip")
12083 (set_attr "mode" "SI")])
12085 (define_expand "bswap<mode>2"
12086 [(set (match_operand:SWI48 0 "register_operand" "")
12087 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12090 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12092 rtx x = operands[0];
12094 emit_move_insn (x, operands[1]);
12095 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12096 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12097 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12102 (define_insn "*bswap<mode>2_movbe"
12103 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12104 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12106 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12109 movbe\t{%1, %0|%0, %1}
12110 movbe\t{%1, %0|%0, %1}"
12111 [(set_attr "type" "bitmanip,imov,imov")
12112 (set_attr "modrm" "0,1,1")
12113 (set_attr "prefix_0f" "*,1,1")
12114 (set_attr "prefix_extra" "*,1,1")
12115 (set_attr "mode" "<MODE>")])
12117 (define_insn "*bswap<mode>2_1"
12118 [(set (match_operand:SWI48 0 "register_operand" "=r")
12119 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12122 [(set_attr "type" "bitmanip")
12123 (set_attr "modrm" "0")
12124 (set_attr "mode" "<MODE>")])
12126 (define_insn "*bswaphi_lowpart_1"
12127 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12128 (bswap:HI (match_dup 0)))
12129 (clobber (reg:CC FLAGS_REG))]
12130 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12132 xchg{b}\t{%h0, %b0|%b0, %h0}
12133 rol{w}\t{$8, %0|%0, 8}"
12134 [(set_attr "length" "2,4")
12135 (set_attr "mode" "QI,HI")])
12137 (define_insn "bswaphi_lowpart"
12138 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12139 (bswap:HI (match_dup 0)))
12140 (clobber (reg:CC FLAGS_REG))]
12142 "rol{w}\t{$8, %0|%0, 8}"
12143 [(set_attr "length" "4")
12144 (set_attr "mode" "HI")])
12146 (define_expand "paritydi2"
12147 [(set (match_operand:DI 0 "register_operand" "")
12148 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12151 rtx scratch = gen_reg_rtx (QImode);
12154 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12155 NULL_RTX, operands[1]));
12157 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12158 gen_rtx_REG (CCmode, FLAGS_REG),
12160 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12163 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12166 rtx tmp = gen_reg_rtx (SImode);
12168 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12169 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12174 (define_expand "paritysi2"
12175 [(set (match_operand:SI 0 "register_operand" "")
12176 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12179 rtx scratch = gen_reg_rtx (QImode);
12182 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12184 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12185 gen_rtx_REG (CCmode, FLAGS_REG),
12187 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12189 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12193 (define_insn_and_split "paritydi2_cmp"
12194 [(set (reg:CC FLAGS_REG)
12195 (parity:CC (match_operand:DI 3 "register_operand" "0")))
12196 (clobber (match_scratch:DI 0 "=r"))
12197 (clobber (match_scratch:SI 1 "=&r"))
12198 (clobber (match_scratch:HI 2 "=Q"))]
12201 "&& reload_completed"
12203 [(set (match_dup 1)
12204 (xor:SI (match_dup 1) (match_dup 4)))
12205 (clobber (reg:CC FLAGS_REG))])
12207 [(set (reg:CC FLAGS_REG)
12208 (parity:CC (match_dup 1)))
12209 (clobber (match_dup 1))
12210 (clobber (match_dup 2))])]
12212 operands[4] = gen_lowpart (SImode, operands[3]);
12216 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12217 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12220 operands[1] = gen_highpart (SImode, operands[3]);
12223 (define_insn_and_split "paritysi2_cmp"
12224 [(set (reg:CC FLAGS_REG)
12225 (parity:CC (match_operand:SI 2 "register_operand" "0")))
12226 (clobber (match_scratch:SI 0 "=r"))
12227 (clobber (match_scratch:HI 1 "=&Q"))]
12230 "&& reload_completed"
12232 [(set (match_dup 1)
12233 (xor:HI (match_dup 1) (match_dup 3)))
12234 (clobber (reg:CC FLAGS_REG))])
12236 [(set (reg:CC FLAGS_REG)
12237 (parity:CC (match_dup 1)))
12238 (clobber (match_dup 1))])]
12240 operands[3] = gen_lowpart (HImode, operands[2]);
12242 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12243 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12246 (define_insn "*parityhi2_cmp"
12247 [(set (reg:CC FLAGS_REG)
12248 (parity:CC (match_operand:HI 1 "register_operand" "0")))
12249 (clobber (match_scratch:HI 0 "=Q"))]
12251 "xor{b}\t{%h0, %b0|%b0, %h0}"
12252 [(set_attr "length" "2")
12253 (set_attr "mode" "HI")])
12255 (define_insn "*parityqi2_cmp"
12256 [(set (reg:CC FLAGS_REG)
12257 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
12260 [(set_attr "length" "2")
12261 (set_attr "mode" "QI")])
12263 ;; Thread-local storage patterns for ELF.
12265 ;; Note that these code sequences must appear exactly as shown
12266 ;; in order to allow linker relaxation.
12268 (define_insn "*tls_global_dynamic_32_gnu"
12269 [(set (match_operand:SI 0 "register_operand" "=a")
12270 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12271 (match_operand:SI 2 "tls_symbolic_operand" "")
12272 (match_operand:SI 3 "call_insn_operand" "")]
12274 (clobber (match_scratch:SI 4 "=d"))
12275 (clobber (match_scratch:SI 5 "=c"))
12276 (clobber (reg:CC FLAGS_REG))]
12277 "!TARGET_64BIT && TARGET_GNU_TLS"
12278 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12279 [(set_attr "type" "multi")
12280 (set_attr "length" "12")])
12282 (define_expand "tls_global_dynamic_32"
12283 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12286 (match_operand:SI 1 "tls_symbolic_operand" "")
12289 (clobber (match_scratch:SI 4 ""))
12290 (clobber (match_scratch:SI 5 ""))
12291 (clobber (reg:CC FLAGS_REG))])]
12295 operands[2] = pic_offset_table_rtx;
12298 operands[2] = gen_reg_rtx (Pmode);
12299 emit_insn (gen_set_got (operands[2]));
12301 if (TARGET_GNU2_TLS)
12303 emit_insn (gen_tls_dynamic_gnu2_32
12304 (operands[0], operands[1], operands[2]));
12307 operands[3] = ix86_tls_get_addr ();
12310 (define_insn "*tls_global_dynamic_64"
12311 [(set (match_operand:DI 0 "register_operand" "=a")
12312 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12313 (match_operand:DI 3 "" "")))
12314 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12317 { 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"; }
12318 [(set_attr "type" "multi")
12319 (set_attr "length" "16")])
12321 (define_expand "tls_global_dynamic_64"
12322 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12323 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12324 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12328 if (TARGET_GNU2_TLS)
12330 emit_insn (gen_tls_dynamic_gnu2_64
12331 (operands[0], operands[1]));
12334 operands[2] = ix86_tls_get_addr ();
12337 (define_insn "*tls_local_dynamic_base_32_gnu"
12338 [(set (match_operand:SI 0 "register_operand" "=a")
12339 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12340 (match_operand:SI 2 "call_insn_operand" "")]
12341 UNSPEC_TLS_LD_BASE))
12342 (clobber (match_scratch:SI 3 "=d"))
12343 (clobber (match_scratch:SI 4 "=c"))
12344 (clobber (reg:CC FLAGS_REG))]
12345 "!TARGET_64BIT && TARGET_GNU_TLS"
12346 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12347 [(set_attr "type" "multi")
12348 (set_attr "length" "11")])
12350 (define_expand "tls_local_dynamic_base_32"
12351 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12352 (unspec:SI [(match_dup 1) (match_dup 2)]
12353 UNSPEC_TLS_LD_BASE))
12354 (clobber (match_scratch:SI 3 ""))
12355 (clobber (match_scratch:SI 4 ""))
12356 (clobber (reg:CC FLAGS_REG))])]
12360 operands[1] = pic_offset_table_rtx;
12363 operands[1] = gen_reg_rtx (Pmode);
12364 emit_insn (gen_set_got (operands[1]));
12366 if (TARGET_GNU2_TLS)
12368 emit_insn (gen_tls_dynamic_gnu2_32
12369 (operands[0], ix86_tls_module_base (), operands[1]));
12372 operands[2] = ix86_tls_get_addr ();
12375 (define_insn "*tls_local_dynamic_base_64"
12376 [(set (match_operand:DI 0 "register_operand" "=a")
12377 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12378 (match_operand:DI 2 "" "")))
12379 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12381 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12382 [(set_attr "type" "multi")
12383 (set_attr "length" "12")])
12385 (define_expand "tls_local_dynamic_base_64"
12386 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12387 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12388 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12391 if (TARGET_GNU2_TLS)
12393 emit_insn (gen_tls_dynamic_gnu2_64
12394 (operands[0], ix86_tls_module_base ()));
12397 operands[1] = ix86_tls_get_addr ();
12400 ;; Local dynamic of a single variable is a lose. Show combine how
12401 ;; to convert that back to global dynamic.
12403 (define_insn_and_split "*tls_local_dynamic_32_once"
12404 [(set (match_operand:SI 0 "register_operand" "=a")
12405 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12406 (match_operand:SI 2 "call_insn_operand" "")]
12407 UNSPEC_TLS_LD_BASE)
12408 (const:SI (unspec:SI
12409 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12411 (clobber (match_scratch:SI 4 "=d"))
12412 (clobber (match_scratch:SI 5 "=c"))
12413 (clobber (reg:CC FLAGS_REG))]
12417 [(parallel [(set (match_dup 0)
12418 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12420 (clobber (match_dup 4))
12421 (clobber (match_dup 5))
12422 (clobber (reg:CC FLAGS_REG))])]
12425 ;; Load and add the thread base pointer from %gs:0.
12427 (define_insn "*load_tp_si"
12428 [(set (match_operand:SI 0 "register_operand" "=r")
12429 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12431 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12432 [(set_attr "type" "imov")
12433 (set_attr "modrm" "0")
12434 (set_attr "length" "7")
12435 (set_attr "memory" "load")
12436 (set_attr "imm_disp" "false")])
12438 (define_insn "*add_tp_si"
12439 [(set (match_operand:SI 0 "register_operand" "=r")
12440 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12441 (match_operand:SI 1 "register_operand" "0")))
12442 (clobber (reg:CC FLAGS_REG))]
12444 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12445 [(set_attr "type" "alu")
12446 (set_attr "modrm" "0")
12447 (set_attr "length" "7")
12448 (set_attr "memory" "load")
12449 (set_attr "imm_disp" "false")])
12451 (define_insn "*load_tp_di"
12452 [(set (match_operand:DI 0 "register_operand" "=r")
12453 (unspec:DI [(const_int 0)] UNSPEC_TP))]
12455 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12456 [(set_attr "type" "imov")
12457 (set_attr "modrm" "0")
12458 (set_attr "length" "7")
12459 (set_attr "memory" "load")
12460 (set_attr "imm_disp" "false")])
12462 (define_insn "*add_tp_di"
12463 [(set (match_operand:DI 0 "register_operand" "=r")
12464 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12465 (match_operand:DI 1 "register_operand" "0")))
12466 (clobber (reg:CC FLAGS_REG))]
12468 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12469 [(set_attr "type" "alu")
12470 (set_attr "modrm" "0")
12471 (set_attr "length" "7")
12472 (set_attr "memory" "load")
12473 (set_attr "imm_disp" "false")])
12475 ;; GNU2 TLS patterns can be split.
12477 (define_expand "tls_dynamic_gnu2_32"
12478 [(set (match_dup 3)
12479 (plus:SI (match_operand:SI 2 "register_operand" "")
12481 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12484 [(set (match_operand:SI 0 "register_operand" "")
12485 (unspec:SI [(match_dup 1) (match_dup 3)
12486 (match_dup 2) (reg:SI SP_REG)]
12488 (clobber (reg:CC FLAGS_REG))])]
12489 "!TARGET_64BIT && TARGET_GNU2_TLS"
12491 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12492 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12495 (define_insn "*tls_dynamic_lea_32"
12496 [(set (match_operand:SI 0 "register_operand" "=r")
12497 (plus:SI (match_operand:SI 1 "register_operand" "b")
12499 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12500 UNSPEC_TLSDESC))))]
12501 "!TARGET_64BIT && TARGET_GNU2_TLS"
12502 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12503 [(set_attr "type" "lea")
12504 (set_attr "mode" "SI")
12505 (set_attr "length" "6")
12506 (set_attr "length_address" "4")])
12508 (define_insn "*tls_dynamic_call_32"
12509 [(set (match_operand:SI 0 "register_operand" "=a")
12510 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12511 (match_operand:SI 2 "register_operand" "0")
12512 ;; we have to make sure %ebx still points to the GOT
12513 (match_operand:SI 3 "register_operand" "b")
12516 (clobber (reg:CC FLAGS_REG))]
12517 "!TARGET_64BIT && TARGET_GNU2_TLS"
12518 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12519 [(set_attr "type" "call")
12520 (set_attr "length" "2")
12521 (set_attr "length_address" "0")])
12523 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12524 [(set (match_operand:SI 0 "register_operand" "=&a")
12526 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12527 (match_operand:SI 4 "" "")
12528 (match_operand:SI 2 "register_operand" "b")
12531 (const:SI (unspec:SI
12532 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12534 (clobber (reg:CC FLAGS_REG))]
12535 "!TARGET_64BIT && TARGET_GNU2_TLS"
12538 [(set (match_dup 0) (match_dup 5))]
12540 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12541 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12544 (define_expand "tls_dynamic_gnu2_64"
12545 [(set (match_dup 2)
12546 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12549 [(set (match_operand:DI 0 "register_operand" "")
12550 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12552 (clobber (reg:CC FLAGS_REG))])]
12553 "TARGET_64BIT && TARGET_GNU2_TLS"
12555 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12556 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12559 (define_insn "*tls_dynamic_lea_64"
12560 [(set (match_operand:DI 0 "register_operand" "=r")
12561 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12563 "TARGET_64BIT && TARGET_GNU2_TLS"
12564 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12565 [(set_attr "type" "lea")
12566 (set_attr "mode" "DI")
12567 (set_attr "length" "7")
12568 (set_attr "length_address" "4")])
12570 (define_insn "*tls_dynamic_call_64"
12571 [(set (match_operand:DI 0 "register_operand" "=a")
12572 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12573 (match_operand:DI 2 "register_operand" "0")
12576 (clobber (reg:CC FLAGS_REG))]
12577 "TARGET_64BIT && TARGET_GNU2_TLS"
12578 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12579 [(set_attr "type" "call")
12580 (set_attr "length" "2")
12581 (set_attr "length_address" "0")])
12583 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12584 [(set (match_operand:DI 0 "register_operand" "=&a")
12586 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12587 (match_operand:DI 3 "" "")
12590 (const:DI (unspec:DI
12591 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12593 (clobber (reg:CC FLAGS_REG))]
12594 "TARGET_64BIT && TARGET_GNU2_TLS"
12597 [(set (match_dup 0) (match_dup 4))]
12599 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12600 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12605 ;; These patterns match the binary 387 instructions for addM3, subM3,
12606 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12607 ;; SFmode. The first is the normal insn, the second the same insn but
12608 ;; with one operand a conversion, and the third the same insn but with
12609 ;; the other operand a conversion. The conversion may be SFmode or
12610 ;; SImode if the target mode DFmode, but only SImode if the target mode
12613 ;; Gcc is slightly more smart about handling normal two address instructions
12614 ;; so use special patterns for add and mull.
12616 (define_insn "*fop_<mode>_comm_mixed_avx"
12617 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12618 (match_operator:MODEF 3 "binary_fp_operator"
12619 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12620 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12621 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12622 && COMMUTATIVE_ARITH_P (operands[3])
12623 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12624 "* return output_387_binary_op (insn, operands);"
12625 [(set (attr "type")
12626 (if_then_else (eq_attr "alternative" "1")
12627 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12628 (const_string "ssemul")
12629 (const_string "sseadd"))
12630 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12631 (const_string "fmul")
12632 (const_string "fop"))))
12633 (set_attr "prefix" "orig,maybe_vex")
12634 (set_attr "mode" "<MODE>")])
12636 (define_insn "*fop_<mode>_comm_mixed"
12637 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12638 (match_operator:MODEF 3 "binary_fp_operator"
12639 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12640 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12641 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12642 && COMMUTATIVE_ARITH_P (operands[3])
12643 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12644 "* return output_387_binary_op (insn, operands);"
12645 [(set (attr "type")
12646 (if_then_else (eq_attr "alternative" "1")
12647 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12648 (const_string "ssemul")
12649 (const_string "sseadd"))
12650 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12651 (const_string "fmul")
12652 (const_string "fop"))))
12653 (set_attr "mode" "<MODE>")])
12655 (define_insn "*fop_<mode>_comm_avx"
12656 [(set (match_operand:MODEF 0 "register_operand" "=x")
12657 (match_operator:MODEF 3 "binary_fp_operator"
12658 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12659 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12660 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12661 && COMMUTATIVE_ARITH_P (operands[3])
12662 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12663 "* return output_387_binary_op (insn, operands);"
12664 [(set (attr "type")
12665 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12666 (const_string "ssemul")
12667 (const_string "sseadd")))
12668 (set_attr "prefix" "vex")
12669 (set_attr "mode" "<MODE>")])
12671 (define_insn "*fop_<mode>_comm_sse"
12672 [(set (match_operand:MODEF 0 "register_operand" "=x")
12673 (match_operator:MODEF 3 "binary_fp_operator"
12674 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12675 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12676 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12677 && COMMUTATIVE_ARITH_P (operands[3])
12678 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12679 "* return output_387_binary_op (insn, operands);"
12680 [(set (attr "type")
12681 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12682 (const_string "ssemul")
12683 (const_string "sseadd")))
12684 (set_attr "mode" "<MODE>")])
12686 (define_insn "*fop_<mode>_comm_i387"
12687 [(set (match_operand:MODEF 0 "register_operand" "=f")
12688 (match_operator:MODEF 3 "binary_fp_operator"
12689 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12690 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12691 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12692 && COMMUTATIVE_ARITH_P (operands[3])
12693 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12694 "* return output_387_binary_op (insn, operands);"
12695 [(set (attr "type")
12696 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12697 (const_string "fmul")
12698 (const_string "fop")))
12699 (set_attr "mode" "<MODE>")])
12701 (define_insn "*fop_<mode>_1_mixed_avx"
12702 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12703 (match_operator:MODEF 3 "binary_fp_operator"
12704 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12705 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12706 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12707 && !COMMUTATIVE_ARITH_P (operands[3])
12708 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12709 "* return output_387_binary_op (insn, operands);"
12710 [(set (attr "type")
12711 (cond [(and (eq_attr "alternative" "2")
12712 (match_operand:MODEF 3 "mult_operator" ""))
12713 (const_string "ssemul")
12714 (and (eq_attr "alternative" "2")
12715 (match_operand:MODEF 3 "div_operator" ""))
12716 (const_string "ssediv")
12717 (eq_attr "alternative" "2")
12718 (const_string "sseadd")
12719 (match_operand:MODEF 3 "mult_operator" "")
12720 (const_string "fmul")
12721 (match_operand:MODEF 3 "div_operator" "")
12722 (const_string "fdiv")
12724 (const_string "fop")))
12725 (set_attr "prefix" "orig,orig,maybe_vex")
12726 (set_attr "mode" "<MODE>")])
12728 (define_insn "*fop_<mode>_1_mixed"
12729 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12730 (match_operator:MODEF 3 "binary_fp_operator"
12731 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12732 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12733 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12734 && !COMMUTATIVE_ARITH_P (operands[3])
12735 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12736 "* return output_387_binary_op (insn, operands);"
12737 [(set (attr "type")
12738 (cond [(and (eq_attr "alternative" "2")
12739 (match_operand:MODEF 3 "mult_operator" ""))
12740 (const_string "ssemul")
12741 (and (eq_attr "alternative" "2")
12742 (match_operand:MODEF 3 "div_operator" ""))
12743 (const_string "ssediv")
12744 (eq_attr "alternative" "2")
12745 (const_string "sseadd")
12746 (match_operand:MODEF 3 "mult_operator" "")
12747 (const_string "fmul")
12748 (match_operand:MODEF 3 "div_operator" "")
12749 (const_string "fdiv")
12751 (const_string "fop")))
12752 (set_attr "mode" "<MODE>")])
12754 (define_insn "*rcpsf2_sse"
12755 [(set (match_operand:SF 0 "register_operand" "=x")
12756 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12759 "%vrcpss\t{%1, %d0|%d0, %1}"
12760 [(set_attr "type" "sse")
12761 (set_attr "atom_sse_attr" "rcp")
12762 (set_attr "prefix" "maybe_vex")
12763 (set_attr "mode" "SF")])
12765 (define_insn "*fop_<mode>_1_avx"
12766 [(set (match_operand:MODEF 0 "register_operand" "=x")
12767 (match_operator:MODEF 3 "binary_fp_operator"
12768 [(match_operand:MODEF 1 "register_operand" "x")
12769 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12770 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12771 && !COMMUTATIVE_ARITH_P (operands[3])"
12772 "* return output_387_binary_op (insn, operands);"
12773 [(set (attr "type")
12774 (cond [(match_operand:MODEF 3 "mult_operator" "")
12775 (const_string "ssemul")
12776 (match_operand:MODEF 3 "div_operator" "")
12777 (const_string "ssediv")
12779 (const_string "sseadd")))
12780 (set_attr "prefix" "vex")
12781 (set_attr "mode" "<MODE>")])
12783 (define_insn "*fop_<mode>_1_sse"
12784 [(set (match_operand:MODEF 0 "register_operand" "=x")
12785 (match_operator:MODEF 3 "binary_fp_operator"
12786 [(match_operand:MODEF 1 "register_operand" "0")
12787 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12788 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12789 && !COMMUTATIVE_ARITH_P (operands[3])"
12790 "* return output_387_binary_op (insn, operands);"
12791 [(set (attr "type")
12792 (cond [(match_operand:MODEF 3 "mult_operator" "")
12793 (const_string "ssemul")
12794 (match_operand:MODEF 3 "div_operator" "")
12795 (const_string "ssediv")
12797 (const_string "sseadd")))
12798 (set_attr "mode" "<MODE>")])
12800 ;; This pattern is not fully shadowed by the pattern above.
12801 (define_insn "*fop_<mode>_1_i387"
12802 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12803 (match_operator:MODEF 3 "binary_fp_operator"
12804 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12805 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12806 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12807 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12808 && !COMMUTATIVE_ARITH_P (operands[3])
12809 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12810 "* return output_387_binary_op (insn, operands);"
12811 [(set (attr "type")
12812 (cond [(match_operand:MODEF 3 "mult_operator" "")
12813 (const_string "fmul")
12814 (match_operand:MODEF 3 "div_operator" "")
12815 (const_string "fdiv")
12817 (const_string "fop")))
12818 (set_attr "mode" "<MODE>")])
12820 ;; ??? Add SSE splitters for these!
12821 (define_insn "*fop_<MODEF:mode>_2_i387"
12822 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12823 (match_operator:MODEF 3 "binary_fp_operator"
12825 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12826 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12827 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12828 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12829 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12830 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12831 [(set (attr "type")
12832 (cond [(match_operand:MODEF 3 "mult_operator" "")
12833 (const_string "fmul")
12834 (match_operand:MODEF 3 "div_operator" "")
12835 (const_string "fdiv")
12837 (const_string "fop")))
12838 (set_attr "fp_int_src" "true")
12839 (set_attr "mode" "<X87MODEI12:MODE>")])
12841 (define_insn "*fop_<MODEF:mode>_3_i387"
12842 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12843 (match_operator:MODEF 3 "binary_fp_operator"
12844 [(match_operand:MODEF 1 "register_operand" "0,0")
12846 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12847 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12848 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12849 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12850 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12851 [(set (attr "type")
12852 (cond [(match_operand:MODEF 3 "mult_operator" "")
12853 (const_string "fmul")
12854 (match_operand:MODEF 3 "div_operator" "")
12855 (const_string "fdiv")
12857 (const_string "fop")))
12858 (set_attr "fp_int_src" "true")
12859 (set_attr "mode" "<MODE>")])
12861 (define_insn "*fop_df_4_i387"
12862 [(set (match_operand:DF 0 "register_operand" "=f,f")
12863 (match_operator:DF 3 "binary_fp_operator"
12865 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12866 (match_operand:DF 2 "register_operand" "0,f")]))]
12867 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12868 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12869 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12870 "* return output_387_binary_op (insn, operands);"
12871 [(set (attr "type")
12872 (cond [(match_operand:DF 3 "mult_operator" "")
12873 (const_string "fmul")
12874 (match_operand:DF 3 "div_operator" "")
12875 (const_string "fdiv")
12877 (const_string "fop")))
12878 (set_attr "mode" "SF")])
12880 (define_insn "*fop_df_5_i387"
12881 [(set (match_operand:DF 0 "register_operand" "=f,f")
12882 (match_operator:DF 3 "binary_fp_operator"
12883 [(match_operand:DF 1 "register_operand" "0,f")
12885 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12886 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12887 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12888 "* return output_387_binary_op (insn, operands);"
12889 [(set (attr "type")
12890 (cond [(match_operand:DF 3 "mult_operator" "")
12891 (const_string "fmul")
12892 (match_operand:DF 3 "div_operator" "")
12893 (const_string "fdiv")
12895 (const_string "fop")))
12896 (set_attr "mode" "SF")])
12898 (define_insn "*fop_df_6_i387"
12899 [(set (match_operand:DF 0 "register_operand" "=f,f")
12900 (match_operator:DF 3 "binary_fp_operator"
12902 (match_operand:SF 1 "register_operand" "0,f"))
12904 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12905 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12906 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12907 "* return output_387_binary_op (insn, operands);"
12908 [(set (attr "type")
12909 (cond [(match_operand:DF 3 "mult_operator" "")
12910 (const_string "fmul")
12911 (match_operand:DF 3 "div_operator" "")
12912 (const_string "fdiv")
12914 (const_string "fop")))
12915 (set_attr "mode" "SF")])
12917 (define_insn "*fop_xf_comm_i387"
12918 [(set (match_operand:XF 0 "register_operand" "=f")
12919 (match_operator:XF 3 "binary_fp_operator"
12920 [(match_operand:XF 1 "register_operand" "%0")
12921 (match_operand:XF 2 "register_operand" "f")]))]
12923 && COMMUTATIVE_ARITH_P (operands[3])"
12924 "* return output_387_binary_op (insn, operands);"
12925 [(set (attr "type")
12926 (if_then_else (match_operand:XF 3 "mult_operator" "")
12927 (const_string "fmul")
12928 (const_string "fop")))
12929 (set_attr "mode" "XF")])
12931 (define_insn "*fop_xf_1_i387"
12932 [(set (match_operand:XF 0 "register_operand" "=f,f")
12933 (match_operator:XF 3 "binary_fp_operator"
12934 [(match_operand:XF 1 "register_operand" "0,f")
12935 (match_operand:XF 2 "register_operand" "f,0")]))]
12937 && !COMMUTATIVE_ARITH_P (operands[3])"
12938 "* return output_387_binary_op (insn, operands);"
12939 [(set (attr "type")
12940 (cond [(match_operand:XF 3 "mult_operator" "")
12941 (const_string "fmul")
12942 (match_operand:XF 3 "div_operator" "")
12943 (const_string "fdiv")
12945 (const_string "fop")))
12946 (set_attr "mode" "XF")])
12948 (define_insn "*fop_xf_2_i387"
12949 [(set (match_operand:XF 0 "register_operand" "=f,f")
12950 (match_operator:XF 3 "binary_fp_operator"
12952 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12953 (match_operand:XF 2 "register_operand" "0,0")]))]
12954 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12955 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12956 [(set (attr "type")
12957 (cond [(match_operand:XF 3 "mult_operator" "")
12958 (const_string "fmul")
12959 (match_operand:XF 3 "div_operator" "")
12960 (const_string "fdiv")
12962 (const_string "fop")))
12963 (set_attr "fp_int_src" "true")
12964 (set_attr "mode" "<MODE>")])
12966 (define_insn "*fop_xf_3_i387"
12967 [(set (match_operand:XF 0 "register_operand" "=f,f")
12968 (match_operator:XF 3 "binary_fp_operator"
12969 [(match_operand:XF 1 "register_operand" "0,0")
12971 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12972 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12973 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12974 [(set (attr "type")
12975 (cond [(match_operand:XF 3 "mult_operator" "")
12976 (const_string "fmul")
12977 (match_operand:XF 3 "div_operator" "")
12978 (const_string "fdiv")
12980 (const_string "fop")))
12981 (set_attr "fp_int_src" "true")
12982 (set_attr "mode" "<MODE>")])
12984 (define_insn "*fop_xf_4_i387"
12985 [(set (match_operand:XF 0 "register_operand" "=f,f")
12986 (match_operator:XF 3 "binary_fp_operator"
12988 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12989 (match_operand:XF 2 "register_operand" "0,f")]))]
12991 "* return output_387_binary_op (insn, operands);"
12992 [(set (attr "type")
12993 (cond [(match_operand:XF 3 "mult_operator" "")
12994 (const_string "fmul")
12995 (match_operand:XF 3 "div_operator" "")
12996 (const_string "fdiv")
12998 (const_string "fop")))
12999 (set_attr "mode" "<MODE>")])
13001 (define_insn "*fop_xf_5_i387"
13002 [(set (match_operand:XF 0 "register_operand" "=f,f")
13003 (match_operator:XF 3 "binary_fp_operator"
13004 [(match_operand:XF 1 "register_operand" "0,f")
13006 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13008 "* return output_387_binary_op (insn, operands);"
13009 [(set (attr "type")
13010 (cond [(match_operand:XF 3 "mult_operator" "")
13011 (const_string "fmul")
13012 (match_operand:XF 3 "div_operator" "")
13013 (const_string "fdiv")
13015 (const_string "fop")))
13016 (set_attr "mode" "<MODE>")])
13018 (define_insn "*fop_xf_6_i387"
13019 [(set (match_operand:XF 0 "register_operand" "=f,f")
13020 (match_operator:XF 3 "binary_fp_operator"
13022 (match_operand:MODEF 1 "register_operand" "0,f"))
13024 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13026 "* return output_387_binary_op (insn, operands);"
13027 [(set (attr "type")
13028 (cond [(match_operand:XF 3 "mult_operator" "")
13029 (const_string "fmul")
13030 (match_operand:XF 3 "div_operator" "")
13031 (const_string "fdiv")
13033 (const_string "fop")))
13034 (set_attr "mode" "<MODE>")])
13037 [(set (match_operand 0 "register_operand" "")
13038 (match_operator 3 "binary_fp_operator"
13039 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13040 (match_operand 2 "register_operand" "")]))]
13042 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13043 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13046 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13047 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13048 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13049 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13050 GET_MODE (operands[3]),
13053 ix86_free_from_memory (GET_MODE (operands[1]));
13058 [(set (match_operand 0 "register_operand" "")
13059 (match_operator 3 "binary_fp_operator"
13060 [(match_operand 1 "register_operand" "")
13061 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13063 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13064 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13067 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13068 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13069 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13070 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13071 GET_MODE (operands[3]),
13074 ix86_free_from_memory (GET_MODE (operands[2]));
13078 ;; FPU special functions.
13080 ;; This pattern implements a no-op XFmode truncation for
13081 ;; all fancy i386 XFmode math functions.
13083 (define_insn "truncxf<mode>2_i387_noop_unspec"
13084 [(set (match_operand:MODEF 0 "register_operand" "=f")
13085 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13086 UNSPEC_TRUNC_NOOP))]
13087 "TARGET_USE_FANCY_MATH_387"
13088 "* return output_387_reg_move (insn, operands);"
13089 [(set_attr "type" "fmov")
13090 (set_attr "mode" "<MODE>")])
13092 (define_insn "sqrtxf2"
13093 [(set (match_operand:XF 0 "register_operand" "=f")
13094 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13095 "TARGET_USE_FANCY_MATH_387"
13097 [(set_attr "type" "fpspc")
13098 (set_attr "mode" "XF")
13099 (set_attr "athlon_decode" "direct")
13100 (set_attr "amdfam10_decode" "direct")])
13102 (define_insn "sqrt_extend<mode>xf2_i387"
13103 [(set (match_operand:XF 0 "register_operand" "=f")
13106 (match_operand:MODEF 1 "register_operand" "0"))))]
13107 "TARGET_USE_FANCY_MATH_387"
13109 [(set_attr "type" "fpspc")
13110 (set_attr "mode" "XF")
13111 (set_attr "athlon_decode" "direct")
13112 (set_attr "amdfam10_decode" "direct")])
13114 (define_insn "*rsqrtsf2_sse"
13115 [(set (match_operand:SF 0 "register_operand" "=x")
13116 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13119 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13120 [(set_attr "type" "sse")
13121 (set_attr "atom_sse_attr" "rcp")
13122 (set_attr "prefix" "maybe_vex")
13123 (set_attr "mode" "SF")])
13125 (define_expand "rsqrtsf2"
13126 [(set (match_operand:SF 0 "register_operand" "")
13127 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13131 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13135 (define_insn "*sqrt<mode>2_sse"
13136 [(set (match_operand:MODEF 0 "register_operand" "=x")
13138 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13139 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13140 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13141 [(set_attr "type" "sse")
13142 (set_attr "atom_sse_attr" "sqrt")
13143 (set_attr "prefix" "maybe_vex")
13144 (set_attr "mode" "<MODE>")
13145 (set_attr "athlon_decode" "*")
13146 (set_attr "amdfam10_decode" "*")])
13148 (define_expand "sqrt<mode>2"
13149 [(set (match_operand:MODEF 0 "register_operand" "")
13151 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13152 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13153 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13155 if (<MODE>mode == SFmode
13156 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13157 && flag_finite_math_only && !flag_trapping_math
13158 && flag_unsafe_math_optimizations)
13160 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13164 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13166 rtx op0 = gen_reg_rtx (XFmode);
13167 rtx op1 = force_reg (<MODE>mode, operands[1]);
13169 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13170 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13175 (define_insn "fpremxf4_i387"
13176 [(set (match_operand:XF 0 "register_operand" "=f")
13177 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13178 (match_operand:XF 3 "register_operand" "1")]
13180 (set (match_operand:XF 1 "register_operand" "=u")
13181 (unspec:XF [(match_dup 2) (match_dup 3)]
13183 (set (reg:CCFP FPSR_REG)
13184 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13186 "TARGET_USE_FANCY_MATH_387"
13188 [(set_attr "type" "fpspc")
13189 (set_attr "mode" "XF")])
13191 (define_expand "fmodxf3"
13192 [(use (match_operand:XF 0 "register_operand" ""))
13193 (use (match_operand:XF 1 "general_operand" ""))
13194 (use (match_operand:XF 2 "general_operand" ""))]
13195 "TARGET_USE_FANCY_MATH_387"
13197 rtx label = gen_label_rtx ();
13199 rtx op1 = gen_reg_rtx (XFmode);
13200 rtx op2 = gen_reg_rtx (XFmode);
13202 emit_move_insn (op2, operands[2]);
13203 emit_move_insn (op1, operands[1]);
13205 emit_label (label);
13206 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13207 ix86_emit_fp_unordered_jump (label);
13208 LABEL_NUSES (label) = 1;
13210 emit_move_insn (operands[0], op1);
13214 (define_expand "fmod<mode>3"
13215 [(use (match_operand:MODEF 0 "register_operand" ""))
13216 (use (match_operand:MODEF 1 "general_operand" ""))
13217 (use (match_operand:MODEF 2 "general_operand" ""))]
13218 "TARGET_USE_FANCY_MATH_387"
13220 rtx label = gen_label_rtx ();
13222 rtx op1 = gen_reg_rtx (XFmode);
13223 rtx op2 = gen_reg_rtx (XFmode);
13225 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13226 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13228 emit_label (label);
13229 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13230 ix86_emit_fp_unordered_jump (label);
13231 LABEL_NUSES (label) = 1;
13233 /* Truncate the result properly for strict SSE math. */
13234 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13235 && !TARGET_MIX_SSE_I387)
13236 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13238 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13243 (define_insn "fprem1xf4_i387"
13244 [(set (match_operand:XF 0 "register_operand" "=f")
13245 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13246 (match_operand:XF 3 "register_operand" "1")]
13248 (set (match_operand:XF 1 "register_operand" "=u")
13249 (unspec:XF [(match_dup 2) (match_dup 3)]
13251 (set (reg:CCFP FPSR_REG)
13252 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13254 "TARGET_USE_FANCY_MATH_387"
13256 [(set_attr "type" "fpspc")
13257 (set_attr "mode" "XF")])
13259 (define_expand "remainderxf3"
13260 [(use (match_operand:XF 0 "register_operand" ""))
13261 (use (match_operand:XF 1 "general_operand" ""))
13262 (use (match_operand:XF 2 "general_operand" ""))]
13263 "TARGET_USE_FANCY_MATH_387"
13265 rtx label = gen_label_rtx ();
13267 rtx op1 = gen_reg_rtx (XFmode);
13268 rtx op2 = gen_reg_rtx (XFmode);
13270 emit_move_insn (op2, operands[2]);
13271 emit_move_insn (op1, operands[1]);
13273 emit_label (label);
13274 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13275 ix86_emit_fp_unordered_jump (label);
13276 LABEL_NUSES (label) = 1;
13278 emit_move_insn (operands[0], op1);
13282 (define_expand "remainder<mode>3"
13283 [(use (match_operand:MODEF 0 "register_operand" ""))
13284 (use (match_operand:MODEF 1 "general_operand" ""))
13285 (use (match_operand:MODEF 2 "general_operand" ""))]
13286 "TARGET_USE_FANCY_MATH_387"
13288 rtx label = gen_label_rtx ();
13290 rtx op1 = gen_reg_rtx (XFmode);
13291 rtx op2 = gen_reg_rtx (XFmode);
13293 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13294 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13296 emit_label (label);
13298 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13299 ix86_emit_fp_unordered_jump (label);
13300 LABEL_NUSES (label) = 1;
13302 /* Truncate the result properly for strict SSE math. */
13303 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13304 && !TARGET_MIX_SSE_I387)
13305 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13307 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13312 (define_insn "*sinxf2_i387"
13313 [(set (match_operand:XF 0 "register_operand" "=f")
13314 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13315 "TARGET_USE_FANCY_MATH_387
13316 && flag_unsafe_math_optimizations"
13318 [(set_attr "type" "fpspc")
13319 (set_attr "mode" "XF")])
13321 (define_insn "*sin_extend<mode>xf2_i387"
13322 [(set (match_operand:XF 0 "register_operand" "=f")
13323 (unspec:XF [(float_extend:XF
13324 (match_operand:MODEF 1 "register_operand" "0"))]
13326 "TARGET_USE_FANCY_MATH_387
13327 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13328 || TARGET_MIX_SSE_I387)
13329 && flag_unsafe_math_optimizations"
13331 [(set_attr "type" "fpspc")
13332 (set_attr "mode" "XF")])
13334 (define_insn "*cosxf2_i387"
13335 [(set (match_operand:XF 0 "register_operand" "=f")
13336 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13337 "TARGET_USE_FANCY_MATH_387
13338 && flag_unsafe_math_optimizations"
13340 [(set_attr "type" "fpspc")
13341 (set_attr "mode" "XF")])
13343 (define_insn "*cos_extend<mode>xf2_i387"
13344 [(set (match_operand:XF 0 "register_operand" "=f")
13345 (unspec:XF [(float_extend:XF
13346 (match_operand:MODEF 1 "register_operand" "0"))]
13348 "TARGET_USE_FANCY_MATH_387
13349 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13350 || TARGET_MIX_SSE_I387)
13351 && flag_unsafe_math_optimizations"
13353 [(set_attr "type" "fpspc")
13354 (set_attr "mode" "XF")])
13356 ;; When sincos pattern is defined, sin and cos builtin functions will be
13357 ;; expanded to sincos pattern with one of its outputs left unused.
13358 ;; CSE pass will figure out if two sincos patterns can be combined,
13359 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13360 ;; depending on the unused output.
13362 (define_insn "sincosxf3"
13363 [(set (match_operand:XF 0 "register_operand" "=f")
13364 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13365 UNSPEC_SINCOS_COS))
13366 (set (match_operand:XF 1 "register_operand" "=u")
13367 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13368 "TARGET_USE_FANCY_MATH_387
13369 && flag_unsafe_math_optimizations"
13371 [(set_attr "type" "fpspc")
13372 (set_attr "mode" "XF")])
13375 [(set (match_operand:XF 0 "register_operand" "")
13376 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13377 UNSPEC_SINCOS_COS))
13378 (set (match_operand:XF 1 "register_operand" "")
13379 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13380 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13381 && !(reload_completed || reload_in_progress)"
13382 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13386 [(set (match_operand:XF 0 "register_operand" "")
13387 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13388 UNSPEC_SINCOS_COS))
13389 (set (match_operand:XF 1 "register_operand" "")
13390 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13391 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13392 && !(reload_completed || reload_in_progress)"
13393 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13396 (define_insn "sincos_extend<mode>xf3_i387"
13397 [(set (match_operand:XF 0 "register_operand" "=f")
13398 (unspec:XF [(float_extend:XF
13399 (match_operand:MODEF 2 "register_operand" "0"))]
13400 UNSPEC_SINCOS_COS))
13401 (set (match_operand:XF 1 "register_operand" "=u")
13402 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13403 "TARGET_USE_FANCY_MATH_387
13404 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13405 || TARGET_MIX_SSE_I387)
13406 && flag_unsafe_math_optimizations"
13408 [(set_attr "type" "fpspc")
13409 (set_attr "mode" "XF")])
13412 [(set (match_operand:XF 0 "register_operand" "")
13413 (unspec:XF [(float_extend:XF
13414 (match_operand:MODEF 2 "register_operand" ""))]
13415 UNSPEC_SINCOS_COS))
13416 (set (match_operand:XF 1 "register_operand" "")
13417 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13418 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13419 && !(reload_completed || reload_in_progress)"
13420 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13424 [(set (match_operand:XF 0 "register_operand" "")
13425 (unspec:XF [(float_extend:XF
13426 (match_operand:MODEF 2 "register_operand" ""))]
13427 UNSPEC_SINCOS_COS))
13428 (set (match_operand:XF 1 "register_operand" "")
13429 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13430 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13431 && !(reload_completed || reload_in_progress)"
13432 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13435 (define_expand "sincos<mode>3"
13436 [(use (match_operand:MODEF 0 "register_operand" ""))
13437 (use (match_operand:MODEF 1 "register_operand" ""))
13438 (use (match_operand:MODEF 2 "register_operand" ""))]
13439 "TARGET_USE_FANCY_MATH_387
13440 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13441 || TARGET_MIX_SSE_I387)
13442 && flag_unsafe_math_optimizations"
13444 rtx op0 = gen_reg_rtx (XFmode);
13445 rtx op1 = gen_reg_rtx (XFmode);
13447 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13448 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13449 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13453 (define_insn "fptanxf4_i387"
13454 [(set (match_operand:XF 0 "register_operand" "=f")
13455 (match_operand:XF 3 "const_double_operand" "F"))
13456 (set (match_operand:XF 1 "register_operand" "=u")
13457 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13459 "TARGET_USE_FANCY_MATH_387
13460 && flag_unsafe_math_optimizations
13461 && standard_80387_constant_p (operands[3]) == 2"
13463 [(set_attr "type" "fpspc")
13464 (set_attr "mode" "XF")])
13466 (define_insn "fptan_extend<mode>xf4_i387"
13467 [(set (match_operand:MODEF 0 "register_operand" "=f")
13468 (match_operand:MODEF 3 "const_double_operand" "F"))
13469 (set (match_operand:XF 1 "register_operand" "=u")
13470 (unspec:XF [(float_extend:XF
13471 (match_operand:MODEF 2 "register_operand" "0"))]
13473 "TARGET_USE_FANCY_MATH_387
13474 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13475 || TARGET_MIX_SSE_I387)
13476 && flag_unsafe_math_optimizations
13477 && standard_80387_constant_p (operands[3]) == 2"
13479 [(set_attr "type" "fpspc")
13480 (set_attr "mode" "XF")])
13482 (define_expand "tanxf2"
13483 [(use (match_operand:XF 0 "register_operand" ""))
13484 (use (match_operand:XF 1 "register_operand" ""))]
13485 "TARGET_USE_FANCY_MATH_387
13486 && flag_unsafe_math_optimizations"
13488 rtx one = gen_reg_rtx (XFmode);
13489 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13491 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13495 (define_expand "tan<mode>2"
13496 [(use (match_operand:MODEF 0 "register_operand" ""))
13497 (use (match_operand:MODEF 1 "register_operand" ""))]
13498 "TARGET_USE_FANCY_MATH_387
13499 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13500 || TARGET_MIX_SSE_I387)
13501 && flag_unsafe_math_optimizations"
13503 rtx op0 = gen_reg_rtx (XFmode);
13505 rtx one = gen_reg_rtx (<MODE>mode);
13506 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13508 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13509 operands[1], op2));
13510 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13514 (define_insn "*fpatanxf3_i387"
13515 [(set (match_operand:XF 0 "register_operand" "=f")
13516 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13517 (match_operand:XF 2 "register_operand" "u")]
13519 (clobber (match_scratch:XF 3 "=2"))]
13520 "TARGET_USE_FANCY_MATH_387
13521 && flag_unsafe_math_optimizations"
13523 [(set_attr "type" "fpspc")
13524 (set_attr "mode" "XF")])
13526 (define_insn "fpatan_extend<mode>xf3_i387"
13527 [(set (match_operand:XF 0 "register_operand" "=f")
13528 (unspec:XF [(float_extend:XF
13529 (match_operand:MODEF 1 "register_operand" "0"))
13531 (match_operand:MODEF 2 "register_operand" "u"))]
13533 (clobber (match_scratch:XF 3 "=2"))]
13534 "TARGET_USE_FANCY_MATH_387
13535 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13536 || TARGET_MIX_SSE_I387)
13537 && flag_unsafe_math_optimizations"
13539 [(set_attr "type" "fpspc")
13540 (set_attr "mode" "XF")])
13542 (define_expand "atan2xf3"
13543 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13544 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13545 (match_operand:XF 1 "register_operand" "")]
13547 (clobber (match_scratch:XF 3 ""))])]
13548 "TARGET_USE_FANCY_MATH_387
13549 && flag_unsafe_math_optimizations"
13552 (define_expand "atan2<mode>3"
13553 [(use (match_operand:MODEF 0 "register_operand" ""))
13554 (use (match_operand:MODEF 1 "register_operand" ""))
13555 (use (match_operand:MODEF 2 "register_operand" ""))]
13556 "TARGET_USE_FANCY_MATH_387
13557 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13558 || TARGET_MIX_SSE_I387)
13559 && flag_unsafe_math_optimizations"
13561 rtx op0 = gen_reg_rtx (XFmode);
13563 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13564 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13568 (define_expand "atanxf2"
13569 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13570 (unspec:XF [(match_dup 2)
13571 (match_operand:XF 1 "register_operand" "")]
13573 (clobber (match_scratch:XF 3 ""))])]
13574 "TARGET_USE_FANCY_MATH_387
13575 && flag_unsafe_math_optimizations"
13577 operands[2] = gen_reg_rtx (XFmode);
13578 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13581 (define_expand "atan<mode>2"
13582 [(use (match_operand:MODEF 0 "register_operand" ""))
13583 (use (match_operand:MODEF 1 "register_operand" ""))]
13584 "TARGET_USE_FANCY_MATH_387
13585 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13586 || TARGET_MIX_SSE_I387)
13587 && flag_unsafe_math_optimizations"
13589 rtx op0 = gen_reg_rtx (XFmode);
13591 rtx op2 = gen_reg_rtx (<MODE>mode);
13592 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13594 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13595 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13599 (define_expand "asinxf2"
13600 [(set (match_dup 2)
13601 (mult:XF (match_operand:XF 1 "register_operand" "")
13603 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13604 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13605 (parallel [(set (match_operand:XF 0 "register_operand" "")
13606 (unspec:XF [(match_dup 5) (match_dup 1)]
13608 (clobber (match_scratch:XF 6 ""))])]
13609 "TARGET_USE_FANCY_MATH_387
13610 && flag_unsafe_math_optimizations"
13614 if (optimize_insn_for_size_p ())
13617 for (i = 2; i < 6; i++)
13618 operands[i] = gen_reg_rtx (XFmode);
13620 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13623 (define_expand "asin<mode>2"
13624 [(use (match_operand:MODEF 0 "register_operand" ""))
13625 (use (match_operand:MODEF 1 "general_operand" ""))]
13626 "TARGET_USE_FANCY_MATH_387
13627 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13628 || TARGET_MIX_SSE_I387)
13629 && flag_unsafe_math_optimizations"
13631 rtx op0 = gen_reg_rtx (XFmode);
13632 rtx op1 = gen_reg_rtx (XFmode);
13634 if (optimize_insn_for_size_p ())
13637 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13638 emit_insn (gen_asinxf2 (op0, op1));
13639 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13643 (define_expand "acosxf2"
13644 [(set (match_dup 2)
13645 (mult:XF (match_operand:XF 1 "register_operand" "")
13647 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13648 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13649 (parallel [(set (match_operand:XF 0 "register_operand" "")
13650 (unspec:XF [(match_dup 1) (match_dup 5)]
13652 (clobber (match_scratch:XF 6 ""))])]
13653 "TARGET_USE_FANCY_MATH_387
13654 && flag_unsafe_math_optimizations"
13658 if (optimize_insn_for_size_p ())
13661 for (i = 2; i < 6; i++)
13662 operands[i] = gen_reg_rtx (XFmode);
13664 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13667 (define_expand "acos<mode>2"
13668 [(use (match_operand:MODEF 0 "register_operand" ""))
13669 (use (match_operand:MODEF 1 "general_operand" ""))]
13670 "TARGET_USE_FANCY_MATH_387
13671 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13672 || TARGET_MIX_SSE_I387)
13673 && flag_unsafe_math_optimizations"
13675 rtx op0 = gen_reg_rtx (XFmode);
13676 rtx op1 = gen_reg_rtx (XFmode);
13678 if (optimize_insn_for_size_p ())
13681 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13682 emit_insn (gen_acosxf2 (op0, op1));
13683 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13687 (define_insn "fyl2xxf3_i387"
13688 [(set (match_operand:XF 0 "register_operand" "=f")
13689 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13690 (match_operand:XF 2 "register_operand" "u")]
13692 (clobber (match_scratch:XF 3 "=2"))]
13693 "TARGET_USE_FANCY_MATH_387
13694 && flag_unsafe_math_optimizations"
13696 [(set_attr "type" "fpspc")
13697 (set_attr "mode" "XF")])
13699 (define_insn "fyl2x_extend<mode>xf3_i387"
13700 [(set (match_operand:XF 0 "register_operand" "=f")
13701 (unspec:XF [(float_extend:XF
13702 (match_operand:MODEF 1 "register_operand" "0"))
13703 (match_operand:XF 2 "register_operand" "u")]
13705 (clobber (match_scratch:XF 3 "=2"))]
13706 "TARGET_USE_FANCY_MATH_387
13707 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13708 || TARGET_MIX_SSE_I387)
13709 && flag_unsafe_math_optimizations"
13711 [(set_attr "type" "fpspc")
13712 (set_attr "mode" "XF")])
13714 (define_expand "logxf2"
13715 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13716 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13717 (match_dup 2)] UNSPEC_FYL2X))
13718 (clobber (match_scratch:XF 3 ""))])]
13719 "TARGET_USE_FANCY_MATH_387
13720 && flag_unsafe_math_optimizations"
13722 operands[2] = gen_reg_rtx (XFmode);
13723 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13726 (define_expand "log<mode>2"
13727 [(use (match_operand:MODEF 0 "register_operand" ""))
13728 (use (match_operand:MODEF 1 "register_operand" ""))]
13729 "TARGET_USE_FANCY_MATH_387
13730 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13731 || TARGET_MIX_SSE_I387)
13732 && flag_unsafe_math_optimizations"
13734 rtx op0 = gen_reg_rtx (XFmode);
13736 rtx op2 = gen_reg_rtx (XFmode);
13737 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13739 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13740 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13744 (define_expand "log10xf2"
13745 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13746 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13747 (match_dup 2)] UNSPEC_FYL2X))
13748 (clobber (match_scratch:XF 3 ""))])]
13749 "TARGET_USE_FANCY_MATH_387
13750 && flag_unsafe_math_optimizations"
13752 operands[2] = gen_reg_rtx (XFmode);
13753 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13756 (define_expand "log10<mode>2"
13757 [(use (match_operand:MODEF 0 "register_operand" ""))
13758 (use (match_operand:MODEF 1 "register_operand" ""))]
13759 "TARGET_USE_FANCY_MATH_387
13760 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13761 || TARGET_MIX_SSE_I387)
13762 && flag_unsafe_math_optimizations"
13764 rtx op0 = gen_reg_rtx (XFmode);
13766 rtx op2 = gen_reg_rtx (XFmode);
13767 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13769 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13770 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13774 (define_expand "log2xf2"
13775 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13776 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13777 (match_dup 2)] UNSPEC_FYL2X))
13778 (clobber (match_scratch:XF 3 ""))])]
13779 "TARGET_USE_FANCY_MATH_387
13780 && flag_unsafe_math_optimizations"
13782 operands[2] = gen_reg_rtx (XFmode);
13783 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13786 (define_expand "log2<mode>2"
13787 [(use (match_operand:MODEF 0 "register_operand" ""))
13788 (use (match_operand:MODEF 1 "register_operand" ""))]
13789 "TARGET_USE_FANCY_MATH_387
13790 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13791 || TARGET_MIX_SSE_I387)
13792 && flag_unsafe_math_optimizations"
13794 rtx op0 = gen_reg_rtx (XFmode);
13796 rtx op2 = gen_reg_rtx (XFmode);
13797 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13799 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13800 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13804 (define_insn "fyl2xp1xf3_i387"
13805 [(set (match_operand:XF 0 "register_operand" "=f")
13806 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13807 (match_operand:XF 2 "register_operand" "u")]
13809 (clobber (match_scratch:XF 3 "=2"))]
13810 "TARGET_USE_FANCY_MATH_387
13811 && flag_unsafe_math_optimizations"
13813 [(set_attr "type" "fpspc")
13814 (set_attr "mode" "XF")])
13816 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13817 [(set (match_operand:XF 0 "register_operand" "=f")
13818 (unspec:XF [(float_extend:XF
13819 (match_operand:MODEF 1 "register_operand" "0"))
13820 (match_operand:XF 2 "register_operand" "u")]
13822 (clobber (match_scratch:XF 3 "=2"))]
13823 "TARGET_USE_FANCY_MATH_387
13824 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13825 || TARGET_MIX_SSE_I387)
13826 && flag_unsafe_math_optimizations"
13828 [(set_attr "type" "fpspc")
13829 (set_attr "mode" "XF")])
13831 (define_expand "log1pxf2"
13832 [(use (match_operand:XF 0 "register_operand" ""))
13833 (use (match_operand:XF 1 "register_operand" ""))]
13834 "TARGET_USE_FANCY_MATH_387
13835 && flag_unsafe_math_optimizations"
13837 if (optimize_insn_for_size_p ())
13840 ix86_emit_i387_log1p (operands[0], operands[1]);
13844 (define_expand "log1p<mode>2"
13845 [(use (match_operand:MODEF 0 "register_operand" ""))
13846 (use (match_operand:MODEF 1 "register_operand" ""))]
13847 "TARGET_USE_FANCY_MATH_387
13848 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13849 || TARGET_MIX_SSE_I387)
13850 && flag_unsafe_math_optimizations"
13854 if (optimize_insn_for_size_p ())
13857 op0 = gen_reg_rtx (XFmode);
13859 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13861 ix86_emit_i387_log1p (op0, operands[1]);
13862 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13866 (define_insn "fxtractxf3_i387"
13867 [(set (match_operand:XF 0 "register_operand" "=f")
13868 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13869 UNSPEC_XTRACT_FRACT))
13870 (set (match_operand:XF 1 "register_operand" "=u")
13871 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13872 "TARGET_USE_FANCY_MATH_387
13873 && flag_unsafe_math_optimizations"
13875 [(set_attr "type" "fpspc")
13876 (set_attr "mode" "XF")])
13878 (define_insn "fxtract_extend<mode>xf3_i387"
13879 [(set (match_operand:XF 0 "register_operand" "=f")
13880 (unspec:XF [(float_extend:XF
13881 (match_operand:MODEF 2 "register_operand" "0"))]
13882 UNSPEC_XTRACT_FRACT))
13883 (set (match_operand:XF 1 "register_operand" "=u")
13884 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13885 "TARGET_USE_FANCY_MATH_387
13886 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13887 || TARGET_MIX_SSE_I387)
13888 && flag_unsafe_math_optimizations"
13890 [(set_attr "type" "fpspc")
13891 (set_attr "mode" "XF")])
13893 (define_expand "logbxf2"
13894 [(parallel [(set (match_dup 2)
13895 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13896 UNSPEC_XTRACT_FRACT))
13897 (set (match_operand:XF 0 "register_operand" "")
13898 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13899 "TARGET_USE_FANCY_MATH_387
13900 && flag_unsafe_math_optimizations"
13902 operands[2] = gen_reg_rtx (XFmode);
13905 (define_expand "logb<mode>2"
13906 [(use (match_operand:MODEF 0 "register_operand" ""))
13907 (use (match_operand:MODEF 1 "register_operand" ""))]
13908 "TARGET_USE_FANCY_MATH_387
13909 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13910 || TARGET_MIX_SSE_I387)
13911 && flag_unsafe_math_optimizations"
13913 rtx op0 = gen_reg_rtx (XFmode);
13914 rtx op1 = gen_reg_rtx (XFmode);
13916 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13917 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13921 (define_expand "ilogbxf2"
13922 [(use (match_operand:SI 0 "register_operand" ""))
13923 (use (match_operand:XF 1 "register_operand" ""))]
13924 "TARGET_USE_FANCY_MATH_387
13925 && flag_unsafe_math_optimizations"
13929 if (optimize_insn_for_size_p ())
13932 op0 = gen_reg_rtx (XFmode);
13933 op1 = gen_reg_rtx (XFmode);
13935 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13936 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13940 (define_expand "ilogb<mode>2"
13941 [(use (match_operand:SI 0 "register_operand" ""))
13942 (use (match_operand:MODEF 1 "register_operand" ""))]
13943 "TARGET_USE_FANCY_MATH_387
13944 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13945 || TARGET_MIX_SSE_I387)
13946 && flag_unsafe_math_optimizations"
13950 if (optimize_insn_for_size_p ())
13953 op0 = gen_reg_rtx (XFmode);
13954 op1 = gen_reg_rtx (XFmode);
13956 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13957 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13961 (define_insn "*f2xm1xf2_i387"
13962 [(set (match_operand:XF 0 "register_operand" "=f")
13963 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13965 "TARGET_USE_FANCY_MATH_387
13966 && flag_unsafe_math_optimizations"
13968 [(set_attr "type" "fpspc")
13969 (set_attr "mode" "XF")])
13971 (define_insn "*fscalexf4_i387"
13972 [(set (match_operand:XF 0 "register_operand" "=f")
13973 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13974 (match_operand:XF 3 "register_operand" "1")]
13975 UNSPEC_FSCALE_FRACT))
13976 (set (match_operand:XF 1 "register_operand" "=u")
13977 (unspec:XF [(match_dup 2) (match_dup 3)]
13978 UNSPEC_FSCALE_EXP))]
13979 "TARGET_USE_FANCY_MATH_387
13980 && flag_unsafe_math_optimizations"
13982 [(set_attr "type" "fpspc")
13983 (set_attr "mode" "XF")])
13985 (define_expand "expNcorexf3"
13986 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13987 (match_operand:XF 2 "register_operand" "")))
13988 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13989 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13990 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13991 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13992 (parallel [(set (match_operand:XF 0 "register_operand" "")
13993 (unspec:XF [(match_dup 8) (match_dup 4)]
13994 UNSPEC_FSCALE_FRACT))
13996 (unspec:XF [(match_dup 8) (match_dup 4)]
13997 UNSPEC_FSCALE_EXP))])]
13998 "TARGET_USE_FANCY_MATH_387
13999 && flag_unsafe_math_optimizations"
14003 if (optimize_insn_for_size_p ())
14006 for (i = 3; i < 10; i++)
14007 operands[i] = gen_reg_rtx (XFmode);
14009 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14012 (define_expand "expxf2"
14013 [(use (match_operand:XF 0 "register_operand" ""))
14014 (use (match_operand:XF 1 "register_operand" ""))]
14015 "TARGET_USE_FANCY_MATH_387
14016 && flag_unsafe_math_optimizations"
14020 if (optimize_insn_for_size_p ())
14023 op2 = gen_reg_rtx (XFmode);
14024 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14026 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14030 (define_expand "exp<mode>2"
14031 [(use (match_operand:MODEF 0 "register_operand" ""))
14032 (use (match_operand:MODEF 1 "general_operand" ""))]
14033 "TARGET_USE_FANCY_MATH_387
14034 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14035 || TARGET_MIX_SSE_I387)
14036 && flag_unsafe_math_optimizations"
14040 if (optimize_insn_for_size_p ())
14043 op0 = gen_reg_rtx (XFmode);
14044 op1 = gen_reg_rtx (XFmode);
14046 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14047 emit_insn (gen_expxf2 (op0, op1));
14048 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14052 (define_expand "exp10xf2"
14053 [(use (match_operand:XF 0 "register_operand" ""))
14054 (use (match_operand:XF 1 "register_operand" ""))]
14055 "TARGET_USE_FANCY_MATH_387
14056 && flag_unsafe_math_optimizations"
14060 if (optimize_insn_for_size_p ())
14063 op2 = gen_reg_rtx (XFmode);
14064 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14066 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14070 (define_expand "exp10<mode>2"
14071 [(use (match_operand:MODEF 0 "register_operand" ""))
14072 (use (match_operand:MODEF 1 "general_operand" ""))]
14073 "TARGET_USE_FANCY_MATH_387
14074 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14075 || TARGET_MIX_SSE_I387)
14076 && flag_unsafe_math_optimizations"
14080 if (optimize_insn_for_size_p ())
14083 op0 = gen_reg_rtx (XFmode);
14084 op1 = gen_reg_rtx (XFmode);
14086 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14087 emit_insn (gen_exp10xf2 (op0, op1));
14088 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14092 (define_expand "exp2xf2"
14093 [(use (match_operand:XF 0 "register_operand" ""))
14094 (use (match_operand:XF 1 "register_operand" ""))]
14095 "TARGET_USE_FANCY_MATH_387
14096 && flag_unsafe_math_optimizations"
14100 if (optimize_insn_for_size_p ())
14103 op2 = gen_reg_rtx (XFmode);
14104 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14106 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14110 (define_expand "exp2<mode>2"
14111 [(use (match_operand:MODEF 0 "register_operand" ""))
14112 (use (match_operand:MODEF 1 "general_operand" ""))]
14113 "TARGET_USE_FANCY_MATH_387
14114 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14115 || TARGET_MIX_SSE_I387)
14116 && flag_unsafe_math_optimizations"
14120 if (optimize_insn_for_size_p ())
14123 op0 = gen_reg_rtx (XFmode);
14124 op1 = gen_reg_rtx (XFmode);
14126 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14127 emit_insn (gen_exp2xf2 (op0, op1));
14128 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14132 (define_expand "expm1xf2"
14133 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14135 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14136 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14137 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14138 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14139 (parallel [(set (match_dup 7)
14140 (unspec:XF [(match_dup 6) (match_dup 4)]
14141 UNSPEC_FSCALE_FRACT))
14143 (unspec:XF [(match_dup 6) (match_dup 4)]
14144 UNSPEC_FSCALE_EXP))])
14145 (parallel [(set (match_dup 10)
14146 (unspec:XF [(match_dup 9) (match_dup 8)]
14147 UNSPEC_FSCALE_FRACT))
14148 (set (match_dup 11)
14149 (unspec:XF [(match_dup 9) (match_dup 8)]
14150 UNSPEC_FSCALE_EXP))])
14151 (set (match_dup 12) (minus:XF (match_dup 10)
14152 (float_extend:XF (match_dup 13))))
14153 (set (match_operand:XF 0 "register_operand" "")
14154 (plus:XF (match_dup 12) (match_dup 7)))]
14155 "TARGET_USE_FANCY_MATH_387
14156 && flag_unsafe_math_optimizations"
14160 if (optimize_insn_for_size_p ())
14163 for (i = 2; i < 13; i++)
14164 operands[i] = gen_reg_rtx (XFmode);
14167 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14169 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14172 (define_expand "expm1<mode>2"
14173 [(use (match_operand:MODEF 0 "register_operand" ""))
14174 (use (match_operand:MODEF 1 "general_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);
14186 op1 = gen_reg_rtx (XFmode);
14188 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14189 emit_insn (gen_expm1xf2 (op0, op1));
14190 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14194 (define_expand "ldexpxf3"
14195 [(set (match_dup 3)
14196 (float:XF (match_operand:SI 2 "register_operand" "")))
14197 (parallel [(set (match_operand:XF 0 " register_operand" "")
14198 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14200 UNSPEC_FSCALE_FRACT))
14202 (unspec:XF [(match_dup 1) (match_dup 3)]
14203 UNSPEC_FSCALE_EXP))])]
14204 "TARGET_USE_FANCY_MATH_387
14205 && flag_unsafe_math_optimizations"
14207 if (optimize_insn_for_size_p ())
14210 operands[3] = gen_reg_rtx (XFmode);
14211 operands[4] = gen_reg_rtx (XFmode);
14214 (define_expand "ldexp<mode>3"
14215 [(use (match_operand:MODEF 0 "register_operand" ""))
14216 (use (match_operand:MODEF 1 "general_operand" ""))
14217 (use (match_operand:SI 2 "register_operand" ""))]
14218 "TARGET_USE_FANCY_MATH_387
14219 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14220 || TARGET_MIX_SSE_I387)
14221 && flag_unsafe_math_optimizations"
14225 if (optimize_insn_for_size_p ())
14228 op0 = gen_reg_rtx (XFmode);
14229 op1 = gen_reg_rtx (XFmode);
14231 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14232 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14233 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14237 (define_expand "scalbxf3"
14238 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14239 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14240 (match_operand:XF 2 "register_operand" "")]
14241 UNSPEC_FSCALE_FRACT))
14243 (unspec:XF [(match_dup 1) (match_dup 2)]
14244 UNSPEC_FSCALE_EXP))])]
14245 "TARGET_USE_FANCY_MATH_387
14246 && flag_unsafe_math_optimizations"
14248 if (optimize_insn_for_size_p ())
14251 operands[3] = gen_reg_rtx (XFmode);
14254 (define_expand "scalb<mode>3"
14255 [(use (match_operand:MODEF 0 "register_operand" ""))
14256 (use (match_operand:MODEF 1 "general_operand" ""))
14257 (use (match_operand:MODEF 2 "general_operand" ""))]
14258 "TARGET_USE_FANCY_MATH_387
14259 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14260 || TARGET_MIX_SSE_I387)
14261 && flag_unsafe_math_optimizations"
14265 if (optimize_insn_for_size_p ())
14268 op0 = gen_reg_rtx (XFmode);
14269 op1 = gen_reg_rtx (XFmode);
14270 op2 = gen_reg_rtx (XFmode);
14272 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14273 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14274 emit_insn (gen_scalbxf3 (op0, op1, op2));
14275 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14279 (define_expand "significandxf2"
14280 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14281 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14282 UNSPEC_XTRACT_FRACT))
14284 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14285 "TARGET_USE_FANCY_MATH_387
14286 && flag_unsafe_math_optimizations"
14288 operands[2] = gen_reg_rtx (XFmode);
14291 (define_expand "significand<mode>2"
14292 [(use (match_operand:MODEF 0 "register_operand" ""))
14293 (use (match_operand:MODEF 1 "register_operand" ""))]
14294 "TARGET_USE_FANCY_MATH_387
14295 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14296 || TARGET_MIX_SSE_I387)
14297 && flag_unsafe_math_optimizations"
14299 rtx op0 = gen_reg_rtx (XFmode);
14300 rtx op1 = gen_reg_rtx (XFmode);
14302 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14303 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14308 (define_insn "sse4_1_round<mode>2"
14309 [(set (match_operand:MODEF 0 "register_operand" "=x")
14310 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14311 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14314 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14315 [(set_attr "type" "ssecvt")
14316 (set_attr "prefix_extra" "1")
14317 (set_attr "prefix" "maybe_vex")
14318 (set_attr "mode" "<MODE>")])
14320 (define_insn "rintxf2"
14321 [(set (match_operand:XF 0 "register_operand" "=f")
14322 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14324 "TARGET_USE_FANCY_MATH_387
14325 && flag_unsafe_math_optimizations"
14327 [(set_attr "type" "fpspc")
14328 (set_attr "mode" "XF")])
14330 (define_expand "rint<mode>2"
14331 [(use (match_operand:MODEF 0 "register_operand" ""))
14332 (use (match_operand:MODEF 1 "register_operand" ""))]
14333 "(TARGET_USE_FANCY_MATH_387
14334 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14335 || TARGET_MIX_SSE_I387)
14336 && flag_unsafe_math_optimizations)
14337 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14338 && !flag_trapping_math)"
14340 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14341 && !flag_trapping_math)
14343 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14346 emit_insn (gen_sse4_1_round<mode>2
14347 (operands[0], operands[1], GEN_INT (0x04)));
14349 ix86_expand_rint (operand0, operand1);
14353 rtx op0 = gen_reg_rtx (XFmode);
14354 rtx op1 = gen_reg_rtx (XFmode);
14356 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14357 emit_insn (gen_rintxf2 (op0, op1));
14359 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14364 (define_expand "round<mode>2"
14365 [(match_operand:MODEF 0 "register_operand" "")
14366 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14367 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14368 && !flag_trapping_math && !flag_rounding_math"
14370 if (optimize_insn_for_size_p ())
14372 if (TARGET_64BIT || (<MODE>mode != DFmode))
14373 ix86_expand_round (operand0, operand1);
14375 ix86_expand_rounddf_32 (operand0, operand1);
14379 (define_insn_and_split "*fistdi2_1"
14380 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14381 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14383 "TARGET_USE_FANCY_MATH_387
14384 && can_create_pseudo_p ()"
14389 if (memory_operand (operands[0], VOIDmode))
14390 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14393 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14394 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14399 [(set_attr "type" "fpspc")
14400 (set_attr "mode" "DI")])
14402 (define_insn "fistdi2"
14403 [(set (match_operand:DI 0 "memory_operand" "=m")
14404 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14406 (clobber (match_scratch:XF 2 "=&1f"))]
14407 "TARGET_USE_FANCY_MATH_387"
14408 "* return output_fix_trunc (insn, operands, 0);"
14409 [(set_attr "type" "fpspc")
14410 (set_attr "mode" "DI")])
14412 (define_insn "fistdi2_with_temp"
14413 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14414 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14416 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14417 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14418 "TARGET_USE_FANCY_MATH_387"
14420 [(set_attr "type" "fpspc")
14421 (set_attr "mode" "DI")])
14424 [(set (match_operand:DI 0 "register_operand" "")
14425 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14427 (clobber (match_operand:DI 2 "memory_operand" ""))
14428 (clobber (match_scratch 3 ""))]
14430 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14431 (clobber (match_dup 3))])
14432 (set (match_dup 0) (match_dup 2))]
14436 [(set (match_operand:DI 0 "memory_operand" "")
14437 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14439 (clobber (match_operand:DI 2 "memory_operand" ""))
14440 (clobber (match_scratch 3 ""))]
14442 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14443 (clobber (match_dup 3))])]
14446 (define_insn_and_split "*fist<mode>2_1"
14447 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14448 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14450 "TARGET_USE_FANCY_MATH_387
14451 && can_create_pseudo_p ()"
14456 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14457 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14461 [(set_attr "type" "fpspc")
14462 (set_attr "mode" "<MODE>")])
14464 (define_insn "fist<mode>2"
14465 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14466 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14468 "TARGET_USE_FANCY_MATH_387"
14469 "* return output_fix_trunc (insn, operands, 0);"
14470 [(set_attr "type" "fpspc")
14471 (set_attr "mode" "<MODE>")])
14473 (define_insn "fist<mode>2_with_temp"
14474 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14475 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14477 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14478 "TARGET_USE_FANCY_MATH_387"
14480 [(set_attr "type" "fpspc")
14481 (set_attr "mode" "<MODE>")])
14484 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14485 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14487 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14489 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14490 (set (match_dup 0) (match_dup 2))]
14494 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14495 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14497 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14499 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14502 (define_expand "lrintxf<mode>2"
14503 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14504 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14506 "TARGET_USE_FANCY_MATH_387"
14509 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14510 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14511 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14512 UNSPEC_FIX_NOTRUNC))]
14513 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14514 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14517 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14518 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14519 (match_operand:MODEF 1 "register_operand" "")]
14520 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14521 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14522 && !flag_trapping_math && !flag_rounding_math"
14524 if (optimize_insn_for_size_p ())
14526 ix86_expand_lround (operand0, operand1);
14530 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14531 (define_insn_and_split "frndintxf2_floor"
14532 [(set (match_operand:XF 0 "register_operand" "")
14533 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14534 UNSPEC_FRNDINT_FLOOR))
14535 (clobber (reg:CC FLAGS_REG))]
14536 "TARGET_USE_FANCY_MATH_387
14537 && flag_unsafe_math_optimizations
14538 && can_create_pseudo_p ()"
14543 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14545 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14546 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14548 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14549 operands[2], operands[3]));
14552 [(set_attr "type" "frndint")
14553 (set_attr "i387_cw" "floor")
14554 (set_attr "mode" "XF")])
14556 (define_insn "frndintxf2_floor_i387"
14557 [(set (match_operand:XF 0 "register_operand" "=f")
14558 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14559 UNSPEC_FRNDINT_FLOOR))
14560 (use (match_operand:HI 2 "memory_operand" "m"))
14561 (use (match_operand:HI 3 "memory_operand" "m"))]
14562 "TARGET_USE_FANCY_MATH_387
14563 && flag_unsafe_math_optimizations"
14564 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14565 [(set_attr "type" "frndint")
14566 (set_attr "i387_cw" "floor")
14567 (set_attr "mode" "XF")])
14569 (define_expand "floorxf2"
14570 [(use (match_operand:XF 0 "register_operand" ""))
14571 (use (match_operand:XF 1 "register_operand" ""))]
14572 "TARGET_USE_FANCY_MATH_387
14573 && flag_unsafe_math_optimizations"
14575 if (optimize_insn_for_size_p ())
14577 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14581 (define_expand "floor<mode>2"
14582 [(use (match_operand:MODEF 0 "register_operand" ""))
14583 (use (match_operand:MODEF 1 "register_operand" ""))]
14584 "(TARGET_USE_FANCY_MATH_387
14585 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14586 || TARGET_MIX_SSE_I387)
14587 && flag_unsafe_math_optimizations)
14588 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14589 && !flag_trapping_math)"
14591 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14592 && !flag_trapping_math
14593 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14595 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14598 emit_insn (gen_sse4_1_round<mode>2
14599 (operands[0], operands[1], GEN_INT (0x01)));
14600 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14601 ix86_expand_floorceil (operand0, operand1, true);
14603 ix86_expand_floorceildf_32 (operand0, operand1, true);
14609 if (optimize_insn_for_size_p ())
14612 op0 = gen_reg_rtx (XFmode);
14613 op1 = gen_reg_rtx (XFmode);
14614 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14615 emit_insn (gen_frndintxf2_floor (op0, op1));
14617 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14622 (define_insn_and_split "*fist<mode>2_floor_1"
14623 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14624 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14625 UNSPEC_FIST_FLOOR))
14626 (clobber (reg:CC FLAGS_REG))]
14627 "TARGET_USE_FANCY_MATH_387
14628 && flag_unsafe_math_optimizations
14629 && can_create_pseudo_p ()"
14634 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14636 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14637 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14638 if (memory_operand (operands[0], VOIDmode))
14639 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14640 operands[2], operands[3]));
14643 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14644 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14645 operands[2], operands[3],
14650 [(set_attr "type" "fistp")
14651 (set_attr "i387_cw" "floor")
14652 (set_attr "mode" "<MODE>")])
14654 (define_insn "fistdi2_floor"
14655 [(set (match_operand:DI 0 "memory_operand" "=m")
14656 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14657 UNSPEC_FIST_FLOOR))
14658 (use (match_operand:HI 2 "memory_operand" "m"))
14659 (use (match_operand:HI 3 "memory_operand" "m"))
14660 (clobber (match_scratch:XF 4 "=&1f"))]
14661 "TARGET_USE_FANCY_MATH_387
14662 && flag_unsafe_math_optimizations"
14663 "* return output_fix_trunc (insn, operands, 0);"
14664 [(set_attr "type" "fistp")
14665 (set_attr "i387_cw" "floor")
14666 (set_attr "mode" "DI")])
14668 (define_insn "fistdi2_floor_with_temp"
14669 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14670 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14671 UNSPEC_FIST_FLOOR))
14672 (use (match_operand:HI 2 "memory_operand" "m,m"))
14673 (use (match_operand:HI 3 "memory_operand" "m,m"))
14674 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14675 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14676 "TARGET_USE_FANCY_MATH_387
14677 && flag_unsafe_math_optimizations"
14679 [(set_attr "type" "fistp")
14680 (set_attr "i387_cw" "floor")
14681 (set_attr "mode" "DI")])
14684 [(set (match_operand:DI 0 "register_operand" "")
14685 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14686 UNSPEC_FIST_FLOOR))
14687 (use (match_operand:HI 2 "memory_operand" ""))
14688 (use (match_operand:HI 3 "memory_operand" ""))
14689 (clobber (match_operand:DI 4 "memory_operand" ""))
14690 (clobber (match_scratch 5 ""))]
14692 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14693 (use (match_dup 2))
14694 (use (match_dup 3))
14695 (clobber (match_dup 5))])
14696 (set (match_dup 0) (match_dup 4))]
14700 [(set (match_operand:DI 0 "memory_operand" "")
14701 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14702 UNSPEC_FIST_FLOOR))
14703 (use (match_operand:HI 2 "memory_operand" ""))
14704 (use (match_operand:HI 3 "memory_operand" ""))
14705 (clobber (match_operand:DI 4 "memory_operand" ""))
14706 (clobber (match_scratch 5 ""))]
14708 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14709 (use (match_dup 2))
14710 (use (match_dup 3))
14711 (clobber (match_dup 5))])]
14714 (define_insn "fist<mode>2_floor"
14715 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14716 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14717 UNSPEC_FIST_FLOOR))
14718 (use (match_operand:HI 2 "memory_operand" "m"))
14719 (use (match_operand:HI 3 "memory_operand" "m"))]
14720 "TARGET_USE_FANCY_MATH_387
14721 && flag_unsafe_math_optimizations"
14722 "* return output_fix_trunc (insn, operands, 0);"
14723 [(set_attr "type" "fistp")
14724 (set_attr "i387_cw" "floor")
14725 (set_attr "mode" "<MODE>")])
14727 (define_insn "fist<mode>2_floor_with_temp"
14728 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14729 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14730 UNSPEC_FIST_FLOOR))
14731 (use (match_operand:HI 2 "memory_operand" "m,m"))
14732 (use (match_operand:HI 3 "memory_operand" "m,m"))
14733 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14734 "TARGET_USE_FANCY_MATH_387
14735 && flag_unsafe_math_optimizations"
14737 [(set_attr "type" "fistp")
14738 (set_attr "i387_cw" "floor")
14739 (set_attr "mode" "<MODE>")])
14742 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14743 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14744 UNSPEC_FIST_FLOOR))
14745 (use (match_operand:HI 2 "memory_operand" ""))
14746 (use (match_operand:HI 3 "memory_operand" ""))
14747 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14749 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14750 UNSPEC_FIST_FLOOR))
14751 (use (match_dup 2))
14752 (use (match_dup 3))])
14753 (set (match_dup 0) (match_dup 4))]
14757 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14758 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14759 UNSPEC_FIST_FLOOR))
14760 (use (match_operand:HI 2 "memory_operand" ""))
14761 (use (match_operand:HI 3 "memory_operand" ""))
14762 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14764 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14765 UNSPEC_FIST_FLOOR))
14766 (use (match_dup 2))
14767 (use (match_dup 3))])]
14770 (define_expand "lfloorxf<mode>2"
14771 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14772 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14773 UNSPEC_FIST_FLOOR))
14774 (clobber (reg:CC FLAGS_REG))])]
14775 "TARGET_USE_FANCY_MATH_387
14776 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14777 && flag_unsafe_math_optimizations"
14780 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14781 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14782 (match_operand:MODEF 1 "register_operand" "")]
14783 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14784 && !flag_trapping_math"
14786 if (TARGET_64BIT && optimize_insn_for_size_p ())
14788 ix86_expand_lfloorceil (operand0, operand1, true);
14792 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14793 (define_insn_and_split "frndintxf2_ceil"
14794 [(set (match_operand:XF 0 "register_operand" "")
14795 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14796 UNSPEC_FRNDINT_CEIL))
14797 (clobber (reg:CC FLAGS_REG))]
14798 "TARGET_USE_FANCY_MATH_387
14799 && flag_unsafe_math_optimizations
14800 && can_create_pseudo_p ()"
14805 ix86_optimize_mode_switching[I387_CEIL] = 1;
14807 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14808 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14810 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14811 operands[2], operands[3]));
14814 [(set_attr "type" "frndint")
14815 (set_attr "i387_cw" "ceil")
14816 (set_attr "mode" "XF")])
14818 (define_insn "frndintxf2_ceil_i387"
14819 [(set (match_operand:XF 0 "register_operand" "=f")
14820 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14821 UNSPEC_FRNDINT_CEIL))
14822 (use (match_operand:HI 2 "memory_operand" "m"))
14823 (use (match_operand:HI 3 "memory_operand" "m"))]
14824 "TARGET_USE_FANCY_MATH_387
14825 && flag_unsafe_math_optimizations"
14826 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14827 [(set_attr "type" "frndint")
14828 (set_attr "i387_cw" "ceil")
14829 (set_attr "mode" "XF")])
14831 (define_expand "ceilxf2"
14832 [(use (match_operand:XF 0 "register_operand" ""))
14833 (use (match_operand:XF 1 "register_operand" ""))]
14834 "TARGET_USE_FANCY_MATH_387
14835 && flag_unsafe_math_optimizations"
14837 if (optimize_insn_for_size_p ())
14839 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14843 (define_expand "ceil<mode>2"
14844 [(use (match_operand:MODEF 0 "register_operand" ""))
14845 (use (match_operand:MODEF 1 "register_operand" ""))]
14846 "(TARGET_USE_FANCY_MATH_387
14847 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14848 || TARGET_MIX_SSE_I387)
14849 && flag_unsafe_math_optimizations)
14850 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14851 && !flag_trapping_math)"
14853 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14854 && !flag_trapping_math
14855 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14858 emit_insn (gen_sse4_1_round<mode>2
14859 (operands[0], operands[1], GEN_INT (0x02)));
14860 else if (optimize_insn_for_size_p ())
14862 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14863 ix86_expand_floorceil (operand0, operand1, false);
14865 ix86_expand_floorceildf_32 (operand0, operand1, false);
14871 if (optimize_insn_for_size_p ())
14874 op0 = gen_reg_rtx (XFmode);
14875 op1 = gen_reg_rtx (XFmode);
14876 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14877 emit_insn (gen_frndintxf2_ceil (op0, op1));
14879 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14884 (define_insn_and_split "*fist<mode>2_ceil_1"
14885 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14886 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14888 (clobber (reg:CC FLAGS_REG))]
14889 "TARGET_USE_FANCY_MATH_387
14890 && flag_unsafe_math_optimizations
14891 && can_create_pseudo_p ()"
14896 ix86_optimize_mode_switching[I387_CEIL] = 1;
14898 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14899 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14900 if (memory_operand (operands[0], VOIDmode))
14901 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14902 operands[2], operands[3]));
14905 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14906 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14907 operands[2], operands[3],
14912 [(set_attr "type" "fistp")
14913 (set_attr "i387_cw" "ceil")
14914 (set_attr "mode" "<MODE>")])
14916 (define_insn "fistdi2_ceil"
14917 [(set (match_operand:DI 0 "memory_operand" "=m")
14918 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14920 (use (match_operand:HI 2 "memory_operand" "m"))
14921 (use (match_operand:HI 3 "memory_operand" "m"))
14922 (clobber (match_scratch:XF 4 "=&1f"))]
14923 "TARGET_USE_FANCY_MATH_387
14924 && flag_unsafe_math_optimizations"
14925 "* return output_fix_trunc (insn, operands, 0);"
14926 [(set_attr "type" "fistp")
14927 (set_attr "i387_cw" "ceil")
14928 (set_attr "mode" "DI")])
14930 (define_insn "fistdi2_ceil_with_temp"
14931 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14932 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14934 (use (match_operand:HI 2 "memory_operand" "m,m"))
14935 (use (match_operand:HI 3 "memory_operand" "m,m"))
14936 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14937 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14938 "TARGET_USE_FANCY_MATH_387
14939 && flag_unsafe_math_optimizations"
14941 [(set_attr "type" "fistp")
14942 (set_attr "i387_cw" "ceil")
14943 (set_attr "mode" "DI")])
14946 [(set (match_operand:DI 0 "register_operand" "")
14947 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14949 (use (match_operand:HI 2 "memory_operand" ""))
14950 (use (match_operand:HI 3 "memory_operand" ""))
14951 (clobber (match_operand:DI 4 "memory_operand" ""))
14952 (clobber (match_scratch 5 ""))]
14954 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14955 (use (match_dup 2))
14956 (use (match_dup 3))
14957 (clobber (match_dup 5))])
14958 (set (match_dup 0) (match_dup 4))]
14962 [(set (match_operand:DI 0 "memory_operand" "")
14963 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14965 (use (match_operand:HI 2 "memory_operand" ""))
14966 (use (match_operand:HI 3 "memory_operand" ""))
14967 (clobber (match_operand:DI 4 "memory_operand" ""))
14968 (clobber (match_scratch 5 ""))]
14970 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14971 (use (match_dup 2))
14972 (use (match_dup 3))
14973 (clobber (match_dup 5))])]
14976 (define_insn "fist<mode>2_ceil"
14977 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14978 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14980 (use (match_operand:HI 2 "memory_operand" "m"))
14981 (use (match_operand:HI 3 "memory_operand" "m"))]
14982 "TARGET_USE_FANCY_MATH_387
14983 && flag_unsafe_math_optimizations"
14984 "* return output_fix_trunc (insn, operands, 0);"
14985 [(set_attr "type" "fistp")
14986 (set_attr "i387_cw" "ceil")
14987 (set_attr "mode" "<MODE>")])
14989 (define_insn "fist<mode>2_ceil_with_temp"
14990 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14991 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14993 (use (match_operand:HI 2 "memory_operand" "m,m"))
14994 (use (match_operand:HI 3 "memory_operand" "m,m"))
14995 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14996 "TARGET_USE_FANCY_MATH_387
14997 && flag_unsafe_math_optimizations"
14999 [(set_attr "type" "fistp")
15000 (set_attr "i387_cw" "ceil")
15001 (set_attr "mode" "<MODE>")])
15004 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15005 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15007 (use (match_operand:HI 2 "memory_operand" ""))
15008 (use (match_operand:HI 3 "memory_operand" ""))
15009 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15011 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15013 (use (match_dup 2))
15014 (use (match_dup 3))])
15015 (set (match_dup 0) (match_dup 4))]
15019 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15020 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15022 (use (match_operand:HI 2 "memory_operand" ""))
15023 (use (match_operand:HI 3 "memory_operand" ""))
15024 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15026 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15028 (use (match_dup 2))
15029 (use (match_dup 3))])]
15032 (define_expand "lceilxf<mode>2"
15033 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15034 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15036 (clobber (reg:CC FLAGS_REG))])]
15037 "TARGET_USE_FANCY_MATH_387
15038 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15039 && flag_unsafe_math_optimizations"
15042 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15043 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15044 (match_operand:MODEF 1 "register_operand" "")]
15045 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15046 && !flag_trapping_math"
15048 ix86_expand_lfloorceil (operand0, operand1, false);
15052 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15053 (define_insn_and_split "frndintxf2_trunc"
15054 [(set (match_operand:XF 0 "register_operand" "")
15055 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15056 UNSPEC_FRNDINT_TRUNC))
15057 (clobber (reg:CC FLAGS_REG))]
15058 "TARGET_USE_FANCY_MATH_387
15059 && flag_unsafe_math_optimizations
15060 && can_create_pseudo_p ()"
15065 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15067 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15068 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15070 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15071 operands[2], operands[3]));
15074 [(set_attr "type" "frndint")
15075 (set_attr "i387_cw" "trunc")
15076 (set_attr "mode" "XF")])
15078 (define_insn "frndintxf2_trunc_i387"
15079 [(set (match_operand:XF 0 "register_operand" "=f")
15080 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15081 UNSPEC_FRNDINT_TRUNC))
15082 (use (match_operand:HI 2 "memory_operand" "m"))
15083 (use (match_operand:HI 3 "memory_operand" "m"))]
15084 "TARGET_USE_FANCY_MATH_387
15085 && flag_unsafe_math_optimizations"
15086 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15087 [(set_attr "type" "frndint")
15088 (set_attr "i387_cw" "trunc")
15089 (set_attr "mode" "XF")])
15091 (define_expand "btruncxf2"
15092 [(use (match_operand:XF 0 "register_operand" ""))
15093 (use (match_operand:XF 1 "register_operand" ""))]
15094 "TARGET_USE_FANCY_MATH_387
15095 && flag_unsafe_math_optimizations"
15097 if (optimize_insn_for_size_p ())
15099 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15103 (define_expand "btrunc<mode>2"
15104 [(use (match_operand:MODEF 0 "register_operand" ""))
15105 (use (match_operand:MODEF 1 "register_operand" ""))]
15106 "(TARGET_USE_FANCY_MATH_387
15107 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15108 || TARGET_MIX_SSE_I387)
15109 && flag_unsafe_math_optimizations)
15110 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15111 && !flag_trapping_math)"
15113 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15114 && !flag_trapping_math
15115 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15118 emit_insn (gen_sse4_1_round<mode>2
15119 (operands[0], operands[1], GEN_INT (0x03)));
15120 else if (optimize_insn_for_size_p ())
15122 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15123 ix86_expand_trunc (operand0, operand1);
15125 ix86_expand_truncdf_32 (operand0, operand1);
15131 if (optimize_insn_for_size_p ())
15134 op0 = gen_reg_rtx (XFmode);
15135 op1 = gen_reg_rtx (XFmode);
15136 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15137 emit_insn (gen_frndintxf2_trunc (op0, op1));
15139 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15144 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15145 (define_insn_and_split "frndintxf2_mask_pm"
15146 [(set (match_operand:XF 0 "register_operand" "")
15147 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15148 UNSPEC_FRNDINT_MASK_PM))
15149 (clobber (reg:CC FLAGS_REG))]
15150 "TARGET_USE_FANCY_MATH_387
15151 && flag_unsafe_math_optimizations
15152 && can_create_pseudo_p ()"
15157 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15159 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15160 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15162 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15163 operands[2], operands[3]));
15166 [(set_attr "type" "frndint")
15167 (set_attr "i387_cw" "mask_pm")
15168 (set_attr "mode" "XF")])
15170 (define_insn "frndintxf2_mask_pm_i387"
15171 [(set (match_operand:XF 0 "register_operand" "=f")
15172 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15173 UNSPEC_FRNDINT_MASK_PM))
15174 (use (match_operand:HI 2 "memory_operand" "m"))
15175 (use (match_operand:HI 3 "memory_operand" "m"))]
15176 "TARGET_USE_FANCY_MATH_387
15177 && flag_unsafe_math_optimizations"
15178 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15179 [(set_attr "type" "frndint")
15180 (set_attr "i387_cw" "mask_pm")
15181 (set_attr "mode" "XF")])
15183 (define_expand "nearbyintxf2"
15184 [(use (match_operand:XF 0 "register_operand" ""))
15185 (use (match_operand:XF 1 "register_operand" ""))]
15186 "TARGET_USE_FANCY_MATH_387
15187 && flag_unsafe_math_optimizations"
15189 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15194 (define_expand "nearbyint<mode>2"
15195 [(use (match_operand:MODEF 0 "register_operand" ""))
15196 (use (match_operand:MODEF 1 "register_operand" ""))]
15197 "TARGET_USE_FANCY_MATH_387
15198 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15199 || TARGET_MIX_SSE_I387)
15200 && flag_unsafe_math_optimizations"
15202 rtx op0 = gen_reg_rtx (XFmode);
15203 rtx op1 = gen_reg_rtx (XFmode);
15205 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15206 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15208 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15212 (define_insn "fxam<mode>2_i387"
15213 [(set (match_operand:HI 0 "register_operand" "=a")
15215 [(match_operand:X87MODEF 1 "register_operand" "f")]
15217 "TARGET_USE_FANCY_MATH_387"
15218 "fxam\n\tfnstsw\t%0"
15219 [(set_attr "type" "multi")
15220 (set_attr "length" "4")
15221 (set_attr "unit" "i387")
15222 (set_attr "mode" "<MODE>")])
15224 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15225 [(set (match_operand:HI 0 "register_operand" "")
15227 [(match_operand:MODEF 1 "memory_operand" "")]
15229 "TARGET_USE_FANCY_MATH_387
15230 && can_create_pseudo_p ()"
15233 [(set (match_dup 2)(match_dup 1))
15235 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15237 operands[2] = gen_reg_rtx (<MODE>mode);
15239 MEM_VOLATILE_P (operands[1]) = 1;
15241 [(set_attr "type" "multi")
15242 (set_attr "unit" "i387")
15243 (set_attr "mode" "<MODE>")])
15245 (define_expand "isinfxf2"
15246 [(use (match_operand:SI 0 "register_operand" ""))
15247 (use (match_operand:XF 1 "register_operand" ""))]
15248 "TARGET_USE_FANCY_MATH_387
15249 && TARGET_C99_FUNCTIONS"
15251 rtx mask = GEN_INT (0x45);
15252 rtx val = GEN_INT (0x05);
15256 rtx scratch = gen_reg_rtx (HImode);
15257 rtx res = gen_reg_rtx (QImode);
15259 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15261 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15262 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15263 cond = gen_rtx_fmt_ee (EQ, QImode,
15264 gen_rtx_REG (CCmode, FLAGS_REG),
15266 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15267 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15271 (define_expand "isinf<mode>2"
15272 [(use (match_operand:SI 0 "register_operand" ""))
15273 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15274 "TARGET_USE_FANCY_MATH_387
15275 && TARGET_C99_FUNCTIONS
15276 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15278 rtx mask = GEN_INT (0x45);
15279 rtx val = GEN_INT (0x05);
15283 rtx scratch = gen_reg_rtx (HImode);
15284 rtx res = gen_reg_rtx (QImode);
15286 /* Remove excess precision by forcing value through memory. */
15287 if (memory_operand (operands[1], VOIDmode))
15288 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15291 enum ix86_stack_slot slot = (virtuals_instantiated
15294 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15296 emit_move_insn (temp, operands[1]);
15297 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15300 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15301 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15302 cond = gen_rtx_fmt_ee (EQ, QImode,
15303 gen_rtx_REG (CCmode, FLAGS_REG),
15305 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15306 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15310 (define_expand "signbit<mode>2"
15311 [(use (match_operand:SI 0 "register_operand" ""))
15312 (use (match_operand:X87MODEF 1 "register_operand" ""))]
15313 "TARGET_USE_FANCY_MATH_387
15314 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15316 rtx mask = GEN_INT (0x0200);
15318 rtx scratch = gen_reg_rtx (HImode);
15320 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15321 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15325 ;; Block operation instructions
15328 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15331 [(set_attr "length" "1")
15332 (set_attr "length_immediate" "0")
15333 (set_attr "modrm" "0")])
15335 (define_expand "movmemsi"
15336 [(use (match_operand:BLK 0 "memory_operand" ""))
15337 (use (match_operand:BLK 1 "memory_operand" ""))
15338 (use (match_operand:SI 2 "nonmemory_operand" ""))
15339 (use (match_operand:SI 3 "const_int_operand" ""))
15340 (use (match_operand:SI 4 "const_int_operand" ""))
15341 (use (match_operand:SI 5 "const_int_operand" ""))]
15344 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15345 operands[4], operands[5]))
15351 (define_expand "movmemdi"
15352 [(use (match_operand:BLK 0 "memory_operand" ""))
15353 (use (match_operand:BLK 1 "memory_operand" ""))
15354 (use (match_operand:DI 2 "nonmemory_operand" ""))
15355 (use (match_operand:DI 3 "const_int_operand" ""))
15356 (use (match_operand:SI 4 "const_int_operand" ""))
15357 (use (match_operand:SI 5 "const_int_operand" ""))]
15360 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15361 operands[4], operands[5]))
15367 ;; Most CPUs don't like single string operations
15368 ;; Handle this case here to simplify previous expander.
15370 (define_expand "strmov"
15371 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15372 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15373 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15374 (clobber (reg:CC FLAGS_REG))])
15375 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15376 (clobber (reg:CC FLAGS_REG))])]
15379 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15381 /* If .md ever supports :P for Pmode, these can be directly
15382 in the pattern above. */
15383 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15384 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15386 /* Can't use this if the user has appropriated esi or edi. */
15387 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15388 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15390 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15391 operands[2], operands[3],
15392 operands[5], operands[6]));
15396 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15399 (define_expand "strmov_singleop"
15400 [(parallel [(set (match_operand 1 "memory_operand" "")
15401 (match_operand 3 "memory_operand" ""))
15402 (set (match_operand 0 "register_operand" "")
15403 (match_operand 4 "" ""))
15404 (set (match_operand 2 "register_operand" "")
15405 (match_operand 5 "" ""))])]
15407 "ix86_current_function_needs_cld = 1;")
15409 (define_insn "*strmovdi_rex_1"
15410 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15411 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15412 (set (match_operand:DI 0 "register_operand" "=D")
15413 (plus:DI (match_dup 2)
15415 (set (match_operand:DI 1 "register_operand" "=S")
15416 (plus:DI (match_dup 3)
15420 [(set_attr "type" "str")
15421 (set_attr "mode" "DI")
15422 (set_attr "memory" "both")])
15424 (define_insn "*strmovsi_1"
15425 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15426 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15427 (set (match_operand:SI 0 "register_operand" "=D")
15428 (plus:SI (match_dup 2)
15430 (set (match_operand:SI 1 "register_operand" "=S")
15431 (plus:SI (match_dup 3)
15435 [(set_attr "type" "str")
15436 (set_attr "mode" "SI")
15437 (set_attr "memory" "both")])
15439 (define_insn "*strmovsi_rex_1"
15440 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15441 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15442 (set (match_operand:DI 0 "register_operand" "=D")
15443 (plus:DI (match_dup 2)
15445 (set (match_operand:DI 1 "register_operand" "=S")
15446 (plus:DI (match_dup 3)
15450 [(set_attr "type" "str")
15451 (set_attr "mode" "SI")
15452 (set_attr "memory" "both")])
15454 (define_insn "*strmovhi_1"
15455 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15456 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15457 (set (match_operand:SI 0 "register_operand" "=D")
15458 (plus:SI (match_dup 2)
15460 (set (match_operand:SI 1 "register_operand" "=S")
15461 (plus:SI (match_dup 3)
15465 [(set_attr "type" "str")
15466 (set_attr "memory" "both")
15467 (set_attr "mode" "HI")])
15469 (define_insn "*strmovhi_rex_1"
15470 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15471 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15472 (set (match_operand:DI 0 "register_operand" "=D")
15473 (plus:DI (match_dup 2)
15475 (set (match_operand:DI 1 "register_operand" "=S")
15476 (plus:DI (match_dup 3)
15480 [(set_attr "type" "str")
15481 (set_attr "memory" "both")
15482 (set_attr "mode" "HI")])
15484 (define_insn "*strmovqi_1"
15485 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15486 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15487 (set (match_operand:SI 0 "register_operand" "=D")
15488 (plus:SI (match_dup 2)
15490 (set (match_operand:SI 1 "register_operand" "=S")
15491 (plus:SI (match_dup 3)
15495 [(set_attr "type" "str")
15496 (set_attr "memory" "both")
15497 (set_attr "mode" "QI")])
15499 (define_insn "*strmovqi_rex_1"
15500 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15501 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15502 (set (match_operand:DI 0 "register_operand" "=D")
15503 (plus:DI (match_dup 2)
15505 (set (match_operand:DI 1 "register_operand" "=S")
15506 (plus:DI (match_dup 3)
15510 [(set_attr "type" "str")
15511 (set_attr "memory" "both")
15512 (set_attr "prefix_rex" "0")
15513 (set_attr "mode" "QI")])
15515 (define_expand "rep_mov"
15516 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15517 (set (match_operand 0 "register_operand" "")
15518 (match_operand 5 "" ""))
15519 (set (match_operand 2 "register_operand" "")
15520 (match_operand 6 "" ""))
15521 (set (match_operand 1 "memory_operand" "")
15522 (match_operand 3 "memory_operand" ""))
15523 (use (match_dup 4))])]
15525 "ix86_current_function_needs_cld = 1;")
15527 (define_insn "*rep_movdi_rex64"
15528 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15529 (set (match_operand:DI 0 "register_operand" "=D")
15530 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15532 (match_operand:DI 3 "register_operand" "0")))
15533 (set (match_operand:DI 1 "register_operand" "=S")
15534 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15535 (match_operand:DI 4 "register_operand" "1")))
15536 (set (mem:BLK (match_dup 3))
15537 (mem:BLK (match_dup 4)))
15538 (use (match_dup 5))]
15541 [(set_attr "type" "str")
15542 (set_attr "prefix_rep" "1")
15543 (set_attr "memory" "both")
15544 (set_attr "mode" "DI")])
15546 (define_insn "*rep_movsi"
15547 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15548 (set (match_operand:SI 0 "register_operand" "=D")
15549 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15551 (match_operand:SI 3 "register_operand" "0")))
15552 (set (match_operand:SI 1 "register_operand" "=S")
15553 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15554 (match_operand:SI 4 "register_operand" "1")))
15555 (set (mem:BLK (match_dup 3))
15556 (mem:BLK (match_dup 4)))
15557 (use (match_dup 5))]
15559 "rep{%;} movs{l|d}"
15560 [(set_attr "type" "str")
15561 (set_attr "prefix_rep" "1")
15562 (set_attr "memory" "both")
15563 (set_attr "mode" "SI")])
15565 (define_insn "*rep_movsi_rex64"
15566 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15567 (set (match_operand:DI 0 "register_operand" "=D")
15568 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15570 (match_operand:DI 3 "register_operand" "0")))
15571 (set (match_operand:DI 1 "register_operand" "=S")
15572 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15573 (match_operand:DI 4 "register_operand" "1")))
15574 (set (mem:BLK (match_dup 3))
15575 (mem:BLK (match_dup 4)))
15576 (use (match_dup 5))]
15578 "rep{%;} movs{l|d}"
15579 [(set_attr "type" "str")
15580 (set_attr "prefix_rep" "1")
15581 (set_attr "memory" "both")
15582 (set_attr "mode" "SI")])
15584 (define_insn "*rep_movqi"
15585 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15586 (set (match_operand:SI 0 "register_operand" "=D")
15587 (plus:SI (match_operand:SI 3 "register_operand" "0")
15588 (match_operand:SI 5 "register_operand" "2")))
15589 (set (match_operand:SI 1 "register_operand" "=S")
15590 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15591 (set (mem:BLK (match_dup 3))
15592 (mem:BLK (match_dup 4)))
15593 (use (match_dup 5))]
15596 [(set_attr "type" "str")
15597 (set_attr "prefix_rep" "1")
15598 (set_attr "memory" "both")
15599 (set_attr "mode" "SI")])
15601 (define_insn "*rep_movqi_rex64"
15602 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15603 (set (match_operand:DI 0 "register_operand" "=D")
15604 (plus:DI (match_operand:DI 3 "register_operand" "0")
15605 (match_operand:DI 5 "register_operand" "2")))
15606 (set (match_operand:DI 1 "register_operand" "=S")
15607 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15608 (set (mem:BLK (match_dup 3))
15609 (mem:BLK (match_dup 4)))
15610 (use (match_dup 5))]
15613 [(set_attr "type" "str")
15614 (set_attr "prefix_rep" "1")
15615 (set_attr "memory" "both")
15616 (set_attr "mode" "SI")])
15618 (define_expand "setmemsi"
15619 [(use (match_operand:BLK 0 "memory_operand" ""))
15620 (use (match_operand:SI 1 "nonmemory_operand" ""))
15621 (use (match_operand 2 "const_int_operand" ""))
15622 (use (match_operand 3 "const_int_operand" ""))
15623 (use (match_operand:SI 4 "const_int_operand" ""))
15624 (use (match_operand:SI 5 "const_int_operand" ""))]
15627 if (ix86_expand_setmem (operands[0], operands[1],
15628 operands[2], operands[3],
15629 operands[4], operands[5]))
15635 (define_expand "setmemdi"
15636 [(use (match_operand:BLK 0 "memory_operand" ""))
15637 (use (match_operand:DI 1 "nonmemory_operand" ""))
15638 (use (match_operand 2 "const_int_operand" ""))
15639 (use (match_operand 3 "const_int_operand" ""))
15640 (use (match_operand 4 "const_int_operand" ""))
15641 (use (match_operand 5 "const_int_operand" ""))]
15644 if (ix86_expand_setmem (operands[0], operands[1],
15645 operands[2], operands[3],
15646 operands[4], operands[5]))
15652 ;; Most CPUs don't like single string operations
15653 ;; Handle this case here to simplify previous expander.
15655 (define_expand "strset"
15656 [(set (match_operand 1 "memory_operand" "")
15657 (match_operand 2 "register_operand" ""))
15658 (parallel [(set (match_operand 0 "register_operand" "")
15660 (clobber (reg:CC FLAGS_REG))])]
15663 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15664 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15666 /* If .md ever supports :P for Pmode, this can be directly
15667 in the pattern above. */
15668 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15669 GEN_INT (GET_MODE_SIZE (GET_MODE
15671 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15673 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15679 (define_expand "strset_singleop"
15680 [(parallel [(set (match_operand 1 "memory_operand" "")
15681 (match_operand 2 "register_operand" ""))
15682 (set (match_operand 0 "register_operand" "")
15683 (match_operand 3 "" ""))])]
15685 "ix86_current_function_needs_cld = 1;")
15687 (define_insn "*strsetdi_rex_1"
15688 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15689 (match_operand:DI 2 "register_operand" "a"))
15690 (set (match_operand:DI 0 "register_operand" "=D")
15691 (plus:DI (match_dup 1)
15695 [(set_attr "type" "str")
15696 (set_attr "memory" "store")
15697 (set_attr "mode" "DI")])
15699 (define_insn "*strsetsi_1"
15700 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15701 (match_operand:SI 2 "register_operand" "a"))
15702 (set (match_operand:SI 0 "register_operand" "=D")
15703 (plus:SI (match_dup 1)
15707 [(set_attr "type" "str")
15708 (set_attr "memory" "store")
15709 (set_attr "mode" "SI")])
15711 (define_insn "*strsetsi_rex_1"
15712 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15713 (match_operand:SI 2 "register_operand" "a"))
15714 (set (match_operand:DI 0 "register_operand" "=D")
15715 (plus:DI (match_dup 1)
15719 [(set_attr "type" "str")
15720 (set_attr "memory" "store")
15721 (set_attr "mode" "SI")])
15723 (define_insn "*strsethi_1"
15724 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15725 (match_operand:HI 2 "register_operand" "a"))
15726 (set (match_operand:SI 0 "register_operand" "=D")
15727 (plus:SI (match_dup 1)
15731 [(set_attr "type" "str")
15732 (set_attr "memory" "store")
15733 (set_attr "mode" "HI")])
15735 (define_insn "*strsethi_rex_1"
15736 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15737 (match_operand:HI 2 "register_operand" "a"))
15738 (set (match_operand:DI 0 "register_operand" "=D")
15739 (plus:DI (match_dup 1)
15743 [(set_attr "type" "str")
15744 (set_attr "memory" "store")
15745 (set_attr "mode" "HI")])
15747 (define_insn "*strsetqi_1"
15748 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15749 (match_operand:QI 2 "register_operand" "a"))
15750 (set (match_operand:SI 0 "register_operand" "=D")
15751 (plus:SI (match_dup 1)
15755 [(set_attr "type" "str")
15756 (set_attr "memory" "store")
15757 (set_attr "mode" "QI")])
15759 (define_insn "*strsetqi_rex_1"
15760 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15761 (match_operand:QI 2 "register_operand" "a"))
15762 (set (match_operand:DI 0 "register_operand" "=D")
15763 (plus:DI (match_dup 1)
15767 [(set_attr "type" "str")
15768 (set_attr "memory" "store")
15769 (set_attr "prefix_rex" "0")
15770 (set_attr "mode" "QI")])
15772 (define_expand "rep_stos"
15773 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15774 (set (match_operand 0 "register_operand" "")
15775 (match_operand 4 "" ""))
15776 (set (match_operand 2 "memory_operand" "") (const_int 0))
15777 (use (match_operand 3 "register_operand" ""))
15778 (use (match_dup 1))])]
15780 "ix86_current_function_needs_cld = 1;")
15782 (define_insn "*rep_stosdi_rex64"
15783 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15784 (set (match_operand:DI 0 "register_operand" "=D")
15785 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15787 (match_operand:DI 3 "register_operand" "0")))
15788 (set (mem:BLK (match_dup 3))
15790 (use (match_operand:DI 2 "register_operand" "a"))
15791 (use (match_dup 4))]
15794 [(set_attr "type" "str")
15795 (set_attr "prefix_rep" "1")
15796 (set_attr "memory" "store")
15797 (set_attr "mode" "DI")])
15799 (define_insn "*rep_stossi"
15800 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15801 (set (match_operand:SI 0 "register_operand" "=D")
15802 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15804 (match_operand:SI 3 "register_operand" "0")))
15805 (set (mem:BLK (match_dup 3))
15807 (use (match_operand:SI 2 "register_operand" "a"))
15808 (use (match_dup 4))]
15810 "rep{%;} stos{l|d}"
15811 [(set_attr "type" "str")
15812 (set_attr "prefix_rep" "1")
15813 (set_attr "memory" "store")
15814 (set_attr "mode" "SI")])
15816 (define_insn "*rep_stossi_rex64"
15817 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15818 (set (match_operand:DI 0 "register_operand" "=D")
15819 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15821 (match_operand:DI 3 "register_operand" "0")))
15822 (set (mem:BLK (match_dup 3))
15824 (use (match_operand:SI 2 "register_operand" "a"))
15825 (use (match_dup 4))]
15827 "rep{%;} stos{l|d}"
15828 [(set_attr "type" "str")
15829 (set_attr "prefix_rep" "1")
15830 (set_attr "memory" "store")
15831 (set_attr "mode" "SI")])
15833 (define_insn "*rep_stosqi"
15834 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15835 (set (match_operand:SI 0 "register_operand" "=D")
15836 (plus:SI (match_operand:SI 3 "register_operand" "0")
15837 (match_operand:SI 4 "register_operand" "1")))
15838 (set (mem:BLK (match_dup 3))
15840 (use (match_operand:QI 2 "register_operand" "a"))
15841 (use (match_dup 4))]
15844 [(set_attr "type" "str")
15845 (set_attr "prefix_rep" "1")
15846 (set_attr "memory" "store")
15847 (set_attr "mode" "QI")])
15849 (define_insn "*rep_stosqi_rex64"
15850 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15851 (set (match_operand:DI 0 "register_operand" "=D")
15852 (plus:DI (match_operand:DI 3 "register_operand" "0")
15853 (match_operand:DI 4 "register_operand" "1")))
15854 (set (mem:BLK (match_dup 3))
15856 (use (match_operand:QI 2 "register_operand" "a"))
15857 (use (match_dup 4))]
15860 [(set_attr "type" "str")
15861 (set_attr "prefix_rep" "1")
15862 (set_attr "memory" "store")
15863 (set_attr "prefix_rex" "0")
15864 (set_attr "mode" "QI")])
15866 (define_expand "cmpstrnsi"
15867 [(set (match_operand:SI 0 "register_operand" "")
15868 (compare:SI (match_operand:BLK 1 "general_operand" "")
15869 (match_operand:BLK 2 "general_operand" "")))
15870 (use (match_operand 3 "general_operand" ""))
15871 (use (match_operand 4 "immediate_operand" ""))]
15874 rtx addr1, addr2, out, outlow, count, countreg, align;
15876 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15879 /* Can't use this if the user has appropriated esi or edi. */
15880 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15885 out = gen_reg_rtx (SImode);
15887 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15888 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15889 if (addr1 != XEXP (operands[1], 0))
15890 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15891 if (addr2 != XEXP (operands[2], 0))
15892 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15894 count = operands[3];
15895 countreg = ix86_zero_extend_to_Pmode (count);
15897 /* %%% Iff we are testing strict equality, we can use known alignment
15898 to good advantage. This may be possible with combine, particularly
15899 once cc0 is dead. */
15900 align = operands[4];
15902 if (CONST_INT_P (count))
15904 if (INTVAL (count) == 0)
15906 emit_move_insn (operands[0], const0_rtx);
15909 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15910 operands[1], operands[2]));
15914 rtx (*cmp_insn)(rtx, rtx);
15917 cmp_insn = gen_cmpdi_1;
15919 cmp_insn = gen_cmpsi_1;
15920 emit_insn (cmp_insn (countreg, countreg));
15921 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15922 operands[1], operands[2]));
15925 outlow = gen_lowpart (QImode, out);
15926 emit_insn (gen_cmpintqi (outlow));
15927 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15929 if (operands[0] != out)
15930 emit_move_insn (operands[0], out);
15935 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15937 (define_expand "cmpintqi"
15938 [(set (match_dup 1)
15939 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15941 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15942 (parallel [(set (match_operand:QI 0 "register_operand" "")
15943 (minus:QI (match_dup 1)
15945 (clobber (reg:CC FLAGS_REG))])]
15947 "operands[1] = gen_reg_rtx (QImode);
15948 operands[2] = gen_reg_rtx (QImode);")
15950 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15951 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15953 (define_expand "cmpstrnqi_nz_1"
15954 [(parallel [(set (reg:CC FLAGS_REG)
15955 (compare:CC (match_operand 4 "memory_operand" "")
15956 (match_operand 5 "memory_operand" "")))
15957 (use (match_operand 2 "register_operand" ""))
15958 (use (match_operand:SI 3 "immediate_operand" ""))
15959 (clobber (match_operand 0 "register_operand" ""))
15960 (clobber (match_operand 1 "register_operand" ""))
15961 (clobber (match_dup 2))])]
15963 "ix86_current_function_needs_cld = 1;")
15965 (define_insn "*cmpstrnqi_nz_1"
15966 [(set (reg:CC FLAGS_REG)
15967 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15968 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15969 (use (match_operand:SI 6 "register_operand" "2"))
15970 (use (match_operand:SI 3 "immediate_operand" "i"))
15971 (clobber (match_operand:SI 0 "register_operand" "=S"))
15972 (clobber (match_operand:SI 1 "register_operand" "=D"))
15973 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15976 [(set_attr "type" "str")
15977 (set_attr "mode" "QI")
15978 (set_attr "prefix_rep" "1")])
15980 (define_insn "*cmpstrnqi_nz_rex_1"
15981 [(set (reg:CC FLAGS_REG)
15982 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15983 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15984 (use (match_operand:DI 6 "register_operand" "2"))
15985 (use (match_operand:SI 3 "immediate_operand" "i"))
15986 (clobber (match_operand:DI 0 "register_operand" "=S"))
15987 (clobber (match_operand:DI 1 "register_operand" "=D"))
15988 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15991 [(set_attr "type" "str")
15992 (set_attr "mode" "QI")
15993 (set_attr "prefix_rex" "0")
15994 (set_attr "prefix_rep" "1")])
15996 ;; The same, but the count is not known to not be zero.
15998 (define_expand "cmpstrnqi_1"
15999 [(parallel [(set (reg:CC FLAGS_REG)
16000 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16002 (compare:CC (match_operand 4 "memory_operand" "")
16003 (match_operand 5 "memory_operand" ""))
16005 (use (match_operand:SI 3 "immediate_operand" ""))
16006 (use (reg:CC FLAGS_REG))
16007 (clobber (match_operand 0 "register_operand" ""))
16008 (clobber (match_operand 1 "register_operand" ""))
16009 (clobber (match_dup 2))])]
16011 "ix86_current_function_needs_cld = 1;")
16013 (define_insn "*cmpstrnqi_1"
16014 [(set (reg:CC FLAGS_REG)
16015 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16017 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16018 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16020 (use (match_operand:SI 3 "immediate_operand" "i"))
16021 (use (reg:CC FLAGS_REG))
16022 (clobber (match_operand:SI 0 "register_operand" "=S"))
16023 (clobber (match_operand:SI 1 "register_operand" "=D"))
16024 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16027 [(set_attr "type" "str")
16028 (set_attr "mode" "QI")
16029 (set_attr "prefix_rep" "1")])
16031 (define_insn "*cmpstrnqi_rex_1"
16032 [(set (reg:CC FLAGS_REG)
16033 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16035 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16036 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16038 (use (match_operand:SI 3 "immediate_operand" "i"))
16039 (use (reg:CC FLAGS_REG))
16040 (clobber (match_operand:DI 0 "register_operand" "=S"))
16041 (clobber (match_operand:DI 1 "register_operand" "=D"))
16042 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16045 [(set_attr "type" "str")
16046 (set_attr "mode" "QI")
16047 (set_attr "prefix_rex" "0")
16048 (set_attr "prefix_rep" "1")])
16050 (define_expand "strlensi"
16051 [(set (match_operand:SI 0 "register_operand" "")
16052 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16053 (match_operand:QI 2 "immediate_operand" "")
16054 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16057 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16063 (define_expand "strlendi"
16064 [(set (match_operand:DI 0 "register_operand" "")
16065 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16066 (match_operand:QI 2 "immediate_operand" "")
16067 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16070 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16076 (define_expand "strlenqi_1"
16077 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16078 (clobber (match_operand 1 "register_operand" ""))
16079 (clobber (reg:CC FLAGS_REG))])]
16081 "ix86_current_function_needs_cld = 1;")
16083 (define_insn "*strlenqi_1"
16084 [(set (match_operand:SI 0 "register_operand" "=&c")
16085 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16086 (match_operand:QI 2 "register_operand" "a")
16087 (match_operand:SI 3 "immediate_operand" "i")
16088 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16089 (clobber (match_operand:SI 1 "register_operand" "=D"))
16090 (clobber (reg:CC FLAGS_REG))]
16093 [(set_attr "type" "str")
16094 (set_attr "mode" "QI")
16095 (set_attr "prefix_rep" "1")])
16097 (define_insn "*strlenqi_rex_1"
16098 [(set (match_operand:DI 0 "register_operand" "=&c")
16099 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16100 (match_operand:QI 2 "register_operand" "a")
16101 (match_operand:DI 3 "immediate_operand" "i")
16102 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16103 (clobber (match_operand:DI 1 "register_operand" "=D"))
16104 (clobber (reg:CC FLAGS_REG))]
16107 [(set_attr "type" "str")
16108 (set_attr "mode" "QI")
16109 (set_attr "prefix_rex" "0")
16110 (set_attr "prefix_rep" "1")])
16112 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16113 ;; handled in combine, but it is not currently up to the task.
16114 ;; When used for their truth value, the cmpstrn* expanders generate
16123 ;; The intermediate three instructions are unnecessary.
16125 ;; This one handles cmpstrn*_nz_1...
16128 (set (reg:CC FLAGS_REG)
16129 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16130 (mem:BLK (match_operand 5 "register_operand" ""))))
16131 (use (match_operand 6 "register_operand" ""))
16132 (use (match_operand:SI 3 "immediate_operand" ""))
16133 (clobber (match_operand 0 "register_operand" ""))
16134 (clobber (match_operand 1 "register_operand" ""))
16135 (clobber (match_operand 2 "register_operand" ""))])
16136 (set (match_operand:QI 7 "register_operand" "")
16137 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16138 (set (match_operand:QI 8 "register_operand" "")
16139 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16140 (set (reg FLAGS_REG)
16141 (compare (match_dup 7) (match_dup 8)))
16143 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16145 (set (reg:CC FLAGS_REG)
16146 (compare:CC (mem:BLK (match_dup 4))
16147 (mem:BLK (match_dup 5))))
16148 (use (match_dup 6))
16149 (use (match_dup 3))
16150 (clobber (match_dup 0))
16151 (clobber (match_dup 1))
16152 (clobber (match_dup 2))])]
16155 ;; ...and this one handles cmpstrn*_1.
16158 (set (reg:CC FLAGS_REG)
16159 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16161 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16162 (mem:BLK (match_operand 5 "register_operand" "")))
16164 (use (match_operand:SI 3 "immediate_operand" ""))
16165 (use (reg:CC FLAGS_REG))
16166 (clobber (match_operand 0 "register_operand" ""))
16167 (clobber (match_operand 1 "register_operand" ""))
16168 (clobber (match_operand 2 "register_operand" ""))])
16169 (set (match_operand:QI 7 "register_operand" "")
16170 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16171 (set (match_operand:QI 8 "register_operand" "")
16172 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16173 (set (reg FLAGS_REG)
16174 (compare (match_dup 7) (match_dup 8)))
16176 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16178 (set (reg:CC FLAGS_REG)
16179 (if_then_else:CC (ne (match_dup 6)
16181 (compare:CC (mem:BLK (match_dup 4))
16182 (mem:BLK (match_dup 5)))
16184 (use (match_dup 3))
16185 (use (reg:CC FLAGS_REG))
16186 (clobber (match_dup 0))
16187 (clobber (match_dup 1))
16188 (clobber (match_dup 2))])]
16193 ;; Conditional move instructions.
16195 (define_expand "mov<mode>cc"
16196 [(set (match_operand:SWIM 0 "register_operand" "")
16197 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16198 (match_operand:SWIM 2 "general_operand" "")
16199 (match_operand:SWIM 3 "general_operand" "")))]
16201 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16203 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16204 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16205 ;; So just document what we're doing explicitly.
16207 (define_expand "x86_mov<mode>cc_0_m1"
16209 [(set (match_operand:SWI48 0 "register_operand" "")
16210 (if_then_else:SWI48
16211 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16212 [(match_operand 1 "flags_reg_operand" "")
16216 (clobber (reg:CC FLAGS_REG))])]
16220 (define_insn "*x86_mov<mode>cc_0_m1"
16221 [(set (match_operand:SWI48 0 "register_operand" "=r")
16222 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16223 [(reg FLAGS_REG) (const_int 0)])
16226 (clobber (reg:CC FLAGS_REG))]
16228 "sbb{<imodesuffix>}\t%0, %0"
16229 ; Since we don't have the proper number of operands for an alu insn,
16230 ; fill in all the blanks.
16231 [(set_attr "type" "alu")
16232 (set_attr "use_carry" "1")
16233 (set_attr "pent_pair" "pu")
16234 (set_attr "memory" "none")
16235 (set_attr "imm_disp" "false")
16236 (set_attr "mode" "<MODE>")
16237 (set_attr "length_immediate" "0")])
16239 (define_insn "*x86_mov<mode>cc_0_m1_se"
16240 [(set (match_operand:SWI48 0 "register_operand" "=r")
16241 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16242 [(reg FLAGS_REG) (const_int 0)])
16245 (clobber (reg:CC FLAGS_REG))]
16247 "sbb{<imodesuffix>}\t%0, %0"
16248 [(set_attr "type" "alu")
16249 (set_attr "use_carry" "1")
16250 (set_attr "pent_pair" "pu")
16251 (set_attr "memory" "none")
16252 (set_attr "imm_disp" "false")
16253 (set_attr "mode" "<MODE>")
16254 (set_attr "length_immediate" "0")])
16256 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16257 [(set (match_operand:SWI48 0 "register_operand" "=r")
16258 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16259 [(reg FLAGS_REG) (const_int 0)])))]
16261 "sbb{<imodesuffix>}\t%0, %0"
16262 [(set_attr "type" "alu")
16263 (set_attr "use_carry" "1")
16264 (set_attr "pent_pair" "pu")
16265 (set_attr "memory" "none")
16266 (set_attr "imm_disp" "false")
16267 (set_attr "mode" "<MODE>")
16268 (set_attr "length_immediate" "0")])
16270 (define_insn "*mov<mode>cc_noc"
16271 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16272 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16273 [(reg FLAGS_REG) (const_int 0)])
16274 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16275 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16276 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16278 cmov%O2%C1\t{%2, %0|%0, %2}
16279 cmov%O2%c1\t{%3, %0|%0, %3}"
16280 [(set_attr "type" "icmov")
16281 (set_attr "mode" "<MODE>")])
16283 (define_insn_and_split "*movqicc_noc"
16284 [(set (match_operand:QI 0 "register_operand" "=r,r")
16285 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16286 [(match_operand 4 "flags_reg_operand" "")
16288 (match_operand:QI 2 "register_operand" "r,0")
16289 (match_operand:QI 3 "register_operand" "0,r")))]
16290 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16292 "&& reload_completed"
16293 [(set (match_dup 0)
16294 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16297 "operands[0] = gen_lowpart (SImode, operands[0]);
16298 operands[2] = gen_lowpart (SImode, operands[2]);
16299 operands[3] = gen_lowpart (SImode, operands[3]);"
16300 [(set_attr "type" "icmov")
16301 (set_attr "mode" "SI")])
16303 (define_expand "mov<mode>cc"
16304 [(set (match_operand:X87MODEF 0 "register_operand" "")
16305 (if_then_else:X87MODEF
16306 (match_operand 1 "ix86_fp_comparison_operator" "")
16307 (match_operand:X87MODEF 2 "register_operand" "")
16308 (match_operand:X87MODEF 3 "register_operand" "")))]
16309 "(TARGET_80387 && TARGET_CMOVE)
16310 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16311 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16313 (define_insn "*movsfcc_1_387"
16314 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16315 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16316 [(reg FLAGS_REG) (const_int 0)])
16317 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16318 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16319 "TARGET_80387 && TARGET_CMOVE
16320 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16322 fcmov%F1\t{%2, %0|%0, %2}
16323 fcmov%f1\t{%3, %0|%0, %3}
16324 cmov%O2%C1\t{%2, %0|%0, %2}
16325 cmov%O2%c1\t{%3, %0|%0, %3}"
16326 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16327 (set_attr "mode" "SF,SF,SI,SI")])
16329 (define_insn "*movdfcc_1"
16330 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16331 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16332 [(reg FLAGS_REG) (const_int 0)])
16333 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16334 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16335 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16336 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16338 fcmov%F1\t{%2, %0|%0, %2}
16339 fcmov%f1\t{%3, %0|%0, %3}
16342 [(set_attr "type" "fcmov,fcmov,multi,multi")
16343 (set_attr "mode" "DF")])
16345 (define_insn "*movdfcc_1_rex64"
16346 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16347 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16348 [(reg FLAGS_REG) (const_int 0)])
16349 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16350 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16351 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16352 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16354 fcmov%F1\t{%2, %0|%0, %2}
16355 fcmov%f1\t{%3, %0|%0, %3}
16356 cmov%O2%C1\t{%2, %0|%0, %2}
16357 cmov%O2%c1\t{%3, %0|%0, %3}"
16358 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16359 (set_attr "mode" "DF")])
16362 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16363 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16364 [(match_operand 4 "flags_reg_operand" "")
16366 (match_operand:DF 2 "nonimmediate_operand" "")
16367 (match_operand:DF 3 "nonimmediate_operand" "")))]
16368 "!TARGET_64BIT && reload_completed"
16369 [(set (match_dup 2)
16370 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16374 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16378 split_di (&operands[2], 2, &operands[5], &operands[7]);
16379 split_di (&operands[0], 1, &operands[2], &operands[3]);
16382 (define_insn "*movxfcc_1"
16383 [(set (match_operand:XF 0 "register_operand" "=f,f")
16384 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16385 [(reg FLAGS_REG) (const_int 0)])
16386 (match_operand:XF 2 "register_operand" "f,0")
16387 (match_operand:XF 3 "register_operand" "0,f")))]
16388 "TARGET_80387 && TARGET_CMOVE"
16390 fcmov%F1\t{%2, %0|%0, %2}
16391 fcmov%f1\t{%3, %0|%0, %3}"
16392 [(set_attr "type" "fcmov")
16393 (set_attr "mode" "XF")])
16395 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16396 ;; the scalar versions to have only XMM registers as operands.
16398 ;; XOP conditional move
16399 (define_insn "*xop_pcmov_<mode>"
16400 [(set (match_operand:MODEF 0 "register_operand" "=x")
16401 (if_then_else:MODEF
16402 (match_operand:MODEF 1 "register_operand" "x")
16403 (match_operand:MODEF 2 "register_operand" "x")
16404 (match_operand:MODEF 3 "register_operand" "x")))]
16406 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16407 [(set_attr "type" "sse4arg")])
16409 ;; These versions of the min/max patterns are intentionally ignorant of
16410 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16411 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16412 ;; are undefined in this condition, we're certain this is correct.
16414 (define_insn "*avx_<code><mode>3"
16415 [(set (match_operand:MODEF 0 "register_operand" "=x")
16417 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16418 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16419 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16420 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16421 [(set_attr "type" "sseadd")
16422 (set_attr "prefix" "vex")
16423 (set_attr "mode" "<MODE>")])
16425 (define_insn "<code><mode>3"
16426 [(set (match_operand:MODEF 0 "register_operand" "=x")
16428 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16429 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16430 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16431 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16432 [(set_attr "type" "sseadd")
16433 (set_attr "mode" "<MODE>")])
16435 ;; These versions of the min/max patterns implement exactly the operations
16436 ;; min = (op1 < op2 ? op1 : op2)
16437 ;; max = (!(op1 < op2) ? op1 : op2)
16438 ;; Their operands are not commutative, and thus they may be used in the
16439 ;; presence of -0.0 and NaN.
16441 (define_insn "*avx_ieee_smin<mode>3"
16442 [(set (match_operand:MODEF 0 "register_operand" "=x")
16444 [(match_operand:MODEF 1 "register_operand" "x")
16445 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16447 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16448 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16449 [(set_attr "type" "sseadd")
16450 (set_attr "prefix" "vex")
16451 (set_attr "mode" "<MODE>")])
16453 (define_insn "*ieee_smin<mode>3"
16454 [(set (match_operand:MODEF 0 "register_operand" "=x")
16456 [(match_operand:MODEF 1 "register_operand" "0")
16457 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16459 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16460 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16461 [(set_attr "type" "sseadd")
16462 (set_attr "mode" "<MODE>")])
16464 (define_insn "*avx_ieee_smax<mode>3"
16465 [(set (match_operand:MODEF 0 "register_operand" "=x")
16467 [(match_operand:MODEF 1 "register_operand" "0")
16468 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16470 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16471 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16472 [(set_attr "type" "sseadd")
16473 (set_attr "prefix" "vex")
16474 (set_attr "mode" "<MODE>")])
16476 (define_insn "*ieee_smax<mode>3"
16477 [(set (match_operand:MODEF 0 "register_operand" "=x")
16479 [(match_operand:MODEF 1 "register_operand" "0")
16480 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16482 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16483 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16484 [(set_attr "type" "sseadd")
16485 (set_attr "mode" "<MODE>")])
16487 ;; Make two stack loads independent:
16489 ;; fld %st(0) -> fld bb
16490 ;; fmul bb fmul %st(1), %st
16492 ;; Actually we only match the last two instructions for simplicity.
16494 [(set (match_operand 0 "fp_register_operand" "")
16495 (match_operand 1 "fp_register_operand" ""))
16497 (match_operator 2 "binary_fp_operator"
16499 (match_operand 3 "memory_operand" "")]))]
16500 "REGNO (operands[0]) != REGNO (operands[1])"
16501 [(set (match_dup 0) (match_dup 3))
16502 (set (match_dup 0) (match_dup 4))]
16504 ;; The % modifier is not operational anymore in peephole2's, so we have to
16505 ;; swap the operands manually in the case of addition and multiplication.
16506 "if (COMMUTATIVE_ARITH_P (operands[2]))
16507 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16508 operands[0], operands[1]);
16510 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16511 operands[1], operands[0]);")
16513 ;; Conditional addition patterns
16514 (define_expand "add<mode>cc"
16515 [(match_operand:SWI 0 "register_operand" "")
16516 (match_operand 1 "comparison_operator" "")
16517 (match_operand:SWI 2 "register_operand" "")
16518 (match_operand:SWI 3 "const_int_operand" "")]
16520 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16523 ;; Misc patterns (?)
16525 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16526 ;; Otherwise there will be nothing to keep
16528 ;; [(set (reg ebp) (reg esp))]
16529 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16530 ;; (clobber (eflags)]
16531 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16533 ;; in proper program order.
16534 (define_insn "pro_epilogue_adjust_stack_1"
16535 [(set (match_operand:SI 0 "register_operand" "=r,r")
16536 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16537 (match_operand:SI 2 "immediate_operand" "i,i")))
16538 (clobber (reg:CC FLAGS_REG))
16539 (clobber (mem:BLK (scratch)))]
16542 switch (get_attr_type (insn))
16545 return "mov{l}\t{%1, %0|%0, %1}";
16548 if (CONST_INT_P (operands[2])
16549 && (INTVAL (operands[2]) == 128
16550 || (INTVAL (operands[2]) < 0
16551 && INTVAL (operands[2]) != -128)))
16553 operands[2] = GEN_INT (-INTVAL (operands[2]));
16554 return "sub{l}\t{%2, %0|%0, %2}";
16556 return "add{l}\t{%2, %0|%0, %2}";
16559 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16560 return "lea{l}\t{%a2, %0|%0, %a2}";
16563 gcc_unreachable ();
16566 [(set (attr "type")
16567 (cond [(and (eq_attr "alternative" "0")
16568 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16569 (const_string "alu")
16570 (match_operand:SI 2 "const0_operand" "")
16571 (const_string "imov")
16573 (const_string "lea")))
16574 (set (attr "length_immediate")
16575 (cond [(eq_attr "type" "imov")
16577 (and (eq_attr "type" "alu")
16578 (match_operand 2 "const128_operand" ""))
16581 (const_string "*")))
16582 (set_attr "mode" "SI")])
16584 (define_insn "pro_epilogue_adjust_stack_rex64"
16585 [(set (match_operand:DI 0 "register_operand" "=r,r")
16586 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16587 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16588 (clobber (reg:CC FLAGS_REG))
16589 (clobber (mem:BLK (scratch)))]
16592 switch (get_attr_type (insn))
16595 return "mov{q}\t{%1, %0|%0, %1}";
16598 if (CONST_INT_P (operands[2])
16599 /* Avoid overflows. */
16600 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
16601 && (INTVAL (operands[2]) == 128
16602 || (INTVAL (operands[2]) < 0
16603 && INTVAL (operands[2]) != -128)))
16605 operands[2] = GEN_INT (-INTVAL (operands[2]));
16606 return "sub{q}\t{%2, %0|%0, %2}";
16608 return "add{q}\t{%2, %0|%0, %2}";
16611 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16612 return "lea{q}\t{%a2, %0|%0, %a2}";
16615 gcc_unreachable ();
16618 [(set (attr "type")
16619 (cond [(and (eq_attr "alternative" "0")
16620 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16621 (const_string "alu")
16622 (match_operand:DI 2 "const0_operand" "")
16623 (const_string "imov")
16625 (const_string "lea")))
16626 (set (attr "length_immediate")
16627 (cond [(eq_attr "type" "imov")
16629 (and (eq_attr "type" "alu")
16630 (match_operand 2 "const128_operand" ""))
16633 (const_string "*")))
16634 (set_attr "mode" "DI")])
16636 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16637 [(set (match_operand:DI 0 "register_operand" "=r,r")
16638 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16639 (match_operand:DI 3 "immediate_operand" "i,i")))
16640 (use (match_operand:DI 2 "register_operand" "r,r"))
16641 (clobber (reg:CC FLAGS_REG))
16642 (clobber (mem:BLK (scratch)))]
16645 switch (get_attr_type (insn))
16648 return "add{q}\t{%2, %0|%0, %2}";
16651 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16652 return "lea{q}\t{%a2, %0|%0, %a2}";
16655 gcc_unreachable ();
16658 [(set_attr "type" "alu,lea")
16659 (set_attr "mode" "DI")])
16661 (define_insn "allocate_stack_worker_32"
16662 [(set (match_operand:SI 0 "register_operand" "=a")
16663 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16664 UNSPECV_STACK_PROBE))
16665 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16666 (clobber (reg:CC FLAGS_REG))]
16667 "!TARGET_64BIT && TARGET_STACK_PROBE"
16669 [(set_attr "type" "multi")
16670 (set_attr "length" "5")])
16672 (define_insn "allocate_stack_worker_64"
16673 [(set (match_operand:DI 0 "register_operand" "=a")
16674 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16675 UNSPECV_STACK_PROBE))
16676 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16677 (clobber (reg:DI R10_REG))
16678 (clobber (reg:DI R11_REG))
16679 (clobber (reg:CC FLAGS_REG))]
16680 "TARGET_64BIT && TARGET_STACK_PROBE"
16682 [(set_attr "type" "multi")
16683 (set_attr "length" "5")])
16685 (define_expand "allocate_stack"
16686 [(match_operand 0 "register_operand" "")
16687 (match_operand 1 "general_operand" "")]
16688 "TARGET_STACK_PROBE"
16692 #ifndef CHECK_STACK_LIMIT
16693 #define CHECK_STACK_LIMIT 0
16696 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16697 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16699 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16700 stack_pointer_rtx, 0, OPTAB_DIRECT);
16701 if (x != stack_pointer_rtx)
16702 emit_move_insn (stack_pointer_rtx, x);
16706 x = copy_to_mode_reg (Pmode, operands[1]);
16708 x = gen_allocate_stack_worker_64 (x, x);
16710 x = gen_allocate_stack_worker_32 (x, x);
16714 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16718 ;; Use IOR for stack probes, this is shorter.
16719 (define_expand "probe_stack"
16720 [(match_operand 0 "memory_operand" "")]
16723 if (GET_MODE (operands[0]) == DImode)
16724 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
16726 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
16730 (define_expand "builtin_setjmp_receiver"
16731 [(label_ref (match_operand 0 "" ""))]
16732 "!TARGET_64BIT && flag_pic"
16738 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16739 rtx label_rtx = gen_label_rtx ();
16740 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16741 xops[0] = xops[1] = picreg;
16742 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16743 ix86_expand_binary_operator (MINUS, SImode, xops);
16747 emit_insn (gen_set_got (pic_offset_table_rtx));
16751 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16754 [(set (match_operand 0 "register_operand" "")
16755 (match_operator 3 "promotable_binary_operator"
16756 [(match_operand 1 "register_operand" "")
16757 (match_operand 2 "aligned_operand" "")]))
16758 (clobber (reg:CC FLAGS_REG))]
16759 "! TARGET_PARTIAL_REG_STALL && reload_completed
16760 && ((GET_MODE (operands[0]) == HImode
16761 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16762 /* ??? next two lines just !satisfies_constraint_K (...) */
16763 || !CONST_INT_P (operands[2])
16764 || satisfies_constraint_K (operands[2])))
16765 || (GET_MODE (operands[0]) == QImode
16766 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16767 [(parallel [(set (match_dup 0)
16768 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16769 (clobber (reg:CC FLAGS_REG))])]
16770 "operands[0] = gen_lowpart (SImode, operands[0]);
16771 operands[1] = gen_lowpart (SImode, operands[1]);
16772 if (GET_CODE (operands[3]) != ASHIFT)
16773 operands[2] = gen_lowpart (SImode, operands[2]);
16774 PUT_MODE (operands[3], SImode);")
16776 ; Promote the QImode tests, as i386 has encoding of the AND
16777 ; instruction with 32-bit sign-extended immediate and thus the
16778 ; instruction size is unchanged, except in the %eax case for
16779 ; which it is increased by one byte, hence the ! optimize_size.
16781 [(set (match_operand 0 "flags_reg_operand" "")
16782 (match_operator 2 "compare_operator"
16783 [(and (match_operand 3 "aligned_operand" "")
16784 (match_operand 4 "const_int_operand" ""))
16786 (set (match_operand 1 "register_operand" "")
16787 (and (match_dup 3) (match_dup 4)))]
16788 "! TARGET_PARTIAL_REG_STALL && reload_completed
16789 && optimize_insn_for_speed_p ()
16790 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16791 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16792 /* Ensure that the operand will remain sign-extended immediate. */
16793 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16794 [(parallel [(set (match_dup 0)
16795 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16798 (and:SI (match_dup 3) (match_dup 4)))])]
16801 = gen_int_mode (INTVAL (operands[4])
16802 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16803 operands[1] = gen_lowpart (SImode, operands[1]);
16804 operands[3] = gen_lowpart (SImode, operands[3]);
16807 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16808 ; the TEST instruction with 32-bit sign-extended immediate and thus
16809 ; the instruction size would at least double, which is not what we
16810 ; want even with ! optimize_size.
16812 [(set (match_operand 0 "flags_reg_operand" "")
16813 (match_operator 1 "compare_operator"
16814 [(and (match_operand:HI 2 "aligned_operand" "")
16815 (match_operand:HI 3 "const_int_operand" ""))
16817 "! TARGET_PARTIAL_REG_STALL && reload_completed
16818 && ! TARGET_FAST_PREFIX
16819 && optimize_insn_for_speed_p ()
16820 /* Ensure that the operand will remain sign-extended immediate. */
16821 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16822 [(set (match_dup 0)
16823 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16827 = gen_int_mode (INTVAL (operands[3])
16828 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16829 operands[2] = gen_lowpart (SImode, operands[2]);
16833 [(set (match_operand 0 "register_operand" "")
16834 (neg (match_operand 1 "register_operand" "")))
16835 (clobber (reg:CC FLAGS_REG))]
16836 "! TARGET_PARTIAL_REG_STALL && reload_completed
16837 && (GET_MODE (operands[0]) == HImode
16838 || (GET_MODE (operands[0]) == QImode
16839 && (TARGET_PROMOTE_QImode
16840 || optimize_insn_for_size_p ())))"
16841 [(parallel [(set (match_dup 0)
16842 (neg:SI (match_dup 1)))
16843 (clobber (reg:CC FLAGS_REG))])]
16844 "operands[0] = gen_lowpart (SImode, operands[0]);
16845 operands[1] = gen_lowpart (SImode, operands[1]);")
16848 [(set (match_operand 0 "register_operand" "")
16849 (not (match_operand 1 "register_operand" "")))]
16850 "! TARGET_PARTIAL_REG_STALL && reload_completed
16851 && (GET_MODE (operands[0]) == HImode
16852 || (GET_MODE (operands[0]) == QImode
16853 && (TARGET_PROMOTE_QImode
16854 || optimize_insn_for_size_p ())))"
16855 [(set (match_dup 0)
16856 (not:SI (match_dup 1)))]
16857 "operands[0] = gen_lowpart (SImode, operands[0]);
16858 operands[1] = gen_lowpart (SImode, operands[1]);")
16861 [(set (match_operand 0 "register_operand" "")
16862 (if_then_else (match_operator 1 "comparison_operator"
16863 [(reg FLAGS_REG) (const_int 0)])
16864 (match_operand 2 "register_operand" "")
16865 (match_operand 3 "register_operand" "")))]
16866 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16867 && (GET_MODE (operands[0]) == HImode
16868 || (GET_MODE (operands[0]) == QImode
16869 && (TARGET_PROMOTE_QImode
16870 || optimize_insn_for_size_p ())))"
16871 [(set (match_dup 0)
16872 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16873 "operands[0] = gen_lowpart (SImode, operands[0]);
16874 operands[2] = gen_lowpart (SImode, operands[2]);
16875 operands[3] = gen_lowpart (SImode, operands[3]);")
16878 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16879 ;; transform a complex memory operation into two memory to register operations.
16881 ;; Don't push memory operands
16883 [(set (match_operand:SI 0 "push_operand" "")
16884 (match_operand:SI 1 "memory_operand" ""))
16885 (match_scratch:SI 2 "r")]
16886 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16887 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16888 [(set (match_dup 2) (match_dup 1))
16889 (set (match_dup 0) (match_dup 2))]
16893 [(set (match_operand:DI 0 "push_operand" "")
16894 (match_operand:DI 1 "memory_operand" ""))
16895 (match_scratch:DI 2 "r")]
16896 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16897 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16898 [(set (match_dup 2) (match_dup 1))
16899 (set (match_dup 0) (match_dup 2))]
16902 ;; We need to handle SFmode only, because DFmode and XFmode is split to
16905 [(set (match_operand:SF 0 "push_operand" "")
16906 (match_operand:SF 1 "memory_operand" ""))
16907 (match_scratch:SF 2 "r")]
16908 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16909 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16910 [(set (match_dup 2) (match_dup 1))
16911 (set (match_dup 0) (match_dup 2))]
16915 [(set (match_operand:HI 0 "push_operand" "")
16916 (match_operand:HI 1 "memory_operand" ""))
16917 (match_scratch:HI 2 "r")]
16918 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16919 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16920 [(set (match_dup 2) (match_dup 1))
16921 (set (match_dup 0) (match_dup 2))]
16925 [(set (match_operand:QI 0 "push_operand" "")
16926 (match_operand:QI 1 "memory_operand" ""))
16927 (match_scratch:QI 2 "q")]
16928 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16929 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16930 [(set (match_dup 2) (match_dup 1))
16931 (set (match_dup 0) (match_dup 2))]
16934 ;; Don't move an immediate directly to memory when the instruction
16937 [(match_scratch:SI 1 "r")
16938 (set (match_operand:SI 0 "memory_operand" "")
16940 "optimize_insn_for_speed_p ()
16941 && ! TARGET_USE_MOV0
16942 && TARGET_SPLIT_LONG_MOVES
16943 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16944 && peep2_regno_dead_p (0, FLAGS_REG)"
16945 [(parallel [(set (match_dup 1) (const_int 0))
16946 (clobber (reg:CC FLAGS_REG))])
16947 (set (match_dup 0) (match_dup 1))]
16951 [(match_scratch:HI 1 "r")
16952 (set (match_operand:HI 0 "memory_operand" "")
16954 "optimize_insn_for_speed_p ()
16955 && ! TARGET_USE_MOV0
16956 && TARGET_SPLIT_LONG_MOVES
16957 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16958 && peep2_regno_dead_p (0, FLAGS_REG)"
16959 [(parallel [(set (match_dup 2) (const_int 0))
16960 (clobber (reg:CC FLAGS_REG))])
16961 (set (match_dup 0) (match_dup 1))]
16962 "operands[2] = gen_lowpart (SImode, operands[1]);")
16965 [(match_scratch:QI 1 "q")
16966 (set (match_operand:QI 0 "memory_operand" "")
16968 "optimize_insn_for_speed_p ()
16969 && ! TARGET_USE_MOV0
16970 && TARGET_SPLIT_LONG_MOVES
16971 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16972 && peep2_regno_dead_p (0, FLAGS_REG)"
16973 [(parallel [(set (match_dup 2) (const_int 0))
16974 (clobber (reg:CC FLAGS_REG))])
16975 (set (match_dup 0) (match_dup 1))]
16976 "operands[2] = gen_lowpart (SImode, operands[1]);")
16979 [(match_scratch:SI 2 "r")
16980 (set (match_operand:SI 0 "memory_operand" "")
16981 (match_operand:SI 1 "immediate_operand" ""))]
16982 "optimize_insn_for_speed_p ()
16983 && TARGET_SPLIT_LONG_MOVES
16984 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16985 [(set (match_dup 2) (match_dup 1))
16986 (set (match_dup 0) (match_dup 2))]
16990 [(match_scratch:HI 2 "r")
16991 (set (match_operand:HI 0 "memory_operand" "")
16992 (match_operand:HI 1 "immediate_operand" ""))]
16993 "optimize_insn_for_speed_p ()
16994 && TARGET_SPLIT_LONG_MOVES
16995 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16996 [(set (match_dup 2) (match_dup 1))
16997 (set (match_dup 0) (match_dup 2))]
17001 [(match_scratch:QI 2 "q")
17002 (set (match_operand:QI 0 "memory_operand" "")
17003 (match_operand:QI 1 "immediate_operand" ""))]
17004 "optimize_insn_for_speed_p ()
17005 && TARGET_SPLIT_LONG_MOVES
17006 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17007 [(set (match_dup 2) (match_dup 1))
17008 (set (match_dup 0) (match_dup 2))]
17011 ;; Don't compare memory with zero, load and use a test instead.
17013 [(set (match_operand 0 "flags_reg_operand" "")
17014 (match_operator 1 "compare_operator"
17015 [(match_operand:SI 2 "memory_operand" "")
17017 (match_scratch:SI 3 "r")]
17018 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17019 [(set (match_dup 3) (match_dup 2))
17020 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17023 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17024 ;; Don't split NOTs with a displacement operand, because resulting XOR
17025 ;; will not be pairable anyway.
17027 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17028 ;; represented using a modRM byte. The XOR replacement is long decoded,
17029 ;; so this split helps here as well.
17031 ;; Note: Can't do this as a regular split because we can't get proper
17032 ;; lifetime information then.
17035 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17036 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17037 "optimize_insn_for_speed_p ()
17038 && ((TARGET_NOT_UNPAIRABLE
17039 && (!MEM_P (operands[0])
17040 || !memory_displacement_operand (operands[0], SImode)))
17041 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
17042 && peep2_regno_dead_p (0, FLAGS_REG)"
17043 [(parallel [(set (match_dup 0)
17044 (xor:SI (match_dup 1) (const_int -1)))
17045 (clobber (reg:CC FLAGS_REG))])]
17049 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17050 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17051 "optimize_insn_for_speed_p ()
17052 && ((TARGET_NOT_UNPAIRABLE
17053 && (!MEM_P (operands[0])
17054 || !memory_displacement_operand (operands[0], HImode)))
17055 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
17056 && peep2_regno_dead_p (0, FLAGS_REG)"
17057 [(parallel [(set (match_dup 0)
17058 (xor:HI (match_dup 1) (const_int -1)))
17059 (clobber (reg:CC FLAGS_REG))])]
17063 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17064 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17065 "optimize_insn_for_speed_p ()
17066 && ((TARGET_NOT_UNPAIRABLE
17067 && (!MEM_P (operands[0])
17068 || !memory_displacement_operand (operands[0], QImode)))
17069 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
17070 && peep2_regno_dead_p (0, FLAGS_REG)"
17071 [(parallel [(set (match_dup 0)
17072 (xor:QI (match_dup 1) (const_int -1)))
17073 (clobber (reg:CC FLAGS_REG))])]
17076 ;; Non pairable "test imm, reg" instructions can be translated to
17077 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17078 ;; byte opcode instead of two, have a short form for byte operands),
17079 ;; so do it for other CPUs as well. Given that the value was dead,
17080 ;; this should not create any new dependencies. Pass on the sub-word
17081 ;; versions if we're concerned about partial register stalls.
17084 [(set (match_operand 0 "flags_reg_operand" "")
17085 (match_operator 1 "compare_operator"
17086 [(and:SI (match_operand:SI 2 "register_operand" "")
17087 (match_operand:SI 3 "immediate_operand" ""))
17089 "ix86_match_ccmode (insn, CCNOmode)
17090 && (true_regnum (operands[2]) != AX_REG
17091 || satisfies_constraint_K (operands[3]))
17092 && peep2_reg_dead_p (1, operands[2])"
17094 [(set (match_dup 0)
17095 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17098 (and:SI (match_dup 2) (match_dup 3)))])]
17101 ;; We don't need to handle HImode case, because it will be promoted to SImode
17102 ;; on ! TARGET_PARTIAL_REG_STALL
17105 [(set (match_operand 0 "flags_reg_operand" "")
17106 (match_operator 1 "compare_operator"
17107 [(and:QI (match_operand:QI 2 "register_operand" "")
17108 (match_operand:QI 3 "immediate_operand" ""))
17110 "! TARGET_PARTIAL_REG_STALL
17111 && ix86_match_ccmode (insn, CCNOmode)
17112 && true_regnum (operands[2]) != AX_REG
17113 && peep2_reg_dead_p (1, operands[2])"
17115 [(set (match_dup 0)
17116 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17119 (and:QI (match_dup 2) (match_dup 3)))])]
17123 [(set (match_operand 0 "flags_reg_operand" "")
17124 (match_operator 1 "compare_operator"
17127 (match_operand 2 "ext_register_operand" "")
17130 (match_operand 3 "const_int_operand" ""))
17132 "! TARGET_PARTIAL_REG_STALL
17133 && ix86_match_ccmode (insn, CCNOmode)
17134 && true_regnum (operands[2]) != AX_REG
17135 && peep2_reg_dead_p (1, operands[2])"
17136 [(parallel [(set (match_dup 0)
17145 (set (zero_extract:SI (match_dup 2)
17156 ;; Don't do logical operations with memory inputs.
17158 [(match_scratch:SI 2 "r")
17159 (parallel [(set (match_operand:SI 0 "register_operand" "")
17160 (match_operator:SI 3 "arith_or_logical_operator"
17162 (match_operand:SI 1 "memory_operand" "")]))
17163 (clobber (reg:CC FLAGS_REG))])]
17164 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17165 [(set (match_dup 2) (match_dup 1))
17166 (parallel [(set (match_dup 0)
17167 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17168 (clobber (reg:CC FLAGS_REG))])]
17172 [(match_scratch:SI 2 "r")
17173 (parallel [(set (match_operand:SI 0 "register_operand" "")
17174 (match_operator:SI 3 "arith_or_logical_operator"
17175 [(match_operand:SI 1 "memory_operand" "")
17177 (clobber (reg:CC FLAGS_REG))])]
17178 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17179 [(set (match_dup 2) (match_dup 1))
17180 (parallel [(set (match_dup 0)
17181 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17182 (clobber (reg:CC FLAGS_REG))])]
17185 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17186 ;; refers to the destination of the load!
17189 [(set (match_operand:SI 0 "register_operand" "")
17190 (match_operand:SI 1 "register_operand" ""))
17191 (parallel [(set (match_dup 0)
17192 (match_operator:SI 3 "commutative_operator"
17194 (match_operand:SI 2 "memory_operand" "")]))
17195 (clobber (reg:CC FLAGS_REG))])]
17196 "REGNO (operands[0]) != REGNO (operands[1])
17197 && GENERAL_REGNO_P (REGNO (operands[0]))
17198 && GENERAL_REGNO_P (REGNO (operands[1]))"
17199 [(set (match_dup 0) (match_dup 4))
17200 (parallel [(set (match_dup 0)
17201 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17202 (clobber (reg:CC FLAGS_REG))])]
17203 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17206 [(set (match_operand 0 "register_operand" "")
17207 (match_operand 1 "register_operand" ""))
17209 (match_operator 3 "commutative_operator"
17211 (match_operand 2 "memory_operand" "")]))]
17212 "REGNO (operands[0]) != REGNO (operands[1])
17213 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17214 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17215 [(set (match_dup 0) (match_dup 2))
17217 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17220 ; Don't do logical operations with memory outputs
17222 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17223 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17224 ; the same decoder scheduling characteristics as the original.
17227 [(match_scratch:SI 2 "r")
17228 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17229 (match_operator:SI 3 "arith_or_logical_operator"
17231 (match_operand:SI 1 "nonmemory_operand" "")]))
17232 (clobber (reg:CC FLAGS_REG))])]
17233 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17234 /* Do not split stack checking probes. */
17235 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17236 [(set (match_dup 2) (match_dup 0))
17237 (parallel [(set (match_dup 2)
17238 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17239 (clobber (reg:CC FLAGS_REG))])
17240 (set (match_dup 0) (match_dup 2))]
17244 [(match_scratch:SI 2 "r")
17245 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17246 (match_operator:SI 3 "arith_or_logical_operator"
17247 [(match_operand:SI 1 "nonmemory_operand" "")
17249 (clobber (reg:CC FLAGS_REG))])]
17250 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17251 /* Do not split stack checking probes. */
17252 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17253 [(set (match_dup 2) (match_dup 0))
17254 (parallel [(set (match_dup 2)
17255 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17256 (clobber (reg:CC FLAGS_REG))])
17257 (set (match_dup 0) (match_dup 2))]
17260 ;; Attempt to always use XOR for zeroing registers.
17262 [(set (match_operand 0 "register_operand" "")
17263 (match_operand 1 "const0_operand" ""))]
17264 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17265 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17266 && GENERAL_REG_P (operands[0])
17267 && peep2_regno_dead_p (0, FLAGS_REG)"
17268 [(parallel [(set (match_dup 0) (const_int 0))
17269 (clobber (reg:CC FLAGS_REG))])]
17271 operands[0] = gen_lowpart (word_mode, operands[0]);
17275 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17277 "(GET_MODE (operands[0]) == QImode
17278 || GET_MODE (operands[0]) == HImode)
17279 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17280 && peep2_regno_dead_p (0, FLAGS_REG)"
17281 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17282 (clobber (reg:CC FLAGS_REG))])])
17284 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17286 [(set (match_operand 0 "register_operand" "")
17288 "(GET_MODE (operands[0]) == HImode
17289 || GET_MODE (operands[0]) == SImode
17290 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17291 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17292 && peep2_regno_dead_p (0, FLAGS_REG)"
17293 [(parallel [(set (match_dup 0) (const_int -1))
17294 (clobber (reg:CC FLAGS_REG))])]
17295 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17298 ;; Attempt to convert simple leas to adds. These can be created by
17301 [(set (match_operand:SI 0 "register_operand" "")
17302 (plus:SI (match_dup 0)
17303 (match_operand:SI 1 "nonmemory_operand" "")))]
17304 "peep2_regno_dead_p (0, FLAGS_REG)"
17305 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17306 (clobber (reg:CC FLAGS_REG))])]
17310 [(set (match_operand:SI 0 "register_operand" "")
17311 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17312 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17313 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17314 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17315 (clobber (reg:CC FLAGS_REG))])]
17316 "operands[2] = gen_lowpart (SImode, operands[2]);")
17319 [(set (match_operand:DI 0 "register_operand" "")
17320 (plus:DI (match_dup 0)
17321 (match_operand:DI 1 "x86_64_general_operand" "")))]
17322 "peep2_regno_dead_p (0, FLAGS_REG)"
17323 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17324 (clobber (reg:CC FLAGS_REG))])]
17328 [(set (match_operand:SI 0 "register_operand" "")
17329 (mult:SI (match_dup 0)
17330 (match_operand:SI 1 "const_int_operand" "")))]
17331 "exact_log2 (INTVAL (operands[1])) >= 0
17332 && peep2_regno_dead_p (0, FLAGS_REG)"
17333 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17334 (clobber (reg:CC FLAGS_REG))])]
17335 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17338 [(set (match_operand:DI 0 "register_operand" "")
17339 (mult:DI (match_dup 0)
17340 (match_operand:DI 1 "const_int_operand" "")))]
17341 "exact_log2 (INTVAL (operands[1])) >= 0
17342 && peep2_regno_dead_p (0, FLAGS_REG)"
17343 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17344 (clobber (reg:CC FLAGS_REG))])]
17345 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17348 [(set (match_operand:SI 0 "register_operand" "")
17349 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17350 (match_operand:DI 2 "const_int_operand" "")) 0))]
17351 "exact_log2 (INTVAL (operands[2])) >= 0
17352 && REGNO (operands[0]) == REGNO (operands[1])
17353 && peep2_regno_dead_p (0, FLAGS_REG)"
17354 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17355 (clobber (reg:CC FLAGS_REG))])]
17356 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17358 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17359 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17360 ;; many CPUs it is also faster, since special hardware to avoid esp
17361 ;; dependencies is present.
17363 ;; While some of these conversions may be done using splitters, we use peepholes
17364 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17366 ;; Convert prologue esp subtractions to push.
17367 ;; We need register to push. In order to keep verify_flow_info happy we have
17369 ;; - use scratch and clobber it in order to avoid dependencies
17370 ;; - use already live register
17371 ;; We can't use the second way right now, since there is no reliable way how to
17372 ;; verify that given register is live. First choice will also most likely in
17373 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17374 ;; call clobbered registers are dead. We may want to use base pointer as an
17375 ;; alternative when no register is available later.
17378 [(match_scratch:SI 0 "r")
17379 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17380 (clobber (reg:CC FLAGS_REG))
17381 (clobber (mem:BLK (scratch)))])]
17382 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17383 [(clobber (match_dup 0))
17384 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17385 (clobber (mem:BLK (scratch)))])])
17388 [(match_scratch:SI 0 "r")
17389 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17390 (clobber (reg:CC FLAGS_REG))
17391 (clobber (mem:BLK (scratch)))])]
17392 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17393 [(clobber (match_dup 0))
17394 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17395 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17396 (clobber (mem:BLK (scratch)))])])
17398 ;; Convert esp subtractions to push.
17400 [(match_scratch:SI 0 "r")
17401 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17402 (clobber (reg:CC FLAGS_REG))])]
17403 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17404 [(clobber (match_dup 0))
17405 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17408 [(match_scratch:SI 0 "r")
17409 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17410 (clobber (reg:CC FLAGS_REG))])]
17411 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17412 [(clobber (match_dup 0))
17413 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17414 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17416 ;; Convert epilogue deallocator to pop.
17418 [(match_scratch:SI 0 "r")
17419 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17420 (clobber (reg:CC FLAGS_REG))
17421 (clobber (mem:BLK (scratch)))])]
17422 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17423 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17424 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17425 (clobber (mem:BLK (scratch)))])]
17428 ;; Two pops case is tricky, since pop causes dependency on destination register.
17429 ;; We use two registers if available.
17431 [(match_scratch:SI 0 "r")
17432 (match_scratch:SI 1 "r")
17433 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17434 (clobber (reg:CC FLAGS_REG))
17435 (clobber (mem:BLK (scratch)))])]
17436 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17437 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17438 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17439 (clobber (mem:BLK (scratch)))])
17440 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17441 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17445 [(match_scratch:SI 0 "r")
17446 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17447 (clobber (reg:CC FLAGS_REG))
17448 (clobber (mem:BLK (scratch)))])]
17449 "optimize_insn_for_size_p ()"
17450 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17451 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17452 (clobber (mem:BLK (scratch)))])
17453 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17454 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17457 ;; Convert esp additions to pop.
17459 [(match_scratch:SI 0 "r")
17460 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17461 (clobber (reg:CC FLAGS_REG))])]
17463 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17464 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17467 ;; Two pops case is tricky, since pop causes dependency on destination register.
17468 ;; We use two registers if available.
17470 [(match_scratch:SI 0 "r")
17471 (match_scratch:SI 1 "r")
17472 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17473 (clobber (reg:CC FLAGS_REG))])]
17475 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17476 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17477 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17478 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17482 [(match_scratch:SI 0 "r")
17483 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17484 (clobber (reg:CC FLAGS_REG))])]
17485 "optimize_insn_for_size_p ()"
17486 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17487 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17488 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17489 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17492 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17493 ;; required and register dies. Similarly for 128 to -128.
17495 [(set (match_operand 0 "flags_reg_operand" "")
17496 (match_operator 1 "compare_operator"
17497 [(match_operand 2 "register_operand" "")
17498 (match_operand 3 "const_int_operand" "")]))]
17499 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17500 && incdec_operand (operands[3], GET_MODE (operands[3])))
17501 || (!TARGET_FUSE_CMP_AND_BRANCH
17502 && INTVAL (operands[3]) == 128))
17503 && ix86_match_ccmode (insn, CCGCmode)
17504 && peep2_reg_dead_p (1, operands[2])"
17505 [(parallel [(set (match_dup 0)
17506 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17507 (clobber (match_dup 2))])]
17511 [(match_scratch:DI 0 "r")
17512 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17513 (clobber (reg:CC FLAGS_REG))
17514 (clobber (mem:BLK (scratch)))])]
17515 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17516 [(clobber (match_dup 0))
17517 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17518 (clobber (mem:BLK (scratch)))])])
17521 [(match_scratch:DI 0 "r")
17522 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17523 (clobber (reg:CC FLAGS_REG))
17524 (clobber (mem:BLK (scratch)))])]
17525 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17526 [(clobber (match_dup 0))
17527 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17528 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17529 (clobber (mem:BLK (scratch)))])])
17531 ;; Convert esp subtractions to push.
17533 [(match_scratch:DI 0 "r")
17534 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17535 (clobber (reg:CC FLAGS_REG))])]
17536 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17537 [(clobber (match_dup 0))
17538 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17541 [(match_scratch:DI 0 "r")
17542 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17543 (clobber (reg:CC FLAGS_REG))])]
17544 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17545 [(clobber (match_dup 0))
17546 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17547 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17549 ;; Convert epilogue deallocator to pop.
17551 [(match_scratch:DI 0 "r")
17552 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17553 (clobber (reg:CC FLAGS_REG))
17554 (clobber (mem:BLK (scratch)))])]
17555 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17556 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17557 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17558 (clobber (mem:BLK (scratch)))])]
17561 ;; Two pops case is tricky, since pop causes dependency on destination register.
17562 ;; We use two registers if available.
17564 [(match_scratch:DI 0 "r")
17565 (match_scratch:DI 1 "r")
17566 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17567 (clobber (reg:CC FLAGS_REG))
17568 (clobber (mem:BLK (scratch)))])]
17569 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17570 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17571 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17572 (clobber (mem:BLK (scratch)))])
17573 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17574 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17578 [(match_scratch:DI 0 "r")
17579 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17580 (clobber (reg:CC FLAGS_REG))
17581 (clobber (mem:BLK (scratch)))])]
17582 "optimize_insn_for_size_p ()"
17583 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17584 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17585 (clobber (mem:BLK (scratch)))])
17586 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17587 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17590 ;; Convert esp additions to pop.
17592 [(match_scratch:DI 0 "r")
17593 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17594 (clobber (reg:CC FLAGS_REG))])]
17596 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17597 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17600 ;; Two pops case is tricky, since pop causes dependency on destination register.
17601 ;; We use two registers if available.
17603 [(match_scratch:DI 0 "r")
17604 (match_scratch:DI 1 "r")
17605 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17606 (clobber (reg:CC FLAGS_REG))])]
17608 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17609 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17610 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17611 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17615 [(match_scratch:DI 0 "r")
17616 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17617 (clobber (reg:CC FLAGS_REG))])]
17618 "optimize_insn_for_size_p ()"
17619 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17620 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17621 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17622 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17625 ;; Convert imul by three, five and nine into lea
17628 [(set (match_operand:SI 0 "register_operand" "")
17629 (mult:SI (match_operand:SI 1 "register_operand" "")
17630 (match_operand:SI 2 "const_int_operand" "")))
17631 (clobber (reg:CC FLAGS_REG))])]
17632 "INTVAL (operands[2]) == 3
17633 || INTVAL (operands[2]) == 5
17634 || INTVAL (operands[2]) == 9"
17635 [(set (match_dup 0)
17636 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
17638 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17642 [(set (match_operand:SI 0 "register_operand" "")
17643 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17644 (match_operand:SI 2 "const_int_operand" "")))
17645 (clobber (reg:CC FLAGS_REG))])]
17646 "optimize_insn_for_speed_p ()
17647 && (INTVAL (operands[2]) == 3
17648 || INTVAL (operands[2]) == 5
17649 || INTVAL (operands[2]) == 9)"
17650 [(set (match_dup 0) (match_dup 1))
17652 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
17654 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17658 [(set (match_operand:DI 0 "register_operand" "")
17659 (mult:DI (match_operand:DI 1 "register_operand" "")
17660 (match_operand:DI 2 "const_int_operand" "")))
17661 (clobber (reg:CC FLAGS_REG))])]
17663 && (INTVAL (operands[2]) == 3
17664 || INTVAL (operands[2]) == 5
17665 || INTVAL (operands[2]) == 9)"
17666 [(set (match_dup 0)
17667 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
17669 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17673 [(set (match_operand:DI 0 "register_operand" "")
17674 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17675 (match_operand:DI 2 "const_int_operand" "")))
17676 (clobber (reg:CC FLAGS_REG))])]
17678 && optimize_insn_for_speed_p ()
17679 && (INTVAL (operands[2]) == 3
17680 || INTVAL (operands[2]) == 5
17681 || INTVAL (operands[2]) == 9)"
17682 [(set (match_dup 0) (match_dup 1))
17684 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
17686 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17688 ;; Imul $32bit_imm, mem, reg is vector decoded, while
17689 ;; imul $32bit_imm, reg, reg is direct decoded.
17691 [(match_scratch:DI 3 "r")
17692 (parallel [(set (match_operand:DI 0 "register_operand" "")
17693 (mult:DI (match_operand:DI 1 "memory_operand" "")
17694 (match_operand:DI 2 "immediate_operand" "")))
17695 (clobber (reg:CC FLAGS_REG))])]
17696 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17697 && !satisfies_constraint_K (operands[2])"
17698 [(set (match_dup 3) (match_dup 1))
17699 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
17700 (clobber (reg:CC FLAGS_REG))])]
17704 [(match_scratch:SI 3 "r")
17705 (parallel [(set (match_operand:SI 0 "register_operand" "")
17706 (mult:SI (match_operand:SI 1 "memory_operand" "")
17707 (match_operand:SI 2 "immediate_operand" "")))
17708 (clobber (reg:CC FLAGS_REG))])]
17709 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17710 && !satisfies_constraint_K (operands[2])"
17711 [(set (match_dup 3) (match_dup 1))
17712 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
17713 (clobber (reg:CC FLAGS_REG))])]
17717 [(match_scratch:SI 3 "r")
17718 (parallel [(set (match_operand:DI 0 "register_operand" "")
17720 (mult:SI (match_operand:SI 1 "memory_operand" "")
17721 (match_operand:SI 2 "immediate_operand" ""))))
17722 (clobber (reg:CC FLAGS_REG))])]
17723 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17724 && !satisfies_constraint_K (operands[2])"
17725 [(set (match_dup 3) (match_dup 1))
17726 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17727 (clobber (reg:CC FLAGS_REG))])]
17730 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17731 ;; Convert it into imul reg, reg
17732 ;; It would be better to force assembler to encode instruction using long
17733 ;; immediate, but there is apparently no way to do so.
17735 [(parallel [(set (match_operand:DI 0 "register_operand" "")
17736 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17737 (match_operand:DI 2 "const_int_operand" "")))
17738 (clobber (reg:CC FLAGS_REG))])
17739 (match_scratch:DI 3 "r")]
17740 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17741 && satisfies_constraint_K (operands[2])"
17742 [(set (match_dup 3) (match_dup 2))
17743 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
17744 (clobber (reg:CC FLAGS_REG))])]
17746 if (!rtx_equal_p (operands[0], operands[1]))
17747 emit_move_insn (operands[0], operands[1]);
17751 [(parallel [(set (match_operand:SI 0 "register_operand" "")
17752 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17753 (match_operand:SI 2 "const_int_operand" "")))
17754 (clobber (reg:CC FLAGS_REG))])
17755 (match_scratch:SI 3 "r")]
17756 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17757 && satisfies_constraint_K (operands[2])"
17758 [(set (match_dup 3) (match_dup 2))
17759 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
17760 (clobber (reg:CC FLAGS_REG))])]
17762 if (!rtx_equal_p (operands[0], operands[1]))
17763 emit_move_insn (operands[0], operands[1]);
17767 [(parallel [(set (match_operand:HI 0 "register_operand" "")
17768 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
17769 (match_operand:HI 2 "immediate_operand" "")))
17770 (clobber (reg:CC FLAGS_REG))])
17771 (match_scratch:HI 3 "r")]
17772 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
17773 [(set (match_dup 3) (match_dup 2))
17774 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
17775 (clobber (reg:CC FLAGS_REG))])]
17777 if (!rtx_equal_p (operands[0], operands[1]))
17778 emit_move_insn (operands[0], operands[1]);
17781 ;; After splitting up read-modify operations, array accesses with memory
17782 ;; operands might end up in form:
17784 ;; movl 4(%esp), %edx
17786 ;; instead of pre-splitting:
17788 ;; addl 4(%esp), %eax
17790 ;; movl 4(%esp), %edx
17791 ;; leal (%edx,%eax,4), %eax
17794 [(parallel [(set (match_operand 0 "register_operand" "")
17795 (ashift (match_operand 1 "register_operand" "")
17796 (match_operand 2 "const_int_operand" "")))
17797 (clobber (reg:CC FLAGS_REG))])
17798 (set (match_operand 3 "register_operand")
17799 (match_operand 4 "x86_64_general_operand" ""))
17800 (parallel [(set (match_operand 5 "register_operand" "")
17801 (plus (match_operand 6 "register_operand" "")
17802 (match_operand 7 "register_operand" "")))
17803 (clobber (reg:CC FLAGS_REG))])]
17804 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17805 /* Validate MODE for lea. */
17806 && ((!TARGET_PARTIAL_REG_STALL
17807 && (GET_MODE (operands[0]) == QImode
17808 || GET_MODE (operands[0]) == HImode))
17809 || GET_MODE (operands[0]) == SImode
17810 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17811 /* We reorder load and the shift. */
17812 && !rtx_equal_p (operands[1], operands[3])
17813 && !reg_overlap_mentioned_p (operands[0], operands[4])
17814 /* Last PLUS must consist of operand 0 and 3. */
17815 && !rtx_equal_p (operands[0], operands[3])
17816 && (rtx_equal_p (operands[3], operands[6])
17817 || rtx_equal_p (operands[3], operands[7]))
17818 && (rtx_equal_p (operands[0], operands[6])
17819 || rtx_equal_p (operands[0], operands[7]))
17820 /* The intermediate operand 0 must die or be same as output. */
17821 && (rtx_equal_p (operands[0], operands[5])
17822 || peep2_reg_dead_p (3, operands[0]))"
17823 [(set (match_dup 3) (match_dup 4))
17824 (set (match_dup 0) (match_dup 1))]
17826 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
17827 int scale = 1 << INTVAL (operands[2]);
17828 rtx index = gen_lowpart (Pmode, operands[1]);
17829 rtx base = gen_lowpart (Pmode, operands[3]);
17830 rtx dest = gen_lowpart (mode, operands[5]);
17832 operands[1] = gen_rtx_PLUS (Pmode, base,
17833 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17835 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17836 operands[0] = dest;
17839 ;; Call-value patterns last so that the wildcard operand does not
17840 ;; disrupt insn-recog's switch tables.
17842 (define_insn "*call_value_pop_0"
17843 [(set (match_operand 0 "" "")
17844 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17845 (match_operand:SI 2 "" "")))
17846 (set (reg:SI SP_REG)
17847 (plus:SI (reg:SI SP_REG)
17848 (match_operand:SI 3 "immediate_operand" "")))]
17851 if (SIBLING_CALL_P (insn))
17854 return "call\t%P1";
17856 [(set_attr "type" "callv")])
17858 (define_insn "*call_value_pop_1"
17859 [(set (match_operand 0 "" "")
17860 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17861 (match_operand:SI 2 "" "")))
17862 (set (reg:SI SP_REG)
17863 (plus:SI (reg:SI SP_REG)
17864 (match_operand:SI 3 "immediate_operand" "i")))]
17865 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17867 if (constant_call_address_operand (operands[1], Pmode))
17868 return "call\t%P1";
17869 return "call\t%A1";
17871 [(set_attr "type" "callv")])
17873 (define_insn "*sibcall_value_pop_1"
17874 [(set (match_operand 0 "" "")
17875 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17876 (match_operand:SI 2 "" "")))
17877 (set (reg:SI SP_REG)
17878 (plus:SI (reg:SI SP_REG)
17879 (match_operand:SI 3 "immediate_operand" "i,i")))]
17880 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17884 [(set_attr "type" "callv")])
17886 (define_insn "*call_value_0"
17887 [(set (match_operand 0 "" "")
17888 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17889 (match_operand:SI 2 "" "")))]
17892 if (SIBLING_CALL_P (insn))
17895 return "call\t%P1";
17897 [(set_attr "type" "callv")])
17899 (define_insn "*call_value_0_rex64"
17900 [(set (match_operand 0 "" "")
17901 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17902 (match_operand:DI 2 "const_int_operand" "")))]
17905 if (SIBLING_CALL_P (insn))
17908 return "call\t%P1";
17910 [(set_attr "type" "callv")])
17912 (define_insn "*call_value_0_rex64_ms_sysv"
17913 [(set (match_operand 0 "" "")
17914 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17915 (match_operand:DI 2 "const_int_operand" "")))
17916 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17917 (clobber (reg:TI XMM6_REG))
17918 (clobber (reg:TI XMM7_REG))
17919 (clobber (reg:TI XMM8_REG))
17920 (clobber (reg:TI XMM9_REG))
17921 (clobber (reg:TI XMM10_REG))
17922 (clobber (reg:TI XMM11_REG))
17923 (clobber (reg:TI XMM12_REG))
17924 (clobber (reg:TI XMM13_REG))
17925 (clobber (reg:TI XMM14_REG))
17926 (clobber (reg:TI XMM15_REG))
17927 (clobber (reg:DI SI_REG))
17928 (clobber (reg:DI DI_REG))]
17929 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17931 if (SIBLING_CALL_P (insn))
17934 return "call\t%P1";
17936 [(set_attr "type" "callv")])
17938 (define_insn "*call_value_1"
17939 [(set (match_operand 0 "" "")
17940 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17941 (match_operand:SI 2 "" "")))]
17942 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17944 if (constant_call_address_operand (operands[1], Pmode))
17945 return "call\t%P1";
17946 return "call\t%A1";
17948 [(set_attr "type" "callv")])
17950 (define_insn "*sibcall_value_1"
17951 [(set (match_operand 0 "" "")
17952 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17953 (match_operand:SI 2 "" "")))]
17954 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17958 [(set_attr "type" "callv")])
17960 (define_insn "*call_value_1_rex64"
17961 [(set (match_operand 0 "" "")
17962 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17963 (match_operand:DI 2 "" "")))]
17964 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17965 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17967 if (constant_call_address_operand (operands[1], Pmode))
17968 return "call\t%P1";
17969 return "call\t%A1";
17971 [(set_attr "type" "callv")])
17973 (define_insn "*call_value_1_rex64_ms_sysv"
17974 [(set (match_operand 0 "" "")
17975 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17976 (match_operand:DI 2 "" "")))
17977 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17978 (clobber (reg:TI XMM6_REG))
17979 (clobber (reg:TI XMM7_REG))
17980 (clobber (reg:TI XMM8_REG))
17981 (clobber (reg:TI XMM9_REG))
17982 (clobber (reg:TI XMM10_REG))
17983 (clobber (reg:TI XMM11_REG))
17984 (clobber (reg:TI XMM12_REG))
17985 (clobber (reg:TI XMM13_REG))
17986 (clobber (reg:TI XMM14_REG))
17987 (clobber (reg:TI XMM15_REG))
17988 (clobber (reg:DI SI_REG))
17989 (clobber (reg:DI DI_REG))]
17990 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17992 if (constant_call_address_operand (operands[1], Pmode))
17993 return "call\t%P1";
17994 return "call\t%A1";
17996 [(set_attr "type" "callv")])
17998 (define_insn "*call_value_1_rex64_large"
17999 [(set (match_operand 0 "" "")
18000 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
18001 (match_operand:DI 2 "" "")))]
18002 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18004 [(set_attr "type" "callv")])
18006 (define_insn "*sibcall_value_1_rex64"
18007 [(set (match_operand 0 "" "")
18008 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
18009 (match_operand:DI 2 "" "")))]
18010 "TARGET_64BIT && SIBLING_CALL_P (insn)"
18014 [(set_attr "type" "callv")])
18016 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18017 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18018 ;; caught for use by garbage collectors and the like. Using an insn that
18019 ;; maps to SIGILL makes it more likely the program will rightfully die.
18020 ;; Keeping with tradition, "6" is in honor of #UD.
18021 (define_insn "trap"
18022 [(trap_if (const_int 1) (const_int 6))]
18024 { return ASM_SHORT "0x0b0f"; }
18025 [(set_attr "length" "2")])
18027 (define_expand "sse_prologue_save"
18028 [(parallel [(set (match_operand:BLK 0 "" "")
18029 (unspec:BLK [(reg:DI XMM0_REG)
18036 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18037 (clobber (reg:CC FLAGS_REG))
18038 (clobber (match_operand:DI 1 "register_operand" ""))
18039 (use (match_operand:DI 2 "immediate_operand" ""))
18040 (use (label_ref:DI (match_operand 3 "" "")))
18041 (clobber (match_operand:DI 4 "register_operand" ""))
18042 (use (match_dup 1))])]
18046 ;; Pre-reload version of prologue save. Until after prologue generation we don't know
18047 ;; what the size of save instruction will be.
18048 ;; Operand 0+operand 6 is the memory save area
18049 ;; Operand 1 is number of registers to save (will get overwritten to operand 5)
18050 ;; Operand 2 is number of non-vaargs SSE arguments
18051 ;; Operand 3 is label starting the save block
18052 ;; Operand 4 is used for temporary computation of jump address
18053 (define_insn "*sse_prologue_save_insn1"
18054 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18055 (match_operand:DI 6 "const_int_operand" "n")))
18056 (unspec:BLK [(reg:DI XMM0_REG)
18063 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18064 (clobber (reg:CC FLAGS_REG))
18065 (clobber (match_operand:DI 1 "register_operand" "=r"))
18066 (use (match_operand:DI 2 "const_int_operand" "i"))
18067 (use (label_ref:DI (match_operand 3 "" "X")))
18068 (clobber (match_operand:DI 4 "register_operand" "=&r"))
18069 (use (match_operand:DI 5 "register_operand" "1"))]
18071 && INTVAL (operands[6]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18072 && INTVAL (operands[6]) + INTVAL (operands[2]) * 16 >= -128"
18074 [(set_attr "type" "other")
18075 (set_attr "memory" "store")
18076 (set_attr "mode" "DI")])
18078 ;; We know size of save instruction; expand the computation of jump address
18079 ;; in the jumptable.
18081 [(parallel [(set (match_operand:BLK 0 "" "")
18082 (unspec:BLK [(reg:DI XMM0_REG)
18089 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18090 (clobber (reg:CC FLAGS_REG))
18091 (clobber (match_operand:DI 1 "register_operand" ""))
18092 (use (match_operand:DI 2 "const_int_operand" ""))
18093 (use (match_operand 3 "" ""))
18094 (clobber (match_operand:DI 4 "register_operand" ""))
18095 (use (match_operand:DI 5 "register_operand" ""))])]
18097 [(parallel [(set (match_dup 0)
18098 (unspec:BLK [(reg:DI XMM0_REG)
18105 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
18106 (use (match_dup 1))
18107 (use (match_dup 2))
18108 (use (match_dup 3))
18109 (use (match_dup 5))])]
18111 /* Movaps is 4 bytes, AVX and movsd is 5 bytes. */
18112 int size = 4 + (TARGET_AVX || crtl->stack_alignment_needed < 128);
18114 /* Compute address to jump to:
18115 label - eax*size + nnamed_sse_arguments*size. */
18117 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
18120 gen_rtx_MULT (Pmode, operands[1],
18123 else if (size == 4)
18124 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
18125 gen_rtx_MULT (Pmode, operands[1],
18128 gcc_unreachable ();
18129 if (INTVAL (operands[2]))
18132 gen_rtx_CONST (DImode,
18133 gen_rtx_PLUS (DImode,
18135 GEN_INT (INTVAL (operands[2])
18138 emit_move_insn (operands[1], operands[3]);
18139 emit_insn (gen_subdi3 (operands[1], operands[1], operands[4]));
18140 operands[5] = GEN_INT (size);
18143 (define_insn "sse_prologue_save_insn"
18144 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18145 (match_operand:DI 4 "const_int_operand" "n")))
18146 (unspec:BLK [(reg:DI XMM0_REG)
18153 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
18154 (use (match_operand:DI 1 "register_operand" "r"))
18155 (use (match_operand:DI 2 "const_int_operand" "i"))
18156 (use (label_ref:DI (match_operand 3 "" "X")))
18157 (use (match_operand:DI 5 "const_int_operand" "i"))]
18159 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18160 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
18163 operands[0] = gen_rtx_MEM (Pmode,
18164 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
18165 /* VEX instruction with a REX prefix will #UD. */
18166 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
18167 gcc_unreachable ();
18169 output_asm_insn ("jmp\t%A1", operands);
18170 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
18172 operands[4] = adjust_address (operands[0], DImode, i*16);
18173 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
18174 PUT_MODE (operands[4], TImode);
18175 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
18176 output_asm_insn ("rex", operands);
18177 if (crtl->stack_alignment_needed < 128)
18178 output_asm_insn ("%vmovsd\t{%5, %4|%4, %5}", operands);
18180 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
18182 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18183 CODE_LABEL_NUMBER (operands[3]));
18186 [(set_attr "type" "other")
18187 (set_attr "length_immediate" "0")
18188 (set_attr "length_address" "0")
18189 ;; 2 bytes for jump and opernds[4] bytes for each save.
18190 (set (attr "length")
18191 (plus (const_int 2)
18192 (mult (symbol_ref ("INTVAL (operands[5])"))
18193 (symbol_ref ("X86_64_SSE_REGPARM_MAX - INTVAL (operands[2])")))))
18194 (set_attr "memory" "store")
18195 (set_attr "modrm" "0")
18196 (set_attr "prefix" "maybe_vex")
18197 (set_attr "mode" "DI")])
18199 (define_expand "prefetch"
18200 [(prefetch (match_operand 0 "address_operand" "")
18201 (match_operand:SI 1 "const_int_operand" "")
18202 (match_operand:SI 2 "const_int_operand" ""))]
18203 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
18205 int rw = INTVAL (operands[1]);
18206 int locality = INTVAL (operands[2]);
18208 gcc_assert (rw == 0 || rw == 1);
18209 gcc_assert (locality >= 0 && locality <= 3);
18210 gcc_assert (GET_MODE (operands[0]) == Pmode
18211 || GET_MODE (operands[0]) == VOIDmode);
18213 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18214 supported by SSE counterpart or the SSE prefetch is not available
18215 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18217 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
18218 operands[2] = GEN_INT (3);
18220 operands[1] = const0_rtx;
18223 (define_insn "*prefetch_sse"
18224 [(prefetch (match_operand:SI 0 "address_operand" "p")
18226 (match_operand:SI 1 "const_int_operand" ""))]
18227 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
18229 static const char * const patterns[4] = {
18230 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18233 int locality = INTVAL (operands[1]);
18234 gcc_assert (locality >= 0 && locality <= 3);
18236 return patterns[locality];
18238 [(set_attr "type" "sse")
18239 (set_attr "atom_sse_attr" "prefetch")
18240 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18241 (set_attr "memory" "none")])
18243 (define_insn "*prefetch_sse_rex"
18244 [(prefetch (match_operand:DI 0 "address_operand" "p")
18246 (match_operand:SI 1 "const_int_operand" ""))]
18247 "TARGET_PREFETCH_SSE && TARGET_64BIT"
18249 static const char * const patterns[4] = {
18250 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18253 int locality = INTVAL (operands[1]);
18254 gcc_assert (locality >= 0 && locality <= 3);
18256 return patterns[locality];
18258 [(set_attr "type" "sse")
18259 (set_attr "atom_sse_attr" "prefetch")
18260 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18261 (set_attr "memory" "none")])
18263 (define_insn "*prefetch_3dnow"
18264 [(prefetch (match_operand:SI 0 "address_operand" "p")
18265 (match_operand:SI 1 "const_int_operand" "n")
18267 "TARGET_3DNOW && !TARGET_64BIT"
18269 if (INTVAL (operands[1]) == 0)
18270 return "prefetch\t%a0";
18272 return "prefetchw\t%a0";
18274 [(set_attr "type" "mmx")
18275 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18276 (set_attr "memory" "none")])
18278 (define_insn "*prefetch_3dnow_rex"
18279 [(prefetch (match_operand:DI 0 "address_operand" "p")
18280 (match_operand:SI 1 "const_int_operand" "n")
18282 "TARGET_3DNOW && TARGET_64BIT"
18284 if (INTVAL (operands[1]) == 0)
18285 return "prefetch\t%a0";
18287 return "prefetchw\t%a0";
18289 [(set_attr "type" "mmx")
18290 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18291 (set_attr "memory" "none")])
18293 (define_expand "stack_protect_set"
18294 [(match_operand 0 "memory_operand" "")
18295 (match_operand 1 "memory_operand" "")]
18298 #ifdef TARGET_THREAD_SSP_OFFSET
18300 emit_insn (gen_stack_tls_protect_set_di (operands[0],
18301 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18303 emit_insn (gen_stack_tls_protect_set_si (operands[0],
18304 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18307 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18309 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18314 (define_insn "stack_protect_set_si"
18315 [(set (match_operand:SI 0 "memory_operand" "=m")
18316 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18317 (set (match_scratch:SI 2 "=&r") (const_int 0))
18318 (clobber (reg:CC FLAGS_REG))]
18320 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18321 [(set_attr "type" "multi")])
18323 (define_insn "stack_protect_set_di"
18324 [(set (match_operand:DI 0 "memory_operand" "=m")
18325 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18326 (set (match_scratch:DI 2 "=&r") (const_int 0))
18327 (clobber (reg:CC FLAGS_REG))]
18329 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18330 [(set_attr "type" "multi")])
18332 (define_insn "stack_tls_protect_set_si"
18333 [(set (match_operand:SI 0 "memory_operand" "=m")
18334 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18335 (set (match_scratch:SI 2 "=&r") (const_int 0))
18336 (clobber (reg:CC FLAGS_REG))]
18338 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18339 [(set_attr "type" "multi")])
18341 (define_insn "stack_tls_protect_set_di"
18342 [(set (match_operand:DI 0 "memory_operand" "=m")
18343 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18344 (set (match_scratch:DI 2 "=&r") (const_int 0))
18345 (clobber (reg:CC FLAGS_REG))]
18348 /* The kernel uses a different segment register for performance reasons; a
18349 system call would not have to trash the userspace segment register,
18350 which would be expensive */
18351 if (ix86_cmodel != CM_KERNEL)
18352 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18354 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18356 [(set_attr "type" "multi")])
18358 (define_expand "stack_protect_test"
18359 [(match_operand 0 "memory_operand" "")
18360 (match_operand 1 "memory_operand" "")
18361 (match_operand 2 "" "")]
18364 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18366 #ifdef TARGET_THREAD_SSP_OFFSET
18368 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18369 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18371 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18372 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18375 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18377 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18380 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18381 flags, const0_rtx, operands[2]));
18385 (define_insn "stack_protect_test_si"
18386 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18387 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18388 (match_operand:SI 2 "memory_operand" "m")]
18390 (clobber (match_scratch:SI 3 "=&r"))]
18392 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18393 [(set_attr "type" "multi")])
18395 (define_insn "stack_protect_test_di"
18396 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18397 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18398 (match_operand:DI 2 "memory_operand" "m")]
18400 (clobber (match_scratch:DI 3 "=&r"))]
18402 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18403 [(set_attr "type" "multi")])
18405 (define_insn "stack_tls_protect_test_si"
18406 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18407 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18408 (match_operand:SI 2 "const_int_operand" "i")]
18409 UNSPEC_SP_TLS_TEST))
18410 (clobber (match_scratch:SI 3 "=r"))]
18412 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18413 [(set_attr "type" "multi")])
18415 (define_insn "stack_tls_protect_test_di"
18416 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18417 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18418 (match_operand:DI 2 "const_int_operand" "i")]
18419 UNSPEC_SP_TLS_TEST))
18420 (clobber (match_scratch:DI 3 "=r"))]
18423 /* The kernel uses a different segment register for performance reasons; a
18424 system call would not have to trash the userspace segment register,
18425 which would be expensive */
18426 if (ix86_cmodel != CM_KERNEL)
18427 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18429 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18431 [(set_attr "type" "multi")])
18433 (define_insn "sse4_2_crc32<mode>"
18434 [(set (match_operand:SI 0 "register_operand" "=r")
18436 [(match_operand:SI 1 "register_operand" "0")
18437 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18439 "TARGET_SSE4_2 || TARGET_CRC32"
18440 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18441 [(set_attr "type" "sselog1")
18442 (set_attr "prefix_rep" "1")
18443 (set_attr "prefix_extra" "1")
18444 (set (attr "prefix_data16")
18445 (if_then_else (match_operand:HI 2 "" "")
18447 (const_string "*")))
18448 (set (attr "prefix_rex")
18449 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18451 (const_string "*")))
18452 (set_attr "mode" "SI")])
18454 (define_insn "sse4_2_crc32di"
18455 [(set (match_operand:DI 0 "register_operand" "=r")
18457 [(match_operand:DI 1 "register_operand" "0")
18458 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18460 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18461 "crc32{q}\t{%2, %0|%0, %2}"
18462 [(set_attr "type" "sselog1")
18463 (set_attr "prefix_rep" "1")
18464 (set_attr "prefix_extra" "1")
18465 (set_attr "mode" "DI")])
18467 (define_expand "rdpmc"
18468 [(match_operand:DI 0 "register_operand" "")
18469 (match_operand:SI 1 "register_operand" "")]
18472 rtx reg = gen_reg_rtx (DImode);
18475 /* Force operand 1 into ECX. */
18476 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18477 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18478 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18483 rtvec vec = rtvec_alloc (2);
18484 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18485 rtx upper = gen_reg_rtx (DImode);
18486 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18487 gen_rtvec (1, const0_rtx),
18489 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18490 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18492 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18493 NULL, 1, OPTAB_DIRECT);
18494 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18498 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18499 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18503 (define_insn "*rdpmc"
18504 [(set (match_operand:DI 0 "register_operand" "=A")
18505 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18509 [(set_attr "type" "other")
18510 (set_attr "length" "2")])
18512 (define_insn "*rdpmc_rex64"
18513 [(set (match_operand:DI 0 "register_operand" "=a")
18514 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18516 (set (match_operand:DI 1 "register_operand" "=d")
18517 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18520 [(set_attr "type" "other")
18521 (set_attr "length" "2")])
18523 (define_expand "rdtsc"
18524 [(set (match_operand:DI 0 "register_operand" "")
18525 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18530 rtvec vec = rtvec_alloc (2);
18531 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18532 rtx upper = gen_reg_rtx (DImode);
18533 rtx lower = gen_reg_rtx (DImode);
18534 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18535 gen_rtvec (1, const0_rtx),
18537 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18538 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18540 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18541 NULL, 1, OPTAB_DIRECT);
18542 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18544 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18549 (define_insn "*rdtsc"
18550 [(set (match_operand:DI 0 "register_operand" "=A")
18551 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18554 [(set_attr "type" "other")
18555 (set_attr "length" "2")])
18557 (define_insn "*rdtsc_rex64"
18558 [(set (match_operand:DI 0 "register_operand" "=a")
18559 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18560 (set (match_operand:DI 1 "register_operand" "=d")
18561 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18564 [(set_attr "type" "other")
18565 (set_attr "length" "2")])
18567 (define_expand "rdtscp"
18568 [(match_operand:DI 0 "register_operand" "")
18569 (match_operand:SI 1 "memory_operand" "")]
18572 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18573 gen_rtvec (1, const0_rtx),
18575 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18576 gen_rtvec (1, const0_rtx),
18578 rtx reg = gen_reg_rtx (DImode);
18579 rtx tmp = gen_reg_rtx (SImode);
18583 rtvec vec = rtvec_alloc (3);
18584 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18585 rtx upper = gen_reg_rtx (DImode);
18586 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18587 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18588 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18590 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18591 NULL, 1, OPTAB_DIRECT);
18592 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18597 rtvec vec = rtvec_alloc (2);
18598 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18599 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18600 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18603 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18604 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18608 (define_insn "*rdtscp"
18609 [(set (match_operand:DI 0 "register_operand" "=A")
18610 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18611 (set (match_operand:SI 1 "register_operand" "=c")
18612 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18615 [(set_attr "type" "other")
18616 (set_attr "length" "3")])
18618 (define_insn "*rdtscp_rex64"
18619 [(set (match_operand:DI 0 "register_operand" "=a")
18620 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18621 (set (match_operand:DI 1 "register_operand" "=d")
18622 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18623 (set (match_operand:SI 2 "register_operand" "=c")
18624 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18627 [(set_attr "type" "other")
18628 (set_attr "length" "3")])
18630 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18632 ;; LWP instructions
18634 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18636 (define_expand "lwp_llwpcb"
18637 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18638 UNSPECV_LLWP_INTRINSIC)]
18642 (define_insn "*lwp_llwpcb<mode>1"
18643 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18644 UNSPECV_LLWP_INTRINSIC)]
18647 [(set_attr "type" "lwp")
18648 (set_attr "mode" "<MODE>")
18649 (set_attr "length" "5")])
18651 (define_expand "lwp_slwpcb"
18652 [(set (match_operand 0 "register_operand" "=r")
18653 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18657 emit_insn (gen_lwp_slwpcbdi (operands[0]));
18659 emit_insn (gen_lwp_slwpcbsi (operands[0]));
18663 (define_insn "lwp_slwpcb<mode>"
18664 [(set (match_operand:P 0 "register_operand" "=r")
18665 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18668 [(set_attr "type" "lwp")
18669 (set_attr "mode" "<MODE>")
18670 (set_attr "length" "5")])
18672 (define_expand "lwp_lwpval<mode>3"
18673 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18674 (match_operand:SI 2 "nonimmediate_operand" "rm")
18675 (match_operand:SI 3 "const_int_operand" "i")]
18676 UNSPECV_LWPVAL_INTRINSIC)]
18678 "/* Avoid unused variable warning. */
18681 (define_insn "*lwp_lwpval<mode>3_1"
18682 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18683 (match_operand:SI 1 "nonimmediate_operand" "rm")
18684 (match_operand:SI 2 "const_int_operand" "i")]
18685 UNSPECV_LWPVAL_INTRINSIC)]
18687 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18688 [(set_attr "type" "lwp")
18689 (set_attr "mode" "<MODE>")
18690 (set (attr "length")
18691 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18693 (define_expand "lwp_lwpins<mode>3"
18694 [(set (reg:CCC FLAGS_REG)
18695 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18696 (match_operand:SI 2 "nonimmediate_operand" "rm")
18697 (match_operand:SI 3 "const_int_operand" "i")]
18698 UNSPECV_LWPINS_INTRINSIC))
18699 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18700 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18704 (define_insn "*lwp_lwpins<mode>3_1"
18705 [(set (reg:CCC FLAGS_REG)
18706 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18707 (match_operand:SI 1 "nonimmediate_operand" "rm")
18708 (match_operand:SI 2 "const_int_operand" "i")]
18709 UNSPECV_LWPINS_INTRINSIC))]
18711 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18712 [(set_attr "type" "lwp")
18713 (set_attr "mode" "<MODE>")
18714 (set (attr "length")
18715 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18719 (include "sync.md")